diff options
371 files changed, 3825 insertions, 2001 deletions
diff --git a/Documentation/ABI/testing/sysfs-ata b/Documentation/ABI/testing/sysfs-ata index aa4296498859..9ab0ef1dd1c7 100644 --- a/Documentation/ABI/testing/sysfs-ata +++ b/Documentation/ABI/testing/sysfs-ata | |||
| @@ -1,110 +1,139 @@ | |||
| 1 | What: /sys/class/ata_... | 1 | What: /sys/class/ata_... |
| 2 | Date: August 2008 | ||
| 3 | Contact: Gwendal Grignou<gwendal@google.com> | ||
| 4 | Description: | 2 | Description: |
| 5 | 3 | Provide a place in sysfs for storing the ATA topology of the | |
| 6 | Provide a place in sysfs for storing the ATA topology of the system. This allows | 4 | system. This allows retrieving various information about ATA |
| 7 | retrieving various information about ATA objects. | 5 | objects. |
| 8 | 6 | ||
| 9 | Files under /sys/class/ata_port | 7 | Files under /sys/class/ata_port |
| 10 | ------------------------------- | 8 | ------------------------------- |
| 11 | 9 | ||
| 12 | For each port, a directory ataX is created where X is the ata_port_id of | 10 | For each port, a directory ataX is created where X is the ata_port_id of the |
| 13 | the port. The device parent is the ata host device. | 11 | port. The device parent is the ata host device. |
| 14 | 12 | ||
| 15 | idle_irq (read) | ||
| 16 | 13 | ||
| 17 | Number of IRQ received by the port while idle [some ata HBA only]. | 14 | What: /sys/class/ata_port/ataX/nr_pmp_links |
| 15 | What: /sys/class/ata_port/ataX/idle_irq | ||
| 16 | Date: May, 2010 | ||
| 17 | KernelVersion: v2.6.37 | ||
| 18 | Contact: Gwendal Grignou <gwendal@chromium.org> | ||
| 19 | Description: | ||
| 20 | nr_pmp_links: (RO) If a SATA Port Multiplier (PM) is | ||
| 21 | connected, the number of links behind it. | ||
| 18 | 22 | ||
| 19 | nr_pmp_links (read) | 23 | idle_irq: (RO) Number of IRQ received by the port while |
| 24 | idle [some ata HBA only]. | ||
| 20 | 25 | ||
| 21 | If a SATA Port Multiplier (PM) is connected, number of link behind it. | 26 | |
| 27 | What: /sys/class/ata_port/ataX/port_no | ||
| 28 | Date: May, 2013 | ||
| 29 | KernelVersion: v3.11 | ||
| 30 | Contact: Gwendal Grignou <gwendal@chromium.org> | ||
| 31 | Description: | ||
| 32 | (RO) Host local port number. While registering host controller, | ||
| 33 | port numbers are tracked based upon number of ports available on | ||
| 34 | the controller. This attribute is needed by udev for composing | ||
| 35 | persistent links in /dev/disk/by-path. | ||
| 22 | 36 | ||
| 23 | Files under /sys/class/ata_link | 37 | Files under /sys/class/ata_link |
| 24 | ------------------------------- | 38 | ------------------------------- |
| 25 | 39 | ||
| 26 | Behind each port, there is a ata_link. If there is a SATA PM in the | 40 | Behind each port, there is a ata_link. If there is a SATA PM in the topology, 15 |
| 27 | topology, 15 ata_link objects are created. | 41 | ata_link objects are created. |
| 28 | |||
| 29 | If a link is behind a port, the directory name is linkX, where X is | ||
| 30 | ata_port_id of the port. | ||
| 31 | If a link is behind a PM, its name is linkX.Y where X is ata_port_id | ||
| 32 | of the parent port and Y the PM port. | ||
| 33 | 42 | ||
| 34 | hw_sata_spd_limit | 43 | If a link is behind a port, the directory name is linkX, where X is ata_port_id |
| 44 | of the port. If a link is behind a PM, its name is linkX.Y where X is | ||
| 45 | ata_port_id of the parent port and Y the PM port. | ||
| 35 | 46 | ||
| 36 | Maximum speed supported by the connected SATA device. | ||
| 37 | 47 | ||
| 38 | sata_spd_limit | 48 | What: /sys/class/ata_link/linkX[.Y]/hw_sata_spd_limit |
| 49 | What: /sys/class/ata_link/linkX[.Y]/sata_spd_limit | ||
| 50 | What: /sys/class/ata_link/linkX[.Y]/sata_spd | ||
| 51 | Date: May, 2010 | ||
| 52 | KernelVersion: v2.6.37 | ||
| 53 | Contact: Gwendal Grignou <gwendal@chromium.org> | ||
| 54 | Description: | ||
| 55 | hw_sata_spd_limit: (RO) Maximum speed supported by the | ||
| 56 | connected SATA device. | ||
| 39 | 57 | ||
| 40 | Maximum speed imposed by libata. | 58 | sata_spd_limit: (RO) Maximum speed imposed by libata. |
| 41 | 59 | ||
| 42 | sata_spd | 60 | sata_spd: (RO) Current speed of the link |
| 61 | eg. 1.5, 3 Gbps etc. | ||
| 43 | 62 | ||
| 44 | Current speed of the link [1.5, 3Gps,...]. | ||
| 45 | 63 | ||
| 46 | Files under /sys/class/ata_device | 64 | Files under /sys/class/ata_device |
| 47 | --------------------------------- | 65 | --------------------------------- |
| 48 | 66 | ||
| 49 | Behind each link, up to two ata device are created. | 67 | Behind each link, up to two ata devices are created. |
| 50 | The name of the directory is devX[.Y].Z where: | 68 | The name of the directory is devX[.Y].Z where: |
| 51 | - X is ata_port_id of the port where the device is connected, | 69 | - X is ata_port_id of the port where the device is connected, |
| 52 | - Y the port of the PM if any, and | 70 | - Y the port of the PM if any, and |
| 53 | - Z the device id: for PATA, there is usually 2 devices [0,1], | 71 | - Z the device id: for PATA, there is usually 2 devices [0,1], only 1 for SATA. |
| 54 | only 1 for SATA. | 72 | |
| 55 | 73 | ||
| 56 | class | 74 | What: /sys/class/ata_device/devX[.Y].Z/spdn_cnt |
| 57 | Device class. Can be "ata" for disk, "atapi" for packet device, | 75 | What: /sys/class/ata_device/devX[.Y].Z/gscr |
| 58 | "pmp" for PM, or "none" if no device was found behind the link. | 76 | What: /sys/class/ata_device/devX[.Y].Z/ering |
| 59 | 77 | What: /sys/class/ata_device/devX[.Y].Z/id | |
| 60 | dma_mode | 78 | What: /sys/class/ata_device/devX[.Y].Z/pio_mode |
| 79 | What: /sys/class/ata_device/devX[.Y].Z/xfer_mode | ||
| 80 | What: /sys/class/ata_device/devX[.Y].Z/dma_mode | ||
| 81 | What: /sys/class/ata_device/devX[.Y].Z/class | ||
| 82 | Date: May, 2010 | ||
| 83 | KernelVersion: v2.6.37 | ||
| 84 | Contact: Gwendal Grignou <gwendal@chromium.org> | ||
| 85 | Description: | ||
| 86 | spdn_cnt: (RO) Number of times libata decided to lower the | ||
| 87 | speed of link due to errors. | ||
| 61 | 88 | ||
| 62 | Transfer modes supported by the device when in DMA mode. | 89 | gscr: (RO) Cached result of the dump of PM GSCR |
| 63 | Mostly used by PATA device. | 90 | register. Valid registers are: |
| 64 | 91 | ||
| 65 | pio_mode | 92 | 0: SATA_PMP_GSCR_PROD_ID, |
| 93 | 1: SATA_PMP_GSCR_REV, | ||
| 94 | 2: SATA_PMP_GSCR_PORT_INFO, | ||
| 95 | 32: SATA_PMP_GSCR_ERROR, | ||
| 96 | 33: SATA_PMP_GSCR_ERROR_EN, | ||
| 97 | 64: SATA_PMP_GSCR_FEAT, | ||
| 98 | 96: SATA_PMP_GSCR_FEAT_EN, | ||
| 99 | 130: SATA_PMP_GSCR_SII_GPIO | ||
| 66 | 100 | ||
| 67 | Transfer modes supported by the device when in PIO mode. | 101 | Only valid if the device is a PM. |
| 68 | Mostly used by PATA device. | ||
| 69 | 102 | ||
| 70 | xfer_mode | 103 | ering: (RO) Formatted output of the error ring of the |
| 104 | device. | ||
| 71 | 105 | ||
| 72 | Current transfer mode. | 106 | id: (RO) Cached result of IDENTIFY command, as |
| 107 | described in ATA8 7.16 and 7.17. Only valid if | ||
| 108 | the device is not a PM. | ||
| 73 | 109 | ||
| 74 | id | 110 | pio_mode: (RO) Transfer modes supported by the device when |
| 111 | in PIO mode. Mostly used by PATA device. | ||
| 75 | 112 | ||
| 76 | Cached result of IDENTIFY command, as described in ATA8 7.16 and 7.17. | 113 | xfer_mode: (RO) Current transfer mode |
| 77 | Only valid if the device is not a PM. | ||
| 78 | 114 | ||
| 79 | gscr | 115 | dma_mode: (RO) Transfer modes supported by the device when |
| 116 | in DMA mode. Mostly used by PATA device. | ||
| 80 | 117 | ||
| 81 | Cached result of the dump of PM GSCR register. | 118 | class: (RO) Device class. Can be "ata" for disk, |
| 82 | Valid registers are: | 119 | "atapi" for packet device, "pmp" for PM, or |
| 83 | 0: SATA_PMP_GSCR_PROD_ID, | 120 | "none" if no device was found behind the link. |
| 84 | 1: SATA_PMP_GSCR_REV, | ||
| 85 | 2: SATA_PMP_GSCR_PORT_INFO, | ||
| 86 | 32: SATA_PMP_GSCR_ERROR, | ||
| 87 | 33: SATA_PMP_GSCR_ERROR_EN, | ||
| 88 | 64: SATA_PMP_GSCR_FEAT, | ||
| 89 | 96: SATA_PMP_GSCR_FEAT_EN, | ||
| 90 | 130: SATA_PMP_GSCR_SII_GPIO | ||
| 91 | Only valid if the device is a PM. | ||
| 92 | 121 | ||
| 93 | trim | ||
| 94 | 122 | ||
| 95 | Shows the DSM TRIM mode currently used by the device. Valid | 123 | What: /sys/class/ata_device/devX[.Y].Z/trim |
| 96 | values are: | 124 | Date: May, 2015 |
| 97 | unsupported: Drive does not support DSM TRIM | 125 | KernelVersion: v4.10 |
| 98 | unqueued: Drive supports unqueued DSM TRIM only | 126 | Contact: Gwendal Grignou <gwendal@chromium.org> |
| 99 | queued: Drive supports queued DSM TRIM | 127 | Description: |
| 100 | forced_unqueued: Drive's queued DSM support is known to be | 128 | (RO) Shows the DSM TRIM mode currently used by the device. Valid |
| 101 | buggy and only unqueued TRIM commands | 129 | values are: |
| 102 | are sent | ||
| 103 | 130 | ||
| 104 | spdn_cnt | 131 | unsupported: Drive does not support DSM TRIM |
| 105 | 132 | ||
| 106 | Number of time libata decided to lower the speed of link due to errors. | 133 | unqueued: Drive supports unqueued DSM TRIM only |
| 107 | 134 | ||
| 108 | ering | 135 | queued: Drive supports queued DSM TRIM |
| 109 | 136 | ||
| 110 | Formatted output of the error ring of the device. | 137 | forced_unqueued: Drive's queued DSM support is known to |
| 138 | be buggy and only unqueued TRIM commands | ||
| 139 | are sent | ||
diff --git a/Documentation/ABI/testing/sysfs-block-device b/Documentation/ABI/testing/sysfs-block-device new file mode 100644 index 000000000000..82ef6eab042d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-block-device | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | What: /sys/block/*/device/sw_activity | ||
| 2 | Date: Jun, 2008 | ||
| 3 | KernelVersion: v2.6.27 | ||
| 4 | Contact: linux-ide@vger.kernel.org | ||
| 5 | Description: | ||
| 6 | (RW) Used by drivers which support software controlled activity | ||
| 7 | LEDs. | ||
| 8 | |||
| 9 | It has the following valid values: | ||
| 10 | |||
| 11 | 0 OFF - the LED is not activated on activity | ||
| 12 | 1 BLINK_ON - the LED blinks on every 10ms when activity is | ||
| 13 | detected. | ||
| 14 | 2 BLINK_OFF - the LED is on when idle, and blinks off | ||
| 15 | every 10ms when activity is detected. | ||
| 16 | |||
| 17 | Note that the user must turn sw_activity OFF it they wish to | ||
| 18 | control the activity LED via the em_message file. | ||
| 19 | |||
| 20 | |||
| 21 | What: /sys/block/*/device/unload_heads | ||
| 22 | Date: Sep, 2008 | ||
| 23 | KernelVersion: v2.6.28 | ||
| 24 | Contact: linux-ide@vger.kernel.org | ||
| 25 | Description: | ||
| 26 | (RW) Hard disk shock protection | ||
| 27 | |||
| 28 | Writing an integer value to this file will take the heads of the | ||
| 29 | respective drive off the platter and block all I/O operations | ||
| 30 | for the specified number of milliseconds. | ||
| 31 | |||
| 32 | - If the device does not support the unload heads feature, | ||
| 33 | access is denied with -EOPNOTSUPP. | ||
| 34 | - The maximal value accepted for a timeout is 30000 | ||
| 35 | milliseconds. | ||
| 36 | - A previously set timeout can be cancelled and disk can resume | ||
| 37 | normal operation immediately by specifying a timeout of 0. | ||
| 38 | - Some hard drives only comply with an earlier version of the | ||
| 39 | ATA standard, but support the unload feature nonetheless. | ||
| 40 | There is no safe way Linux can detect these devices, so this | ||
| 41 | is not enabled by default. If it is known that your device | ||
| 42 | does support the unload feature, then you can tell the kernel | ||
| 43 | to enable it by writing -1. It can be disabled again by | ||
| 44 | writing -2. | ||
| 45 | - Values below -2 are rejected with -EINVAL | ||
| 46 | |||
| 47 | For more information, see | ||
| 48 | Documentation/laptops/disk-shock-protection.txt | ||
| 49 | |||
| 50 | |||
| 51 | What: /sys/block/*/device/ncq_prio_enable | ||
| 52 | Date: Oct, 2016 | ||
| 53 | KernelVersion: v4.10 | ||
| 54 | Contact: linux-ide@vger.kernel.org | ||
| 55 | Description: | ||
| 56 | (RW) Write to the file to turn on or off the SATA ncq (native | ||
| 57 | command queueing) support. By default this feature is turned | ||
| 58 | off. | ||
diff --git a/Documentation/ABI/testing/sysfs-class-scsi_host b/Documentation/ABI/testing/sysfs-class-scsi_host index 0eb255e7db12..bafc59fd7b69 100644 --- a/Documentation/ABI/testing/sysfs-class-scsi_host +++ b/Documentation/ABI/testing/sysfs-class-scsi_host | |||
| @@ -27,3 +27,92 @@ Description: This file contains the current status of the "SSD Smart Path" | |||
| 27 | the direct i/o path to physical devices. This setting is | 27 | the direct i/o path to physical devices. This setting is |
| 28 | controller wide, affecting all configured logical drives on the | 28 | controller wide, affecting all configured logical drives on the |
| 29 | controller. This file is readable and writable. | 29 | controller. This file is readable and writable. |
| 30 | |||
| 31 | What: /sys/class/scsi_host/hostX/link_power_management_policy | ||
| 32 | Date: Oct, 2007 | ||
| 33 | KernelVersion: v2.6.24 | ||
| 34 | Contact: linux-ide@vger.kernel.org | ||
| 35 | Description: | ||
| 36 | (RW) This parameter allows the user to read and set the link | ||
| 37 | (interface) power management. | ||
| 38 | |||
| 39 | There are four possible options: | ||
| 40 | |||
| 41 | min_power: Tell the controller to try to make the link use the | ||
| 42 | least possible power when possible. This may sacrifice some | ||
| 43 | performance due to increased latency when coming out of lower | ||
| 44 | power states. | ||
| 45 | |||
| 46 | max_performance: Generally, this means no power management. | ||
| 47 | Tell the controller to have performance be a priority over power | ||
| 48 | management. | ||
| 49 | |||
| 50 | medium_power: Tell the controller to enter a lower power state | ||
| 51 | when possible, but do not enter the lowest power state, thus | ||
| 52 | improving latency over min_power setting. | ||
| 53 | |||
| 54 | med_power_with_dipm: Identical to the existing medium_power | ||
| 55 | setting except that it enables dipm (device initiated power | ||
| 56 | management) on top, which makes it match the Windows IRST (Intel | ||
| 57 | Rapid Storage Technology) driver settings. This setting is also | ||
| 58 | close to min_power, except that: | ||
| 59 | a) It does not use host-initiated slumber mode, but it does | ||
| 60 | allow device-initiated slumber | ||
| 61 | b) It does not enable low power device sleep mode (DevSlp). | ||
| 62 | |||
| 63 | What: /sys/class/scsi_host/hostX/em_message | ||
| 64 | What: /sys/class/scsi_host/hostX/em_message_type | ||
| 65 | Date: Jun, 2008 | ||
| 66 | KernelVersion: v2.6.27 | ||
| 67 | Contact: linux-ide@vger.kernel.org | ||
| 68 | Description: | ||
| 69 | em_message: (RW) Enclosure management support. For the LED | ||
| 70 | protocol, writes and reads correspond to the LED message format | ||
| 71 | as defined in the AHCI spec. | ||
| 72 | |||
| 73 | The user must turn sw_activity (under /sys/block/*/device/) OFF | ||
| 74 | it they wish to control the activity LED via the em_message | ||
| 75 | file. | ||
| 76 | |||
| 77 | em_message_type: (RO) Displays the current enclosure management | ||
| 78 | protocol that is being used by the driver (for eg. LED, SAF-TE, | ||
| 79 | SES-2, SGPIO etc). | ||
| 80 | |||
| 81 | What: /sys/class/scsi_host/hostX/ahci_port_cmd | ||
| 82 | What: /sys/class/scsi_host/hostX/ahci_host_caps | ||
| 83 | What: /sys/class/scsi_host/hostX/ahci_host_cap2 | ||
| 84 | Date: Mar, 2010 | ||
| 85 | KernelVersion: v2.6.35 | ||
| 86 | Contact: linux-ide@vger.kernel.org | ||
| 87 | Description: | ||
| 88 | [to be documented] | ||
| 89 | |||
| 90 | What: /sys/class/scsi_host/hostX/ahci_host_version | ||
| 91 | Date: Mar, 2010 | ||
| 92 | KernelVersion: v2.6.35 | ||
| 93 | Contact: linux-ide@vger.kernel.org | ||
| 94 | Description: | ||
| 95 | (RO) Display the version of the AHCI spec implemented by the | ||
| 96 | host. | ||
| 97 | |||
| 98 | What: /sys/class/scsi_host/hostX/em_buffer | ||
| 99 | Date: Apr, 2010 | ||
| 100 | KernelVersion: v2.6.35 | ||
| 101 | Contact: linux-ide@vger.kernel.org | ||
| 102 | Description: | ||
| 103 | (RW) Allows access to AHCI EM (enclosure management) buffer | ||
| 104 | directly if the host supports EM. | ||
| 105 | |||
| 106 | For eg. the AHCI driver supports SGPIO EM messages but the | ||
| 107 | SATA/AHCI specs do not define the SGPIO message format of the EM | ||
| 108 | buffer. Different hardware(HW) vendors may have different | ||
| 109 | definitions. With the em_buffer attribute, this issue can be | ||
| 110 | solved by allowing HW vendors to provide userland drivers and | ||
| 111 | tools for their SGPIO initiators. | ||
| 112 | |||
| 113 | What: /sys/class/scsi_host/hostX/em_message_supported | ||
| 114 | Date: Oct, 2009 | ||
| 115 | KernelVersion: v2.6.39 | ||
| 116 | Contact: linux-ide@vger.kernel.org | ||
| 117 | Description: | ||
| 118 | (RO) Displays supported enclosure management message types. | ||
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt index 6394ea9e3b9e..58b12e25bbb1 100644 --- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt +++ b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt | |||
| @@ -16,6 +16,7 @@ Required properties: | |||
| 16 | - ddc: phandle to the hdmi ddc node | 16 | - ddc: phandle to the hdmi ddc node |
| 17 | - phy: phandle to the hdmi phy node | 17 | - phy: phandle to the hdmi phy node |
| 18 | - samsung,syscon-phandle: phandle for system controller node for PMU. | 18 | - samsung,syscon-phandle: phandle for system controller node for PMU. |
| 19 | - #sound-dai-cells: should be 0. | ||
| 19 | 20 | ||
| 20 | Required properties for Exynos 4210, 4212, 5420 and 5433: | 21 | Required properties for Exynos 4210, 4212, 5420 and 5433: |
| 21 | - clocks: list of clock IDs from SoC clock driver. | 22 | - clocks: list of clock IDs from SoC clock driver. |
diff --git a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt index e9ebb8a20e0d..ba24ca7ba95e 100644 --- a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt +++ b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt | |||
| @@ -3,11 +3,11 @@ Device-Tree bindings for sigma delta modulator | |||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use | 4 | - compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use |
| 5 | as a generic SD modulator if modulator not specified in compatible list. | 5 | as a generic SD modulator if modulator not specified in compatible list. |
| 6 | - #io-channel-cells = <1>: See the IIO bindings section "IIO consumers". | 6 | - #io-channel-cells = <0>: See the IIO bindings section "IIO consumers". |
| 7 | 7 | ||
| 8 | Example node: | 8 | Example node: |
| 9 | 9 | ||
| 10 | ads1202: adc@0 { | 10 | ads1202: adc@0 { |
| 11 | compatible = "sd-modulator"; | 11 | compatible = "sd-modulator"; |
| 12 | #io-channel-cells = <1>; | 12 | #io-channel-cells = <0>; |
| 13 | }; | 13 | }; |
diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt index 1d4d0f49c9d0..8c033d48e2ba 100644 --- a/Documentation/devicetree/bindings/net/dsa/marvell.txt +++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt | |||
| @@ -50,14 +50,15 @@ Example: | |||
| 50 | compatible = "marvell,mv88e6085"; | 50 | compatible = "marvell,mv88e6085"; |
| 51 | reg = <0>; | 51 | reg = <0>; |
| 52 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; | 52 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; |
| 53 | }; | 53 | |
| 54 | mdio { | 54 | mdio { |
| 55 | #address-cells = <1>; | 55 | #address-cells = <1>; |
| 56 | #size-cells = <0>; | 56 | #size-cells = <0>; |
| 57 | switch1phy0: switch1phy0@0 { | 57 | switch1phy0: switch1phy0@0 { |
| 58 | reg = <0>; | 58 | reg = <0>; |
| 59 | interrupt-parent = <&switch0>; | 59 | interrupt-parent = <&switch0>; |
| 60 | interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; | 60 | interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; |
| 61 | }; | ||
| 61 | }; | 62 | }; |
| 62 | }; | 63 | }; |
| 63 | }; | 64 | }; |
| @@ -74,23 +75,24 @@ Example: | |||
| 74 | compatible = "marvell,mv88e6390"; | 75 | compatible = "marvell,mv88e6390"; |
| 75 | reg = <0>; | 76 | reg = <0>; |
| 76 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; | 77 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; |
| 77 | }; | 78 | |
| 78 | mdio { | 79 | mdio { |
| 79 | #address-cells = <1>; | 80 | #address-cells = <1>; |
| 80 | #size-cells = <0>; | 81 | #size-cells = <0>; |
| 81 | switch1phy0: switch1phy0@0 { | 82 | switch1phy0: switch1phy0@0 { |
| 82 | reg = <0>; | 83 | reg = <0>; |
| 83 | interrupt-parent = <&switch0>; | 84 | interrupt-parent = <&switch0>; |
| 84 | interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; | 85 | interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; |
| 86 | }; | ||
| 85 | }; | 87 | }; |
| 86 | }; | ||
| 87 | 88 | ||
| 88 | mdio1 { | 89 | mdio1 { |
| 89 | compatible = "marvell,mv88e6xxx-mdio-external"; | 90 | compatible = "marvell,mv88e6xxx-mdio-external"; |
| 90 | #address-cells = <1>; | 91 | #address-cells = <1>; |
| 91 | #size-cells = <0>; | 92 | #size-cells = <0>; |
| 92 | switch1phy9: switch1phy0@9 { | 93 | switch1phy9: switch1phy0@9 { |
| 93 | reg = <9>; | 94 | reg = <9>; |
| 95 | }; | ||
| 94 | }; | 96 | }; |
| 95 | }; | 97 | }; |
| 96 | }; | 98 | }; |
diff --git a/Documentation/devicetree/bindings/net/renesas,ravb.txt b/Documentation/devicetree/bindings/net/renesas,ravb.txt index 92fd4b2f17b2..b4dc455eb155 100644 --- a/Documentation/devicetree/bindings/net/renesas,ravb.txt +++ b/Documentation/devicetree/bindings/net/renesas,ravb.txt | |||
| @@ -27,7 +27,11 @@ Required properties: | |||
| 27 | SoC-specific version corresponding to the platform first followed by | 27 | SoC-specific version corresponding to the platform first followed by |
| 28 | the generic version. | 28 | the generic version. |
| 29 | 29 | ||
| 30 | - reg: offset and length of (1) the register block and (2) the stream buffer. | 30 | - reg: Offset and length of (1) the register block and (2) the stream buffer. |
| 31 | The region for the register block is mandatory. | ||
| 32 | The region for the stream buffer is optional, as it is only present on | ||
| 33 | R-Car Gen2 and RZ/G1 SoCs, and on R-Car H3 (R8A7795), M3-W (R8A7796), | ||
| 34 | and M3-N (R8A77965). | ||
| 31 | - interrupts: A list of interrupt-specifiers, one for each entry in | 35 | - interrupts: A list of interrupt-specifiers, one for each entry in |
| 32 | interrupt-names. | 36 | interrupt-names. |
| 33 | If interrupt-names is not present, an interrupt specifier | 37 | If interrupt-names is not present, an interrupt specifier |
diff --git a/Documentation/networking/segmentation-offloads.txt b/Documentation/networking/segmentation-offloads.txt index d47480b61ac6..aca542ec125c 100644 --- a/Documentation/networking/segmentation-offloads.txt +++ b/Documentation/networking/segmentation-offloads.txt | |||
| @@ -20,8 +20,8 @@ TCP Segmentation Offload | |||
| 20 | 20 | ||
| 21 | TCP segmentation allows a device to segment a single frame into multiple | 21 | TCP segmentation allows a device to segment a single frame into multiple |
| 22 | frames with a data payload size specified in skb_shinfo()->gso_size. | 22 | frames with a data payload size specified in skb_shinfo()->gso_size. |
| 23 | When TCP segmentation requested the bit for either SKB_GSO_TCP or | 23 | When TCP segmentation requested the bit for either SKB_GSO_TCPV4 or |
| 24 | SKB_GSO_TCP6 should be set in skb_shinfo()->gso_type and | 24 | SKB_GSO_TCPV6 should be set in skb_shinfo()->gso_type and |
| 25 | skb_shinfo()->gso_size should be set to a non-zero value. | 25 | skb_shinfo()->gso_size should be set to a non-zero value. |
| 26 | 26 | ||
| 27 | TCP segmentation is dependent on support for the use of partial checksum | 27 | TCP segmentation is dependent on support for the use of partial checksum |
| @@ -153,8 +153,18 @@ To signal this, gso_size is set to the special value GSO_BY_FRAGS. | |||
| 153 | 153 | ||
| 154 | Therefore, any code in the core networking stack must be aware of the | 154 | Therefore, any code in the core networking stack must be aware of the |
| 155 | possibility that gso_size will be GSO_BY_FRAGS and handle that case | 155 | possibility that gso_size will be GSO_BY_FRAGS and handle that case |
| 156 | appropriately. (For size checks, the skb_gso_validate_*_len family of | 156 | appropriately. |
| 157 | helpers do this automatically.) | 157 | |
| 158 | There are some helpers to make this easier: | ||
| 159 | |||
| 160 | - skb_is_gso(skb) && skb_is_gso_sctp(skb) is the best way to see if | ||
| 161 | an skb is an SCTP GSO skb. | ||
| 162 | |||
| 163 | - For size checks, the skb_gso_validate_*_len family of helpers correctly | ||
| 164 | considers GSO_BY_FRAGS. | ||
| 165 | |||
| 166 | - For manipulating packets, skb_increase_gso_size and skb_decrease_gso_size | ||
| 167 | will check for GSO_BY_FRAGS and WARN if asked to manipulate these skbs. | ||
| 158 | 168 | ||
| 159 | This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits | 169 | This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits |
| 160 | set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE. | 170 | set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE. |
diff --git a/MAINTAINERS b/MAINTAINERS index 205c8fc12a9c..73c0cdabf755 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -10334,7 +10334,7 @@ F: drivers/oprofile/ | |||
| 10334 | F: include/linux/oprofile.h | 10334 | F: include/linux/oprofile.h |
| 10335 | 10335 | ||
| 10336 | ORACLE CLUSTER FILESYSTEM 2 (OCFS2) | 10336 | ORACLE CLUSTER FILESYSTEM 2 (OCFS2) |
| 10337 | M: Mark Fasheh <mfasheh@versity.com> | 10337 | M: Mark Fasheh <mark@fasheh.com> |
| 10338 | M: Joel Becker <jlbec@evilplan.org> | 10338 | M: Joel Becker <jlbec@evilplan.org> |
| 10339 | L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers) | 10339 | L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers) |
| 10340 | W: http://ocfs2.wiki.kernel.org | 10340 | W: http://ocfs2.wiki.kernel.org |
| @@ -10844,6 +10844,7 @@ F: drivers/platform/x86/peaq-wmi.c | |||
| 10844 | PER-CPU MEMORY ALLOCATOR | 10844 | PER-CPU MEMORY ALLOCATOR |
| 10845 | M: Tejun Heo <tj@kernel.org> | 10845 | M: Tejun Heo <tj@kernel.org> |
| 10846 | M: Christoph Lameter <cl@linux.com> | 10846 | M: Christoph Lameter <cl@linux.com> |
| 10847 | M: Dennis Zhou <dennisszhou@gmail.com> | ||
| 10847 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git | 10848 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git |
| 10848 | S: Maintained | 10849 | S: Maintained |
| 10849 | F: include/linux/percpu*.h | 10850 | F: include/linux/percpu*.h |
| @@ -826,6 +826,15 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) | |||
| 826 | # disable invalid "can't wrap" optimizations for signed / pointers | 826 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 827 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) | 827 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
| 828 | 828 | ||
| 829 | # clang sets -fmerge-all-constants by default as optimization, but this | ||
| 830 | # is non-conforming behavior for C and in fact breaks the kernel, so we | ||
| 831 | # need to disable it here generally. | ||
| 832 | KBUILD_CFLAGS += $(call cc-option,-fno-merge-all-constants) | ||
| 833 | |||
| 834 | # for gcc -fno-merge-all-constants disables everything, but it is fine | ||
| 835 | # to have actual conforming behavior enabled. | ||
| 836 | KBUILD_CFLAGS += $(call cc-option,-fmerge-constants) | ||
| 837 | |||
| 829 | # Make sure -fstack-check isn't enabled (like gentoo apparently did) | 838 | # Make sure -fstack-check isn't enabled (like gentoo apparently did) |
| 830 | KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) | 839 | KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) |
| 831 | 840 | ||
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 8c704f1e53c2..2dbb2c9f1ec1 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
| @@ -972,3 +972,13 @@ int pmd_clear_huge(pmd_t *pmdp) | |||
| 972 | pmd_clear(pmdp); | 972 | pmd_clear(pmdp); |
| 973 | return 1; | 973 | return 1; |
| 974 | } | 974 | } |
| 975 | |||
| 976 | int pud_free_pmd_page(pud_t *pud) | ||
| 977 | { | ||
| 978 | return pud_none(*pud); | ||
| 979 | } | ||
| 980 | |||
| 981 | int pmd_free_pte_page(pmd_t *pmd) | ||
| 982 | { | ||
| 983 | return pmd_none(*pmd); | ||
| 984 | } | ||
diff --git a/arch/h8300/include/asm/byteorder.h b/arch/h8300/include/asm/byteorder.h index ecff2d1ca5a3..6eaa7ad5fc2c 100644 --- a/arch/h8300/include/asm/byteorder.h +++ b/arch/h8300/include/asm/byteorder.h | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #ifndef __H8300_BYTEORDER_H__ | 2 | #ifndef __H8300_BYTEORDER_H__ |
| 3 | #define __H8300_BYTEORDER_H__ | 3 | #define __H8300_BYTEORDER_H__ |
| 4 | 4 | ||
| 5 | #define __BIG_ENDIAN __ORDER_BIG_ENDIAN__ | ||
| 6 | #include <linux/byteorder/big_endian.h> | 5 | #include <linux/byteorder/big_endian.h> |
| 7 | 6 | ||
| 8 | #endif | 7 | #endif |
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 692ae85a3e3d..8e3a1fc2bc39 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig | |||
| @@ -13,6 +13,8 @@ choice | |||
| 13 | config SOC_AMAZON_SE | 13 | config SOC_AMAZON_SE |
| 14 | bool "Amazon SE" | 14 | bool "Amazon SE" |
| 15 | select SOC_TYPE_XWAY | 15 | select SOC_TYPE_XWAY |
| 16 | select MFD_SYSCON | ||
| 17 | select MFD_CORE | ||
| 16 | 18 | ||
| 17 | config SOC_XWAY | 19 | config SOC_XWAY |
| 18 | bool "XWAY" | 20 | bool "XWAY" |
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 52500d3b7004..e0af39b33e28 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c | |||
| @@ -549,9 +549,9 @@ void __init ltq_soc_init(void) | |||
| 549 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), | 549 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), |
| 550 | ltq_ar9_fpi_hz(), CLOCK_250M); | 550 | ltq_ar9_fpi_hz(), CLOCK_250M); |
| 551 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); | 551 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); |
| 552 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); | 552 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); |
| 553 | clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); | 553 | clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); |
| 554 | clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); | 554 | clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); |
| 555 | clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); | 555 | clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); |
| 556 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | 556 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); |
| 557 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | 557 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); |
| @@ -560,7 +560,7 @@ void __init ltq_soc_init(void) | |||
| 560 | } else { | 560 | } else { |
| 561 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), | 561 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), |
| 562 | ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); | 562 | ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); |
| 563 | clkdev_add_pmu("1f203018.usb2-phy", "ctrl", 1, 0, PMU_USB0); | 563 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); |
| 564 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); | 564 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); |
| 565 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | 565 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); |
| 566 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | 566 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); |
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index 1b274742077d..d2718de60b9b 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c | |||
| @@ -170,6 +170,28 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 170 | u32 n1; | 170 | u32 n1; |
| 171 | u32 rev; | 171 | u32 rev; |
| 172 | 172 | ||
| 173 | /* Early detection of CMP support */ | ||
| 174 | mips_cm_probe(); | ||
| 175 | mips_cpc_probe(); | ||
| 176 | |||
| 177 | if (mips_cps_numiocu(0)) { | ||
| 178 | /* | ||
| 179 | * mips_cm_probe() wipes out bootloader | ||
| 180 | * config for CM regions and we have to configure them | ||
| 181 | * again. This SoC cannot talk to pamlbus devices | ||
| 182 | * witout proper iocu region set up. | ||
| 183 | * | ||
| 184 | * FIXME: it would be better to do this with values | ||
| 185 | * from DT, but we need this very early because | ||
| 186 | * without this we cannot talk to pretty much anything | ||
| 187 | * including serial. | ||
| 188 | */ | ||
| 189 | write_gcr_reg0_base(MT7621_PALMBUS_BASE); | ||
| 190 | write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE | | ||
| 191 | CM_GCR_REGn_MASK_CMTGT_IOCU0); | ||
| 192 | __sync(); | ||
| 193 | } | ||
| 194 | |||
| 173 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); | 195 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); |
| 174 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); | 196 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); |
| 175 | 197 | ||
| @@ -194,26 +216,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 194 | 216 | ||
| 195 | rt2880_pinmux_data = mt7621_pinmux_data; | 217 | rt2880_pinmux_data = mt7621_pinmux_data; |
| 196 | 218 | ||
| 197 | /* Early detection of CMP support */ | ||
| 198 | mips_cm_probe(); | ||
| 199 | mips_cpc_probe(); | ||
| 200 | |||
| 201 | if (mips_cps_numiocu(0)) { | ||
| 202 | /* | ||
| 203 | * mips_cm_probe() wipes out bootloader | ||
| 204 | * config for CM regions and we have to configure them | ||
| 205 | * again. This SoC cannot talk to pamlbus devices | ||
| 206 | * witout proper iocu region set up. | ||
| 207 | * | ||
| 208 | * FIXME: it would be better to do this with values | ||
| 209 | * from DT, but we need this very early because | ||
| 210 | * without this we cannot talk to pretty much anything | ||
| 211 | * including serial. | ||
| 212 | */ | ||
| 213 | write_gcr_reg0_base(MT7621_PALMBUS_BASE); | ||
| 214 | write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE | | ||
| 215 | CM_GCR_REGn_MASK_CMTGT_IOCU0); | ||
| 216 | } | ||
| 217 | 219 | ||
| 218 | if (!register_cps_smp_ops()) | 220 | if (!register_cps_smp_ops()) |
| 219 | return; | 221 | return; |
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c index 64543d66e76b..e9531fea23a2 100644 --- a/arch/mips/ralink/reset.c +++ b/arch/mips/ralink/reset.c | |||
| @@ -96,16 +96,9 @@ static void ralink_restart(char *command) | |||
| 96 | unreachable(); | 96 | unreachable(); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void ralink_halt(void) | ||
| 100 | { | ||
| 101 | local_irq_disable(); | ||
| 102 | unreachable(); | ||
| 103 | } | ||
| 104 | |||
| 105 | static int __init mips_reboot_setup(void) | 99 | static int __init mips_reboot_setup(void) |
| 106 | { | 100 | { |
| 107 | _machine_restart = ralink_restart; | 101 | _machine_restart = ralink_restart; |
| 108 | _machine_halt = ralink_halt; | ||
| 109 | 102 | ||
| 110 | return 0; | 103 | return 0; |
| 111 | } | 104 | } |
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 140d33288e78..88797c80b3e0 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c | |||
| @@ -2118,7 +2118,8 @@ static int x86_pmu_event_init(struct perf_event *event) | |||
| 2118 | event->destroy(event); | 2118 | event->destroy(event); |
| 2119 | } | 2119 | } |
| 2120 | 2120 | ||
| 2121 | if (READ_ONCE(x86_pmu.attr_rdpmc)) | 2121 | if (READ_ONCE(x86_pmu.attr_rdpmc) && |
| 2122 | !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS)) | ||
| 2122 | event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED; | 2123 | event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED; |
| 2123 | 2124 | ||
| 2124 | return err; | 2125 | return err; |
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 56457cb73448..1e41d7508d99 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
| @@ -2952,9 +2952,9 @@ static void intel_pebs_aliases_skl(struct perf_event *event) | |||
| 2952 | return intel_pebs_aliases_precdist(event); | 2952 | return intel_pebs_aliases_precdist(event); |
| 2953 | } | 2953 | } |
| 2954 | 2954 | ||
| 2955 | static unsigned long intel_pmu_free_running_flags(struct perf_event *event) | 2955 | static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) |
| 2956 | { | 2956 | { |
| 2957 | unsigned long flags = x86_pmu.free_running_flags; | 2957 | unsigned long flags = x86_pmu.large_pebs_flags; |
| 2958 | 2958 | ||
| 2959 | if (event->attr.use_clockid) | 2959 | if (event->attr.use_clockid) |
| 2960 | flags &= ~PERF_SAMPLE_TIME; | 2960 | flags &= ~PERF_SAMPLE_TIME; |
| @@ -2976,8 +2976,8 @@ static int intel_pmu_hw_config(struct perf_event *event) | |||
| 2976 | if (!event->attr.freq) { | 2976 | if (!event->attr.freq) { |
| 2977 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; | 2977 | event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD; |
| 2978 | if (!(event->attr.sample_type & | 2978 | if (!(event->attr.sample_type & |
| 2979 | ~intel_pmu_free_running_flags(event))) | 2979 | ~intel_pmu_large_pebs_flags(event))) |
| 2980 | event->hw.flags |= PERF_X86_EVENT_FREERUNNING; | 2980 | event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS; |
| 2981 | } | 2981 | } |
| 2982 | if (x86_pmu.pebs_aliases) | 2982 | if (x86_pmu.pebs_aliases) |
| 2983 | x86_pmu.pebs_aliases(event); | 2983 | x86_pmu.pebs_aliases(event); |
| @@ -3194,7 +3194,7 @@ static unsigned bdw_limit_period(struct perf_event *event, unsigned left) | |||
| 3194 | X86_CONFIG(.event=0xc0, .umask=0x01)) { | 3194 | X86_CONFIG(.event=0xc0, .umask=0x01)) { |
| 3195 | if (left < 128) | 3195 | if (left < 128) |
| 3196 | left = 128; | 3196 | left = 128; |
| 3197 | left &= ~0x3fu; | 3197 | left &= ~0x3fULL; |
| 3198 | } | 3198 | } |
| 3199 | return left; | 3199 | return left; |
| 3200 | } | 3200 | } |
| @@ -3460,7 +3460,7 @@ static __initconst const struct x86_pmu core_pmu = { | |||
| 3460 | .event_map = intel_pmu_event_map, | 3460 | .event_map = intel_pmu_event_map, |
| 3461 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), | 3461 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), |
| 3462 | .apic = 1, | 3462 | .apic = 1, |
| 3463 | .free_running_flags = PEBS_FREERUNNING_FLAGS, | 3463 | .large_pebs_flags = LARGE_PEBS_FLAGS, |
| 3464 | 3464 | ||
| 3465 | /* | 3465 | /* |
| 3466 | * Intel PMCs cannot be accessed sanely above 32-bit width, | 3466 | * Intel PMCs cannot be accessed sanely above 32-bit width, |
| @@ -3502,7 +3502,7 @@ static __initconst const struct x86_pmu intel_pmu = { | |||
| 3502 | .event_map = intel_pmu_event_map, | 3502 | .event_map = intel_pmu_event_map, |
| 3503 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), | 3503 | .max_events = ARRAY_SIZE(intel_perfmon_event_map), |
| 3504 | .apic = 1, | 3504 | .apic = 1, |
| 3505 | .free_running_flags = PEBS_FREERUNNING_FLAGS, | 3505 | .large_pebs_flags = LARGE_PEBS_FLAGS, |
| 3506 | /* | 3506 | /* |
| 3507 | * Intel PMCs cannot be accessed sanely above 32 bit width, | 3507 | * Intel PMCs cannot be accessed sanely above 32 bit width, |
| 3508 | * so we install an artificial 1<<31 period regardless of | 3508 | * so we install an artificial 1<<31 period regardless of |
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 18c25ab28557..d8015235ba76 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c | |||
| @@ -935,7 +935,7 @@ void intel_pmu_pebs_add(struct perf_event *event) | |||
| 935 | bool needed_cb = pebs_needs_sched_cb(cpuc); | 935 | bool needed_cb = pebs_needs_sched_cb(cpuc); |
| 936 | 936 | ||
| 937 | cpuc->n_pebs++; | 937 | cpuc->n_pebs++; |
| 938 | if (hwc->flags & PERF_X86_EVENT_FREERUNNING) | 938 | if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS) |
| 939 | cpuc->n_large_pebs++; | 939 | cpuc->n_large_pebs++; |
| 940 | 940 | ||
| 941 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); | 941 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); |
| @@ -975,7 +975,7 @@ void intel_pmu_pebs_del(struct perf_event *event) | |||
| 975 | bool needed_cb = pebs_needs_sched_cb(cpuc); | 975 | bool needed_cb = pebs_needs_sched_cb(cpuc); |
| 976 | 976 | ||
| 977 | cpuc->n_pebs--; | 977 | cpuc->n_pebs--; |
| 978 | if (hwc->flags & PERF_X86_EVENT_FREERUNNING) | 978 | if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS) |
| 979 | cpuc->n_large_pebs--; | 979 | cpuc->n_large_pebs--; |
| 980 | 980 | ||
| 981 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); | 981 | pebs_update_state(needed_cb, cpuc, event->ctx->pmu); |
| @@ -1530,7 +1530,7 @@ void __init intel_ds_init(void) | |||
| 1530 | x86_pmu.pebs_record_size = | 1530 | x86_pmu.pebs_record_size = |
| 1531 | sizeof(struct pebs_record_skl); | 1531 | sizeof(struct pebs_record_skl); |
| 1532 | x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; | 1532 | x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; |
| 1533 | x86_pmu.free_running_flags |= PERF_SAMPLE_TIME; | 1533 | x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME; |
| 1534 | break; | 1534 | break; |
| 1535 | 1535 | ||
| 1536 | default: | 1536 | default: |
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 22ec65bc033a..c98b943e58b4 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c | |||
| @@ -3343,6 +3343,7 @@ static struct extra_reg skx_uncore_cha_extra_regs[] = { | |||
| 3343 | SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4), | 3343 | SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4), |
| 3344 | SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8), | 3344 | SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8), |
| 3345 | SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8), | 3345 | SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8), |
| 3346 | SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3), | ||
| 3346 | EVENT_EXTRA_END | 3347 | EVENT_EXTRA_END |
| 3347 | }; | 3348 | }; |
| 3348 | 3349 | ||
| @@ -3562,24 +3563,27 @@ static struct intel_uncore_type *skx_msr_uncores[] = { | |||
| 3562 | NULL, | 3563 | NULL, |
| 3563 | }; | 3564 | }; |
| 3564 | 3565 | ||
| 3566 | /* | ||
| 3567 | * To determine the number of CHAs, it should read bits 27:0 in the CAPID6 | ||
| 3568 | * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083. | ||
| 3569 | */ | ||
| 3570 | #define SKX_CAPID6 0x9c | ||
| 3571 | #define SKX_CHA_BIT_MASK GENMASK(27, 0) | ||
| 3572 | |||
| 3565 | static int skx_count_chabox(void) | 3573 | static int skx_count_chabox(void) |
| 3566 | { | 3574 | { |
| 3567 | struct pci_dev *chabox_dev = NULL; | 3575 | struct pci_dev *dev = NULL; |
| 3568 | int bus, count = 0; | 3576 | u32 val = 0; |
| 3569 | 3577 | ||
| 3570 | while (1) { | 3578 | dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev); |
| 3571 | chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev); | 3579 | if (!dev) |
| 3572 | if (!chabox_dev) | 3580 | goto out; |
| 3573 | break; | ||
| 3574 | if (count == 0) | ||
| 3575 | bus = chabox_dev->bus->number; | ||
| 3576 | if (bus != chabox_dev->bus->number) | ||
| 3577 | break; | ||
| 3578 | count++; | ||
| 3579 | } | ||
| 3580 | 3581 | ||
| 3581 | pci_dev_put(chabox_dev); | 3582 | pci_read_config_dword(dev, SKX_CAPID6, &val); |
| 3582 | return count; | 3583 | val &= SKX_CHA_BIT_MASK; |
| 3584 | out: | ||
| 3585 | pci_dev_put(dev); | ||
| 3586 | return hweight32(val); | ||
| 3583 | } | 3587 | } |
| 3584 | 3588 | ||
| 3585 | void skx_uncore_cpu_init(void) | 3589 | void skx_uncore_cpu_init(void) |
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 78f91ec1056e..39cd0615f04f 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h | |||
| @@ -69,7 +69,7 @@ struct event_constraint { | |||
| 69 | #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ | 69 | #define PERF_X86_EVENT_RDPMC_ALLOWED 0x0100 /* grant rdpmc permission */ |
| 70 | #define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */ | 70 | #define PERF_X86_EVENT_EXCL_ACCT 0x0200 /* accounted EXCL event */ |
| 71 | #define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */ | 71 | #define PERF_X86_EVENT_AUTO_RELOAD 0x0400 /* use PEBS auto-reload */ |
| 72 | #define PERF_X86_EVENT_FREERUNNING 0x0800 /* use freerunning PEBS */ | 72 | #define PERF_X86_EVENT_LARGE_PEBS 0x0800 /* use large PEBS */ |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | struct amd_nb { | 75 | struct amd_nb { |
| @@ -88,7 +88,7 @@ struct amd_nb { | |||
| 88 | * REGS_USER can be handled for events limited to ring 3. | 88 | * REGS_USER can be handled for events limited to ring 3. |
| 89 | * | 89 | * |
| 90 | */ | 90 | */ |
| 91 | #define PEBS_FREERUNNING_FLAGS \ | 91 | #define LARGE_PEBS_FLAGS \ |
| 92 | (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \ | 92 | (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \ |
| 93 | PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ | 93 | PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ |
| 94 | PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ | 94 | PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ |
| @@ -608,7 +608,7 @@ struct x86_pmu { | |||
| 608 | struct event_constraint *pebs_constraints; | 608 | struct event_constraint *pebs_constraints; |
| 609 | void (*pebs_aliases)(struct perf_event *event); | 609 | void (*pebs_aliases)(struct perf_event *event); |
| 610 | int max_pebs_events; | 610 | int max_pebs_events; |
| 611 | unsigned long free_running_flags; | 611 | unsigned long large_pebs_flags; |
| 612 | 612 | ||
| 613 | /* | 613 | /* |
| 614 | * Intel LBR | 614 | * Intel LBR |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 8b6780751132..5db8b0b10766 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
| @@ -352,6 +352,7 @@ enum vmcs_field { | |||
| 352 | #define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */ | 352 | #define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */ |
| 353 | #define INTR_TYPE_HARD_EXCEPTION (3 << 8) /* processor exception */ | 353 | #define INTR_TYPE_HARD_EXCEPTION (3 << 8) /* processor exception */ |
| 354 | #define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */ | 354 | #define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */ |
| 355 | #define INTR_TYPE_PRIV_SW_EXCEPTION (5 << 8) /* ICE breakpoint - undocumented */ | ||
| 355 | #define INTR_TYPE_SOFT_EXCEPTION (6 << 8) /* software exception */ | 356 | #define INTR_TYPE_SOFT_EXCEPTION (6 << 8) /* software exception */ |
| 356 | 357 | ||
| 357 | /* GUEST_INTERRUPTIBILITY_INFO flags. */ | 358 | /* GUEST_INTERRUPTIBILITY_INFO flags. */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 051dab74e4e9..2d87603f9179 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -1045,6 +1045,13 @@ static inline bool is_machine_check(u32 intr_info) | |||
| 1045 | (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); | 1045 | (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); |
| 1046 | } | 1046 | } |
| 1047 | 1047 | ||
| 1048 | /* Undocumented: icebp/int1 */ | ||
| 1049 | static inline bool is_icebp(u32 intr_info) | ||
| 1050 | { | ||
| 1051 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | ||
| 1052 | == (INTR_TYPE_PRIV_SW_EXCEPTION | INTR_INFO_VALID_MASK); | ||
| 1053 | } | ||
| 1054 | |||
| 1048 | static inline bool cpu_has_vmx_msr_bitmap(void) | 1055 | static inline bool cpu_has_vmx_msr_bitmap(void) |
| 1049 | { | 1056 | { |
| 1050 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS; | 1057 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS; |
| @@ -6179,7 +6186,7 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
| 6179 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { | 6186 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { |
| 6180 | vcpu->arch.dr6 &= ~15; | 6187 | vcpu->arch.dr6 &= ~15; |
| 6181 | vcpu->arch.dr6 |= dr6 | DR6_RTM; | 6188 | vcpu->arch.dr6 |= dr6 | DR6_RTM; |
| 6182 | if (!(dr6 & ~DR6_RESERVED)) /* icebp */ | 6189 | if (is_icebp(intr_info)) |
| 6183 | skip_emulated_instruction(vcpu); | 6190 | skip_emulated_instruction(vcpu); |
| 6184 | 6191 | ||
| 6185 | kvm_queue_exception(vcpu, DB_VECTOR); | 6192 | kvm_queue_exception(vcpu, DB_VECTOR); |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 8b72923f1d35..af11a2890235 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -800,17 +800,11 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, | |||
| 800 | 800 | ||
| 801 | #define PAGE_INUSE 0xFD | 801 | #define PAGE_INUSE 0xFD |
| 802 | 802 | ||
| 803 | static void __meminit free_pagetable(struct page *page, int order, | 803 | static void __meminit free_pagetable(struct page *page, int order) |
| 804 | struct vmem_altmap *altmap) | ||
| 805 | { | 804 | { |
| 806 | unsigned long magic; | 805 | unsigned long magic; |
| 807 | unsigned int nr_pages = 1 << order; | 806 | unsigned int nr_pages = 1 << order; |
| 808 | 807 | ||
| 809 | if (altmap) { | ||
| 810 | vmem_altmap_free(altmap, nr_pages); | ||
| 811 | return; | ||
| 812 | } | ||
| 813 | |||
| 814 | /* bootmem page has reserved flag */ | 808 | /* bootmem page has reserved flag */ |
| 815 | if (PageReserved(page)) { | 809 | if (PageReserved(page)) { |
| 816 | __ClearPageReserved(page); | 810 | __ClearPageReserved(page); |
| @@ -826,9 +820,17 @@ static void __meminit free_pagetable(struct page *page, int order, | |||
| 826 | free_pages((unsigned long)page_address(page), order); | 820 | free_pages((unsigned long)page_address(page), order); |
| 827 | } | 821 | } |
| 828 | 822 | ||
| 829 | static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd, | 823 | static void __meminit free_hugepage_table(struct page *page, |
| 830 | struct vmem_altmap *altmap) | 824 | struct vmem_altmap *altmap) |
| 831 | { | 825 | { |
| 826 | if (altmap) | ||
| 827 | vmem_altmap_free(altmap, PMD_SIZE / PAGE_SIZE); | ||
| 828 | else | ||
| 829 | free_pagetable(page, get_order(PMD_SIZE)); | ||
| 830 | } | ||
| 831 | |||
| 832 | static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd) | ||
| 833 | { | ||
| 832 | pte_t *pte; | 834 | pte_t *pte; |
| 833 | int i; | 835 | int i; |
| 834 | 836 | ||
| @@ -839,14 +841,13 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd, | |||
| 839 | } | 841 | } |
| 840 | 842 | ||
| 841 | /* free a pte talbe */ | 843 | /* free a pte talbe */ |
| 842 | free_pagetable(pmd_page(*pmd), 0, altmap); | 844 | free_pagetable(pmd_page(*pmd), 0); |
| 843 | spin_lock(&init_mm.page_table_lock); | 845 | spin_lock(&init_mm.page_table_lock); |
| 844 | pmd_clear(pmd); | 846 | pmd_clear(pmd); |
| 845 | spin_unlock(&init_mm.page_table_lock); | 847 | spin_unlock(&init_mm.page_table_lock); |
| 846 | } | 848 | } |
| 847 | 849 | ||
| 848 | static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, | 850 | static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud) |
| 849 | struct vmem_altmap *altmap) | ||
| 850 | { | 851 | { |
| 851 | pmd_t *pmd; | 852 | pmd_t *pmd; |
| 852 | int i; | 853 | int i; |
| @@ -858,14 +859,13 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, | |||
| 858 | } | 859 | } |
| 859 | 860 | ||
| 860 | /* free a pmd talbe */ | 861 | /* free a pmd talbe */ |
| 861 | free_pagetable(pud_page(*pud), 0, altmap); | 862 | free_pagetable(pud_page(*pud), 0); |
| 862 | spin_lock(&init_mm.page_table_lock); | 863 | spin_lock(&init_mm.page_table_lock); |
| 863 | pud_clear(pud); | 864 | pud_clear(pud); |
| 864 | spin_unlock(&init_mm.page_table_lock); | 865 | spin_unlock(&init_mm.page_table_lock); |
| 865 | } | 866 | } |
| 866 | 867 | ||
| 867 | static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d, | 868 | static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d) |
| 868 | struct vmem_altmap *altmap) | ||
| 869 | { | 869 | { |
| 870 | pud_t *pud; | 870 | pud_t *pud; |
| 871 | int i; | 871 | int i; |
| @@ -877,7 +877,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d, | |||
| 877 | } | 877 | } |
| 878 | 878 | ||
| 879 | /* free a pud talbe */ | 879 | /* free a pud talbe */ |
| 880 | free_pagetable(p4d_page(*p4d), 0, altmap); | 880 | free_pagetable(p4d_page(*p4d), 0); |
| 881 | spin_lock(&init_mm.page_table_lock); | 881 | spin_lock(&init_mm.page_table_lock); |
| 882 | p4d_clear(p4d); | 882 | p4d_clear(p4d); |
| 883 | spin_unlock(&init_mm.page_table_lock); | 883 | spin_unlock(&init_mm.page_table_lock); |
| @@ -885,7 +885,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d, | |||
| 885 | 885 | ||
| 886 | static void __meminit | 886 | static void __meminit |
| 887 | remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, | 887 | remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, |
| 888 | struct vmem_altmap *altmap, bool direct) | 888 | bool direct) |
| 889 | { | 889 | { |
| 890 | unsigned long next, pages = 0; | 890 | unsigned long next, pages = 0; |
| 891 | pte_t *pte; | 891 | pte_t *pte; |
| @@ -916,7 +916,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, | |||
| 916 | * freed when offlining, or simplely not in use. | 916 | * freed when offlining, or simplely not in use. |
| 917 | */ | 917 | */ |
| 918 | if (!direct) | 918 | if (!direct) |
| 919 | free_pagetable(pte_page(*pte), 0, altmap); | 919 | free_pagetable(pte_page(*pte), 0); |
| 920 | 920 | ||
| 921 | spin_lock(&init_mm.page_table_lock); | 921 | spin_lock(&init_mm.page_table_lock); |
| 922 | pte_clear(&init_mm, addr, pte); | 922 | pte_clear(&init_mm, addr, pte); |
| @@ -939,7 +939,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, | |||
| 939 | 939 | ||
| 940 | page_addr = page_address(pte_page(*pte)); | 940 | page_addr = page_address(pte_page(*pte)); |
| 941 | if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) { | 941 | if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) { |
| 942 | free_pagetable(pte_page(*pte), 0, altmap); | 942 | free_pagetable(pte_page(*pte), 0); |
| 943 | 943 | ||
| 944 | spin_lock(&init_mm.page_table_lock); | 944 | spin_lock(&init_mm.page_table_lock); |
| 945 | pte_clear(&init_mm, addr, pte); | 945 | pte_clear(&init_mm, addr, pte); |
| @@ -974,9 +974,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, | |||
| 974 | if (IS_ALIGNED(addr, PMD_SIZE) && | 974 | if (IS_ALIGNED(addr, PMD_SIZE) && |
| 975 | IS_ALIGNED(next, PMD_SIZE)) { | 975 | IS_ALIGNED(next, PMD_SIZE)) { |
| 976 | if (!direct) | 976 | if (!direct) |
| 977 | free_pagetable(pmd_page(*pmd), | 977 | free_hugepage_table(pmd_page(*pmd), |
| 978 | get_order(PMD_SIZE), | 978 | altmap); |
| 979 | altmap); | ||
| 980 | 979 | ||
| 981 | spin_lock(&init_mm.page_table_lock); | 980 | spin_lock(&init_mm.page_table_lock); |
| 982 | pmd_clear(pmd); | 981 | pmd_clear(pmd); |
| @@ -989,9 +988,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, | |||
| 989 | page_addr = page_address(pmd_page(*pmd)); | 988 | page_addr = page_address(pmd_page(*pmd)); |
| 990 | if (!memchr_inv(page_addr, PAGE_INUSE, | 989 | if (!memchr_inv(page_addr, PAGE_INUSE, |
| 991 | PMD_SIZE)) { | 990 | PMD_SIZE)) { |
| 992 | free_pagetable(pmd_page(*pmd), | 991 | free_hugepage_table(pmd_page(*pmd), |
| 993 | get_order(PMD_SIZE), | 992 | altmap); |
| 994 | altmap); | ||
| 995 | 993 | ||
| 996 | spin_lock(&init_mm.page_table_lock); | 994 | spin_lock(&init_mm.page_table_lock); |
| 997 | pmd_clear(pmd); | 995 | pmd_clear(pmd); |
| @@ -1003,8 +1001,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, | |||
| 1003 | } | 1001 | } |
| 1004 | 1002 | ||
| 1005 | pte_base = (pte_t *)pmd_page_vaddr(*pmd); | 1003 | pte_base = (pte_t *)pmd_page_vaddr(*pmd); |
| 1006 | remove_pte_table(pte_base, addr, next, altmap, direct); | 1004 | remove_pte_table(pte_base, addr, next, direct); |
| 1007 | free_pte_table(pte_base, pmd, altmap); | 1005 | free_pte_table(pte_base, pmd); |
| 1008 | } | 1006 | } |
| 1009 | 1007 | ||
| 1010 | /* Call free_pmd_table() in remove_pud_table(). */ | 1008 | /* Call free_pmd_table() in remove_pud_table(). */ |
| @@ -1033,8 +1031,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, | |||
| 1033 | IS_ALIGNED(next, PUD_SIZE)) { | 1031 | IS_ALIGNED(next, PUD_SIZE)) { |
| 1034 | if (!direct) | 1032 | if (!direct) |
| 1035 | free_pagetable(pud_page(*pud), | 1033 | free_pagetable(pud_page(*pud), |
| 1036 | get_order(PUD_SIZE), | 1034 | get_order(PUD_SIZE)); |
| 1037 | altmap); | ||
| 1038 | 1035 | ||
| 1039 | spin_lock(&init_mm.page_table_lock); | 1036 | spin_lock(&init_mm.page_table_lock); |
| 1040 | pud_clear(pud); | 1037 | pud_clear(pud); |
| @@ -1048,8 +1045,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, | |||
| 1048 | if (!memchr_inv(page_addr, PAGE_INUSE, | 1045 | if (!memchr_inv(page_addr, PAGE_INUSE, |
| 1049 | PUD_SIZE)) { | 1046 | PUD_SIZE)) { |
| 1050 | free_pagetable(pud_page(*pud), | 1047 | free_pagetable(pud_page(*pud), |
| 1051 | get_order(PUD_SIZE), | 1048 | get_order(PUD_SIZE)); |
| 1052 | altmap); | ||
| 1053 | 1049 | ||
| 1054 | spin_lock(&init_mm.page_table_lock); | 1050 | spin_lock(&init_mm.page_table_lock); |
| 1055 | pud_clear(pud); | 1051 | pud_clear(pud); |
| @@ -1062,7 +1058,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, | |||
| 1062 | 1058 | ||
| 1063 | pmd_base = pmd_offset(pud, 0); | 1059 | pmd_base = pmd_offset(pud, 0); |
| 1064 | remove_pmd_table(pmd_base, addr, next, direct, altmap); | 1060 | remove_pmd_table(pmd_base, addr, next, direct, altmap); |
| 1065 | free_pmd_table(pmd_base, pud, altmap); | 1061 | free_pmd_table(pmd_base, pud); |
| 1066 | } | 1062 | } |
| 1067 | 1063 | ||
| 1068 | if (direct) | 1064 | if (direct) |
| @@ -1094,7 +1090,7 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end, | |||
| 1094 | * to adapt for boot-time switching between 4 and 5 level page tables. | 1090 | * to adapt for boot-time switching between 4 and 5 level page tables. |
| 1095 | */ | 1091 | */ |
| 1096 | if (CONFIG_PGTABLE_LEVELS == 5) | 1092 | if (CONFIG_PGTABLE_LEVELS == 5) |
| 1097 | free_pud_table(pud_base, p4d, altmap); | 1093 | free_pud_table(pud_base, p4d); |
| 1098 | } | 1094 | } |
| 1099 | 1095 | ||
| 1100 | if (direct) | 1096 | if (direct) |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 004abf9ebf12..34cda7e0551b 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
| @@ -702,4 +702,52 @@ int pmd_clear_huge(pmd_t *pmd) | |||
| 702 | 702 | ||
| 703 | return 0; | 703 | return 0; |
| 704 | } | 704 | } |
| 705 | |||
| 706 | /** | ||
| 707 | * pud_free_pmd_page - Clear pud entry and free pmd page. | ||
| 708 | * @pud: Pointer to a PUD. | ||
| 709 | * | ||
| 710 | * Context: The pud range has been unmaped and TLB purged. | ||
| 711 | * Return: 1 if clearing the entry succeeded. 0 otherwise. | ||
| 712 | */ | ||
| 713 | int pud_free_pmd_page(pud_t *pud) | ||
| 714 | { | ||
| 715 | pmd_t *pmd; | ||
| 716 | int i; | ||
| 717 | |||
| 718 | if (pud_none(*pud)) | ||
| 719 | return 1; | ||
| 720 | |||
| 721 | pmd = (pmd_t *)pud_page_vaddr(*pud); | ||
| 722 | |||
| 723 | for (i = 0; i < PTRS_PER_PMD; i++) | ||
| 724 | if (!pmd_free_pte_page(&pmd[i])) | ||
| 725 | return 0; | ||
| 726 | |||
| 727 | pud_clear(pud); | ||
| 728 | free_page((unsigned long)pmd); | ||
| 729 | |||
| 730 | return 1; | ||
| 731 | } | ||
| 732 | |||
| 733 | /** | ||
| 734 | * pmd_free_pte_page - Clear pmd entry and free pte page. | ||
| 735 | * @pmd: Pointer to a PMD. | ||
| 736 | * | ||
| 737 | * Context: The pmd range has been unmaped and TLB purged. | ||
| 738 | * Return: 1 if clearing the entry succeeded. 0 otherwise. | ||
| 739 | */ | ||
| 740 | int pmd_free_pte_page(pmd_t *pmd) | ||
| 741 | { | ||
| 742 | pte_t *pte; | ||
| 743 | |||
| 744 | if (pmd_none(*pmd)) | ||
| 745 | return 1; | ||
| 746 | |||
| 747 | pte = (pte_t *)pmd_page_vaddr(*pmd); | ||
| 748 | pmd_clear(pmd); | ||
| 749 | free_page((unsigned long)pte); | ||
| 750 | |||
| 751 | return 1; | ||
| 752 | } | ||
| 705 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ | 753 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ |
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 45e4eb5bcbb2..ce5b2ebd5701 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
| @@ -1188,7 +1188,7 @@ skip_init_addrs: | |||
| 1188 | * may converge on the last pass. In such case do one more | 1188 | * may converge on the last pass. In such case do one more |
| 1189 | * pass to emit the final image | 1189 | * pass to emit the final image |
| 1190 | */ | 1190 | */ |
| 1191 | for (pass = 0; pass < 10 || image; pass++) { | 1191 | for (pass = 0; pass < 20 || image; pass++) { |
| 1192 | proglen = do_jit(prog, addrs, image, oldproglen, &ctx); | 1192 | proglen = do_jit(prog, addrs, image, oldproglen, &ctx); |
| 1193 | if (proglen <= 0) { | 1193 | if (proglen <= 0) { |
| 1194 | image = NULL; | 1194 | image = NULL; |
| @@ -1215,6 +1215,7 @@ skip_init_addrs: | |||
| 1215 | } | 1215 | } |
| 1216 | } | 1216 | } |
| 1217 | oldproglen = proglen; | 1217 | oldproglen = proglen; |
| 1218 | cond_resched(); | ||
| 1218 | } | 1219 | } |
| 1219 | 1220 | ||
| 1220 | if (bpf_jit_enable > 1) | 1221 | if (bpf_jit_enable > 1) |
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 11b113f8e367..ebb626ffb5fa 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c | |||
| @@ -74,10 +74,10 @@ void __init acpi_watchdog_init(void) | |||
| 74 | res.start = gas->address; | 74 | res.start = gas->address; |
| 75 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 75 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
| 76 | res.flags = IORESOURCE_MEM; | 76 | res.flags = IORESOURCE_MEM; |
| 77 | res.end = res.start + ALIGN(gas->access_width, 4); | 77 | res.end = res.start + ALIGN(gas->access_width, 4) - 1; |
| 78 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { | 78 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
| 79 | res.flags = IORESOURCE_IO; | 79 | res.flags = IORESOURCE_IO; |
| 80 | res.end = res.start + gas->access_width; | 80 | res.end = res.start + gas->access_width - 1; |
| 81 | } else { | 81 | } else { |
| 82 | pr_warn("Unsupported address space: %u\n", | 82 | pr_warn("Unsupported address space: %u\n", |
| 83 | gas->space_id); | 83 | gas->space_id); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 7128488a3a72..f2eb6c37ea0a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -70,7 +70,6 @@ static async_cookie_t async_cookie; | |||
| 70 | static bool battery_driver_registered; | 70 | static bool battery_driver_registered; |
| 71 | static int battery_bix_broken_package; | 71 | static int battery_bix_broken_package; |
| 72 | static int battery_notification_delay_ms; | 72 | static int battery_notification_delay_ms; |
| 73 | static int battery_full_discharging; | ||
| 74 | static unsigned int cache_time = 1000; | 73 | static unsigned int cache_time = 1000; |
| 75 | module_param(cache_time, uint, 0644); | 74 | module_param(cache_time, uint, 0644); |
| 76 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 75 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
| @@ -215,12 +214,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
| 215 | return -ENODEV; | 214 | return -ENODEV; |
| 216 | switch (psp) { | 215 | switch (psp) { |
| 217 | case POWER_SUPPLY_PROP_STATUS: | 216 | case POWER_SUPPLY_PROP_STATUS: |
| 218 | if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) { | 217 | if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) |
| 219 | if (battery_full_discharging && battery->rate_now == 0) | 218 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
| 220 | val->intval = POWER_SUPPLY_STATUS_FULL; | 219 | else if (battery->state & ACPI_BATTERY_STATE_CHARGING) |
| 221 | else | ||
| 222 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 223 | } else if (battery->state & ACPI_BATTERY_STATE_CHARGING) | ||
| 224 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 220 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
| 225 | else if (acpi_battery_is_charged(battery)) | 221 | else if (acpi_battery_is_charged(battery)) |
| 226 | val->intval = POWER_SUPPLY_STATUS_FULL; | 222 | val->intval = POWER_SUPPLY_STATUS_FULL; |
| @@ -1170,12 +1166,6 @@ battery_notification_delay_quirk(const struct dmi_system_id *d) | |||
| 1170 | return 0; | 1166 | return 0; |
| 1171 | } | 1167 | } |
| 1172 | 1168 | ||
| 1173 | static int __init battery_full_discharging_quirk(const struct dmi_system_id *d) | ||
| 1174 | { | ||
| 1175 | battery_full_discharging = 1; | ||
| 1176 | return 0; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | static const struct dmi_system_id bat_dmi_table[] __initconst = { | 1169 | static const struct dmi_system_id bat_dmi_table[] __initconst = { |
| 1180 | { | 1170 | { |
| 1181 | .callback = battery_bix_broken_package_quirk, | 1171 | .callback = battery_bix_broken_package_quirk, |
| @@ -1193,38 +1183,6 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { | |||
| 1193 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), | 1183 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), |
| 1194 | }, | 1184 | }, |
| 1195 | }, | 1185 | }, |
| 1196 | { | ||
| 1197 | .callback = battery_full_discharging_quirk, | ||
| 1198 | .ident = "ASUS GL502VSK", | ||
| 1199 | .matches = { | ||
| 1200 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 1201 | DMI_MATCH(DMI_PRODUCT_NAME, "GL502VSK"), | ||
| 1202 | }, | ||
| 1203 | }, | ||
| 1204 | { | ||
| 1205 | .callback = battery_full_discharging_quirk, | ||
| 1206 | .ident = "ASUS UX305LA", | ||
| 1207 | .matches = { | ||
| 1208 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 1209 | DMI_MATCH(DMI_PRODUCT_NAME, "UX305LA"), | ||
| 1210 | }, | ||
| 1211 | }, | ||
| 1212 | { | ||
| 1213 | .callback = battery_full_discharging_quirk, | ||
| 1214 | .ident = "ASUS UX360UA", | ||
| 1215 | .matches = { | ||
| 1216 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 1217 | DMI_MATCH(DMI_PRODUCT_NAME, "UX360UA"), | ||
| 1218 | }, | ||
| 1219 | }, | ||
| 1220 | { | ||
| 1221 | .callback = battery_full_discharging_quirk, | ||
| 1222 | .ident = "ASUS UX410UAK", | ||
| 1223 | .matches = { | ||
| 1224 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 1225 | DMI_MATCH(DMI_PRODUCT_NAME, "UX410UAK"), | ||
| 1226 | }, | ||
| 1227 | }, | ||
| 1228 | {}, | 1186 | {}, |
| 1229 | }; | 1187 | }; |
| 1230 | 1188 | ||
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index bbe48ad20886..eb09ef55c38a 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c | |||
| @@ -2675,10 +2675,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, | |||
| 2675 | else | 2675 | else |
| 2676 | ndr_desc->numa_node = NUMA_NO_NODE; | 2676 | ndr_desc->numa_node = NUMA_NO_NODE; |
| 2677 | 2677 | ||
| 2678 | if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH) | 2678 | /* |
| 2679 | * Persistence domain bits are hierarchical, if | ||
| 2680 | * ACPI_NFIT_CAPABILITY_CACHE_FLUSH is set then | ||
| 2681 | * ACPI_NFIT_CAPABILITY_MEM_FLUSH is implied. | ||
| 2682 | */ | ||
| 2683 | if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH) | ||
| 2679 | set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags); | 2684 | set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags); |
| 2680 | 2685 | else if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH) | |
| 2681 | if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH) | ||
| 2682 | set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags); | 2686 | set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags); |
| 2683 | 2687 | ||
| 2684 | list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { | 2688 | list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 8ccaae3550d2..85167603b9c9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
| @@ -103,25 +103,27 @@ int acpi_map_pxm_to_node(int pxm) | |||
| 103 | */ | 103 | */ |
| 104 | int acpi_map_pxm_to_online_node(int pxm) | 104 | int acpi_map_pxm_to_online_node(int pxm) |
| 105 | { | 105 | { |
| 106 | int node, n, dist, min_dist; | 106 | int node, min_node; |
| 107 | 107 | ||
| 108 | node = acpi_map_pxm_to_node(pxm); | 108 | node = acpi_map_pxm_to_node(pxm); |
| 109 | 109 | ||
| 110 | if (node == NUMA_NO_NODE) | 110 | if (node == NUMA_NO_NODE) |
| 111 | node = 0; | 111 | node = 0; |
| 112 | 112 | ||
| 113 | min_node = node; | ||
| 113 | if (!node_online(node)) { | 114 | if (!node_online(node)) { |
| 114 | min_dist = INT_MAX; | 115 | int min_dist = INT_MAX, dist, n; |
| 116 | |||
| 115 | for_each_online_node(n) { | 117 | for_each_online_node(n) { |
| 116 | dist = node_distance(node, n); | 118 | dist = node_distance(node, n); |
| 117 | if (dist < min_dist) { | 119 | if (dist < min_dist) { |
| 118 | min_dist = dist; | 120 | min_dist = dist; |
| 119 | node = n; | 121 | min_node = n; |
| 120 | } | 122 | } |
| 121 | } | 123 | } |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 124 | return node; | 126 | return min_node; |
| 125 | } | 127 | } |
| 126 | EXPORT_SYMBOL(acpi_map_pxm_to_online_node); | 128 | EXPORT_SYMBOL(acpi_map_pxm_to_online_node); |
| 127 | 129 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 355a95a83a34..1ff17799769d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -550,7 +550,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 550 | .driver_data = board_ahci_yes_fbs }, | 550 | .driver_data = board_ahci_yes_fbs }, |
| 551 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230), | 551 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230), |
| 552 | .driver_data = board_ahci_yes_fbs }, | 552 | .driver_data = board_ahci_yes_fbs }, |
| 553 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), | 553 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */ |
| 554 | .driver_data = board_ahci_yes_fbs }, | ||
| 555 | { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */ | ||
| 554 | .driver_data = board_ahci_yes_fbs }, | 556 | .driver_data = board_ahci_yes_fbs }, |
| 555 | 557 | ||
| 556 | /* Promise */ | 558 | /* Promise */ |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index a0de7a38430c..7adcf3caabd0 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -665,6 +665,16 @@ int ahci_stop_engine(struct ata_port *ap) | |||
| 665 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) | 665 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) |
| 666 | return 0; | 666 | return 0; |
| 667 | 667 | ||
| 668 | /* | ||
| 669 | * Don't try to issue commands but return with ENODEV if the | ||
| 670 | * AHCI controller not available anymore (e.g. due to PCIe hot | ||
| 671 | * unplugging). Otherwise a 500ms delay for each port is added. | ||
| 672 | */ | ||
| 673 | if (tmp == 0xffffffff) { | ||
| 674 | dev_err(ap->host->dev, "AHCI controller unavailable!\n"); | ||
| 675 | return -ENODEV; | ||
| 676 | } | ||
| 677 | |||
| 668 | /* setting HBA to idle */ | 678 | /* setting HBA to idle */ |
| 669 | tmp &= ~PORT_CMD_START; | 679 | tmp &= ~PORT_CMD_START; |
| 670 | writel(tmp, port_mmio + PORT_CMD); | 680 | writel(tmp, port_mmio + PORT_CMD); |
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 341d0ef82cbd..30cc8f1a31e1 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c | |||
| @@ -340,7 +340,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port, | |||
| 340 | * 2) regulator for controlling the targets power (optional) | 340 | * 2) regulator for controlling the targets power (optional) |
| 341 | * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, | 341 | * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, |
| 342 | * or for non devicetree enabled platforms a single clock | 342 | * or for non devicetree enabled platforms a single clock |
| 343 | * 4) phys (optional) | 343 | * 4) phys (optional) |
| 344 | * | 344 | * |
| 345 | * RETURNS: | 345 | * RETURNS: |
| 346 | * The allocated ahci_host_priv on success, otherwise an ERR_PTR value | 346 | * The allocated ahci_host_priv on success, otherwise an ERR_PTR value |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3c09122bf038..7431ccd03316 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4530,6 +4530,25 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4530 | { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, | 4530 | { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, |
| 4531 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, | 4531 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, |
| 4532 | 4532 | ||
| 4533 | /* Crucial BX100 SSD 500GB has broken LPM support */ | ||
| 4534 | { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, | ||
| 4535 | |||
| 4536 | /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */ | ||
| 4537 | { "Crucial_CT512MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | | ||
| 4538 | ATA_HORKAGE_ZERO_AFTER_TRIM | | ||
| 4539 | ATA_HORKAGE_NOLPM, }, | ||
| 4540 | /* 512GB MX100 with newer firmware has only LPM issues */ | ||
| 4541 | { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM | | ||
| 4542 | ATA_HORKAGE_NOLPM, }, | ||
| 4543 | |||
| 4544 | /* 480GB+ M500 SSDs have both queued TRIM and LPM issues */ | ||
| 4545 | { "Crucial_CT480M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | ||
| 4546 | ATA_HORKAGE_ZERO_AFTER_TRIM | | ||
| 4547 | ATA_HORKAGE_NOLPM, }, | ||
| 4548 | { "Crucial_CT960M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | ||
| 4549 | ATA_HORKAGE_ZERO_AFTER_TRIM | | ||
| 4550 | ATA_HORKAGE_NOLPM, }, | ||
| 4551 | |||
| 4533 | /* devices that don't properly handle queued TRIM commands */ | 4552 | /* devices that don't properly handle queued TRIM commands */ |
| 4534 | { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4553 | { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
| 4535 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4554 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| @@ -4541,7 +4560,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
| 4541 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4560 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4542 | { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | | 4561 | { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | |
| 4543 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4562 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4544 | { "Samsung SSD 8*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4563 | { "Samsung SSD 840*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
| 4564 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
| 4565 | { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | ||
| 4545 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4566 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| 4546 | { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | | 4567 | { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
| 4547 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, | 4568 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
| @@ -5401,8 +5422,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
| 5401 | * We guarantee to LLDs that they will have at least one | 5422 | * We guarantee to LLDs that they will have at least one |
| 5402 | * non-zero sg if the command is a data command. | 5423 | * non-zero sg if the command is a data command. |
| 5403 | */ | 5424 | */ |
| 5404 | if (WARN_ON_ONCE(ata_is_data(prot) && | 5425 | if (ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)) |
| 5405 | (!qc->sg || !qc->n_elem || !qc->nbytes))) | ||
| 5406 | goto sys_err; | 5426 | goto sys_err; |
| 5407 | 5427 | ||
| 5408 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5428 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 11c3137d7b0a..c016829a38fd 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -815,7 +815,8 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) | |||
| 815 | 815 | ||
| 816 | if (ap->pflags & ATA_PFLAG_LOADING) | 816 | if (ap->pflags & ATA_PFLAG_LOADING) |
| 817 | ap->pflags &= ~ATA_PFLAG_LOADING; | 817 | ap->pflags &= ~ATA_PFLAG_LOADING; |
| 818 | else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) | 818 | else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && |
| 819 | !(ap->flags & ATA_FLAG_SAS_HOST)) | ||
| 819 | schedule_delayed_work(&ap->hotplug_task, 0); | 820 | schedule_delayed_work(&ap->hotplug_task, 0); |
| 820 | 821 | ||
| 821 | if (ap->pflags & ATA_PFLAG_RECOVERED) | 822 | if (ap->pflags & ATA_PFLAG_RECOVERED) |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 66be961c93a4..89a9d4a2efc8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -3316,6 +3316,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
| 3316 | goto invalid_fld; | 3316 | goto invalid_fld; |
| 3317 | } | 3317 | } |
| 3318 | 3318 | ||
| 3319 | /* We may not issue NCQ commands to devices not supporting NCQ */ | ||
| 3320 | if (ata_is_ncq(tf->protocol) && !ata_ncq_enabled(dev)) { | ||
| 3321 | fp = 1; | ||
| 3322 | goto invalid_fld; | ||
| 3323 | } | ||
| 3324 | |||
| 3319 | /* sanity check for pio multi commands */ | 3325 | /* sanity check for pio multi commands */ |
| 3320 | if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) { | 3326 | if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) { |
| 3321 | fp = 1; | 3327 | fp = 1; |
| @@ -4282,7 +4288,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, | |||
| 4282 | #ifdef ATA_DEBUG | 4288 | #ifdef ATA_DEBUG |
| 4283 | struct scsi_device *scsidev = cmd->device; | 4289 | struct scsi_device *scsidev = cmd->device; |
| 4284 | 4290 | ||
| 4285 | DPRINTK("CDB (%u:%d,%d,%d) %9ph\n", | 4291 | DPRINTK("CDB (%u:%d,%d,%lld) %9ph\n", |
| 4286 | ap->print_id, | 4292 | ap->print_id, |
| 4287 | scsidev->channel, scsidev->id, scsidev->lun, | 4293 | scsidev->channel, scsidev->id, scsidev->lun, |
| 4288 | cmd->cmnd); | 4294 | cmd->cmnd); |
| @@ -4309,7 +4315,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, | |||
| 4309 | if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { | 4315 | if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { |
| 4310 | /* relay SCSI command to ATAPI device */ | 4316 | /* relay SCSI command to ATAPI device */ |
| 4311 | int len = COMMAND_SIZE(scsi_op); | 4317 | int len = COMMAND_SIZE(scsi_op); |
| 4312 | if (unlikely(len > scmd->cmd_len || len > dev->cdb_len)) | 4318 | if (unlikely(len > scmd->cmd_len || |
| 4319 | len > dev->cdb_len || | ||
| 4320 | scmd->cmd_len > ATAPI_CDB_LEN)) | ||
| 4313 | goto bad_cdb_len; | 4321 | goto bad_cdb_len; |
| 4314 | 4322 | ||
| 4315 | xlat_func = atapi_xlat; | 4323 | xlat_func = atapi_xlat; |
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 80ee2f2a50d0..6456e07db72a 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c | |||
| @@ -146,6 +146,7 @@ | |||
| 146 | enum sata_rcar_type { | 146 | enum sata_rcar_type { |
| 147 | RCAR_GEN1_SATA, | 147 | RCAR_GEN1_SATA, |
| 148 | RCAR_GEN2_SATA, | 148 | RCAR_GEN2_SATA, |
| 149 | RCAR_GEN3_SATA, | ||
| 149 | RCAR_R8A7790_ES1_SATA, | 150 | RCAR_R8A7790_ES1_SATA, |
| 150 | }; | 151 | }; |
| 151 | 152 | ||
| @@ -784,26 +785,11 @@ static void sata_rcar_setup_port(struct ata_host *host) | |||
| 784 | ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << 2); | 785 | ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << 2); |
| 785 | } | 786 | } |
| 786 | 787 | ||
| 787 | static void sata_rcar_init_controller(struct ata_host *host) | 788 | static void sata_rcar_init_module(struct sata_rcar_priv *priv) |
| 788 | { | 789 | { |
| 789 | struct sata_rcar_priv *priv = host->private_data; | ||
| 790 | void __iomem *base = priv->base; | 790 | void __iomem *base = priv->base; |
| 791 | u32 val; | 791 | u32 val; |
| 792 | 792 | ||
| 793 | /* reset and setup phy */ | ||
| 794 | switch (priv->type) { | ||
| 795 | case RCAR_GEN1_SATA: | ||
| 796 | sata_rcar_gen1_phy_init(priv); | ||
| 797 | break; | ||
| 798 | case RCAR_GEN2_SATA: | ||
| 799 | case RCAR_R8A7790_ES1_SATA: | ||
| 800 | sata_rcar_gen2_phy_init(priv); | ||
| 801 | break; | ||
| 802 | default: | ||
| 803 | dev_warn(host->dev, "SATA phy is not initialized\n"); | ||
| 804 | break; | ||
| 805 | } | ||
| 806 | |||
| 807 | /* SATA-IP reset state */ | 793 | /* SATA-IP reset state */ |
| 808 | val = ioread32(base + ATAPI_CONTROL1_REG); | 794 | val = ioread32(base + ATAPI_CONTROL1_REG); |
| 809 | val |= ATAPI_CONTROL1_RESET; | 795 | val |= ATAPI_CONTROL1_RESET; |
| @@ -824,10 +810,33 @@ static void sata_rcar_init_controller(struct ata_host *host) | |||
| 824 | /* ack and mask */ | 810 | /* ack and mask */ |
| 825 | iowrite32(0, base + SATAINTSTAT_REG); | 811 | iowrite32(0, base + SATAINTSTAT_REG); |
| 826 | iowrite32(0x7ff, base + SATAINTMASK_REG); | 812 | iowrite32(0x7ff, base + SATAINTMASK_REG); |
| 813 | |||
| 827 | /* enable interrupts */ | 814 | /* enable interrupts */ |
| 828 | iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); | 815 | iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); |
| 829 | } | 816 | } |
| 830 | 817 | ||
| 818 | static void sata_rcar_init_controller(struct ata_host *host) | ||
| 819 | { | ||
| 820 | struct sata_rcar_priv *priv = host->private_data; | ||
| 821 | |||
| 822 | /* reset and setup phy */ | ||
| 823 | switch (priv->type) { | ||
| 824 | case RCAR_GEN1_SATA: | ||
| 825 | sata_rcar_gen1_phy_init(priv); | ||
| 826 | break; | ||
| 827 | case RCAR_GEN2_SATA: | ||
| 828 | case RCAR_GEN3_SATA: | ||
| 829 | case RCAR_R8A7790_ES1_SATA: | ||
| 830 | sata_rcar_gen2_phy_init(priv); | ||
| 831 | break; | ||
| 832 | default: | ||
| 833 | dev_warn(host->dev, "SATA phy is not initialized\n"); | ||
| 834 | break; | ||
| 835 | } | ||
| 836 | |||
| 837 | sata_rcar_init_module(priv); | ||
| 838 | } | ||
| 839 | |||
| 831 | static const struct of_device_id sata_rcar_match[] = { | 840 | static const struct of_device_id sata_rcar_match[] = { |
| 832 | { | 841 | { |
| 833 | /* Deprecated by "renesas,sata-r8a7779" */ | 842 | /* Deprecated by "renesas,sata-r8a7779" */ |
| @@ -856,7 +865,7 @@ static const struct of_device_id sata_rcar_match[] = { | |||
| 856 | }, | 865 | }, |
| 857 | { | 866 | { |
| 858 | .compatible = "renesas,sata-r8a7795", | 867 | .compatible = "renesas,sata-r8a7795", |
| 859 | .data = (void *)RCAR_GEN2_SATA | 868 | .data = (void *)RCAR_GEN3_SATA |
| 860 | }, | 869 | }, |
| 861 | { | 870 | { |
| 862 | .compatible = "renesas,rcar-gen2-sata", | 871 | .compatible = "renesas,rcar-gen2-sata", |
| @@ -864,7 +873,7 @@ static const struct of_device_id sata_rcar_match[] = { | |||
| 864 | }, | 873 | }, |
| 865 | { | 874 | { |
| 866 | .compatible = "renesas,rcar-gen3-sata", | 875 | .compatible = "renesas,rcar-gen3-sata", |
| 867 | .data = (void *)RCAR_GEN2_SATA | 876 | .data = (void *)RCAR_GEN3_SATA |
| 868 | }, | 877 | }, |
| 869 | { }, | 878 | { }, |
| 870 | }; | 879 | }; |
| @@ -982,11 +991,18 @@ static int sata_rcar_resume(struct device *dev) | |||
| 982 | if (ret) | 991 | if (ret) |
| 983 | return ret; | 992 | return ret; |
| 984 | 993 | ||
| 985 | /* ack and mask */ | 994 | if (priv->type == RCAR_GEN3_SATA) { |
| 986 | iowrite32(0, base + SATAINTSTAT_REG); | 995 | sata_rcar_gen2_phy_init(priv); |
| 987 | iowrite32(0x7ff, base + SATAINTMASK_REG); | 996 | sata_rcar_init_module(priv); |
| 988 | /* enable interrupts */ | 997 | } else { |
| 989 | iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); | 998 | /* ack and mask */ |
| 999 | iowrite32(0, base + SATAINTSTAT_REG); | ||
| 1000 | iowrite32(0x7ff, base + SATAINTMASK_REG); | ||
| 1001 | |||
| 1002 | /* enable interrupts */ | ||
| 1003 | iowrite32(ATAPI_INT_ENABLE_SATAINT, | ||
| 1004 | base + ATAPI_INT_ENABLE_REG); | ||
| 1005 | } | ||
| 990 | 1006 | ||
| 991 | ata_host_resume(host); | 1007 | ata_host_resume(host); |
| 992 | 1008 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 60bf04b8f103..366a49c7c08f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -231,7 +231,6 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 231 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, | 231 | { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, |
| 232 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, | 232 | { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, |
| 233 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, | 233 | { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, |
| 234 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | ||
| 235 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, | 234 | { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, |
| 236 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, | 235 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, |
| 237 | { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, | 236 | { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, |
| @@ -264,6 +263,7 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 264 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 263 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
| 265 | 264 | ||
| 266 | /* QCA ROME chipset */ | 265 | /* QCA ROME chipset */ |
| 266 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME }, | ||
| 267 | { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, | 267 | { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, |
| 268 | { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, | 268 | { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, |
| 269 | { USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME }, | 269 | { USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME }, |
| @@ -386,10 +386,10 @@ static const struct usb_device_id blacklist_table[] = { | |||
| 386 | */ | 386 | */ |
| 387 | static const struct dmi_system_id btusb_needs_reset_resume_table[] = { | 387 | static const struct dmi_system_id btusb_needs_reset_resume_table[] = { |
| 388 | { | 388 | { |
| 389 | /* Lenovo Yoga 920 (QCA Rome device 0cf3:e300) */ | 389 | /* Dell OptiPlex 3060 (QCA ROME device 0cf3:e007) */ |
| 390 | .matches = { | 390 | .matches = { |
| 391 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 391 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 392 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920"), | 392 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 3060"), |
| 393 | }, | 393 | }, |
| 394 | }, | 394 | }, |
| 395 | {} | 395 | {} |
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 6314dfb02969..40b9fb247010 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c | |||
| @@ -244,7 +244,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data) | |||
| 244 | 244 | ||
| 245 | bt_dev_dbg(bdev, "Host wake IRQ"); | 245 | bt_dev_dbg(bdev, "Host wake IRQ"); |
| 246 | 246 | ||
| 247 | pm_request_resume(bdev->dev); | 247 | pm_runtime_get(bdev->dev); |
| 248 | pm_runtime_mark_last_busy(bdev->dev); | ||
| 249 | pm_runtime_put_autosuspend(bdev->dev); | ||
| 248 | 250 | ||
| 249 | return IRQ_HANDLED; | 251 | return IRQ_HANDLED; |
| 250 | } | 252 | } |
| @@ -301,7 +303,7 @@ static const struct bcm_set_sleep_mode default_sleep_params = { | |||
| 301 | .usb_auto_sleep = 0, | 303 | .usb_auto_sleep = 0, |
| 302 | .usb_resume_timeout = 0, | 304 | .usb_resume_timeout = 0, |
| 303 | .break_to_host = 0, | 305 | .break_to_host = 0, |
| 304 | .pulsed_host_wake = 0, | 306 | .pulsed_host_wake = 1, |
| 305 | }; | 307 | }; |
| 306 | 308 | ||
| 307 | static int bcm_setup_sleep(struct hci_uart *hu) | 309 | static int bcm_setup_sleep(struct hci_uart *hu) |
| @@ -586,8 +588,11 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) | |||
| 586 | } else if (!bcm->rx_skb) { | 588 | } else if (!bcm->rx_skb) { |
| 587 | /* Delay auto-suspend when receiving completed packet */ | 589 | /* Delay auto-suspend when receiving completed packet */ |
| 588 | mutex_lock(&bcm_device_lock); | 590 | mutex_lock(&bcm_device_lock); |
| 589 | if (bcm->dev && bcm_device_exists(bcm->dev)) | 591 | if (bcm->dev && bcm_device_exists(bcm->dev)) { |
| 590 | pm_request_resume(bcm->dev->dev); | 592 | pm_runtime_get(bcm->dev->dev); |
| 593 | pm_runtime_mark_last_busy(bcm->dev->dev); | ||
| 594 | pm_runtime_put_autosuspend(bcm->dev->dev); | ||
| 595 | } | ||
| 591 | mutex_unlock(&bcm_device_lock); | 596 | mutex_unlock(&bcm_device_lock); |
| 592 | } | 597 | } |
| 593 | 598 | ||
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 44301a3d9963..a07f6451694a 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c | |||
| @@ -449,17 +449,17 @@ struct bcm2835_pll_ana_bits { | |||
| 449 | static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { | 449 | static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { |
| 450 | .mask0 = 0, | 450 | .mask0 = 0, |
| 451 | .set0 = 0, | 451 | .set0 = 0, |
| 452 | .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), | 452 | .mask1 = A2W_PLL_KI_MASK | A2W_PLL_KP_MASK, |
| 453 | .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), | 453 | .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), |
| 454 | .mask3 = (u32)~A2W_PLL_KA_MASK, | 454 | .mask3 = A2W_PLL_KA_MASK, |
| 455 | .set3 = (2 << A2W_PLL_KA_SHIFT), | 455 | .set3 = (2 << A2W_PLL_KA_SHIFT), |
| 456 | .fb_prediv_mask = BIT(14), | 456 | .fb_prediv_mask = BIT(14), |
| 457 | }; | 457 | }; |
| 458 | 458 | ||
| 459 | static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { | 459 | static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { |
| 460 | .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), | 460 | .mask0 = A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK, |
| 461 | .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), | 461 | .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), |
| 462 | .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), | 462 | .mask1 = A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK, |
| 463 | .set1 = (6 << A2W_PLLH_KP_SHIFT), | 463 | .set1 = (6 << A2W_PLLH_KP_SHIFT), |
| 464 | .mask3 = 0, | 464 | .mask3 = 0, |
| 465 | .set3 = 0, | 465 | .set3 = 0, |
| @@ -623,8 +623,10 @@ static int bcm2835_pll_on(struct clk_hw *hw) | |||
| 623 | ~A2W_PLL_CTRL_PWRDN); | 623 | ~A2W_PLL_CTRL_PWRDN); |
| 624 | 624 | ||
| 625 | /* Take the PLL out of reset. */ | 625 | /* Take the PLL out of reset. */ |
| 626 | spin_lock(&cprman->regs_lock); | ||
| 626 | cprman_write(cprman, data->cm_ctrl_reg, | 627 | cprman_write(cprman, data->cm_ctrl_reg, |
| 627 | cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST); | 628 | cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST); |
| 629 | spin_unlock(&cprman->regs_lock); | ||
| 628 | 630 | ||
| 629 | /* Wait for the PLL to lock. */ | 631 | /* Wait for the PLL to lock. */ |
| 630 | timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); | 632 | timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); |
| @@ -701,9 +703,11 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw, | |||
| 701 | } | 703 | } |
| 702 | 704 | ||
| 703 | /* Unmask the reference clock from the oscillator. */ | 705 | /* Unmask the reference clock from the oscillator. */ |
| 706 | spin_lock(&cprman->regs_lock); | ||
| 704 | cprman_write(cprman, A2W_XOSC_CTRL, | 707 | cprman_write(cprman, A2W_XOSC_CTRL, |
| 705 | cprman_read(cprman, A2W_XOSC_CTRL) | | 708 | cprman_read(cprman, A2W_XOSC_CTRL) | |
| 706 | data->reference_enable_mask); | 709 | data->reference_enable_mask); |
| 710 | spin_unlock(&cprman->regs_lock); | ||
| 707 | 711 | ||
| 708 | if (do_ana_setup_first) | 712 | if (do_ana_setup_first) |
| 709 | bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana); | 713 | bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana); |
diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index 9f7f931d6b2f..5eb50c31e455 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c | |||
| @@ -205,6 +205,18 @@ static const struct aspeed_clk_soc_data ast2400_data = { | |||
| 205 | .calc_pll = aspeed_ast2400_calc_pll, | 205 | .calc_pll = aspeed_ast2400_calc_pll, |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | static int aspeed_clk_is_enabled(struct clk_hw *hw) | ||
| 209 | { | ||
| 210 | struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); | ||
| 211 | u32 clk = BIT(gate->clock_idx); | ||
| 212 | u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk; | ||
| 213 | u32 reg; | ||
| 214 | |||
| 215 | regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®); | ||
| 216 | |||
| 217 | return ((reg & clk) == enval) ? 1 : 0; | ||
| 218 | } | ||
| 219 | |||
| 208 | static int aspeed_clk_enable(struct clk_hw *hw) | 220 | static int aspeed_clk_enable(struct clk_hw *hw) |
| 209 | { | 221 | { |
| 210 | struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); | 222 | struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); |
| @@ -215,6 +227,11 @@ static int aspeed_clk_enable(struct clk_hw *hw) | |||
| 215 | 227 | ||
| 216 | spin_lock_irqsave(gate->lock, flags); | 228 | spin_lock_irqsave(gate->lock, flags); |
| 217 | 229 | ||
| 230 | if (aspeed_clk_is_enabled(hw)) { | ||
| 231 | spin_unlock_irqrestore(gate->lock, flags); | ||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 218 | if (gate->reset_idx >= 0) { | 235 | if (gate->reset_idx >= 0) { |
| 219 | /* Put IP in reset */ | 236 | /* Put IP in reset */ |
| 220 | regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst); | 237 | regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst); |
| @@ -255,17 +272,6 @@ static void aspeed_clk_disable(struct clk_hw *hw) | |||
| 255 | spin_unlock_irqrestore(gate->lock, flags); | 272 | spin_unlock_irqrestore(gate->lock, flags); |
| 256 | } | 273 | } |
| 257 | 274 | ||
| 258 | static int aspeed_clk_is_enabled(struct clk_hw *hw) | ||
| 259 | { | ||
| 260 | struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); | ||
| 261 | u32 clk = BIT(gate->clock_idx); | ||
| 262 | u32 reg; | ||
| 263 | |||
| 264 | regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®); | ||
| 265 | |||
| 266 | return (reg & clk) ? 0 : 1; | ||
| 267 | } | ||
| 268 | |||
| 269 | static const struct clk_ops aspeed_clk_gate_ops = { | 275 | static const struct clk_ops aspeed_clk_gate_ops = { |
| 270 | .enable = aspeed_clk_enable, | 276 | .enable = aspeed_clk_enable, |
| 271 | .disable = aspeed_clk_disable, | 277 | .disable = aspeed_clk_disable, |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0f686a9dac3e..076d4244d672 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
| @@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core, | |||
| 1125 | { | 1125 | { |
| 1126 | lockdep_assert_held(&prepare_lock); | 1126 | lockdep_assert_held(&prepare_lock); |
| 1127 | 1127 | ||
| 1128 | if (!core) | 1128 | if (!core) { |
| 1129 | req->rate = 0; | ||
| 1129 | return 0; | 1130 | return 0; |
| 1131 | } | ||
| 1130 | 1132 | ||
| 1131 | clk_core_init_rate_req(core, req); | 1133 | clk_core_init_rate_req(core, req); |
| 1132 | 1134 | ||
| @@ -2309,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees) | |||
| 2309 | 2311 | ||
| 2310 | trace_clk_set_phase(core, degrees); | 2312 | trace_clk_set_phase(core, degrees); |
| 2311 | 2313 | ||
| 2312 | if (core->ops->set_phase) | 2314 | if (core->ops->set_phase) { |
| 2313 | ret = core->ops->set_phase(core->hw, degrees); | 2315 | ret = core->ops->set_phase(core->hw, degrees); |
| 2316 | if (!ret) | ||
| 2317 | core->phase = degrees; | ||
| 2318 | } | ||
| 2314 | 2319 | ||
| 2315 | trace_clk_set_phase_complete(core, degrees); | 2320 | trace_clk_set_phase_complete(core, degrees); |
| 2316 | 2321 | ||
| @@ -2968,22 +2973,37 @@ static int __clk_core_init(struct clk_core *core) | |||
| 2968 | core->rate = core->req_rate = rate; | 2973 | core->rate = core->req_rate = rate; |
| 2969 | 2974 | ||
| 2970 | /* | 2975 | /* |
| 2976 | * Enable CLK_IS_CRITICAL clocks so newly added critical clocks | ||
| 2977 | * don't get accidentally disabled when walking the orphan tree and | ||
| 2978 | * reparenting clocks | ||
| 2979 | */ | ||
| 2980 | if (core->flags & CLK_IS_CRITICAL) { | ||
| 2981 | unsigned long flags; | ||
| 2982 | |||
| 2983 | clk_core_prepare(core); | ||
| 2984 | |||
| 2985 | flags = clk_enable_lock(); | ||
| 2986 | clk_core_enable(core); | ||
| 2987 | clk_enable_unlock(flags); | ||
| 2988 | } | ||
| 2989 | |||
| 2990 | /* | ||
| 2971 | * walk the list of orphan clocks and reparent any that newly finds a | 2991 | * walk the list of orphan clocks and reparent any that newly finds a |
| 2972 | * parent. | 2992 | * parent. |
| 2973 | */ | 2993 | */ |
| 2974 | hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { | 2994 | hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { |
| 2975 | struct clk_core *parent = __clk_init_parent(orphan); | 2995 | struct clk_core *parent = __clk_init_parent(orphan); |
| 2976 | unsigned long flags; | ||
| 2977 | 2996 | ||
| 2978 | /* | 2997 | /* |
| 2979 | * we could call __clk_set_parent, but that would result in a | 2998 | * We need to use __clk_set_parent_before() and _after() to |
| 2980 | * redundant call to the .set_rate op, if it exists | 2999 | * to properly migrate any prepare/enable count of the orphan |
| 3000 | * clock. This is important for CLK_IS_CRITICAL clocks, which | ||
| 3001 | * are enabled during init but might not have a parent yet. | ||
| 2981 | */ | 3002 | */ |
| 2982 | if (parent) { | 3003 | if (parent) { |
| 2983 | /* update the clk tree topology */ | 3004 | /* update the clk tree topology */ |
| 2984 | flags = clk_enable_lock(); | 3005 | __clk_set_parent_before(orphan, parent); |
| 2985 | clk_reparent(orphan, parent); | 3006 | __clk_set_parent_after(orphan, parent, NULL); |
| 2986 | clk_enable_unlock(flags); | ||
| 2987 | __clk_recalc_accuracies(orphan); | 3007 | __clk_recalc_accuracies(orphan); |
| 2988 | __clk_recalc_rates(orphan, 0); | 3008 | __clk_recalc_rates(orphan, 0); |
| 2989 | } | 3009 | } |
| @@ -3000,16 +3020,6 @@ static int __clk_core_init(struct clk_core *core) | |||
| 3000 | if (core->ops->init) | 3020 | if (core->ops->init) |
| 3001 | core->ops->init(core->hw); | 3021 | core->ops->init(core->hw); |
| 3002 | 3022 | ||
| 3003 | if (core->flags & CLK_IS_CRITICAL) { | ||
| 3004 | unsigned long flags; | ||
| 3005 | |||
| 3006 | clk_core_prepare(core); | ||
| 3007 | |||
| 3008 | flags = clk_enable_lock(); | ||
| 3009 | clk_core_enable(core); | ||
| 3010 | clk_enable_unlock(flags); | ||
| 3011 | } | ||
| 3012 | |||
| 3013 | kref_init(&core->ref); | 3023 | kref_init(&core->ref); |
| 3014 | out: | 3024 | out: |
| 3015 | clk_pm_runtime_put(core); | 3025 | clk_pm_runtime_put(core); |
diff --git a/drivers/clk/hisilicon/clk-hi3660-stub.c b/drivers/clk/hisilicon/clk-hi3660-stub.c index 9b6c72bbddf9..e8b2c43b1bb8 100644 --- a/drivers/clk/hisilicon/clk-hi3660-stub.c +++ b/drivers/clk/hisilicon/clk-hi3660-stub.c | |||
| @@ -149,6 +149,8 @@ static int hi3660_stub_clk_probe(struct platform_device *pdev) | |||
| 149 | return PTR_ERR(stub_clk_chan.mbox); | 149 | return PTR_ERR(stub_clk_chan.mbox); |
| 150 | 150 | ||
| 151 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 151 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 152 | if (!res) | ||
| 153 | return -EINVAL; | ||
| 152 | freq_reg = devm_ioremap(dev, res->start, resource_size(res)); | 154 | freq_reg = devm_ioremap(dev, res->start, resource_size(res)); |
| 153 | if (!freq_reg) | 155 | if (!freq_reg) |
| 154 | return -ENOMEM; | 156 | return -ENOMEM; |
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index c864992e6983..caa8bd40692c 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c | |||
| @@ -131,7 +131,17 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_ | |||
| 131 | static struct clk *clk[IMX5_CLK_END]; | 131 | static struct clk *clk[IMX5_CLK_END]; |
| 132 | static struct clk_onecell_data clk_data; | 132 | static struct clk_onecell_data clk_data; |
| 133 | 133 | ||
| 134 | static struct clk ** const uart_clks[] __initconst = { | 134 | static struct clk ** const uart_clks_mx51[] __initconst = { |
| 135 | &clk[IMX5_CLK_UART1_IPG_GATE], | ||
| 136 | &clk[IMX5_CLK_UART1_PER_GATE], | ||
| 137 | &clk[IMX5_CLK_UART2_IPG_GATE], | ||
| 138 | &clk[IMX5_CLK_UART2_PER_GATE], | ||
| 139 | &clk[IMX5_CLK_UART3_IPG_GATE], | ||
| 140 | &clk[IMX5_CLK_UART3_PER_GATE], | ||
| 141 | NULL | ||
| 142 | }; | ||
| 143 | |||
| 144 | static struct clk ** const uart_clks_mx50_mx53[] __initconst = { | ||
| 135 | &clk[IMX5_CLK_UART1_IPG_GATE], | 145 | &clk[IMX5_CLK_UART1_IPG_GATE], |
| 136 | &clk[IMX5_CLK_UART1_PER_GATE], | 146 | &clk[IMX5_CLK_UART1_PER_GATE], |
| 137 | &clk[IMX5_CLK_UART2_IPG_GATE], | 147 | &clk[IMX5_CLK_UART2_IPG_GATE], |
| @@ -321,8 +331,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
| 321 | clk_prepare_enable(clk[IMX5_CLK_TMAX1]); | 331 | clk_prepare_enable(clk[IMX5_CLK_TMAX1]); |
| 322 | clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ | 332 | clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ |
| 323 | clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ | 333 | clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ |
| 324 | |||
| 325 | imx_register_uart_clocks(uart_clks); | ||
| 326 | } | 334 | } |
| 327 | 335 | ||
| 328 | static void __init mx50_clocks_init(struct device_node *np) | 336 | static void __init mx50_clocks_init(struct device_node *np) |
| @@ -388,6 +396,8 @@ static void __init mx50_clocks_init(struct device_node *np) | |||
| 388 | 396 | ||
| 389 | r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); | 397 | r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); |
| 390 | clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); | 398 | clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); |
| 399 | |||
| 400 | imx_register_uart_clocks(uart_clks_mx50_mx53); | ||
| 391 | } | 401 | } |
| 392 | CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init); | 402 | CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init); |
| 393 | 403 | ||
| @@ -477,6 +487,8 @@ static void __init mx51_clocks_init(struct device_node *np) | |||
| 477 | val = readl(MXC_CCM_CLPCR); | 487 | val = readl(MXC_CCM_CLPCR); |
| 478 | val |= 1 << 23; | 488 | val |= 1 << 23; |
| 479 | writel(val, MXC_CCM_CLPCR); | 489 | writel(val, MXC_CCM_CLPCR); |
| 490 | |||
| 491 | imx_register_uart_clocks(uart_clks_mx51); | ||
| 480 | } | 492 | } |
| 481 | CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init); | 493 | CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init); |
| 482 | 494 | ||
| @@ -606,5 +618,7 @@ static void __init mx53_clocks_init(struct device_node *np) | |||
| 606 | 618 | ||
| 607 | r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); | 619 | r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); |
| 608 | clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); | 620 | clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); |
| 621 | |||
| 622 | imx_register_uart_clocks(uart_clks_mx50_mx53); | ||
| 609 | } | 623 | } |
| 610 | CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init); | 624 | CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init); |
diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c index 246957f1a413..b1cc8dbcd327 100644 --- a/drivers/clk/qcom/apcs-msm8916.c +++ b/drivers/clk/qcom/apcs-msm8916.c | |||
| @@ -49,11 +49,10 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) | |||
| 49 | struct clk_regmap_mux_div *a53cc; | 49 | struct clk_regmap_mux_div *a53cc; |
| 50 | struct regmap *regmap; | 50 | struct regmap *regmap; |
| 51 | struct clk_init_data init = { }; | 51 | struct clk_init_data init = { }; |
| 52 | int ret; | 52 | int ret = -ENODEV; |
| 53 | 53 | ||
| 54 | regmap = dev_get_regmap(parent, NULL); | 54 | regmap = dev_get_regmap(parent, NULL); |
| 55 | if (IS_ERR(regmap)) { | 55 | if (!regmap) { |
| 56 | ret = PTR_ERR(regmap); | ||
| 57 | dev_err(dev, "failed to get regmap: %d\n", ret); | 56 | dev_err(dev, "failed to get regmap: %d\n", ret); |
| 58 | return ret; | 57 | return ret; |
| 59 | } | 58 | } |
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 72b16ed1012b..3b97f60540ad 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c | |||
| @@ -762,7 +762,7 @@ static struct ccu_mp out_a_clk = { | |||
| 762 | .features = CCU_FEATURE_FIXED_PREDIV, | 762 | .features = CCU_FEATURE_FIXED_PREDIV, |
| 763 | .hw.init = CLK_HW_INIT_PARENTS("out-a", | 763 | .hw.init = CLK_HW_INIT_PARENTS("out-a", |
| 764 | clk_out_parents, | 764 | clk_out_parents, |
| 765 | &ccu_div_ops, | 765 | &ccu_mp_ops, |
| 766 | 0), | 766 | 0), |
| 767 | }, | 767 | }, |
| 768 | }; | 768 | }; |
| @@ -783,7 +783,7 @@ static struct ccu_mp out_b_clk = { | |||
| 783 | .features = CCU_FEATURE_FIXED_PREDIV, | 783 | .features = CCU_FEATURE_FIXED_PREDIV, |
| 784 | .hw.init = CLK_HW_INIT_PARENTS("out-b", | 784 | .hw.init = CLK_HW_INIT_PARENTS("out-b", |
| 785 | clk_out_parents, | 785 | clk_out_parents, |
| 786 | &ccu_div_ops, | 786 | &ccu_mp_ops, |
| 787 | 0), | 787 | 0), |
| 788 | }, | 788 | }, |
| 789 | }; | 789 | }; |
| @@ -804,7 +804,7 @@ static struct ccu_mp out_c_clk = { | |||
| 804 | .features = CCU_FEATURE_FIXED_PREDIV, | 804 | .features = CCU_FEATURE_FIXED_PREDIV, |
| 805 | .hw.init = CLK_HW_INIT_PARENTS("out-c", | 805 | .hw.init = CLK_HW_INIT_PARENTS("out-c", |
| 806 | clk_out_parents, | 806 | clk_out_parents, |
| 807 | &ccu_div_ops, | 807 | &ccu_mp_ops, |
| 808 | 0), | 808 | 0), |
| 809 | }, | 809 | }, |
| 810 | }; | 810 | }; |
diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index 612491a26070..12e0a2d19911 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c | |||
| @@ -45,7 +45,7 @@ static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = { | |||
| 45 | 45 | ||
| 46 | static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = { | 46 | static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = { |
| 47 | { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, | 47 | { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, |
| 48 | { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP, "lcd_gclk", "lcdc_clkdm" }, | 48 | { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" }, |
| 49 | { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" }, | 49 | { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" }, |
| 50 | { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, | 50 | { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, |
| 51 | { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" }, | 51 | { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" }, |
diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 2b7c2e017665..63c5ddb50187 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c | |||
| @@ -187,7 +187,7 @@ static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst | |||
| 187 | { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, | 187 | { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
| 188 | { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, | 188 | { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
| 189 | { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" }, | 189 | { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" }, |
| 190 | { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "disp_clk", "dss_clkdm" }, | 190 | { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" }, |
| 191 | { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, | 191 | { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, |
| 192 | { 0 }, | 192 | { 0 }, |
| 193 | }; | 193 | }; |
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index afa0d6bfc5c1..421b05392220 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c | |||
| @@ -537,6 +537,8 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) | |||
| 537 | init.parent_names = ®_data->parent; | 537 | init.parent_names = ®_data->parent; |
| 538 | init.num_parents = 1; | 538 | init.num_parents = 1; |
| 539 | init.flags = 0; | 539 | init.flags = 0; |
| 540 | if (reg_data->flags & CLKF_SET_RATE_PARENT) | ||
| 541 | init.flags |= CLK_SET_RATE_PARENT; | ||
| 540 | init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", | 542 | init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", |
| 541 | node->parent->name, node->name, | 543 | node->parent->name, node->name, |
| 542 | reg_data->offset, 0); | 544 | reg_data->offset, 0); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index af1b879a9ee9..66cb10cdc7c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -2063,9 +2063,12 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
| 2063 | 2063 | ||
| 2064 | DRM_INFO("amdgpu: finishing device.\n"); | 2064 | DRM_INFO("amdgpu: finishing device.\n"); |
| 2065 | adev->shutdown = true; | 2065 | adev->shutdown = true; |
| 2066 | if (adev->mode_info.mode_config_initialized) | 2066 | if (adev->mode_info.mode_config_initialized){ |
| 2067 | drm_crtc_force_disable_all(adev->ddev); | 2067 | if (!amdgpu_device_has_dc_support(adev)) |
| 2068 | 2068 | drm_crtc_force_disable_all(adev->ddev); | |
| 2069 | else | ||
| 2070 | drm_atomic_helper_shutdown(adev->ddev); | ||
| 2071 | } | ||
| 2069 | amdgpu_ib_pool_fini(adev); | 2072 | amdgpu_ib_pool_fini(adev); |
| 2070 | amdgpu_fence_driver_fini(adev); | 2073 | amdgpu_fence_driver_fini(adev); |
| 2071 | amdgpu_fbdev_fini(adev); | 2074 | amdgpu_fbdev_fini(adev); |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c345e645f1d7..63c67346d316 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -3134,8 +3134,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, | |||
| 3134 | 3134 | ||
| 3135 | switch (aplane->base.type) { | 3135 | switch (aplane->base.type) { |
| 3136 | case DRM_PLANE_TYPE_PRIMARY: | 3136 | case DRM_PLANE_TYPE_PRIMARY: |
| 3137 | aplane->base.format_default = true; | ||
| 3138 | |||
| 3139 | res = drm_universal_plane_init( | 3137 | res = drm_universal_plane_init( |
| 3140 | dm->adev->ddev, | 3138 | dm->adev->ddev, |
| 3141 | &aplane->base, | 3139 | &aplane->base, |
| @@ -4794,6 +4792,9 @@ static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state, | |||
| 4794 | return -EDEADLK; | 4792 | return -EDEADLK; |
| 4795 | 4793 | ||
| 4796 | crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc); | 4794 | crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc); |
| 4795 | if (IS_ERR(crtc_state)) | ||
| 4796 | return PTR_ERR(crtc_state); | ||
| 4797 | |||
| 4797 | if (crtc->primary == plane && crtc_state->active) { | 4798 | if (crtc->primary == plane && crtc_state->active) { |
| 4798 | if (!plane_state->fb) | 4799 | if (!plane_state->fb) |
| 4799 | return -EINVAL; | 4800 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 9bd142f65f9b..e1acc10e35a2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | |||
| @@ -109,7 +109,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps( | |||
| 109 | struct cea_sad *sad = &sads[i]; | 109 | struct cea_sad *sad = &sads[i]; |
| 110 | 110 | ||
| 111 | edid_caps->audio_modes[i].format_code = sad->format; | 111 | edid_caps->audio_modes[i].format_code = sad->format; |
| 112 | edid_caps->audio_modes[i].channel_count = sad->channels; | 112 | edid_caps->audio_modes[i].channel_count = sad->channels + 1; |
| 113 | edid_caps->audio_modes[i].sample_rate = sad->freq; | 113 | edid_caps->audio_modes[i].sample_rate = sad->freq; |
| 114 | edid_caps->audio_modes[i].sample_size = sad->byte2; | 114 | edid_caps->audio_modes[i].sample_size = sad->byte2; |
| 115 | } | 115 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index a993279a8f2d..f11f17fe08f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | |||
| @@ -496,6 +496,9 @@ struct dce_hwseq_registers { | |||
| 496 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ | 496 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ |
| 497 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | 497 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ |
| 498 | HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\ | 498 | HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\ |
| 499 | HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\ | ||
| 500 | HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\ | ||
| 501 | HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\ | ||
| 499 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ | 502 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ |
| 500 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\ | 503 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\ |
| 501 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ | 504 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ |
| @@ -591,7 +594,10 @@ struct dce_hwseq_registers { | |||
| 591 | type DENTIST_DISPCLK_WDIVIDER; \ | 594 | type DENTIST_DISPCLK_WDIVIDER; \ |
| 592 | type VGA_TEST_ENABLE; \ | 595 | type VGA_TEST_ENABLE; \ |
| 593 | type VGA_TEST_RENDER_START; \ | 596 | type VGA_TEST_RENDER_START; \ |
| 594 | type D1VGA_MODE_ENABLE; | 597 | type D1VGA_MODE_ENABLE; \ |
| 598 | type D2VGA_MODE_ENABLE; \ | ||
| 599 | type D3VGA_MODE_ENABLE; \ | ||
| 600 | type D4VGA_MODE_ENABLE; | ||
| 595 | 601 | ||
| 596 | struct dce_hwseq_shift { | 602 | struct dce_hwseq_shift { |
| 597 | HWSEQ_REG_FIELD_LIST(uint8_t) | 603 | HWSEQ_REG_FIELD_LIST(uint8_t) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c index 3931412ab6d3..87093894ea9e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c | |||
| @@ -128,23 +128,22 @@ static void set_truncation( | |||
| 128 | return; | 128 | return; |
| 129 | } | 129 | } |
| 130 | /* on other format-to do */ | 130 | /* on other format-to do */ |
| 131 | if (params->flags.TRUNCATE_ENABLED == 0 || | 131 | if (params->flags.TRUNCATE_ENABLED == 0) |
| 132 | params->flags.TRUNCATE_DEPTH == 2) | ||
| 133 | return; | 132 | return; |
| 134 | /*Set truncation depth and Enable truncation*/ | 133 | /*Set truncation depth and Enable truncation*/ |
| 135 | REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, | 134 | REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, |
| 136 | FMT_TRUNCATE_EN, 1, | 135 | FMT_TRUNCATE_EN, 1, |
| 137 | FMT_TRUNCATE_DEPTH, | 136 | FMT_TRUNCATE_DEPTH, |
| 138 | params->flags.TRUNCATE_MODE, | 137 | params->flags.TRUNCATE_DEPTH, |
| 139 | FMT_TRUNCATE_MODE, | 138 | FMT_TRUNCATE_MODE, |
| 140 | params->flags.TRUNCATE_DEPTH); | 139 | params->flags.TRUNCATE_MODE); |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | 142 | ||
| 144 | /** | 143 | /** |
| 145 | * set_spatial_dither | 144 | * set_spatial_dither |
| 146 | * 1) set spatial dithering mode: pattern of seed | 145 | * 1) set spatial dithering mode: pattern of seed |
| 147 | * 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp | 146 | * 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp |
| 148 | * 3) set random seed | 147 | * 3) set random seed |
| 149 | * 4) set random mode | 148 | * 4) set random mode |
| 150 | * lfsr is reset every frame or not reset | 149 | * lfsr is reset every frame or not reset |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 072e4485e85e..dc1e010725c1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
| @@ -238,14 +238,24 @@ static void enable_power_gating_plane( | |||
| 238 | static void disable_vga( | 238 | static void disable_vga( |
| 239 | struct dce_hwseq *hws) | 239 | struct dce_hwseq *hws) |
| 240 | { | 240 | { |
| 241 | unsigned int in_vga_mode = 0; | 241 | unsigned int in_vga1_mode = 0; |
| 242 | 242 | unsigned int in_vga2_mode = 0; | |
| 243 | REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga_mode); | 243 | unsigned int in_vga3_mode = 0; |
| 244 | 244 | unsigned int in_vga4_mode = 0; | |
| 245 | if (in_vga_mode == 0) | 245 | |
| 246 | REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode); | ||
| 247 | REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode); | ||
| 248 | REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode); | ||
| 249 | REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode); | ||
| 250 | |||
| 251 | if (in_vga1_mode == 0 && in_vga2_mode == 0 && | ||
| 252 | in_vga3_mode == 0 && in_vga4_mode == 0) | ||
| 246 | return; | 253 | return; |
| 247 | 254 | ||
| 248 | REG_WRITE(D1VGA_CONTROL, 0); | 255 | REG_WRITE(D1VGA_CONTROL, 0); |
| 256 | REG_WRITE(D2VGA_CONTROL, 0); | ||
| 257 | REG_WRITE(D3VGA_CONTROL, 0); | ||
| 258 | REG_WRITE(D4VGA_CONTROL, 0); | ||
| 249 | 259 | ||
| 250 | /* HW Engineer's Notes: | 260 | /* HW Engineer's Notes: |
| 251 | * During switch from vga->extended, if we set the VGA_TEST_ENABLE and | 261 | * During switch from vga->extended, if we set the VGA_TEST_ENABLE and |
diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h index 5f4c2e833a65..d665dd5af5dd 100644 --- a/drivers/gpu/drm/ast/ast_tables.h +++ b/drivers/gpu/drm/ast/ast_tables.h | |||
| @@ -97,7 +97,7 @@ static const struct ast_vbios_dclk_info dclk_table[] = { | |||
| 97 | {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ | 97 | {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ |
| 98 | {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ | 98 | {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ |
| 99 | {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ | 99 | {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ |
| 100 | {0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */ | 100 | {0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */ |
| 101 | {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ | 101 | {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ |
| 102 | {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ | 102 | {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ |
| 103 | {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ | 103 | {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ |
| @@ -127,7 +127,7 @@ static const struct ast_vbios_dclk_info dclk_table_ast2500[] = { | |||
| 127 | {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ | 127 | {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ |
| 128 | {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ | 128 | {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ |
| 129 | {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ | 129 | {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ |
| 130 | {0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */ | 130 | {0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */ |
| 131 | {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ | 131 | {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ |
| 132 | {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ | 132 | {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ |
| 133 | {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ | 133 | {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ |
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index c0530a1af5e3..2dc5e8bed172 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c | |||
| @@ -461,6 +461,12 @@ int drm_mode_getfb(struct drm_device *dev, | |||
| 461 | if (!fb) | 461 | if (!fb) |
| 462 | return -ENOENT; | 462 | return -ENOENT; |
| 463 | 463 | ||
| 464 | /* Multi-planar framebuffers need getfb2. */ | ||
| 465 | if (fb->format->num_planes > 1) { | ||
| 466 | ret = -EINVAL; | ||
| 467 | goto out; | ||
| 468 | } | ||
| 469 | |||
| 464 | r->height = fb->height; | 470 | r->height = fb->height; |
| 465 | r->width = fb->width; | 471 | r->width = fb->width; |
| 466 | r->depth = fb->format->depth; | 472 | r->depth = fb->format->depth; |
| @@ -484,6 +490,7 @@ int drm_mode_getfb(struct drm_device *dev, | |||
| 484 | ret = -ENODEV; | 490 | ret = -ENODEV; |
| 485 | } | 491 | } |
| 486 | 492 | ||
| 493 | out: | ||
| 487 | drm_framebuffer_put(fb); | 494 | drm_framebuffer_put(fb); |
| 488 | 495 | ||
| 489 | return ret; | 496 | return ret; |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f51645a08dca..6aff9d096e13 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -2175,8 +2175,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, | |||
| 2175 | intel_prepare_dp_ddi_buffers(encoder, crtc_state); | 2175 | intel_prepare_dp_ddi_buffers(encoder, crtc_state); |
| 2176 | 2176 | ||
| 2177 | intel_ddi_init_dp_buf_reg(encoder); | 2177 | intel_ddi_init_dp_buf_reg(encoder); |
| 2178 | if (!is_mst) | 2178 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
| 2179 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | ||
| 2180 | intel_dp_start_link_train(intel_dp); | 2179 | intel_dp_start_link_train(intel_dp); |
| 2181 | if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) | 2180 | if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) |
| 2182 | intel_dp_stop_link_train(intel_dp); | 2181 | intel_dp_stop_link_train(intel_dp); |
| @@ -2274,14 +2273,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder, | |||
| 2274 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2273 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 2275 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | 2274 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); |
| 2276 | struct intel_dp *intel_dp = &dig_port->dp; | 2275 | struct intel_dp *intel_dp = &dig_port->dp; |
| 2277 | bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST); | ||
| 2278 | 2276 | ||
| 2279 | /* | 2277 | /* |
| 2280 | * Power down sink before disabling the port, otherwise we end | 2278 | * Power down sink before disabling the port, otherwise we end |
| 2281 | * up getting interrupts from the sink on detecting link loss. | 2279 | * up getting interrupts from the sink on detecting link loss. |
| 2282 | */ | 2280 | */ |
| 2283 | if (!is_mst) | 2281 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
| 2284 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | ||
| 2285 | 2282 | ||
| 2286 | intel_disable_ddi_buf(encoder); | 2283 | intel_disable_ddi_buf(encoder); |
| 2287 | 2284 | ||
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c index 348a4f7ffb67..53747318f4a7 100644 --- a/drivers/gpu/drm/i915/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/intel_hangcheck.c | |||
| @@ -246,7 +246,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd) | |||
| 246 | */ | 246 | */ |
| 247 | tmp = I915_READ_CTL(engine); | 247 | tmp = I915_READ_CTL(engine); |
| 248 | if (tmp & RING_WAIT) { | 248 | if (tmp & RING_WAIT) { |
| 249 | i915_handle_error(dev_priv, 0, | 249 | i915_handle_error(dev_priv, BIT(engine->id), |
| 250 | "Kicking stuck wait on %s", | 250 | "Kicking stuck wait on %s", |
| 251 | engine->name); | 251 | engine->name); |
| 252 | I915_WRITE_CTL(engine, tmp); | 252 | I915_WRITE_CTL(engine, tmp); |
| @@ -258,7 +258,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd) | |||
| 258 | default: | 258 | default: |
| 259 | return ENGINE_DEAD; | 259 | return ENGINE_DEAD; |
| 260 | case 1: | 260 | case 1: |
| 261 | i915_handle_error(dev_priv, 0, | 261 | i915_handle_error(dev_priv, ALL_ENGINES, |
| 262 | "Kicking stuck semaphore on %s", | 262 | "Kicking stuck semaphore on %s", |
| 263 | engine->name); | 263 | engine->name); |
| 264 | I915_WRITE_CTL(engine, tmp); | 264 | I915_WRITE_CTL(engine, tmp); |
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 9a9961802f5c..e83af0f2be86 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c | |||
| @@ -225,7 +225,11 @@ static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, | |||
| 225 | struct drm_crtc_state *old_crtc_state) | 225 | struct drm_crtc_state *old_crtc_state) |
| 226 | { | 226 | { |
| 227 | drm_crtc_vblank_on(crtc); | 227 | drm_crtc_vblank_on(crtc); |
| 228 | } | ||
| 228 | 229 | ||
| 230 | static void ipu_crtc_atomic_flush(struct drm_crtc *crtc, | ||
| 231 | struct drm_crtc_state *old_crtc_state) | ||
| 232 | { | ||
| 229 | spin_lock_irq(&crtc->dev->event_lock); | 233 | spin_lock_irq(&crtc->dev->event_lock); |
| 230 | if (crtc->state->event) { | 234 | if (crtc->state->event) { |
| 231 | WARN_ON(drm_crtc_vblank_get(crtc)); | 235 | WARN_ON(drm_crtc_vblank_get(crtc)); |
| @@ -293,6 +297,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = { | |||
| 293 | .mode_set_nofb = ipu_crtc_mode_set_nofb, | 297 | .mode_set_nofb = ipu_crtc_mode_set_nofb, |
| 294 | .atomic_check = ipu_crtc_atomic_check, | 298 | .atomic_check = ipu_crtc_atomic_check, |
| 295 | .atomic_begin = ipu_crtc_atomic_begin, | 299 | .atomic_begin = ipu_crtc_atomic_begin, |
| 300 | .atomic_flush = ipu_crtc_atomic_flush, | ||
| 296 | .atomic_disable = ipu_crtc_atomic_disable, | 301 | .atomic_disable = ipu_crtc_atomic_disable, |
| 297 | .atomic_enable = ipu_crtc_atomic_enable, | 302 | .atomic_enable = ipu_crtc_atomic_enable, |
| 298 | }; | 303 | }; |
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 57ed56d8623f..d9113faaa62f 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <drm/drm_plane_helper.h> | 22 | #include <drm/drm_plane_helper.h> |
| 23 | 23 | ||
| 24 | #include "video/imx-ipu-v3.h" | 24 | #include "video/imx-ipu-v3.h" |
| 25 | #include "imx-drm.h" | ||
| 25 | #include "ipuv3-plane.h" | 26 | #include "ipuv3-plane.h" |
| 26 | 27 | ||
| 27 | struct ipu_plane_state { | 28 | struct ipu_plane_state { |
| @@ -272,7 +273,7 @@ static void ipu_plane_destroy(struct drm_plane *plane) | |||
| 272 | kfree(ipu_plane); | 273 | kfree(ipu_plane); |
| 273 | } | 274 | } |
| 274 | 275 | ||
| 275 | void ipu_plane_state_reset(struct drm_plane *plane) | 276 | static void ipu_plane_state_reset(struct drm_plane *plane) |
| 276 | { | 277 | { |
| 277 | struct ipu_plane_state *ipu_state; | 278 | struct ipu_plane_state *ipu_state; |
| 278 | 279 | ||
| @@ -292,7 +293,8 @@ void ipu_plane_state_reset(struct drm_plane *plane) | |||
| 292 | plane->state = &ipu_state->base; | 293 | plane->state = &ipu_state->base; |
| 293 | } | 294 | } |
| 294 | 295 | ||
| 295 | struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane) | 296 | static struct drm_plane_state * |
| 297 | ipu_plane_duplicate_state(struct drm_plane *plane) | ||
| 296 | { | 298 | { |
| 297 | struct ipu_plane_state *state; | 299 | struct ipu_plane_state *state; |
| 298 | 300 | ||
| @@ -306,8 +308,8 @@ struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane) | |||
| 306 | return &state->base; | 308 | return &state->base; |
| 307 | } | 309 | } |
| 308 | 310 | ||
| 309 | void ipu_plane_destroy_state(struct drm_plane *plane, | 311 | static void ipu_plane_destroy_state(struct drm_plane *plane, |
| 310 | struct drm_plane_state *state) | 312 | struct drm_plane_state *state) |
| 311 | { | 313 | { |
| 312 | struct ipu_plane_state *ipu_state = to_ipu_plane_state(state); | 314 | struct ipu_plane_state *ipu_state = to_ipu_plane_state(state); |
| 313 | 315 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2e2ca3c6b47d..df9469a8fdb1 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -90,25 +90,18 @@ void radeon_connector_hotplug(struct drm_connector *connector) | |||
| 90 | /* don't do anything if sink is not display port, i.e., | 90 | /* don't do anything if sink is not display port, i.e., |
| 91 | * passive dp->(dvi|hdmi) adaptor | 91 | * passive dp->(dvi|hdmi) adaptor |
| 92 | */ | 92 | */ |
| 93 | if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | 93 | if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT && |
| 94 | int saved_dpms = connector->dpms; | 94 | radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && |
| 95 | /* Only turn off the display if it's physically disconnected */ | 95 | radeon_dp_needs_link_train(radeon_connector)) { |
| 96 | if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { | 96 | /* Don't start link training before we have the DPCD */ |
| 97 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 97 | if (!radeon_dp_getdpcd(radeon_connector)) |
| 98 | } else if (radeon_dp_needs_link_train(radeon_connector)) { | 98 | return; |
| 99 | /* Don't try to start link training before we | 99 | |
| 100 | * have the dpcd */ | 100 | /* Turn the connector off and back on immediately, which |
| 101 | if (!radeon_dp_getdpcd(radeon_connector)) | 101 | * will trigger link training |
| 102 | return; | 102 | */ |
| 103 | 103 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | |
| 104 | /* set it to OFF so that drm_helper_connector_dpms() | 104 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); |
| 105 | * won't return immediately since the current state | ||
| 106 | * is ON at this point. | ||
| 107 | */ | ||
| 108 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
| 109 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
| 110 | } | ||
| 111 | connector->dpms = saved_dpms; | ||
| 112 | } | 105 | } |
| 113 | } | 106 | } |
| 114 | } | 107 | } |
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 4570da0227b4..d9a71f361b14 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
| @@ -111,7 +111,7 @@ static int sun4i_drv_bind(struct device *dev) | |||
| 111 | /* drm_vblank_init calls kcalloc, which can fail */ | 111 | /* drm_vblank_init calls kcalloc, which can fail */ |
| 112 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 112 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
| 113 | if (ret) | 113 | if (ret) |
| 114 | goto free_mem_region; | 114 | goto cleanup_mode_config; |
| 115 | 115 | ||
| 116 | drm->irq_enabled = true; | 116 | drm->irq_enabled = true; |
| 117 | 117 | ||
| @@ -139,7 +139,6 @@ finish_poll: | |||
| 139 | sun4i_framebuffer_free(drm); | 139 | sun4i_framebuffer_free(drm); |
| 140 | cleanup_mode_config: | 140 | cleanup_mode_config: |
| 141 | drm_mode_config_cleanup(drm); | 141 | drm_mode_config_cleanup(drm); |
| 142 | free_mem_region: | ||
| 143 | of_reserved_mem_device_release(dev); | 142 | of_reserved_mem_device_release(dev); |
| 144 | free_drm: | 143 | free_drm: |
| 145 | drm_dev_unref(drm); | 144 | drm_dev_unref(drm); |
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 500b6fb3e028..fa4bcd092eaf 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | |||
| @@ -538,7 +538,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, | |||
| 538 | &sun4i_hdmi_regmap_config); | 538 | &sun4i_hdmi_regmap_config); |
| 539 | if (IS_ERR(hdmi->regmap)) { | 539 | if (IS_ERR(hdmi->regmap)) { |
| 540 | dev_err(dev, "Couldn't create HDMI encoder regmap\n"); | 540 | dev_err(dev, "Couldn't create HDMI encoder regmap\n"); |
| 541 | return PTR_ERR(hdmi->regmap); | 541 | ret = PTR_ERR(hdmi->regmap); |
| 542 | goto err_disable_mod_clk; | ||
| 542 | } | 543 | } |
| 543 | 544 | ||
| 544 | ret = sun4i_tmds_create(hdmi); | 545 | ret = sun4i_tmds_create(hdmi); |
| @@ -551,7 +552,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, | |||
| 551 | hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc"); | 552 | hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc"); |
| 552 | if (IS_ERR(hdmi->ddc_parent_clk)) { | 553 | if (IS_ERR(hdmi->ddc_parent_clk)) { |
| 553 | dev_err(dev, "Couldn't get the HDMI DDC clock\n"); | 554 | dev_err(dev, "Couldn't get the HDMI DDC clock\n"); |
| 554 | return PTR_ERR(hdmi->ddc_parent_clk); | 555 | ret = PTR_ERR(hdmi->ddc_parent_clk); |
| 556 | goto err_disable_mod_clk; | ||
| 555 | } | 557 | } |
| 556 | } else { | 558 | } else { |
| 557 | hdmi->ddc_parent_clk = hdmi->tmds_clk; | 559 | hdmi->ddc_parent_clk = hdmi->tmds_clk; |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 2de586b7c98b..a818ca491605 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | |||
| @@ -103,6 +103,7 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel, | |||
| 103 | 103 | ||
| 104 | if (enabled) { | 104 | if (enabled) { |
| 105 | clk_prepare_enable(clk); | 105 | clk_prepare_enable(clk); |
| 106 | clk_rate_exclusive_get(clk); | ||
| 106 | } else { | 107 | } else { |
| 107 | clk_rate_exclusive_put(clk); | 108 | clk_rate_exclusive_put(clk); |
| 108 | clk_disable_unprepare(clk); | 109 | clk_disable_unprepare(clk); |
| @@ -262,7 +263,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, | |||
| 262 | const struct drm_display_mode *mode) | 263 | const struct drm_display_mode *mode) |
| 263 | { | 264 | { |
| 264 | /* Configure the dot clock */ | 265 | /* Configure the dot clock */ |
| 265 | clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000); | 266 | clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); |
| 266 | 267 | ||
| 267 | /* Set the resolution */ | 268 | /* Set the resolution */ |
| 268 | regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, | 269 | regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, |
| @@ -423,7 +424,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, | |||
| 423 | WARN_ON(!tcon->quirks->has_channel_1); | 424 | WARN_ON(!tcon->quirks->has_channel_1); |
| 424 | 425 | ||
| 425 | /* Configure the dot clock */ | 426 | /* Configure the dot clock */ |
| 426 | clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000); | 427 | clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); |
| 427 | 428 | ||
| 428 | /* Adjust clock delay */ | 429 | /* Adjust clock delay */ |
| 429 | clk_delay = sun4i_tcon_get_clk_delay(mode, 1); | 430 | clk_delay = sun4i_tcon_get_clk_delay(mode, 1); |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index b8403ed48285..fbffe1948b3b 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
| @@ -1903,8 +1903,12 @@ cleanup: | |||
| 1903 | if (!IS_ERR(primary)) | 1903 | if (!IS_ERR(primary)) |
| 1904 | drm_plane_cleanup(primary); | 1904 | drm_plane_cleanup(primary); |
| 1905 | 1905 | ||
| 1906 | if (group && tegra->domain) { | 1906 | if (group && dc->domain) { |
| 1907 | iommu_detach_group(tegra->domain, group); | 1907 | if (group == tegra->group) { |
| 1908 | iommu_detach_group(dc->domain, group); | ||
| 1909 | tegra->group = NULL; | ||
| 1910 | } | ||
| 1911 | |||
| 1908 | dc->domain = NULL; | 1912 | dc->domain = NULL; |
| 1909 | } | 1913 | } |
| 1910 | 1914 | ||
| @@ -1913,8 +1917,10 @@ cleanup: | |||
| 1913 | 1917 | ||
| 1914 | static int tegra_dc_exit(struct host1x_client *client) | 1918 | static int tegra_dc_exit(struct host1x_client *client) |
| 1915 | { | 1919 | { |
| 1920 | struct drm_device *drm = dev_get_drvdata(client->parent); | ||
| 1916 | struct iommu_group *group = iommu_group_get(client->dev); | 1921 | struct iommu_group *group = iommu_group_get(client->dev); |
| 1917 | struct tegra_dc *dc = host1x_client_to_dc(client); | 1922 | struct tegra_dc *dc = host1x_client_to_dc(client); |
| 1923 | struct tegra_drm *tegra = drm->dev_private; | ||
| 1918 | int err; | 1924 | int err; |
| 1919 | 1925 | ||
| 1920 | devm_free_irq(dc->dev, dc->irq, dc); | 1926 | devm_free_irq(dc->dev, dc->irq, dc); |
| @@ -1926,7 +1932,11 @@ static int tegra_dc_exit(struct host1x_client *client) | |||
| 1926 | } | 1932 | } |
| 1927 | 1933 | ||
| 1928 | if (group && dc->domain) { | 1934 | if (group && dc->domain) { |
| 1929 | iommu_detach_group(dc->domain, group); | 1935 | if (group == tegra->group) { |
| 1936 | iommu_detach_group(dc->domain, group); | ||
| 1937 | tegra->group = NULL; | ||
| 1938 | } | ||
| 1939 | |||
| 1930 | dc->domain = NULL; | 1940 | dc->domain = NULL; |
| 1931 | } | 1941 | } |
| 1932 | 1942 | ||
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index d50bddb2e447..7fcf4a242840 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
| @@ -250,6 +250,7 @@ static void tegra_drm_unload(struct drm_device *drm) | |||
| 250 | 250 | ||
| 251 | drm_kms_helper_poll_fini(drm); | 251 | drm_kms_helper_poll_fini(drm); |
| 252 | tegra_drm_fb_exit(drm); | 252 | tegra_drm_fb_exit(drm); |
| 253 | drm_atomic_helper_shutdown(drm); | ||
| 253 | drm_mode_config_cleanup(drm); | 254 | drm_mode_config_cleanup(drm); |
| 254 | 255 | ||
| 255 | err = host1x_device_exit(device); | 256 | err = host1x_device_exit(device); |
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 4d2ed966f9e3..87c5d89bc9ba 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
| @@ -1072,7 +1072,6 @@ static int tegra_dsi_exit(struct host1x_client *client) | |||
| 1072 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); | 1072 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); |
| 1073 | 1073 | ||
| 1074 | tegra_output_exit(&dsi->output); | 1074 | tegra_output_exit(&dsi->output); |
| 1075 | regulator_disable(dsi->vdd); | ||
| 1076 | 1075 | ||
| 1077 | return 0; | 1076 | return 0; |
| 1078 | } | 1077 | } |
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 36a06a993698..94dac79ac3c9 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c | |||
| @@ -297,6 +297,10 @@ int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha) | |||
| 297 | case WIN_COLOR_DEPTH_B8G8R8X8: | 297 | case WIN_COLOR_DEPTH_B8G8R8X8: |
| 298 | *alpha = WIN_COLOR_DEPTH_B8G8R8A8; | 298 | *alpha = WIN_COLOR_DEPTH_B8G8R8A8; |
| 299 | return 0; | 299 | return 0; |
| 300 | |||
| 301 | case WIN_COLOR_DEPTH_B5G6R5: | ||
| 302 | *alpha = opaque; | ||
| 303 | return 0; | ||
| 300 | } | 304 | } |
| 301 | 305 | ||
| 302 | return -EINVAL; | 306 | return -EINVAL; |
| @@ -330,9 +334,6 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra, | |||
| 330 | unsigned int zpos[2]; | 334 | unsigned int zpos[2]; |
| 331 | unsigned int i; | 335 | unsigned int i; |
| 332 | 336 | ||
| 333 | for (i = 0; i < 3; i++) | ||
| 334 | state->dependent[i] = false; | ||
| 335 | |||
| 336 | for (i = 0; i < 2; i++) | 337 | for (i = 0; i < 2; i++) |
| 337 | zpos[i] = 0; | 338 | zpos[i] = 0; |
| 338 | 339 | ||
| @@ -346,6 +347,8 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra, | |||
| 346 | 347 | ||
| 347 | index = tegra_plane_get_overlap_index(tegra, p); | 348 | index = tegra_plane_get_overlap_index(tegra, p); |
| 348 | 349 | ||
| 350 | state->dependent[index] = false; | ||
| 351 | |||
| 349 | /* | 352 | /* |
| 350 | * If any of the other planes is on top of this plane and uses | 353 | * If any of the other planes is on top of this plane and uses |
| 351 | * a format with an alpha component, mark this plane as being | 354 | * a format with an alpha component, mark this plane as being |
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index b5b335c9b2bb..2ebdc6d5a76e 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
| @@ -159,10 +159,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
| 159 | { | 159 | { |
| 160 | unsigned long start = vma->vm_start; | 160 | unsigned long start = vma->vm_start; |
| 161 | unsigned long size = vma->vm_end - vma->vm_start; | 161 | unsigned long size = vma->vm_end - vma->vm_start; |
| 162 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | 162 | unsigned long offset; |
| 163 | unsigned long page, pos; | 163 | unsigned long page, pos; |
| 164 | 164 | ||
| 165 | if (offset + size > info->fix.smem_len) | 165 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) |
| 166 | return -EINVAL; | ||
| 167 | |||
| 168 | offset = vma->vm_pgoff << PAGE_SHIFT; | ||
| 169 | |||
| 170 | if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) | ||
| 166 | return -EINVAL; | 171 | return -EINVAL; |
| 167 | 172 | ||
| 168 | pos = (unsigned long)info->fix.smem_start + offset; | 173 | pos = (unsigned long)info->fix.smem_start + offset; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 184340d486c3..86d25f18aa99 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -1337,6 +1337,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv) | |||
| 1337 | */ | 1337 | */ |
| 1338 | void vmw_svga_disable(struct vmw_private *dev_priv) | 1338 | void vmw_svga_disable(struct vmw_private *dev_priv) |
| 1339 | { | 1339 | { |
| 1340 | /* | ||
| 1341 | * Disabling SVGA will turn off device modesetting capabilities, so | ||
| 1342 | * notify KMS about that so that it doesn't cache atomic state that | ||
| 1343 | * isn't valid anymore, for example crtcs turned on. | ||
| 1344 | * Strictly we'd want to do this under the SVGA lock (or an SVGA mutex), | ||
| 1345 | * but vmw_kms_lost_device() takes the reservation sem and thus we'll | ||
| 1346 | * end up with lock order reversal. Thus, a master may actually perform | ||
| 1347 | * a new modeset just after we call vmw_kms_lost_device() and race with | ||
| 1348 | * vmw_svga_disable(), but that should at worst cause atomic KMS state | ||
| 1349 | * to be inconsistent with the device, causing modesetting problems. | ||
| 1350 | * | ||
| 1351 | */ | ||
| 1352 | vmw_kms_lost_device(dev_priv->dev); | ||
| 1340 | ttm_write_lock(&dev_priv->reservation_sem, false); | 1353 | ttm_write_lock(&dev_priv->reservation_sem, false); |
| 1341 | spin_lock(&dev_priv->svga_lock); | 1354 | spin_lock(&dev_priv->svga_lock); |
| 1342 | if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { | 1355 | if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d08753e8fd94..9116fe8baebc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -938,6 +938,7 @@ int vmw_kms_present(struct vmw_private *dev_priv, | |||
| 938 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 938 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
| 939 | struct drm_file *file_priv); | 939 | struct drm_file *file_priv); |
| 940 | void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv); | 940 | void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv); |
| 941 | void vmw_kms_lost_device(struct drm_device *dev); | ||
| 941 | 942 | ||
| 942 | int vmw_dumb_create(struct drm_file *file_priv, | 943 | int vmw_dumb_create(struct drm_file *file_priv, |
| 943 | struct drm_device *dev, | 944 | struct drm_device *dev, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ead61015cd79..3c824fd7cbf3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <drm/drm_atomic_helper.h> | 31 | #include <drm/drm_atomic_helper.h> |
| 32 | #include <drm/drm_rect.h> | 32 | #include <drm/drm_rect.h> |
| 33 | 33 | ||
| 34 | |||
| 35 | /* Might need a hrtimer here? */ | 34 | /* Might need a hrtimer here? */ |
| 36 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) | 35 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) |
| 37 | 36 | ||
| @@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, | |||
| 2517 | * Helper to be used if an error forces the caller to undo the actions of | 2516 | * Helper to be used if an error forces the caller to undo the actions of |
| 2518 | * vmw_kms_helper_resource_prepare. | 2517 | * vmw_kms_helper_resource_prepare. |
| 2519 | */ | 2518 | */ |
| 2520 | void vmw_kms_helper_resource_revert(struct vmw_resource *res) | 2519 | void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx) |
| 2521 | { | 2520 | { |
| 2522 | vmw_kms_helper_buffer_revert(res->backup); | 2521 | struct vmw_resource *res = ctx->res; |
| 2522 | |||
| 2523 | vmw_kms_helper_buffer_revert(ctx->buf); | ||
| 2524 | vmw_dmabuf_unreference(&ctx->buf); | ||
| 2523 | vmw_resource_unreserve(res, false, NULL, 0); | 2525 | vmw_resource_unreserve(res, false, NULL, 0); |
| 2524 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); | 2526 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); |
| 2525 | } | 2527 | } |
| @@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res) | |||
| 2536 | * interrupted by a signal. | 2538 | * interrupted by a signal. |
| 2537 | */ | 2539 | */ |
| 2538 | int vmw_kms_helper_resource_prepare(struct vmw_resource *res, | 2540 | int vmw_kms_helper_resource_prepare(struct vmw_resource *res, |
| 2539 | bool interruptible) | 2541 | bool interruptible, |
| 2542 | struct vmw_validation_ctx *ctx) | ||
| 2540 | { | 2543 | { |
| 2541 | int ret = 0; | 2544 | int ret = 0; |
| 2542 | 2545 | ||
| 2546 | ctx->buf = NULL; | ||
| 2547 | ctx->res = res; | ||
| 2548 | |||
| 2543 | if (interruptible) | 2549 | if (interruptible) |
| 2544 | ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex); | 2550 | ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex); |
| 2545 | else | 2551 | else |
| @@ -2558,6 +2564,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, | |||
| 2558 | res->dev_priv->has_mob); | 2564 | res->dev_priv->has_mob); |
| 2559 | if (ret) | 2565 | if (ret) |
| 2560 | goto out_unreserve; | 2566 | goto out_unreserve; |
| 2567 | |||
| 2568 | ctx->buf = vmw_dmabuf_reference(res->backup); | ||
| 2561 | } | 2569 | } |
| 2562 | ret = vmw_resource_validate(res); | 2570 | ret = vmw_resource_validate(res); |
| 2563 | if (ret) | 2571 | if (ret) |
| @@ -2565,7 +2573,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res, | |||
| 2565 | return 0; | 2573 | return 0; |
| 2566 | 2574 | ||
| 2567 | out_revert: | 2575 | out_revert: |
| 2568 | vmw_kms_helper_buffer_revert(res->backup); | 2576 | vmw_kms_helper_buffer_revert(ctx->buf); |
| 2569 | out_unreserve: | 2577 | out_unreserve: |
| 2570 | vmw_resource_unreserve(res, false, NULL, 0); | 2578 | vmw_resource_unreserve(res, false, NULL, 0); |
| 2571 | out_unlock: | 2579 | out_unlock: |
| @@ -2581,11 +2589,13 @@ out_unlock: | |||
| 2581 | * @out_fence: Optional pointer to a fence pointer. If non-NULL, a | 2589 | * @out_fence: Optional pointer to a fence pointer. If non-NULL, a |
| 2582 | * ref-counted fence pointer is returned here. | 2590 | * ref-counted fence pointer is returned here. |
| 2583 | */ | 2591 | */ |
| 2584 | void vmw_kms_helper_resource_finish(struct vmw_resource *res, | 2592 | void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, |
| 2585 | struct vmw_fence_obj **out_fence) | 2593 | struct vmw_fence_obj **out_fence) |
| 2586 | { | 2594 | { |
| 2587 | if (res->backup || out_fence) | 2595 | struct vmw_resource *res = ctx->res; |
| 2588 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup, | 2596 | |
| 2597 | if (ctx->buf || out_fence) | ||
| 2598 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, | ||
| 2589 | out_fence, NULL); | 2599 | out_fence, NULL); |
| 2590 | 2600 | ||
| 2591 | vmw_resource_unreserve(res, false, NULL, 0); | 2601 | vmw_resource_unreserve(res, false, NULL, 0); |
| @@ -2851,3 +2861,14 @@ int vmw_kms_set_config(struct drm_mode_set *set, | |||
| 2851 | 2861 | ||
| 2852 | return drm_atomic_helper_set_config(set, ctx); | 2862 | return drm_atomic_helper_set_config(set, ctx); |
| 2853 | } | 2863 | } |
| 2864 | |||
| 2865 | |||
| 2866 | /** | ||
| 2867 | * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost | ||
| 2868 | * | ||
| 2869 | * @dev: Pointer to the drm device | ||
| 2870 | */ | ||
| 2871 | void vmw_kms_lost_device(struct drm_device *dev) | ||
| 2872 | { | ||
| 2873 | drm_atomic_helper_shutdown(dev); | ||
| 2874 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index cd9da2dd79af..3d2ca280eaa7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
| @@ -240,6 +240,11 @@ struct vmw_display_unit { | |||
| 240 | int set_gui_y; | 240 | int set_gui_y; |
| 241 | }; | 241 | }; |
| 242 | 242 | ||
| 243 | struct vmw_validation_ctx { | ||
| 244 | struct vmw_resource *res; | ||
| 245 | struct vmw_dma_buffer *buf; | ||
| 246 | }; | ||
| 247 | |||
| 243 | #define vmw_crtc_to_du(x) \ | 248 | #define vmw_crtc_to_du(x) \ |
| 244 | container_of(x, struct vmw_display_unit, crtc) | 249 | container_of(x, struct vmw_display_unit, crtc) |
| 245 | #define vmw_connector_to_du(x) \ | 250 | #define vmw_connector_to_du(x) \ |
| @@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, | |||
| 296 | struct drm_vmw_fence_rep __user * | 301 | struct drm_vmw_fence_rep __user * |
| 297 | user_fence_rep); | 302 | user_fence_rep); |
| 298 | int vmw_kms_helper_resource_prepare(struct vmw_resource *res, | 303 | int vmw_kms_helper_resource_prepare(struct vmw_resource *res, |
| 299 | bool interruptible); | 304 | bool interruptible, |
| 300 | void vmw_kms_helper_resource_revert(struct vmw_resource *res); | 305 | struct vmw_validation_ctx *ctx); |
| 301 | void vmw_kms_helper_resource_finish(struct vmw_resource *res, | 306 | void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx); |
| 307 | void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, | ||
| 302 | struct vmw_fence_obj **out_fence); | 308 | struct vmw_fence_obj **out_fence); |
| 303 | int vmw_kms_readback(struct vmw_private *dev_priv, | 309 | int vmw_kms_readback(struct vmw_private *dev_priv, |
| 304 | struct drm_file *file_priv, | 310 | struct drm_file *file_priv, |
| @@ -439,5 +445,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, | |||
| 439 | 445 | ||
| 440 | int vmw_kms_set_config(struct drm_mode_set *set, | 446 | int vmw_kms_set_config(struct drm_mode_set *set, |
| 441 | struct drm_modeset_acquire_ctx *ctx); | 447 | struct drm_modeset_acquire_ctx *ctx); |
| 442 | |||
| 443 | #endif | 448 | #endif |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 63a4cd794b73..3ec9eae831b8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
| @@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, | |||
| 909 | struct vmw_framebuffer_surface *vfbs = | 909 | struct vmw_framebuffer_surface *vfbs = |
| 910 | container_of(framebuffer, typeof(*vfbs), base); | 910 | container_of(framebuffer, typeof(*vfbs), base); |
| 911 | struct vmw_kms_sou_surface_dirty sdirty; | 911 | struct vmw_kms_sou_surface_dirty sdirty; |
| 912 | struct vmw_validation_ctx ctx; | ||
| 912 | int ret; | 913 | int ret; |
| 913 | 914 | ||
| 914 | if (!srf) | 915 | if (!srf) |
| 915 | srf = &vfbs->surface->res; | 916 | srf = &vfbs->surface->res; |
| 916 | 917 | ||
| 917 | ret = vmw_kms_helper_resource_prepare(srf, true); | 918 | ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); |
| 918 | if (ret) | 919 | if (ret) |
| 919 | return ret; | 920 | return ret; |
| 920 | 921 | ||
| @@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, | |||
| 933 | ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips, | 934 | ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips, |
| 934 | dest_x, dest_y, num_clips, inc, | 935 | dest_x, dest_y, num_clips, inc, |
| 935 | &sdirty.base); | 936 | &sdirty.base); |
| 936 | vmw_kms_helper_resource_finish(srf, out_fence); | 937 | vmw_kms_helper_resource_finish(&ctx, out_fence); |
| 937 | 938 | ||
| 938 | return ret; | 939 | return ret; |
| 939 | } | 940 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index b68d74888ab1..6b969e5dea2a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | |||
| @@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, | |||
| 980 | struct vmw_framebuffer_surface *vfbs = | 980 | struct vmw_framebuffer_surface *vfbs = |
| 981 | container_of(framebuffer, typeof(*vfbs), base); | 981 | container_of(framebuffer, typeof(*vfbs), base); |
| 982 | struct vmw_stdu_dirty sdirty; | 982 | struct vmw_stdu_dirty sdirty; |
| 983 | struct vmw_validation_ctx ctx; | ||
| 983 | int ret; | 984 | int ret; |
| 984 | 985 | ||
| 985 | if (!srf) | 986 | if (!srf) |
| 986 | srf = &vfbs->surface->res; | 987 | srf = &vfbs->surface->res; |
| 987 | 988 | ||
| 988 | ret = vmw_kms_helper_resource_prepare(srf, true); | 989 | ret = vmw_kms_helper_resource_prepare(srf, true, &ctx); |
| 989 | if (ret) | 990 | if (ret) |
| 990 | return ret; | 991 | return ret; |
| 991 | 992 | ||
| @@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, | |||
| 1008 | dest_x, dest_y, num_clips, inc, | 1009 | dest_x, dest_y, num_clips, inc, |
| 1009 | &sdirty.base); | 1010 | &sdirty.base); |
| 1010 | out_finish: | 1011 | out_finish: |
| 1011 | vmw_kms_helper_resource_finish(srf, out_fence); | 1012 | vmw_kms_helper_resource_finish(&ctx, out_fence); |
| 1012 | 1013 | ||
| 1013 | return ret; | 1014 | return ret; |
| 1014 | } | 1015 | } |
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c index 97b99500153d..83f9dd934a5d 100644 --- a/drivers/gpu/ipu-v3/ipu-prg.c +++ b/drivers/gpu/ipu-v3/ipu-prg.c | |||
| @@ -250,10 +250,14 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan) | |||
| 250 | { | 250 | { |
| 251 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); | 251 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); |
| 252 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; | 252 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; |
| 253 | struct ipu_prg_channel *chan = &prg->chan[prg_chan]; | 253 | struct ipu_prg_channel *chan; |
| 254 | u32 val; | 254 | u32 val; |
| 255 | 255 | ||
| 256 | if (!chan->enabled || prg_chan < 0) | 256 | if (prg_chan < 0) |
| 257 | return; | ||
| 258 | |||
| 259 | chan = &prg->chan[prg_chan]; | ||
| 260 | if (!chan->enabled) | ||
| 257 | return; | 261 | return; |
| 258 | 262 | ||
| 259 | pm_runtime_get_sync(prg->dev); | 263 | pm_runtime_get_sync(prg->dev); |
| @@ -280,13 +284,15 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan, | |||
| 280 | { | 284 | { |
| 281 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); | 285 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); |
| 282 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; | 286 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; |
| 283 | struct ipu_prg_channel *chan = &prg->chan[prg_chan]; | 287 | struct ipu_prg_channel *chan; |
| 284 | u32 val; | 288 | u32 val; |
| 285 | int ret; | 289 | int ret; |
| 286 | 290 | ||
| 287 | if (prg_chan < 0) | 291 | if (prg_chan < 0) |
| 288 | return prg_chan; | 292 | return prg_chan; |
| 289 | 293 | ||
| 294 | chan = &prg->chan[prg_chan]; | ||
| 295 | |||
| 290 | if (chan->enabled) { | 296 | if (chan->enabled) { |
| 291 | ipu_pre_update(prg->pres[chan->used_pre], *eba); | 297 | ipu_pre_update(prg->pres[chan->used_pre], *eba); |
| 292 | return 0; | 298 | return 0; |
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 50e071444a5c..8699bb969e7e 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c | |||
| @@ -417,13 +417,24 @@ __hv_pkt_iter_next(struct vmbus_channel *channel, | |||
| 417 | } | 417 | } |
| 418 | EXPORT_SYMBOL_GPL(__hv_pkt_iter_next); | 418 | EXPORT_SYMBOL_GPL(__hv_pkt_iter_next); |
| 419 | 419 | ||
| 420 | /* How many bytes were read in this iterator cycle */ | ||
| 421 | static u32 hv_pkt_iter_bytes_read(const struct hv_ring_buffer_info *rbi, | ||
| 422 | u32 start_read_index) | ||
| 423 | { | ||
| 424 | if (rbi->priv_read_index >= start_read_index) | ||
| 425 | return rbi->priv_read_index - start_read_index; | ||
| 426 | else | ||
| 427 | return rbi->ring_datasize - start_read_index + | ||
| 428 | rbi->priv_read_index; | ||
| 429 | } | ||
| 430 | |||
| 420 | /* | 431 | /* |
| 421 | * Update host ring buffer after iterating over packets. | 432 | * Update host ring buffer after iterating over packets. |
| 422 | */ | 433 | */ |
| 423 | void hv_pkt_iter_close(struct vmbus_channel *channel) | 434 | void hv_pkt_iter_close(struct vmbus_channel *channel) |
| 424 | { | 435 | { |
| 425 | struct hv_ring_buffer_info *rbi = &channel->inbound; | 436 | struct hv_ring_buffer_info *rbi = &channel->inbound; |
| 426 | u32 orig_write_sz = hv_get_bytes_to_write(rbi); | 437 | u32 curr_write_sz, pending_sz, bytes_read, start_read_index; |
| 427 | 438 | ||
| 428 | /* | 439 | /* |
| 429 | * Make sure all reads are done before we update the read index since | 440 | * Make sure all reads are done before we update the read index since |
| @@ -431,8 +442,12 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) | |||
| 431 | * is updated. | 442 | * is updated. |
| 432 | */ | 443 | */ |
| 433 | virt_rmb(); | 444 | virt_rmb(); |
| 445 | start_read_index = rbi->ring_buffer->read_index; | ||
| 434 | rbi->ring_buffer->read_index = rbi->priv_read_index; | 446 | rbi->ring_buffer->read_index = rbi->priv_read_index; |
| 435 | 447 | ||
| 448 | if (!rbi->ring_buffer->feature_bits.feat_pending_send_sz) | ||
| 449 | return; | ||
| 450 | |||
| 436 | /* | 451 | /* |
| 437 | * Issue a full memory barrier before making the signaling decision. | 452 | * Issue a full memory barrier before making the signaling decision. |
| 438 | * Here is the reason for having this barrier: | 453 | * Here is the reason for having this barrier: |
| @@ -446,26 +461,29 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) | |||
| 446 | */ | 461 | */ |
| 447 | virt_mb(); | 462 | virt_mb(); |
| 448 | 463 | ||
| 449 | /* If host has disabled notifications then skip */ | 464 | pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); |
| 450 | if (rbi->ring_buffer->interrupt_mask) | 465 | if (!pending_sz) |
| 451 | return; | 466 | return; |
| 452 | 467 | ||
| 453 | if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) { | 468 | /* |
| 454 | u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); | 469 | * Ensure the read of write_index in hv_get_bytes_to_write() |
| 470 | * happens after the read of pending_send_sz. | ||
| 471 | */ | ||
| 472 | virt_rmb(); | ||
| 473 | curr_write_sz = hv_get_bytes_to_write(rbi); | ||
| 474 | bytes_read = hv_pkt_iter_bytes_read(rbi, start_read_index); | ||
| 455 | 475 | ||
| 456 | /* | 476 | /* |
| 457 | * If there was space before we began iteration, | 477 | * If there was space before we began iteration, |
| 458 | * then host was not blocked. Also handles case where | 478 | * then host was not blocked. |
| 459 | * pending_sz is zero then host has nothing pending | 479 | */ |
| 460 | * and does not need to be signaled. | ||
| 461 | */ | ||
| 462 | if (orig_write_sz > pending_sz) | ||
| 463 | return; | ||
| 464 | 480 | ||
| 465 | /* If pending write will not fit, don't give false hope. */ | 481 | if (curr_write_sz - bytes_read > pending_sz) |
| 466 | if (hv_get_bytes_to_write(rbi) < pending_sz) | 482 | return; |
| 467 | return; | 483 | |
| 468 | } | 484 | /* If pending write will not fit, don't give false hope. */ |
| 485 | if (curr_write_sz <= pending_sz) | ||
| 486 | return; | ||
| 469 | 487 | ||
| 470 | vmbus_setevent(channel); | 488 | vmbus_setevent(channel); |
| 471 | } | 489 | } |
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 6fe995cf16a6..3e6fd5a8ac5b 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c | |||
| @@ -920,6 +920,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { | |||
| 920 | int st_accel_common_probe(struct iio_dev *indio_dev) | 920 | int st_accel_common_probe(struct iio_dev *indio_dev) |
| 921 | { | 921 | { |
| 922 | struct st_sensor_data *adata = iio_priv(indio_dev); | 922 | struct st_sensor_data *adata = iio_priv(indio_dev); |
| 923 | struct st_sensors_platform_data *pdata = | ||
| 924 | (struct st_sensors_platform_data *)adata->dev->platform_data; | ||
| 923 | int irq = adata->get_irq_data_ready(indio_dev); | 925 | int irq = adata->get_irq_data_ready(indio_dev); |
| 924 | int err; | 926 | int err; |
| 925 | 927 | ||
| @@ -946,7 +948,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev) | |||
| 946 | &adata->sensor_settings->fs.fs_avl[0]; | 948 | &adata->sensor_settings->fs.fs_avl[0]; |
| 947 | adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; | 949 | adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; |
| 948 | 950 | ||
| 949 | err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); | 951 | if (!pdata) |
| 952 | pdata = (struct st_sensors_platform_data *)&default_accel_pdata; | ||
| 953 | |||
| 954 | err = st_sensors_init_sensor(indio_dev, pdata); | ||
| 950 | if (err < 0) | 955 | if (err < 0) |
| 951 | goto st_accel_power_off; | 956 | goto st_accel_power_off; |
| 952 | 957 | ||
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 29fa7736d80c..ede955d9b2a4 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c | |||
| @@ -462,8 +462,10 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) | |||
| 462 | regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); | 462 | regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); |
| 463 | } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--); | 463 | } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--); |
| 464 | 464 | ||
| 465 | if (timeout < 0) | 465 | if (timeout < 0) { |
| 466 | mutex_unlock(&indio_dev->mlock); | ||
| 466 | return -ETIMEDOUT; | 467 | return -ETIMEDOUT; |
| 468 | } | ||
| 467 | } | 469 | } |
| 468 | 470 | ||
| 469 | return 0; | 471 | return 0; |
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index daa026d6a94f..01422d11753c 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c | |||
| @@ -54,7 +54,6 @@ struct stm32_dfsdm_adc { | |||
| 54 | struct stm32_dfsdm *dfsdm; | 54 | struct stm32_dfsdm *dfsdm; |
| 55 | const struct stm32_dfsdm_dev_data *dev_data; | 55 | const struct stm32_dfsdm_dev_data *dev_data; |
| 56 | unsigned int fl_id; | 56 | unsigned int fl_id; |
| 57 | unsigned int ch_id; | ||
| 58 | 57 | ||
| 59 | /* ADC specific */ | 58 | /* ADC specific */ |
| 60 | unsigned int oversamp; | 59 | unsigned int oversamp; |
| @@ -384,7 +383,7 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev, | |||
| 384 | { | 383 | { |
| 385 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 384 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| 386 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | 385 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; |
| 387 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; | 386 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; |
| 388 | unsigned int sample_freq = adc->sample_freq; | 387 | unsigned int sample_freq = adc->sample_freq; |
| 389 | unsigned int spi_freq; | 388 | unsigned int spi_freq; |
| 390 | int ret; | 389 | int ret; |
| @@ -419,18 +418,20 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev, | |||
| 419 | return len; | 418 | return len; |
| 420 | } | 419 | } |
| 421 | 420 | ||
| 422 | static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma) | 421 | static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, |
| 422 | const struct iio_chan_spec *chan, | ||
| 423 | bool dma) | ||
| 423 | { | 424 | { |
| 424 | struct regmap *regmap = adc->dfsdm->regmap; | 425 | struct regmap *regmap = adc->dfsdm->regmap; |
| 425 | int ret; | 426 | int ret; |
| 426 | unsigned int dma_en = 0, cont_en = 0; | 427 | unsigned int dma_en = 0, cont_en = 0; |
| 427 | 428 | ||
| 428 | ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id); | 429 | ret = stm32_dfsdm_start_channel(adc->dfsdm, chan->channel); |
| 429 | if (ret < 0) | 430 | if (ret < 0) |
| 430 | return ret; | 431 | return ret; |
| 431 | 432 | ||
| 432 | ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id, | 433 | ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id, |
| 433 | adc->ch_id); | 434 | chan->channel); |
| 434 | if (ret < 0) | 435 | if (ret < 0) |
| 435 | goto stop_channels; | 436 | goto stop_channels; |
| 436 | 437 | ||
| @@ -464,12 +465,13 @@ stop_channels: | |||
| 464 | 465 | ||
| 465 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | 466 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), |
| 466 | DFSDM_CR1_RCONT_MASK, 0); | 467 | DFSDM_CR1_RCONT_MASK, 0); |
| 467 | stm32_dfsdm_stop_channel(adc->dfsdm, adc->fl_id); | 468 | stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel); |
| 468 | 469 | ||
| 469 | return ret; | 470 | return ret; |
| 470 | } | 471 | } |
| 471 | 472 | ||
| 472 | static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc) | 473 | static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc, |
| 474 | const struct iio_chan_spec *chan) | ||
| 473 | { | 475 | { |
| 474 | struct regmap *regmap = adc->dfsdm->regmap; | 476 | struct regmap *regmap = adc->dfsdm->regmap; |
| 475 | 477 | ||
| @@ -482,7 +484,7 @@ static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc) | |||
| 482 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | 484 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), |
| 483 | DFSDM_CR1_RCONT_MASK, 0); | 485 | DFSDM_CR1_RCONT_MASK, 0); |
| 484 | 486 | ||
| 485 | stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id); | 487 | stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel); |
| 486 | } | 488 | } |
| 487 | 489 | ||
| 488 | static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, | 490 | static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, |
| @@ -609,6 +611,7 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) | |||
| 609 | static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) | 611 | static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) |
| 610 | { | 612 | { |
| 611 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 613 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| 614 | const struct iio_chan_spec *chan = &indio_dev->channels[0]; | ||
| 612 | int ret; | 615 | int ret; |
| 613 | 616 | ||
| 614 | /* Reset adc buffer index */ | 617 | /* Reset adc buffer index */ |
| @@ -618,7 +621,7 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) | |||
| 618 | if (ret < 0) | 621 | if (ret < 0) |
| 619 | return ret; | 622 | return ret; |
| 620 | 623 | ||
| 621 | ret = stm32_dfsdm_start_conv(adc, true); | 624 | ret = stm32_dfsdm_start_conv(adc, chan, true); |
| 622 | if (ret) { | 625 | if (ret) { |
| 623 | dev_err(&indio_dev->dev, "Can't start conversion\n"); | 626 | dev_err(&indio_dev->dev, "Can't start conversion\n"); |
| 624 | goto stop_dfsdm; | 627 | goto stop_dfsdm; |
| @@ -635,7 +638,7 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) | |||
| 635 | return 0; | 638 | return 0; |
| 636 | 639 | ||
| 637 | err_stop_conv: | 640 | err_stop_conv: |
| 638 | stm32_dfsdm_stop_conv(adc); | 641 | stm32_dfsdm_stop_conv(adc, chan); |
| 639 | stop_dfsdm: | 642 | stop_dfsdm: |
| 640 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | 643 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); |
| 641 | 644 | ||
| @@ -645,11 +648,12 @@ stop_dfsdm: | |||
| 645 | static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) | 648 | static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) |
| 646 | { | 649 | { |
| 647 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 650 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| 651 | const struct iio_chan_spec *chan = &indio_dev->channels[0]; | ||
| 648 | 652 | ||
| 649 | if (adc->dma_chan) | 653 | if (adc->dma_chan) |
| 650 | dmaengine_terminate_all(adc->dma_chan); | 654 | dmaengine_terminate_all(adc->dma_chan); |
| 651 | 655 | ||
| 652 | stm32_dfsdm_stop_conv(adc); | 656 | stm32_dfsdm_stop_conv(adc, chan); |
| 653 | 657 | ||
| 654 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | 658 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); |
| 655 | 659 | ||
| @@ -730,7 +734,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev, | |||
| 730 | if (ret < 0) | 734 | if (ret < 0) |
| 731 | goto stop_dfsdm; | 735 | goto stop_dfsdm; |
| 732 | 736 | ||
| 733 | ret = stm32_dfsdm_start_conv(adc, false); | 737 | ret = stm32_dfsdm_start_conv(adc, chan, false); |
| 734 | if (ret < 0) { | 738 | if (ret < 0) { |
| 735 | regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), | 739 | regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), |
| 736 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); | 740 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); |
| @@ -751,7 +755,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev, | |||
| 751 | else | 755 | else |
| 752 | ret = IIO_VAL_INT; | 756 | ret = IIO_VAL_INT; |
| 753 | 757 | ||
| 754 | stm32_dfsdm_stop_conv(adc); | 758 | stm32_dfsdm_stop_conv(adc, chan); |
| 755 | 759 | ||
| 756 | stop_dfsdm: | 760 | stop_dfsdm: |
| 757 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | 761 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); |
| @@ -765,7 +769,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev, | |||
| 765 | { | 769 | { |
| 766 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 770 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
| 767 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | 771 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; |
| 768 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; | 772 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; |
| 769 | unsigned int spi_freq = adc->spi_freq; | 773 | unsigned int spi_freq = adc->spi_freq; |
| 770 | int ret = -EINVAL; | 774 | int ret = -EINVAL; |
| 771 | 775 | ||
| @@ -972,7 +976,6 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, | |||
| 972 | } | 976 | } |
| 973 | ch->scan_type.realbits = 24; | 977 | ch->scan_type.realbits = 24; |
| 974 | ch->scan_type.storagebits = 32; | 978 | ch->scan_type.storagebits = 32; |
| 975 | adc->ch_id = ch->channel; | ||
| 976 | 979 | ||
| 977 | return stm32_dfsdm_chan_configure(adc->dfsdm, | 980 | return stm32_dfsdm_chan_configure(adc->dfsdm, |
| 978 | &adc->dfsdm->ch_list[ch->channel]); | 981 | &adc->dfsdm->ch_list[ch->channel]); |
| @@ -1001,7 +1004,7 @@ static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) | |||
| 1001 | } | 1004 | } |
| 1002 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); | 1005 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); |
| 1003 | 1006 | ||
| 1004 | d_ch = &adc->dfsdm->ch_list[adc->ch_id]; | 1007 | d_ch = &adc->dfsdm->ch_list[ch->channel]; |
| 1005 | if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) | 1008 | if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) |
| 1006 | adc->spi_freq = adc->dfsdm->spi_master_freq; | 1009 | adc->spi_freq = adc->dfsdm->spi_master_freq; |
| 1007 | 1010 | ||
| @@ -1042,8 +1045,8 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) | |||
| 1042 | return -ENOMEM; | 1045 | return -ENOMEM; |
| 1043 | 1046 | ||
| 1044 | for (chan_idx = 0; chan_idx < num_ch; chan_idx++) { | 1047 | for (chan_idx = 0; chan_idx < num_ch; chan_idx++) { |
| 1045 | ch->scan_index = chan_idx; | 1048 | ch[chan_idx].scan_index = chan_idx; |
| 1046 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch); | 1049 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, &ch[chan_idx]); |
| 1047 | if (ret < 0) { | 1050 | if (ret < 0) { |
| 1048 | dev_err(&indio_dev->dev, "Channels init failed\n"); | 1051 | dev_err(&indio_dev->dev, "Channels init failed\n"); |
| 1049 | return ret; | 1052 | return ret; |
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 6290332cfd3f..e50efdcc41ff 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c | |||
| @@ -83,7 +83,7 @@ int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm) | |||
| 83 | { | 83 | { |
| 84 | struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm); | 84 | struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm); |
| 85 | struct device *dev = &priv->pdev->dev; | 85 | struct device *dev = &priv->pdev->dev; |
| 86 | unsigned int clk_div = priv->spi_clk_out_div; | 86 | unsigned int clk_div = priv->spi_clk_out_div, clk_src; |
| 87 | int ret; | 87 | int ret; |
| 88 | 88 | ||
| 89 | if (atomic_inc_return(&priv->n_active_ch) == 1) { | 89 | if (atomic_inc_return(&priv->n_active_ch) == 1) { |
| @@ -100,6 +100,14 @@ int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm) | |||
| 100 | } | 100 | } |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* select clock source, e.g. 0 for "dfsdm" or 1 for "audio" */ | ||
| 104 | clk_src = priv->aclk ? 1 : 0; | ||
| 105 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | ||
| 106 | DFSDM_CHCFGR1_CKOUTSRC_MASK, | ||
| 107 | DFSDM_CHCFGR1_CKOUTSRC(clk_src)); | ||
| 108 | if (ret < 0) | ||
| 109 | goto disable_aclk; | ||
| 110 | |||
| 103 | /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */ | 111 | /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */ |
| 104 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | 112 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), |
| 105 | DFSDM_CHCFGR1_CKOUTDIV_MASK, | 113 | DFSDM_CHCFGR1_CKOUTDIV_MASK, |
| @@ -274,7 +282,7 @@ static int stm32_dfsdm_probe(struct platform_device *pdev) | |||
| 274 | 282 | ||
| 275 | dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm", | 283 | dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm", |
| 276 | dfsdm->base, | 284 | dfsdm->base, |
| 277 | &stm32h7_dfsdm_regmap_cfg); | 285 | dev_data->regmap_cfg); |
| 278 | if (IS_ERR(dfsdm->regmap)) { | 286 | if (IS_ERR(dfsdm->regmap)) { |
| 279 | ret = PTR_ERR(dfsdm->regmap); | 287 | ret = PTR_ERR(dfsdm->regmap); |
| 280 | dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n", | 288 | dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n", |
diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index fbe2431f5b81..1ea9f5513b02 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c | |||
| @@ -133,6 +133,9 @@ static int ccs811_start_sensor_application(struct i2c_client *client) | |||
| 133 | if (ret < 0) | 133 | if (ret < 0) |
| 134 | return ret; | 134 | return ret; |
| 135 | 135 | ||
| 136 | if ((ret & CCS811_STATUS_FW_MODE_APPLICATION)) | ||
| 137 | return 0; | ||
| 138 | |||
| 136 | if ((ret & CCS811_STATUS_APP_VALID_MASK) != | 139 | if ((ret & CCS811_STATUS_APP_VALID_MASK) != |
| 137 | CCS811_STATUS_APP_VALID_LOADED) | 140 | CCS811_STATUS_APP_VALID_LOADED) |
| 138 | return -EIO; | 141 | return -EIO; |
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 349e5c713c03..4ddb6cf7d401 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c | |||
| @@ -640,7 +640,7 @@ int st_press_common_probe(struct iio_dev *indio_dev) | |||
| 640 | press_data->sensor_settings->drdy_irq.int2.addr)) | 640 | press_data->sensor_settings->drdy_irq.int2.addr)) |
| 641 | pdata = (struct st_sensors_platform_data *)&default_press_pdata; | 641 | pdata = (struct st_sensors_platform_data *)&default_press_pdata; |
| 642 | 642 | ||
| 643 | err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); | 643 | err = st_sensors_init_sensor(indio_dev, pdata); |
| 644 | if (err < 0) | 644 | if (err < 0) |
| 645 | goto st_press_power_off; | 645 | goto st_press_power_off; |
| 646 | 646 | ||
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e66963ca58bd..a5367c5efbe7 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -3069,7 +3069,8 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list, | |||
| 3069 | continue; | 3069 | continue; |
| 3070 | 3070 | ||
| 3071 | /* different dest port -> unique */ | 3071 | /* different dest port -> unique */ |
| 3072 | if (!cma_any_port(cur_daddr) && | 3072 | if (!cma_any_port(daddr) && |
| 3073 | !cma_any_port(cur_daddr) && | ||
| 3073 | (dport != cur_dport)) | 3074 | (dport != cur_dport)) |
| 3074 | continue; | 3075 | continue; |
| 3075 | 3076 | ||
| @@ -3080,7 +3081,8 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list, | |||
| 3080 | continue; | 3081 | continue; |
| 3081 | 3082 | ||
| 3082 | /* different dst address -> unique */ | 3083 | /* different dst address -> unique */ |
| 3083 | if (!cma_any_addr(cur_daddr) && | 3084 | if (!cma_any_addr(daddr) && |
| 3085 | !cma_any_addr(cur_daddr) && | ||
| 3084 | cma_addr_cmp(daddr, cur_daddr)) | 3086 | cma_addr_cmp(daddr, cur_daddr)) |
| 3085 | continue; | 3087 | continue; |
| 3086 | 3088 | ||
| @@ -3378,13 +3380,13 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
| 3378 | } | 3380 | } |
| 3379 | #endif | 3381 | #endif |
| 3380 | } | 3382 | } |
| 3383 | daddr = cma_dst_addr(id_priv); | ||
| 3384 | daddr->sa_family = addr->sa_family; | ||
| 3385 | |||
| 3381 | ret = cma_get_port(id_priv); | 3386 | ret = cma_get_port(id_priv); |
| 3382 | if (ret) | 3387 | if (ret) |
| 3383 | goto err2; | 3388 | goto err2; |
| 3384 | 3389 | ||
| 3385 | daddr = cma_dst_addr(id_priv); | ||
| 3386 | daddr->sa_family = addr->sa_family; | ||
| 3387 | |||
| 3388 | return 0; | 3390 | return 0; |
| 3389 | err2: | 3391 | err2: |
| 3390 | if (id_priv->cma_dev) | 3392 | if (id_priv->cma_dev) |
| @@ -4173,6 +4175,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, | |||
| 4173 | struct cma_multicast *mc; | 4175 | struct cma_multicast *mc; |
| 4174 | int ret; | 4176 | int ret; |
| 4175 | 4177 | ||
| 4178 | if (!id->device) | ||
| 4179 | return -EINVAL; | ||
| 4180 | |||
| 4176 | id_priv = container_of(id, struct rdma_id_private, id); | 4181 | id_priv = container_of(id, struct rdma_id_private, id); |
| 4177 | if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) && | 4182 | if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) && |
| 4178 | !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED)) | 4183 | !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED)) |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 3a9d0f5b5881..e5a1e7d81326 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -132,7 +132,7 @@ static inline struct ucma_context *_ucma_find_context(int id, | |||
| 132 | ctx = idr_find(&ctx_idr, id); | 132 | ctx = idr_find(&ctx_idr, id); |
| 133 | if (!ctx) | 133 | if (!ctx) |
| 134 | ctx = ERR_PTR(-ENOENT); | 134 | ctx = ERR_PTR(-ENOENT); |
| 135 | else if (ctx->file != file) | 135 | else if (ctx->file != file || !ctx->cm_id) |
| 136 | ctx = ERR_PTR(-EINVAL); | 136 | ctx = ERR_PTR(-EINVAL); |
| 137 | return ctx; | 137 | return ctx; |
| 138 | } | 138 | } |
| @@ -456,6 +456,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, | |||
| 456 | struct rdma_ucm_create_id cmd; | 456 | struct rdma_ucm_create_id cmd; |
| 457 | struct rdma_ucm_create_id_resp resp; | 457 | struct rdma_ucm_create_id_resp resp; |
| 458 | struct ucma_context *ctx; | 458 | struct ucma_context *ctx; |
| 459 | struct rdma_cm_id *cm_id; | ||
| 459 | enum ib_qp_type qp_type; | 460 | enum ib_qp_type qp_type; |
| 460 | int ret; | 461 | int ret; |
| 461 | 462 | ||
| @@ -476,10 +477,10 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, | |||
| 476 | return -ENOMEM; | 477 | return -ENOMEM; |
| 477 | 478 | ||
| 478 | ctx->uid = cmd.uid; | 479 | ctx->uid = cmd.uid; |
| 479 | ctx->cm_id = rdma_create_id(current->nsproxy->net_ns, | 480 | cm_id = rdma_create_id(current->nsproxy->net_ns, |
| 480 | ucma_event_handler, ctx, cmd.ps, qp_type); | 481 | ucma_event_handler, ctx, cmd.ps, qp_type); |
| 481 | if (IS_ERR(ctx->cm_id)) { | 482 | if (IS_ERR(cm_id)) { |
| 482 | ret = PTR_ERR(ctx->cm_id); | 483 | ret = PTR_ERR(cm_id); |
| 483 | goto err1; | 484 | goto err1; |
| 484 | } | 485 | } |
| 485 | 486 | ||
| @@ -489,14 +490,19 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, | |||
| 489 | ret = -EFAULT; | 490 | ret = -EFAULT; |
| 490 | goto err2; | 491 | goto err2; |
| 491 | } | 492 | } |
| 493 | |||
| 494 | ctx->cm_id = cm_id; | ||
| 492 | return 0; | 495 | return 0; |
| 493 | 496 | ||
| 494 | err2: | 497 | err2: |
| 495 | rdma_destroy_id(ctx->cm_id); | 498 | rdma_destroy_id(cm_id); |
| 496 | err1: | 499 | err1: |
| 497 | mutex_lock(&mut); | 500 | mutex_lock(&mut); |
| 498 | idr_remove(&ctx_idr, ctx->id); | 501 | idr_remove(&ctx_idr, ctx->id); |
| 499 | mutex_unlock(&mut); | 502 | mutex_unlock(&mut); |
| 503 | mutex_lock(&file->mut); | ||
| 504 | list_del(&ctx->list); | ||
| 505 | mutex_unlock(&file->mut); | ||
| 500 | kfree(ctx); | 506 | kfree(ctx); |
| 501 | return ret; | 507 | return ret; |
| 502 | } | 508 | } |
| @@ -664,19 +670,23 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, | |||
| 664 | int in_len, int out_len) | 670 | int in_len, int out_len) |
| 665 | { | 671 | { |
| 666 | struct rdma_ucm_resolve_ip cmd; | 672 | struct rdma_ucm_resolve_ip cmd; |
| 673 | struct sockaddr *src, *dst; | ||
| 667 | struct ucma_context *ctx; | 674 | struct ucma_context *ctx; |
| 668 | int ret; | 675 | int ret; |
| 669 | 676 | ||
| 670 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 677 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 671 | return -EFAULT; | 678 | return -EFAULT; |
| 672 | 679 | ||
| 680 | src = (struct sockaddr *) &cmd.src_addr; | ||
| 681 | dst = (struct sockaddr *) &cmd.dst_addr; | ||
| 682 | if (!rdma_addr_size(src) || !rdma_addr_size(dst)) | ||
| 683 | return -EINVAL; | ||
| 684 | |||
| 673 | ctx = ucma_get_ctx(file, cmd.id); | 685 | ctx = ucma_get_ctx(file, cmd.id); |
| 674 | if (IS_ERR(ctx)) | 686 | if (IS_ERR(ctx)) |
| 675 | return PTR_ERR(ctx); | 687 | return PTR_ERR(ctx); |
| 676 | 688 | ||
| 677 | ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, | 689 | ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); |
| 678 | (struct sockaddr *) &cmd.dst_addr, | ||
| 679 | cmd.timeout_ms); | ||
| 680 | ucma_put_ctx(ctx); | 690 | ucma_put_ctx(ctx); |
| 681 | return ret; | 691 | return ret; |
| 682 | } | 692 | } |
| @@ -1349,7 +1359,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, | |||
| 1349 | return -ENOSPC; | 1359 | return -ENOSPC; |
| 1350 | 1360 | ||
| 1351 | addr = (struct sockaddr *) &cmd->addr; | 1361 | addr = (struct sockaddr *) &cmd->addr; |
| 1352 | if (!cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr))) | 1362 | if (cmd->addr_size != rdma_addr_size(addr)) |
| 1353 | return -EINVAL; | 1363 | return -EINVAL; |
| 1354 | 1364 | ||
| 1355 | if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER) | 1365 | if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER) |
| @@ -1417,6 +1427,9 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file, | |||
| 1417 | join_cmd.uid = cmd.uid; | 1427 | join_cmd.uid = cmd.uid; |
| 1418 | join_cmd.id = cmd.id; | 1428 | join_cmd.id = cmd.id; |
| 1419 | join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); | 1429 | join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); |
| 1430 | if (!join_cmd.addr_size) | ||
| 1431 | return -EINVAL; | ||
| 1432 | |||
| 1420 | join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER; | 1433 | join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER; |
| 1421 | memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); | 1434 | memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); |
| 1422 | 1435 | ||
| @@ -1432,6 +1445,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, | |||
| 1432 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1445 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1433 | return -EFAULT; | 1446 | return -EFAULT; |
| 1434 | 1447 | ||
| 1448 | if (!rdma_addr_size((struct sockaddr *)&cmd.addr)) | ||
| 1449 | return -EINVAL; | ||
| 1450 | |||
| 1435 | return ucma_process_join(file, &cmd, out_len); | 1451 | return ucma_process_join(file, &cmd, out_len); |
| 1436 | } | 1452 | } |
| 1437 | 1453 | ||
diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h index 3eb7a8387116..96f76896488d 100644 --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h | |||
| @@ -57,8 +57,8 @@ | |||
| 57 | #define BNXT_RE_PAGE_SIZE_8M BIT(BNXT_RE_PAGE_SHIFT_8M) | 57 | #define BNXT_RE_PAGE_SIZE_8M BIT(BNXT_RE_PAGE_SHIFT_8M) |
| 58 | #define BNXT_RE_PAGE_SIZE_1G BIT(BNXT_RE_PAGE_SHIFT_1G) | 58 | #define BNXT_RE_PAGE_SIZE_1G BIT(BNXT_RE_PAGE_SHIFT_1G) |
| 59 | 59 | ||
| 60 | #define BNXT_RE_MAX_MR_SIZE_LOW BIT(BNXT_RE_PAGE_SHIFT_1G) | 60 | #define BNXT_RE_MAX_MR_SIZE_LOW BIT_ULL(BNXT_RE_PAGE_SHIFT_1G) |
| 61 | #define BNXT_RE_MAX_MR_SIZE_HIGH BIT(39) | 61 | #define BNXT_RE_MAX_MR_SIZE_HIGH BIT_ULL(39) |
| 62 | #define BNXT_RE_MAX_MR_SIZE BNXT_RE_MAX_MR_SIZE_HIGH | 62 | #define BNXT_RE_MAX_MR_SIZE BNXT_RE_MAX_MR_SIZE_HIGH |
| 63 | 63 | ||
| 64 | #define BNXT_RE_MAX_QPC_COUNT (64 * 1024) | 64 | #define BNXT_RE_MAX_QPC_COUNT (64 * 1024) |
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 0dd75f449872..8301d7e5fa8c 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c | |||
| @@ -3598,7 +3598,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length, | |||
| 3598 | int umem_pgs, page_shift, rc; | 3598 | int umem_pgs, page_shift, rc; |
| 3599 | 3599 | ||
| 3600 | if (length > BNXT_RE_MAX_MR_SIZE) { | 3600 | if (length > BNXT_RE_MAX_MR_SIZE) { |
| 3601 | dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%ld\n", | 3601 | dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%lld\n", |
| 3602 | length, BNXT_RE_MAX_MR_SIZE); | 3602 | length, BNXT_RE_MAX_MR_SIZE); |
| 3603 | return ERR_PTR(-ENOMEM); | 3603 | return ERR_PTR(-ENOMEM); |
| 3604 | } | 3604 | } |
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 06b42c880fd4..3a78faba8d91 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c | |||
| @@ -243,7 +243,7 @@ static void bnxt_qplib_service_nq(unsigned long data) | |||
| 243 | u32 sw_cons, raw_cons; | 243 | u32 sw_cons, raw_cons; |
| 244 | u16 type; | 244 | u16 type; |
| 245 | int budget = nq->budget; | 245 | int budget = nq->budget; |
| 246 | u64 q_handle; | 246 | uintptr_t q_handle; |
| 247 | 247 | ||
| 248 | /* Service the NQ until empty */ | 248 | /* Service the NQ until empty */ |
| 249 | raw_cons = hwq->cons; | 249 | raw_cons = hwq->cons; |
| @@ -526,7 +526,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, | |||
| 526 | 526 | ||
| 527 | /* Configure the request */ | 527 | /* Configure the request */ |
| 528 | req.dpi = cpu_to_le32(srq->dpi->dpi); | 528 | req.dpi = cpu_to_le32(srq->dpi->dpi); |
| 529 | req.srq_handle = cpu_to_le64(srq); | 529 | req.srq_handle = cpu_to_le64((uintptr_t)srq); |
| 530 | 530 | ||
| 531 | req.srq_size = cpu_to_le16((u16)srq->hwq.max_elements); | 531 | req.srq_size = cpu_to_le16((u16)srq->hwq.max_elements); |
| 532 | pbl = &srq->hwq.pbl[PBL_LVL_0]; | 532 | pbl = &srq->hwq.pbl[PBL_LVL_0]; |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 033b6af90de9..da091de4e69d 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
| @@ -4860,19 +4860,19 @@ static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev) | |||
| 4860 | return ib_register_device(&dev->ib_dev, NULL); | 4860 | return ib_register_device(&dev->ib_dev, NULL); |
| 4861 | } | 4861 | } |
| 4862 | 4862 | ||
| 4863 | static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev) | 4863 | static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev) |
| 4864 | { | 4864 | { |
| 4865 | ib_unregister_device(&dev->ib_dev); | 4865 | destroy_umrc_res(dev); |
| 4866 | } | 4866 | } |
| 4867 | 4867 | ||
| 4868 | static int mlx5_ib_stage_umr_res_init(struct mlx5_ib_dev *dev) | 4868 | static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev) |
| 4869 | { | 4869 | { |
| 4870 | return create_umr_res(dev); | 4870 | ib_unregister_device(&dev->ib_dev); |
| 4871 | } | 4871 | } |
| 4872 | 4872 | ||
| 4873 | static void mlx5_ib_stage_umr_res_cleanup(struct mlx5_ib_dev *dev) | 4873 | static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) |
| 4874 | { | 4874 | { |
| 4875 | destroy_umrc_res(dev); | 4875 | return create_umr_res(dev); |
| 4876 | } | 4876 | } |
| 4877 | 4877 | ||
| 4878 | static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev) | 4878 | static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev) |
| @@ -4982,12 +4982,15 @@ static const struct mlx5_ib_profile pf_profile = { | |||
| 4982 | STAGE_CREATE(MLX5_IB_STAGE_BFREG, | 4982 | STAGE_CREATE(MLX5_IB_STAGE_BFREG, |
| 4983 | mlx5_ib_stage_bfrag_init, | 4983 | mlx5_ib_stage_bfrag_init, |
| 4984 | mlx5_ib_stage_bfrag_cleanup), | 4984 | mlx5_ib_stage_bfrag_cleanup), |
| 4985 | STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR, | ||
| 4986 | NULL, | ||
| 4987 | mlx5_ib_stage_pre_ib_reg_umr_cleanup), | ||
| 4985 | STAGE_CREATE(MLX5_IB_STAGE_IB_REG, | 4988 | STAGE_CREATE(MLX5_IB_STAGE_IB_REG, |
| 4986 | mlx5_ib_stage_ib_reg_init, | 4989 | mlx5_ib_stage_ib_reg_init, |
| 4987 | mlx5_ib_stage_ib_reg_cleanup), | 4990 | mlx5_ib_stage_ib_reg_cleanup), |
| 4988 | STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES, | 4991 | STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR, |
| 4989 | mlx5_ib_stage_umr_res_init, | 4992 | mlx5_ib_stage_post_ib_reg_umr_init, |
| 4990 | mlx5_ib_stage_umr_res_cleanup), | 4993 | NULL), |
| 4991 | STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP, | 4994 | STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP, |
| 4992 | mlx5_ib_stage_delay_drop_init, | 4995 | mlx5_ib_stage_delay_drop_init, |
| 4993 | mlx5_ib_stage_delay_drop_cleanup), | 4996 | mlx5_ib_stage_delay_drop_cleanup), |
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 139385129973..a5272499b600 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h | |||
| @@ -739,8 +739,9 @@ enum mlx5_ib_stages { | |||
| 739 | MLX5_IB_STAGE_CONG_DEBUGFS, | 739 | MLX5_IB_STAGE_CONG_DEBUGFS, |
| 740 | MLX5_IB_STAGE_UAR, | 740 | MLX5_IB_STAGE_UAR, |
| 741 | MLX5_IB_STAGE_BFREG, | 741 | MLX5_IB_STAGE_BFREG, |
| 742 | MLX5_IB_STAGE_PRE_IB_REG_UMR, | ||
| 742 | MLX5_IB_STAGE_IB_REG, | 743 | MLX5_IB_STAGE_IB_REG, |
| 743 | MLX5_IB_STAGE_UMR_RESOURCES, | 744 | MLX5_IB_STAGE_POST_IB_REG_UMR, |
| 744 | MLX5_IB_STAGE_DELAY_DROP, | 745 | MLX5_IB_STAGE_DELAY_DROP, |
| 745 | MLX5_IB_STAGE_CLASS_ATTR, | 746 | MLX5_IB_STAGE_CLASS_ATTR, |
| 746 | MLX5_IB_STAGE_MAX, | 747 | MLX5_IB_STAGE_MAX, |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 1961c6a45437..c51c602f06d6 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
| @@ -838,7 +838,8 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, | |||
| 838 | *umem = ib_umem_get(pd->uobject->context, start, length, | 838 | *umem = ib_umem_get(pd->uobject->context, start, length, |
| 839 | access_flags, 0); | 839 | access_flags, 0); |
| 840 | err = PTR_ERR_OR_ZERO(*umem); | 840 | err = PTR_ERR_OR_ZERO(*umem); |
| 841 | if (err < 0) { | 841 | if (err) { |
| 842 | *umem = NULL; | ||
| 842 | mlx5_ib_err(dev, "umem get failed (%d)\n", err); | 843 | mlx5_ib_err(dev, "umem get failed (%d)\n", err); |
| 843 | return err; | 844 | return err; |
| 844 | } | 845 | } |
| @@ -1415,6 +1416,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, | |||
| 1415 | if (err) { | 1416 | if (err) { |
| 1416 | mlx5_ib_warn(dev, "Failed to rereg UMR\n"); | 1417 | mlx5_ib_warn(dev, "Failed to rereg UMR\n"); |
| 1417 | ib_umem_release(mr->umem); | 1418 | ib_umem_release(mr->umem); |
| 1419 | mr->umem = NULL; | ||
| 1418 | clean_mr(dev, mr); | 1420 | clean_mr(dev, mr); |
| 1419 | return err; | 1421 | return err; |
| 1420 | } | 1422 | } |
| @@ -1498,14 +1500,11 @@ static int clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) | |||
| 1498 | u32 key = mr->mmkey.key; | 1500 | u32 key = mr->mmkey.key; |
| 1499 | 1501 | ||
| 1500 | err = destroy_mkey(dev, mr); | 1502 | err = destroy_mkey(dev, mr); |
| 1501 | kfree(mr); | ||
| 1502 | if (err) { | 1503 | if (err) { |
| 1503 | mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n", | 1504 | mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n", |
| 1504 | key, err); | 1505 | key, err); |
| 1505 | return err; | 1506 | return err; |
| 1506 | } | 1507 | } |
| 1507 | } else { | ||
| 1508 | mlx5_mr_cache_free(dev, mr); | ||
| 1509 | } | 1508 | } |
| 1510 | 1509 | ||
| 1511 | return 0; | 1510 | return 0; |
| @@ -1548,6 +1547,11 @@ static int dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) | |||
| 1548 | atomic_sub(npages, &dev->mdev->priv.reg_pages); | 1547 | atomic_sub(npages, &dev->mdev->priv.reg_pages); |
| 1549 | } | 1548 | } |
| 1550 | 1549 | ||
| 1550 | if (!mr->allocated_from_cache) | ||
| 1551 | kfree(mr); | ||
| 1552 | else | ||
| 1553 | mlx5_mr_cache_free(dev, mr); | ||
| 1554 | |||
| 1551 | return 0; | 1555 | return 0; |
| 1552 | } | 1556 | } |
| 1553 | 1557 | ||
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 36197fbac63a..a2e1aa86e133 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
| @@ -1161,7 +1161,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev, | |||
| 1161 | ib_umem_release(sq->ubuffer.umem); | 1161 | ib_umem_release(sq->ubuffer.umem); |
| 1162 | } | 1162 | } |
| 1163 | 1163 | ||
| 1164 | static int get_rq_pas_size(void *qpc) | 1164 | static size_t get_rq_pas_size(void *qpc) |
| 1165 | { | 1165 | { |
| 1166 | u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12; | 1166 | u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12; |
| 1167 | u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride); | 1167 | u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride); |
| @@ -1177,7 +1177,8 @@ static int get_rq_pas_size(void *qpc) | |||
| 1177 | } | 1177 | } |
| 1178 | 1178 | ||
| 1179 | static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev, | 1179 | static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev, |
| 1180 | struct mlx5_ib_rq *rq, void *qpin) | 1180 | struct mlx5_ib_rq *rq, void *qpin, |
| 1181 | size_t qpinlen) | ||
| 1181 | { | 1182 | { |
| 1182 | struct mlx5_ib_qp *mqp = rq->base.container_mibqp; | 1183 | struct mlx5_ib_qp *mqp = rq->base.container_mibqp; |
| 1183 | __be64 *pas; | 1184 | __be64 *pas; |
| @@ -1186,9 +1187,12 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev, | |||
| 1186 | void *rqc; | 1187 | void *rqc; |
| 1187 | void *wq; | 1188 | void *wq; |
| 1188 | void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc); | 1189 | void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc); |
| 1189 | int inlen; | 1190 | size_t rq_pas_size = get_rq_pas_size(qpc); |
| 1191 | size_t inlen; | ||
| 1190 | int err; | 1192 | int err; |
| 1191 | u32 rq_pas_size = get_rq_pas_size(qpc); | 1193 | |
| 1194 | if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas)) | ||
| 1195 | return -EINVAL; | ||
| 1192 | 1196 | ||
| 1193 | inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size; | 1197 | inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size; |
| 1194 | in = kvzalloc(inlen, GFP_KERNEL); | 1198 | in = kvzalloc(inlen, GFP_KERNEL); |
| @@ -1277,7 +1281,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev, | |||
| 1277 | } | 1281 | } |
| 1278 | 1282 | ||
| 1279 | static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, | 1283 | static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, |
| 1280 | u32 *in, | 1284 | u32 *in, size_t inlen, |
| 1281 | struct ib_pd *pd) | 1285 | struct ib_pd *pd) |
| 1282 | { | 1286 | { |
| 1283 | struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp; | 1287 | struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp; |
| @@ -1309,7 +1313,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, | |||
| 1309 | rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING; | 1313 | rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING; |
| 1310 | if (qp->flags & MLX5_IB_QP_PCI_WRITE_END_PADDING) | 1314 | if (qp->flags & MLX5_IB_QP_PCI_WRITE_END_PADDING) |
| 1311 | rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING; | 1315 | rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING; |
| 1312 | err = create_raw_packet_qp_rq(dev, rq, in); | 1316 | err = create_raw_packet_qp_rq(dev, rq, in, inlen); |
| 1313 | if (err) | 1317 | if (err) |
| 1314 | goto err_destroy_sq; | 1318 | goto err_destroy_sq; |
| 1315 | 1319 | ||
| @@ -1872,11 +1876,16 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, | |||
| 1872 | } | 1876 | } |
| 1873 | } | 1877 | } |
| 1874 | 1878 | ||
| 1879 | if (inlen < 0) { | ||
| 1880 | err = -EINVAL; | ||
| 1881 | goto err; | ||
| 1882 | } | ||
| 1883 | |||
| 1875 | if (init_attr->qp_type == IB_QPT_RAW_PACKET || | 1884 | if (init_attr->qp_type == IB_QPT_RAW_PACKET || |
| 1876 | qp->flags & MLX5_IB_QP_UNDERLAY) { | 1885 | qp->flags & MLX5_IB_QP_UNDERLAY) { |
| 1877 | qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr; | 1886 | qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr; |
| 1878 | raw_packet_qp_copy_info(qp, &qp->raw_packet_qp); | 1887 | raw_packet_qp_copy_info(qp, &qp->raw_packet_qp); |
| 1879 | err = create_raw_packet_qp(dev, qp, in, pd); | 1888 | err = create_raw_packet_qp(dev, qp, in, inlen, pd); |
| 1880 | } else { | 1889 | } else { |
| 1881 | err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen); | 1890 | err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen); |
| 1882 | } | 1891 | } |
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c index 6d5fadad9090..3c7522d025f2 100644 --- a/drivers/infiniband/hw/mlx5/srq.c +++ b/drivers/infiniband/hw/mlx5/srq.c | |||
| @@ -241,8 +241,8 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, | |||
| 241 | { | 241 | { |
| 242 | struct mlx5_ib_dev *dev = to_mdev(pd->device); | 242 | struct mlx5_ib_dev *dev = to_mdev(pd->device); |
| 243 | struct mlx5_ib_srq *srq; | 243 | struct mlx5_ib_srq *srq; |
| 244 | int desc_size; | 244 | size_t desc_size; |
| 245 | int buf_size; | 245 | size_t buf_size; |
| 246 | int err; | 246 | int err; |
| 247 | struct mlx5_srq_attr in = {0}; | 247 | struct mlx5_srq_attr in = {0}; |
| 248 | __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); | 248 | __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); |
| @@ -266,15 +266,18 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, | |||
| 266 | 266 | ||
| 267 | desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + | 267 | desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + |
| 268 | srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); | 268 | srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); |
| 269 | if (desc_size == 0 || srq->msrq.max_gs > desc_size) | ||
| 270 | return ERR_PTR(-EINVAL); | ||
| 269 | desc_size = roundup_pow_of_two(desc_size); | 271 | desc_size = roundup_pow_of_two(desc_size); |
| 270 | desc_size = max_t(int, 32, desc_size); | 272 | desc_size = max_t(size_t, 32, desc_size); |
| 273 | if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) | ||
| 274 | return ERR_PTR(-EINVAL); | ||
| 271 | srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / | 275 | srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / |
| 272 | sizeof(struct mlx5_wqe_data_seg); | 276 | sizeof(struct mlx5_wqe_data_seg); |
| 273 | srq->msrq.wqe_shift = ilog2(desc_size); | 277 | srq->msrq.wqe_shift = ilog2(desc_size); |
| 274 | buf_size = srq->msrq.max * desc_size; | 278 | buf_size = srq->msrq.max * desc_size; |
| 275 | mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n", | 279 | if (buf_size < desc_size) |
| 276 | desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs, | 280 | return ERR_PTR(-EINVAL); |
| 277 | srq->msrq.max_avail_gather); | ||
| 278 | in.type = init_attr->srq_type; | 281 | in.type = init_attr->srq_type; |
| 279 | 282 | ||
| 280 | if (pd->uobject) | 283 | if (pd->uobject) |
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 372c074bb1b9..86c1a190d946 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
| @@ -151,7 +151,7 @@ config DVB_MMAP | |||
| 151 | select VIDEOBUF2_VMALLOC | 151 | select VIDEOBUF2_VMALLOC |
| 152 | default n | 152 | default n |
| 153 | help | 153 | help |
| 154 | This option enables DVB experimental memory-mapped API, with | 154 | This option enables DVB experimental memory-mapped API, which |
| 155 | reduces the number of context switches to read DVB buffers, as | 155 | reduces the number of context switches to read DVB buffers, as |
| 156 | the buffers can use mmap() syscalls. | 156 | the buffers can use mmap() syscalls. |
| 157 | 157 | ||
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c index 92f93a880015..aba488cd0e64 100644 --- a/drivers/media/platform/tegra-cec/tegra_cec.c +++ b/drivers/media/platform/tegra-cec/tegra_cec.c | |||
| @@ -172,16 +172,13 @@ static irqreturn_t tegra_cec_irq_handler(int irq, void *data) | |||
| 172 | } | 172 | } |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | if (status & (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN | | 175 | if (status & TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED) { |
| 176 | TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED | | ||
| 177 | TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED | | ||
| 178 | TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) { | ||
| 179 | cec_write(cec, TEGRA_CEC_INT_STAT, | 176 | cec_write(cec, TEGRA_CEC_INT_STAT, |
| 180 | (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN | | 177 | TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED); |
| 181 | TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED | | 178 | cec->rx_done = false; |
| 182 | TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED | | 179 | cec->rx_buf_cnt = 0; |
| 183 | TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)); | 180 | } |
| 184 | } else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) { | 181 | if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) { |
| 185 | u32 v; | 182 | u32 v; |
| 186 | 183 | ||
| 187 | cec_write(cec, TEGRA_CEC_INT_STAT, | 184 | cec_write(cec, TEGRA_CEC_INT_STAT, |
| @@ -255,7 +252,7 @@ static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable) | |||
| 255 | TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED | | 252 | TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED | |
| 256 | TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED | | 253 | TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED | |
| 257 | TEGRA_CEC_INT_MASK_RX_REGISTER_FULL | | 254 | TEGRA_CEC_INT_MASK_RX_REGISTER_FULL | |
| 258 | TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN); | 255 | TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED); |
| 259 | 256 | ||
| 260 | cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE); | 257 | cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE); |
| 261 | return 0; | 258 | return 0; |
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 20135a5de748..2cfb963d9f37 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
| @@ -72,6 +72,7 @@ MODULE_ALIAS("mmc:block"); | |||
| 72 | #define MMC_BLK_TIMEOUT_MS (10 * 1000) | 72 | #define MMC_BLK_TIMEOUT_MS (10 * 1000) |
| 73 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 | 73 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 |
| 74 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) | 74 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) |
| 75 | #define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8) | ||
| 75 | 76 | ||
| 76 | #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ | 77 | #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ |
| 77 | (rq_data_dir(req) == WRITE)) | 78 | (rq_data_dir(req) == WRITE)) |
| @@ -587,6 +588,24 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
| 587 | } | 588 | } |
| 588 | 589 | ||
| 589 | /* | 590 | /* |
| 591 | * Make sure the cache of the PARTITION_CONFIG register and | ||
| 592 | * PARTITION_ACCESS bits is updated in case the ioctl ext_csd write | ||
| 593 | * changed it successfully. | ||
| 594 | */ | ||
| 595 | if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_PART_CONFIG) && | ||
| 596 | (cmd.opcode == MMC_SWITCH)) { | ||
| 597 | struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); | ||
| 598 | u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg); | ||
| 599 | |||
| 600 | /* | ||
| 601 | * Update cache so the next mmc_blk_part_switch call operates | ||
| 602 | * on up-to-date data. | ||
| 603 | */ | ||
| 604 | card->ext_csd.part_config = value; | ||
| 605 | main_md->part_curr = value & EXT_CSD_PART_CONFIG_ACC_MASK; | ||
| 606 | } | ||
| 607 | |||
| 608 | /* | ||
| 590 | * According to the SD specs, some commands require a delay after | 609 | * According to the SD specs, some commands require a delay after |
| 591 | * issuing the command. | 610 | * issuing the command. |
| 592 | */ | 611 | */ |
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 79a5b985ccf5..9c821eedd156 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h | |||
| @@ -82,6 +82,7 @@ struct mmc_fixup { | |||
| 82 | #define CID_MANFID_APACER 0x27 | 82 | #define CID_MANFID_APACER 0x27 |
| 83 | #define CID_MANFID_KINGSTON 0x70 | 83 | #define CID_MANFID_KINGSTON 0x70 |
| 84 | #define CID_MANFID_HYNIX 0x90 | 84 | #define CID_MANFID_HYNIX 0x90 |
| 85 | #define CID_MANFID_NUMONYX 0xFE | ||
| 85 | 86 | ||
| 86 | #define END_FIXUP { NULL } | 87 | #define END_FIXUP { NULL } |
| 87 | 88 | ||
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 75d317623852..5153577754f0 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h | |||
| @@ -109,6 +109,12 @@ static const struct mmc_fixup mmc_ext_csd_fixups[] = { | |||
| 109 | */ | 109 | */ |
| 110 | MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, | 110 | MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, |
| 111 | 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), | 111 | 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), |
| 112 | /* | ||
| 113 | * Certain Micron (Numonyx) eMMC 4.5 cards might get broken when HPI | ||
| 114 | * feature is used so disable the HPI feature for such buggy cards. | ||
| 115 | */ | ||
| 116 | MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_NUMONYX, | ||
| 117 | 0x014e, add_quirk, MMC_QUIRK_BROKEN_HPI, 6), | ||
| 112 | 118 | ||
| 113 | END_FIXUP | 119 | END_FIXUP |
| 114 | }; | 120 | }; |
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index fa41d9422d57..a84aa3f1ae85 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
| @@ -165,9 +165,15 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) | |||
| 165 | static int dw_mci_exynos_runtime_resume(struct device *dev) | 165 | static int dw_mci_exynos_runtime_resume(struct device *dev) |
| 166 | { | 166 | { |
| 167 | struct dw_mci *host = dev_get_drvdata(dev); | 167 | struct dw_mci *host = dev_get_drvdata(dev); |
| 168 | int ret; | ||
| 169 | |||
| 170 | ret = dw_mci_runtime_resume(dev); | ||
| 171 | if (ret) | ||
| 172 | return ret; | ||
| 168 | 173 | ||
| 169 | dw_mci_exynos_config_smu(host); | 174 | dw_mci_exynos_config_smu(host); |
| 170 | return dw_mci_runtime_resume(dev); | 175 | |
| 176 | return ret; | ||
| 171 | } | 177 | } |
| 172 | 178 | ||
| 173 | /** | 179 | /** |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index d9b4acefed31..06d47414d0c1 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -413,7 +413,9 @@ static inline void dw_mci_set_cto(struct dw_mci *host) | |||
| 413 | cto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; | 413 | cto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; |
| 414 | if (cto_div == 0) | 414 | if (cto_div == 0) |
| 415 | cto_div = 1; | 415 | cto_div = 1; |
| 416 | cto_ms = DIV_ROUND_UP(MSEC_PER_SEC * cto_clks * cto_div, host->bus_hz); | 416 | |
| 417 | cto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * cto_clks * cto_div, | ||
| 418 | host->bus_hz); | ||
| 417 | 419 | ||
| 418 | /* add a bit spare time */ | 420 | /* add a bit spare time */ |
| 419 | cto_ms += 10; | 421 | cto_ms += 10; |
| @@ -562,6 +564,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
| 562 | (sizeof(struct idmac_desc_64addr) * | 564 | (sizeof(struct idmac_desc_64addr) * |
| 563 | (i + 1))) >> 32; | 565 | (i + 1))) >> 32; |
| 564 | /* Initialize reserved and buffer size fields to "0" */ | 566 | /* Initialize reserved and buffer size fields to "0" */ |
| 567 | p->des0 = 0; | ||
| 565 | p->des1 = 0; | 568 | p->des1 = 0; |
| 566 | p->des2 = 0; | 569 | p->des2 = 0; |
| 567 | p->des3 = 0; | 570 | p->des3 = 0; |
| @@ -584,6 +587,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
| 584 | i++, p++) { | 587 | i++, p++) { |
| 585 | p->des3 = cpu_to_le32(host->sg_dma + | 588 | p->des3 = cpu_to_le32(host->sg_dma + |
| 586 | (sizeof(struct idmac_desc) * (i + 1))); | 589 | (sizeof(struct idmac_desc) * (i + 1))); |
| 590 | p->des0 = 0; | ||
| 587 | p->des1 = 0; | 591 | p->des1 = 0; |
| 588 | } | 592 | } |
| 589 | 593 | ||
| @@ -1799,8 +1803,8 @@ static bool dw_mci_reset(struct dw_mci *host) | |||
| 1799 | } | 1803 | } |
| 1800 | 1804 | ||
| 1801 | if (host->use_dma == TRANS_MODE_IDMAC) | 1805 | if (host->use_dma == TRANS_MODE_IDMAC) |
| 1802 | /* It is also recommended that we reset and reprogram idmac */ | 1806 | /* It is also required that we reinit idmac */ |
| 1803 | dw_mci_idmac_reset(host); | 1807 | dw_mci_idmac_init(host); |
| 1804 | 1808 | ||
| 1805 | ret = true; | 1809 | ret = true; |
| 1806 | 1810 | ||
| @@ -1948,8 +1952,9 @@ static void dw_mci_set_drto(struct dw_mci *host) | |||
| 1948 | drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; | 1952 | drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; |
| 1949 | if (drto_div == 0) | 1953 | if (drto_div == 0) |
| 1950 | drto_div = 1; | 1954 | drto_div = 1; |
| 1951 | drto_ms = DIV_ROUND_UP(MSEC_PER_SEC * drto_clks * drto_div, | 1955 | |
| 1952 | host->bus_hz); | 1956 | drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div, |
| 1957 | host->bus_hz); | ||
| 1953 | 1958 | ||
| 1954 | /* add a bit spare time */ | 1959 | /* add a bit spare time */ |
| 1955 | drto_ms += 10; | 1960 | drto_ms += 10; |
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 4065da58789d..32321bd596d8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
| @@ -680,7 +680,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
| 680 | host->hw_name = "ACPI"; | 680 | host->hw_name = "ACPI"; |
| 681 | host->ops = &sdhci_acpi_ops_dflt; | 681 | host->ops = &sdhci_acpi_ops_dflt; |
| 682 | host->irq = platform_get_irq(pdev, 0); | 682 | host->irq = platform_get_irq(pdev, 0); |
| 683 | if (host->irq <= 0) { | 683 | if (host->irq < 0) { |
| 684 | err = -EINVAL; | 684 | err = -EINVAL; |
| 685 | goto err_free; | 685 | goto err_free; |
| 686 | } | 686 | } |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index de8c902059b8..7d80a8bb96fe 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
| @@ -479,7 +479,7 @@ static int shrink_ecclayout(struct mtd_info *mtd, | |||
| 479 | for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) { | 479 | for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) { |
| 480 | u32 eccpos; | 480 | u32 eccpos; |
| 481 | 481 | ||
| 482 | ret = mtd_ooblayout_ecc(mtd, section, &oobregion); | 482 | ret = mtd_ooblayout_ecc(mtd, section++, &oobregion); |
| 483 | if (ret < 0) { | 483 | if (ret < 0) { |
| 484 | if (ret != -ERANGE) | 484 | if (ret != -ERANGE) |
| 485 | return ret; | 485 | return ret; |
| @@ -526,7 +526,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to) | |||
| 526 | for (i = 0; i < ARRAY_SIZE(to->eccpos);) { | 526 | for (i = 0; i < ARRAY_SIZE(to->eccpos);) { |
| 527 | u32 eccpos; | 527 | u32 eccpos; |
| 528 | 528 | ||
| 529 | ret = mtd_ooblayout_ecc(mtd, section, &oobregion); | 529 | ret = mtd_ooblayout_ecc(mtd, section++, &oobregion); |
| 530 | if (ret < 0) { | 530 | if (ret < 0) { |
| 531 | if (ret != -ERANGE) | 531 | if (ret != -ERANGE) |
| 532 | return ret; | 532 | return ret; |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 4872a7ba6503..5a9c2f0020c2 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
| @@ -173,14 +173,9 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | |||
| 173 | 173 | ||
| 174 | /* returns nonzero if entire page is blank */ | 174 | /* returns nonzero if entire page is blank */ |
| 175 | static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, | 175 | static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, |
| 176 | u32 *eccstat, unsigned int bufnum) | 176 | u32 eccstat, unsigned int bufnum) |
| 177 | { | 177 | { |
| 178 | u32 reg = eccstat[bufnum / 4]; | 178 | return (eccstat >> ((3 - bufnum % 4) * 8)) & 15; |
| 179 | int errors; | ||
| 180 | |||
| 181 | errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; | ||
| 182 | |||
| 183 | return errors; | ||
| 184 | } | 179 | } |
| 185 | 180 | ||
| 186 | /* | 181 | /* |
| @@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) | |||
| 193 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 188 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
| 194 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | 189 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; |
| 195 | struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; | 190 | struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; |
| 196 | u32 eccstat[4]; | 191 | u32 eccstat; |
| 197 | int i; | 192 | int i; |
| 198 | 193 | ||
| 199 | /* set the chip select for NAND Transaction */ | 194 | /* set the chip select for NAND Transaction */ |
| @@ -228,19 +223,17 @@ static void fsl_ifc_run_command(struct mtd_info *mtd) | |||
| 228 | if (nctrl->eccread) { | 223 | if (nctrl->eccread) { |
| 229 | int errors; | 224 | int errors; |
| 230 | int bufnum = nctrl->page & priv->bufnum_mask; | 225 | int bufnum = nctrl->page & priv->bufnum_mask; |
| 231 | int sector = bufnum * chip->ecc.steps; | 226 | int sector_start = bufnum * chip->ecc.steps; |
| 232 | int sector_end = sector + chip->ecc.steps - 1; | 227 | int sector_end = sector_start + chip->ecc.steps - 1; |
| 233 | __be32 *eccstat_regs; | 228 | __be32 *eccstat_regs; |
| 234 | 229 | ||
| 235 | if (ctrl->version >= FSL_IFC_VERSION_2_0_0) | 230 | eccstat_regs = ifc->ifc_nand.nand_eccstat; |
| 236 | eccstat_regs = ifc->ifc_nand.v2_nand_eccstat; | 231 | eccstat = ifc_in32(&eccstat_regs[sector_start / 4]); |
| 237 | else | ||
| 238 | eccstat_regs = ifc->ifc_nand.v1_nand_eccstat; | ||
| 239 | 232 | ||
| 240 | for (i = sector / 4; i <= sector_end / 4; i++) | 233 | for (i = sector_start; i <= sector_end; i++) { |
| 241 | eccstat[i] = ifc_in32(&eccstat_regs[i]); | 234 | if (i != sector_start && !(i % 4)) |
| 235 | eccstat = ifc_in32(&eccstat_regs[i / 4]); | ||
| 242 | 236 | ||
| 243 | for (i = sector; i <= sector_end; i++) { | ||
| 244 | errors = check_read_ecc(mtd, ctrl, eccstat, i); | 237 | errors = check_read_ecc(mtd, ctrl, eccstat, i); |
| 245 | 238 | ||
| 246 | if (errors == 15) { | 239 | if (errors == 15) { |
| @@ -626,6 +619,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
| 626 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 619 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
| 627 | struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; | 620 | struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs; |
| 628 | u32 nand_fsr; | 621 | u32 nand_fsr; |
| 622 | int status; | ||
| 629 | 623 | ||
| 630 | /* Use READ_STATUS command, but wait for the device to be ready */ | 624 | /* Use READ_STATUS command, but wait for the device to be ready */ |
| 631 | ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | 625 | ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | |
| @@ -640,12 +634,12 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
| 640 | fsl_ifc_run_command(mtd); | 634 | fsl_ifc_run_command(mtd); |
| 641 | 635 | ||
| 642 | nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr); | 636 | nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr); |
| 643 | 637 | status = nand_fsr >> 24; | |
| 644 | /* | 638 | /* |
| 645 | * The chip always seems to report that it is | 639 | * The chip always seems to report that it is |
| 646 | * write-protected, even when it is not. | 640 | * write-protected, even when it is not. |
| 647 | */ | 641 | */ |
| 648 | return nand_fsr | NAND_STATUS_WP; | 642 | return status | NAND_STATUS_WP; |
| 649 | } | 643 | } |
| 650 | 644 | ||
| 651 | /* | 645 | /* |
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 1e37313054f3..6da69af103e6 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c | |||
| @@ -390,37 +390,23 @@ static int cc770_get_berr_counter(const struct net_device *dev, | |||
| 390 | return 0; | 390 | return 0; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) | 393 | static void cc770_tx(struct net_device *dev, int mo) |
| 394 | { | 394 | { |
| 395 | struct cc770_priv *priv = netdev_priv(dev); | 395 | struct cc770_priv *priv = netdev_priv(dev); |
| 396 | struct net_device_stats *stats = &dev->stats; | 396 | struct can_frame *cf = (struct can_frame *)priv->tx_skb->data; |
| 397 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
| 398 | unsigned int mo = obj2msgobj(CC770_OBJ_TX); | ||
| 399 | u8 dlc, rtr; | 397 | u8 dlc, rtr; |
| 400 | u32 id; | 398 | u32 id; |
| 401 | int i; | 399 | int i; |
| 402 | 400 | ||
| 403 | if (can_dropped_invalid_skb(dev, skb)) | ||
| 404 | return NETDEV_TX_OK; | ||
| 405 | |||
| 406 | if ((cc770_read_reg(priv, | ||
| 407 | msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { | ||
| 408 | netdev_err(dev, "TX register is still occupied!\n"); | ||
| 409 | return NETDEV_TX_BUSY; | ||
| 410 | } | ||
| 411 | |||
| 412 | netif_stop_queue(dev); | ||
| 413 | |||
| 414 | dlc = cf->can_dlc; | 401 | dlc = cf->can_dlc; |
| 415 | id = cf->can_id; | 402 | id = cf->can_id; |
| 416 | if (cf->can_id & CAN_RTR_FLAG) | 403 | rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR; |
| 417 | rtr = 0; | 404 | |
| 418 | else | 405 | cc770_write_reg(priv, msgobj[mo].ctrl0, |
| 419 | rtr = MSGCFG_DIR; | 406 | MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); |
| 420 | cc770_write_reg(priv, msgobj[mo].ctrl1, | 407 | cc770_write_reg(priv, msgobj[mo].ctrl1, |
| 421 | RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES); | 408 | RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES); |
| 422 | cc770_write_reg(priv, msgobj[mo].ctrl0, | 409 | |
| 423 | MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES); | ||
| 424 | if (id & CAN_EFF_FLAG) { | 410 | if (id & CAN_EFF_FLAG) { |
| 425 | id &= CAN_EFF_MASK; | 411 | id &= CAN_EFF_MASK; |
| 426 | cc770_write_reg(priv, msgobj[mo].config, | 412 | cc770_write_reg(priv, msgobj[mo].config, |
| @@ -439,22 +425,30 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 439 | for (i = 0; i < dlc; i++) | 425 | for (i = 0; i < dlc; i++) |
| 440 | cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]); | 426 | cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]); |
| 441 | 427 | ||
| 442 | /* Store echo skb before starting the transfer */ | ||
| 443 | can_put_echo_skb(skb, dev, 0); | ||
| 444 | |||
| 445 | cc770_write_reg(priv, msgobj[mo].ctrl1, | 428 | cc770_write_reg(priv, msgobj[mo].ctrl1, |
| 446 | RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); | 429 | RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); |
| 430 | cc770_write_reg(priv, msgobj[mo].ctrl0, | ||
| 431 | MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC); | ||
| 432 | } | ||
| 447 | 433 | ||
| 448 | stats->tx_bytes += dlc; | 434 | static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) |
| 435 | { | ||
| 436 | struct cc770_priv *priv = netdev_priv(dev); | ||
| 437 | unsigned int mo = obj2msgobj(CC770_OBJ_TX); | ||
| 449 | 438 | ||
| 439 | if (can_dropped_invalid_skb(dev, skb)) | ||
| 440 | return NETDEV_TX_OK; | ||
| 450 | 441 | ||
| 451 | /* | 442 | netif_stop_queue(dev); |
| 452 | * HM: We had some cases of repeated IRQs so make sure the | 443 | |
| 453 | * INT is acknowledged I know it's already further up, but | 444 | if ((cc770_read_reg(priv, |
| 454 | * doing again fixed the issue | 445 | msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { |
| 455 | */ | 446 | netdev_err(dev, "TX register is still occupied!\n"); |
| 456 | cc770_write_reg(priv, msgobj[mo].ctrl0, | 447 | return NETDEV_TX_BUSY; |
| 457 | MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); | 448 | } |
| 449 | |||
| 450 | priv->tx_skb = skb; | ||
| 451 | cc770_tx(dev, mo); | ||
| 458 | 452 | ||
| 459 | return NETDEV_TX_OK; | 453 | return NETDEV_TX_OK; |
| 460 | } | 454 | } |
| @@ -680,19 +674,46 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o) | |||
| 680 | struct cc770_priv *priv = netdev_priv(dev); | 674 | struct cc770_priv *priv = netdev_priv(dev); |
| 681 | struct net_device_stats *stats = &dev->stats; | 675 | struct net_device_stats *stats = &dev->stats; |
| 682 | unsigned int mo = obj2msgobj(o); | 676 | unsigned int mo = obj2msgobj(o); |
| 677 | struct can_frame *cf; | ||
| 678 | u8 ctrl1; | ||
| 679 | |||
| 680 | ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); | ||
| 683 | 681 | ||
| 684 | /* Nothing more to send, switch off interrupts */ | ||
| 685 | cc770_write_reg(priv, msgobj[mo].ctrl0, | 682 | cc770_write_reg(priv, msgobj[mo].ctrl0, |
| 686 | MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); | 683 | MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); |
| 687 | /* | 684 | cc770_write_reg(priv, msgobj[mo].ctrl1, |
| 688 | * We had some cases of repeated IRQ so make sure the | 685 | RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES); |
| 689 | * INT is acknowledged | 686 | |
| 687 | if (unlikely(!priv->tx_skb)) { | ||
| 688 | netdev_err(dev, "missing tx skb in tx interrupt\n"); | ||
| 689 | return; | ||
| 690 | } | ||
| 691 | |||
| 692 | if (unlikely(ctrl1 & MSGLST_SET)) { | ||
| 693 | stats->rx_over_errors++; | ||
| 694 | stats->rx_errors++; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* When the CC770 is sending an RTR message and it receives a regular | ||
| 698 | * message that matches the id of the RTR message, it will overwrite the | ||
| 699 | * outgoing message in the TX register. When this happens we must | ||
| 700 | * process the received message and try to transmit the outgoing skb | ||
| 701 | * again. | ||
| 690 | */ | 702 | */ |
| 691 | cc770_write_reg(priv, msgobj[mo].ctrl0, | 703 | if (unlikely(ctrl1 & NEWDAT_SET)) { |
| 692 | MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); | 704 | cc770_rx(dev, mo, ctrl1); |
| 705 | cc770_tx(dev, mo); | ||
| 706 | return; | ||
| 707 | } | ||
| 693 | 708 | ||
| 709 | cf = (struct can_frame *)priv->tx_skb->data; | ||
| 710 | stats->tx_bytes += cf->can_dlc; | ||
| 694 | stats->tx_packets++; | 711 | stats->tx_packets++; |
| 712 | |||
| 713 | can_put_echo_skb(priv->tx_skb, dev, 0); | ||
| 695 | can_get_echo_skb(dev, 0); | 714 | can_get_echo_skb(dev, 0); |
| 715 | priv->tx_skb = NULL; | ||
| 716 | |||
| 696 | netif_wake_queue(dev); | 717 | netif_wake_queue(dev); |
| 697 | } | 718 | } |
| 698 | 719 | ||
| @@ -804,6 +825,7 @@ struct net_device *alloc_cc770dev(int sizeof_priv) | |||
| 804 | priv->can.do_set_bittiming = cc770_set_bittiming; | 825 | priv->can.do_set_bittiming = cc770_set_bittiming; |
| 805 | priv->can.do_set_mode = cc770_set_mode; | 826 | priv->can.do_set_mode = cc770_set_mode; |
| 806 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 827 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; |
| 828 | priv->tx_skb = NULL; | ||
| 807 | 829 | ||
| 808 | memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags)); | 830 | memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags)); |
| 809 | 831 | ||
diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h index a1739db98d91..95752e1d1283 100644 --- a/drivers/net/can/cc770/cc770.h +++ b/drivers/net/can/cc770/cc770.h | |||
| @@ -193,6 +193,8 @@ struct cc770_priv { | |||
| 193 | u8 cpu_interface; /* CPU interface register */ | 193 | u8 cpu_interface; /* CPU interface register */ |
| 194 | u8 clkout; /* Clock out register */ | 194 | u8 clkout; /* Clock out register */ |
| 195 | u8 bus_config; /* Bus conffiguration register */ | 195 | u8 bus_config; /* Bus conffiguration register */ |
| 196 | |||
| 197 | struct sk_buff *tx_skb; | ||
| 196 | }; | 198 | }; |
| 197 | 199 | ||
| 198 | struct net_device *alloc_cc770dev(int sizeof_priv); | 200 | struct net_device *alloc_cc770dev(int sizeof_priv); |
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index 2772d05ff11c..fedd927ba6ed 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2) | 30 | #define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2) |
| 31 | #define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3) | 31 | #define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3) |
| 32 | #define IFI_CANFD_STCMD_BUSOFF BIT(4) | 32 | #define IFI_CANFD_STCMD_BUSOFF BIT(4) |
| 33 | #define IFI_CANFD_STCMD_ERROR_WARNING BIT(5) | ||
| 33 | #define IFI_CANFD_STCMD_BUSMONITOR BIT(16) | 34 | #define IFI_CANFD_STCMD_BUSMONITOR BIT(16) |
| 34 | #define IFI_CANFD_STCMD_LOOPBACK BIT(18) | 35 | #define IFI_CANFD_STCMD_LOOPBACK BIT(18) |
| 35 | #define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24) | 36 | #define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24) |
| @@ -52,7 +53,10 @@ | |||
| 52 | #define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13) | 53 | #define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13) |
| 53 | 54 | ||
| 54 | #define IFI_CANFD_INTERRUPT 0xc | 55 | #define IFI_CANFD_INTERRUPT 0xc |
| 56 | #define IFI_CANFD_INTERRUPT_ERROR_BUSOFF BIT(0) | ||
| 55 | #define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1) | 57 | #define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1) |
| 58 | #define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG BIT(2) | ||
| 59 | #define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC BIT(3) | ||
| 56 | #define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10) | 60 | #define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10) |
| 57 | #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16) | 61 | #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16) |
| 58 | #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22) | 62 | #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22) |
| @@ -61,6 +65,10 @@ | |||
| 61 | #define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31)) | 65 | #define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31)) |
| 62 | 66 | ||
| 63 | #define IFI_CANFD_IRQMASK 0x10 | 67 | #define IFI_CANFD_IRQMASK 0x10 |
| 68 | #define IFI_CANFD_IRQMASK_ERROR_BUSOFF BIT(0) | ||
| 69 | #define IFI_CANFD_IRQMASK_ERROR_WARNING BIT(1) | ||
| 70 | #define IFI_CANFD_IRQMASK_ERROR_STATE_CHG BIT(2) | ||
| 71 | #define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC BIT(3) | ||
| 64 | #define IFI_CANFD_IRQMASK_SET_ERR BIT(7) | 72 | #define IFI_CANFD_IRQMASK_SET_ERR BIT(7) |
| 65 | #define IFI_CANFD_IRQMASK_SET_TS BIT(15) | 73 | #define IFI_CANFD_IRQMASK_SET_TS BIT(15) |
| 66 | #define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16) | 74 | #define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16) |
| @@ -136,6 +144,8 @@ | |||
| 136 | #define IFI_CANFD_SYSCLOCK 0x50 | 144 | #define IFI_CANFD_SYSCLOCK 0x50 |
| 137 | 145 | ||
| 138 | #define IFI_CANFD_VER 0x54 | 146 | #define IFI_CANFD_VER 0x54 |
| 147 | #define IFI_CANFD_VER_REV_MASK 0xff | ||
| 148 | #define IFI_CANFD_VER_REV_MIN_SUPPORTED 0x15 | ||
| 139 | 149 | ||
| 140 | #define IFI_CANFD_IP_ID 0x58 | 150 | #define IFI_CANFD_IP_ID 0x58 |
| 141 | #define IFI_CANFD_IP_ID_VALUE 0xD073CAFD | 151 | #define IFI_CANFD_IP_ID_VALUE 0xD073CAFD |
| @@ -220,7 +230,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable) | |||
| 220 | 230 | ||
| 221 | if (enable) { | 231 | if (enable) { |
| 222 | enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY | | 232 | enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY | |
| 223 | IFI_CANFD_IRQMASK_RXFIFO_NEMPTY; | 233 | IFI_CANFD_IRQMASK_RXFIFO_NEMPTY | |
| 234 | IFI_CANFD_IRQMASK_ERROR_STATE_CHG | | ||
| 235 | IFI_CANFD_IRQMASK_ERROR_WARNING | | ||
| 236 | IFI_CANFD_IRQMASK_ERROR_BUSOFF; | ||
| 224 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 237 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
| 225 | enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER; | 238 | enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER; |
| 226 | } | 239 | } |
| @@ -361,12 +374,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev) | |||
| 361 | return 1; | 374 | return 1; |
| 362 | } | 375 | } |
| 363 | 376 | ||
| 364 | static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr) | 377 | static int ifi_canfd_handle_lec_err(struct net_device *ndev) |
| 365 | { | 378 | { |
| 366 | struct ifi_canfd_priv *priv = netdev_priv(ndev); | 379 | struct ifi_canfd_priv *priv = netdev_priv(ndev); |
| 367 | struct net_device_stats *stats = &ndev->stats; | 380 | struct net_device_stats *stats = &ndev->stats; |
| 368 | struct can_frame *cf; | 381 | struct can_frame *cf; |
| 369 | struct sk_buff *skb; | 382 | struct sk_buff *skb; |
| 383 | u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); | ||
| 370 | const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST | | 384 | const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST | |
| 371 | IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST | | 385 | IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST | |
| 372 | IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST | | 386 | IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST | |
| @@ -449,6 +463,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, | |||
| 449 | 463 | ||
| 450 | switch (new_state) { | 464 | switch (new_state) { |
| 451 | case CAN_STATE_ERROR_ACTIVE: | 465 | case CAN_STATE_ERROR_ACTIVE: |
| 466 | /* error active state */ | ||
| 467 | priv->can.can_stats.error_warning++; | ||
| 468 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
| 469 | break; | ||
| 470 | case CAN_STATE_ERROR_WARNING: | ||
| 452 | /* error warning state */ | 471 | /* error warning state */ |
| 453 | priv->can.can_stats.error_warning++; | 472 | priv->can.can_stats.error_warning++; |
| 454 | priv->can.state = CAN_STATE_ERROR_WARNING; | 473 | priv->can.state = CAN_STATE_ERROR_WARNING; |
| @@ -477,7 +496,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, | |||
| 477 | ifi_canfd_get_berr_counter(ndev, &bec); | 496 | ifi_canfd_get_berr_counter(ndev, &bec); |
| 478 | 497 | ||
| 479 | switch (new_state) { | 498 | switch (new_state) { |
| 480 | case CAN_STATE_ERROR_ACTIVE: | 499 | case CAN_STATE_ERROR_WARNING: |
| 481 | /* error warning state */ | 500 | /* error warning state */ |
| 482 | cf->can_id |= CAN_ERR_CRTL; | 501 | cf->can_id |= CAN_ERR_CRTL; |
| 483 | cf->data[1] = (bec.txerr > bec.rxerr) ? | 502 | cf->data[1] = (bec.txerr > bec.rxerr) ? |
| @@ -510,22 +529,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, | |||
| 510 | return 1; | 529 | return 1; |
| 511 | } | 530 | } |
| 512 | 531 | ||
| 513 | static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd) | 532 | static int ifi_canfd_handle_state_errors(struct net_device *ndev) |
| 514 | { | 533 | { |
| 515 | struct ifi_canfd_priv *priv = netdev_priv(ndev); | 534 | struct ifi_canfd_priv *priv = netdev_priv(ndev); |
| 535 | u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); | ||
| 516 | int work_done = 0; | 536 | int work_done = 0; |
| 517 | u32 isr; | ||
| 518 | 537 | ||
| 519 | /* | 538 | if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) && |
| 520 | * The ErrWarn condition is a little special, since the bit is | 539 | (priv->can.state != CAN_STATE_ERROR_ACTIVE)) { |
| 521 | * located in the INTERRUPT register instead of STCMD register. | 540 | netdev_dbg(ndev, "Error, entered active state\n"); |
| 522 | */ | 541 | work_done += ifi_canfd_handle_state_change(ndev, |
| 523 | isr = readl(priv->base + IFI_CANFD_INTERRUPT); | 542 | CAN_STATE_ERROR_ACTIVE); |
| 524 | if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING) && | 543 | } |
| 544 | |||
| 545 | if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING) && | ||
| 525 | (priv->can.state != CAN_STATE_ERROR_WARNING)) { | 546 | (priv->can.state != CAN_STATE_ERROR_WARNING)) { |
| 526 | /* Clear the interrupt */ | ||
| 527 | writel(IFI_CANFD_INTERRUPT_ERROR_WARNING, | ||
| 528 | priv->base + IFI_CANFD_INTERRUPT); | ||
| 529 | netdev_dbg(ndev, "Error, entered warning state\n"); | 547 | netdev_dbg(ndev, "Error, entered warning state\n"); |
| 530 | work_done += ifi_canfd_handle_state_change(ndev, | 548 | work_done += ifi_canfd_handle_state_change(ndev, |
| 531 | CAN_STATE_ERROR_WARNING); | 549 | CAN_STATE_ERROR_WARNING); |
| @@ -552,18 +570,11 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota) | |||
| 552 | { | 570 | { |
| 553 | struct net_device *ndev = napi->dev; | 571 | struct net_device *ndev = napi->dev; |
| 554 | struct ifi_canfd_priv *priv = netdev_priv(ndev); | 572 | struct ifi_canfd_priv *priv = netdev_priv(ndev); |
| 555 | const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE | | ||
| 556 | IFI_CANFD_STCMD_BUSOFF; | ||
| 557 | int work_done = 0; | ||
| 558 | |||
| 559 | u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); | ||
| 560 | u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); | 573 | u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); |
| 561 | u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); | 574 | int work_done = 0; |
| 562 | 575 | ||
| 563 | /* Handle bus state changes */ | 576 | /* Handle bus state changes */ |
| 564 | if ((stcmd & stcmd_state_mask) || | 577 | work_done += ifi_canfd_handle_state_errors(ndev); |
| 565 | ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) == 0)) | ||
| 566 | work_done += ifi_canfd_handle_state_errors(ndev, stcmd); | ||
| 567 | 578 | ||
| 568 | /* Handle lost messages on RX */ | 579 | /* Handle lost messages on RX */ |
| 569 | if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW) | 580 | if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW) |
| @@ -571,7 +582,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota) | |||
| 571 | 582 | ||
| 572 | /* Handle lec errors on the bus */ | 583 | /* Handle lec errors on the bus */ |
| 573 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 584 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
| 574 | work_done += ifi_canfd_handle_lec_err(ndev, errctr); | 585 | work_done += ifi_canfd_handle_lec_err(ndev); |
| 575 | 586 | ||
| 576 | /* Handle normal messages on RX */ | 587 | /* Handle normal messages on RX */ |
| 577 | if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY)) | 588 | if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY)) |
| @@ -592,12 +603,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id) | |||
| 592 | struct net_device_stats *stats = &ndev->stats; | 603 | struct net_device_stats *stats = &ndev->stats; |
| 593 | const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY | | 604 | const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY | |
| 594 | IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER | | 605 | IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER | |
| 606 | IFI_CANFD_INTERRUPT_ERROR_COUNTER | | ||
| 607 | IFI_CANFD_INTERRUPT_ERROR_STATE_CHG | | ||
| 595 | IFI_CANFD_INTERRUPT_ERROR_WARNING | | 608 | IFI_CANFD_INTERRUPT_ERROR_WARNING | |
| 596 | IFI_CANFD_INTERRUPT_ERROR_COUNTER; | 609 | IFI_CANFD_INTERRUPT_ERROR_BUSOFF; |
| 597 | const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY | | 610 | const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY | |
| 598 | IFI_CANFD_INTERRUPT_TXFIFO_REMOVE; | 611 | IFI_CANFD_INTERRUPT_TXFIFO_REMOVE; |
| 599 | const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ | | 612 | const u32 clr_irq_mask = ~((u32)IFI_CANFD_INTERRUPT_SET_IRQ); |
| 600 | IFI_CANFD_INTERRUPT_ERROR_WARNING)); | ||
| 601 | u32 isr; | 613 | u32 isr; |
| 602 | 614 | ||
| 603 | isr = readl(priv->base + IFI_CANFD_INTERRUPT); | 615 | isr = readl(priv->base + IFI_CANFD_INTERRUPT); |
| @@ -933,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) | |||
| 933 | struct resource *res; | 945 | struct resource *res; |
| 934 | void __iomem *addr; | 946 | void __iomem *addr; |
| 935 | int irq, ret; | 947 | int irq, ret; |
| 936 | u32 id; | 948 | u32 id, rev; |
| 937 | 949 | ||
| 938 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 950 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 939 | addr = devm_ioremap_resource(dev, res); | 951 | addr = devm_ioremap_resource(dev, res); |
| @@ -947,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev) | |||
| 947 | return -EINVAL; | 959 | return -EINVAL; |
| 948 | } | 960 | } |
| 949 | 961 | ||
| 962 | rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK; | ||
| 963 | if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) { | ||
| 964 | dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n", | ||
| 965 | rev, IFI_CANFD_VER_REV_MIN_SUPPORTED); | ||
| 966 | return -EINVAL; | ||
| 967 | } | ||
| 968 | |||
| 950 | ndev = alloc_candev(sizeof(*priv), 1); | 969 | ndev = alloc_candev(sizeof(*priv), 1); |
| 951 | if (!ndev) | 970 | if (!ndev) |
| 952 | return -ENOMEM; | 971 | return -ENOMEM; |
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 2594f7779c6f..b397a33f3d32 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/iopoll.h> | 27 | #include <linux/iopoll.h> |
| 28 | #include <linux/can/dev.h> | 28 | #include <linux/can/dev.h> |
| 29 | #include <linux/pinctrl/consumer.h> | ||
| 29 | 30 | ||
| 30 | /* napi related */ | 31 | /* napi related */ |
| 31 | #define M_CAN_NAPI_WEIGHT 64 | 32 | #define M_CAN_NAPI_WEIGHT 64 |
| @@ -253,7 +254,7 @@ enum m_can_mram_cfg { | |||
| 253 | 254 | ||
| 254 | /* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ | 255 | /* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ |
| 255 | #define RXFC_FWM_SHIFT 24 | 256 | #define RXFC_FWM_SHIFT 24 |
| 256 | #define RXFC_FWM_MASK (0x7f < RXFC_FWM_SHIFT) | 257 | #define RXFC_FWM_MASK (0x7f << RXFC_FWM_SHIFT) |
| 257 | #define RXFC_FS_SHIFT 16 | 258 | #define RXFC_FS_SHIFT 16 |
| 258 | #define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT) | 259 | #define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT) |
| 259 | 260 | ||
| @@ -1700,6 +1701,8 @@ static __maybe_unused int m_can_suspend(struct device *dev) | |||
| 1700 | m_can_clk_stop(priv); | 1701 | m_can_clk_stop(priv); |
| 1701 | } | 1702 | } |
| 1702 | 1703 | ||
| 1704 | pinctrl_pm_select_sleep_state(dev); | ||
| 1705 | |||
| 1703 | priv->can.state = CAN_STATE_SLEEPING; | 1706 | priv->can.state = CAN_STATE_SLEEPING; |
| 1704 | 1707 | ||
| 1705 | return 0; | 1708 | return 0; |
| @@ -1710,6 +1713,8 @@ static __maybe_unused int m_can_resume(struct device *dev) | |||
| 1710 | struct net_device *ndev = dev_get_drvdata(dev); | 1713 | struct net_device *ndev = dev_get_drvdata(dev); |
| 1711 | struct m_can_priv *priv = netdev_priv(ndev); | 1714 | struct m_can_priv *priv = netdev_priv(ndev); |
| 1712 | 1715 | ||
| 1716 | pinctrl_pm_select_default_state(dev); | ||
| 1717 | |||
| 1713 | m_can_init_ram(priv); | 1718 | m_can_init_ram(priv); |
| 1714 | 1719 | ||
| 1715 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1720 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c index 55513411a82e..ed8561d4a90f 100644 --- a/drivers/net/can/peak_canfd/peak_canfd.c +++ b/drivers/net/can/peak_canfd/peak_canfd.c | |||
| @@ -262,7 +262,6 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, | |||
| 262 | 262 | ||
| 263 | spin_lock_irqsave(&priv->echo_lock, flags); | 263 | spin_lock_irqsave(&priv->echo_lock, flags); |
| 264 | can_get_echo_skb(priv->ndev, msg->client); | 264 | can_get_echo_skb(priv->ndev, msg->client); |
| 265 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 266 | 265 | ||
| 267 | /* count bytes of the echo instead of skb */ | 266 | /* count bytes of the echo instead of skb */ |
| 268 | stats->tx_bytes += cf_len; | 267 | stats->tx_bytes += cf_len; |
| @@ -271,6 +270,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, | |||
| 271 | /* restart tx queue (a slot is free) */ | 270 | /* restart tx queue (a slot is free) */ |
| 272 | netif_wake_queue(priv->ndev); | 271 | netif_wake_queue(priv->ndev); |
| 273 | 272 | ||
| 273 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| 276 | 276 | ||
| @@ -333,7 +333,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, | |||
| 333 | 333 | ||
| 334 | /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */ | 334 | /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */ |
| 335 | if (pucan_status_is_rx_barrier(msg)) { | 335 | if (pucan_status_is_rx_barrier(msg)) { |
| 336 | unsigned long flags; | ||
| 337 | 336 | ||
| 338 | if (priv->enable_tx_path) { | 337 | if (priv->enable_tx_path) { |
| 339 | int err = priv->enable_tx_path(priv); | 338 | int err = priv->enable_tx_path(priv); |
| @@ -342,16 +341,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, | |||
| 342 | return err; | 341 | return err; |
| 343 | } | 342 | } |
| 344 | 343 | ||
| 345 | /* restart network queue only if echo skb array is free */ | 344 | /* start network queue (echo_skb array is empty) */ |
| 346 | spin_lock_irqsave(&priv->echo_lock, flags); | 345 | netif_start_queue(ndev); |
| 347 | |||
| 348 | if (!priv->can.echo_skb[priv->echo_idx]) { | ||
| 349 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 350 | |||
| 351 | netif_wake_queue(ndev); | ||
| 352 | } else { | ||
| 353 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 354 | } | ||
| 355 | 346 | ||
| 356 | return 0; | 347 | return 0; |
| 357 | } | 348 | } |
| @@ -726,11 +717,6 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb, | |||
| 726 | */ | 717 | */ |
| 727 | should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]); | 718 | should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]); |
| 728 | 719 | ||
| 729 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 730 | |||
| 731 | /* write the skb on the interface */ | ||
| 732 | priv->write_tx_msg(priv, msg); | ||
| 733 | |||
| 734 | /* stop network tx queue if not enough room to save one more msg too */ | 720 | /* stop network tx queue if not enough room to save one more msg too */ |
| 735 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | 721 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
| 736 | should_stop_tx_queue |= (room_left < | 722 | should_stop_tx_queue |= (room_left < |
| @@ -742,6 +728,11 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb, | |||
| 742 | if (should_stop_tx_queue) | 728 | if (should_stop_tx_queue) |
| 743 | netif_stop_queue(ndev); | 729 | netif_stop_queue(ndev); |
| 744 | 730 | ||
| 731 | spin_unlock_irqrestore(&priv->echo_lock, flags); | ||
| 732 | |||
| 733 | /* write the skb on the interface */ | ||
| 734 | priv->write_tx_msg(priv, msg); | ||
| 735 | |||
| 745 | return NETDEV_TX_OK; | 736 | return NETDEV_TX_OK; |
| 746 | } | 737 | } |
| 747 | 738 | ||
diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c index 788c3464a3b0..3c51a884db87 100644 --- a/drivers/net/can/peak_canfd/peak_pciefd_main.c +++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c | |||
| @@ -349,8 +349,12 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg) | |||
| 349 | priv->tx_pages_free++; | 349 | priv->tx_pages_free++; |
| 350 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 350 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
| 351 | 351 | ||
| 352 | /* wake producer up */ | 352 | /* wake producer up (only if enough room in echo_skb array) */ |
| 353 | netif_wake_queue(priv->ucan.ndev); | 353 | spin_lock_irqsave(&priv->ucan.echo_lock, flags); |
| 354 | if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx]) | ||
| 355 | netif_wake_queue(priv->ucan.ndev); | ||
| 356 | |||
| 357 | spin_unlock_irqrestore(&priv->ucan.echo_lock, flags); | ||
| 354 | } | 358 | } |
| 355 | 359 | ||
| 356 | /* re-enable Rx DMA transfer for this CAN */ | 360 | /* re-enable Rx DMA transfer for this CAN */ |
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index d040aeb45172..15c2a831edf1 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm-sf2.o | 2 | obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm-sf2.o |
| 3 | bcm-sf2-objs := bcm_sf2.o bcm_sf2_cfp.o | 3 | bcm-sf2-objs := bcm_sf2.o bcm_sf2_cfp.o |
| 4 | obj-$(CONFIG_NET_DSA_LOOP) += dsa_loop.o dsa_loop_bdinfo.o | 4 | obj-$(CONFIG_NET_DSA_LOOP) += dsa_loop.o |
| 5 | ifdef CONFIG_NET_DSA_LOOP | ||
| 6 | obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o | ||
| 7 | endif | ||
| 5 | obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o | 8 | obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o |
| 6 | obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o | 9 | obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o |
| 7 | obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o | 10 | obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o |
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index db830a1141d9..63e02a54d537 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c | |||
| @@ -814,8 +814,8 @@ void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data) | |||
| 814 | unsigned int i; | 814 | unsigned int i; |
| 815 | 815 | ||
| 816 | for (i = 0; i < mib_size; i++) | 816 | for (i = 0; i < mib_size; i++) |
| 817 | memcpy(data + i * ETH_GSTRING_LEN, | 817 | strlcpy(data + i * ETH_GSTRING_LEN, |
| 818 | mibs[i].name, ETH_GSTRING_LEN); | 818 | mibs[i].name, ETH_GSTRING_LEN); |
| 819 | } | 819 | } |
| 820 | EXPORT_SYMBOL(b53_get_strings); | 820 | EXPORT_SYMBOL(b53_get_strings); |
| 821 | 821 | ||
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index 29c3075bfb05..fdc673484add 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | config NET_VENDOR_8390 | 5 | config NET_VENDOR_8390 |
| 6 | bool "National Semi-conductor 8390 devices" | 6 | bool "National Semiconductor 8390 devices" |
| 7 | default y | 7 | default y |
| 8 | depends on NET_VENDOR_NATSEMI | 8 | depends on NET_VENDOR_NATSEMI |
| 9 | ---help--- | 9 | ---help--- |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h index 0b49f1aeebd3..fc7383106946 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h | |||
| @@ -36,6 +36,8 @@ | |||
| 36 | #define AQ_CFG_TX_FRAME_MAX (16U * 1024U) | 36 | #define AQ_CFG_TX_FRAME_MAX (16U * 1024U) |
| 37 | #define AQ_CFG_RX_FRAME_MAX (4U * 1024U) | 37 | #define AQ_CFG_RX_FRAME_MAX (4U * 1024U) |
| 38 | 38 | ||
| 39 | #define AQ_CFG_TX_CLEAN_BUDGET 256U | ||
| 40 | |||
| 39 | /* LRO */ | 41 | /* LRO */ |
| 40 | #define AQ_CFG_IS_LRO_DEF 1U | 42 | #define AQ_CFG_IS_LRO_DEF 1U |
| 41 | 43 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index ebbaf63eaf47..c96a92118b8b 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
| @@ -247,6 +247,8 @@ void aq_nic_ndev_init(struct aq_nic_s *self) | |||
| 247 | self->ndev->hw_features |= aq_hw_caps->hw_features; | 247 | self->ndev->hw_features |= aq_hw_caps->hw_features; |
| 248 | self->ndev->features = aq_hw_caps->hw_features; | 248 | self->ndev->features = aq_hw_caps->hw_features; |
| 249 | self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; | 249 | self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; |
| 250 | self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | ||
| 251 | |||
| 250 | self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN; | 252 | self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN; |
| 251 | self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN; | 253 | self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN; |
| 252 | 254 | ||
| @@ -937,3 +939,23 @@ err_exit: | |||
| 937 | out: | 939 | out: |
| 938 | return err; | 940 | return err; |
| 939 | } | 941 | } |
| 942 | |||
| 943 | void aq_nic_shutdown(struct aq_nic_s *self) | ||
| 944 | { | ||
| 945 | int err = 0; | ||
| 946 | |||
| 947 | if (!self->ndev) | ||
| 948 | return; | ||
| 949 | |||
| 950 | rtnl_lock(); | ||
| 951 | |||
| 952 | netif_device_detach(self->ndev); | ||
| 953 | |||
| 954 | err = aq_nic_stop(self); | ||
| 955 | if (err < 0) | ||
| 956 | goto err_exit; | ||
| 957 | aq_nic_deinit(self); | ||
| 958 | |||
| 959 | err_exit: | ||
| 960 | rtnl_unlock(); | ||
| 961 | } \ No newline at end of file | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h index d16b0f1a95aa..219b550d1665 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h | |||
| @@ -118,5 +118,6 @@ struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self); | |||
| 118 | u32 aq_nic_get_fw_version(struct aq_nic_s *self); | 118 | u32 aq_nic_get_fw_version(struct aq_nic_s *self); |
| 119 | int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg); | 119 | int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg); |
| 120 | int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self); | 120 | int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self); |
| 121 | void aq_nic_shutdown(struct aq_nic_s *self); | ||
| 121 | 122 | ||
| 122 | #endif /* AQ_NIC_H */ | 123 | #endif /* AQ_NIC_H */ |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index 87c4308b52a7..ecc6306f940f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | |||
| @@ -323,6 +323,20 @@ static void aq_pci_remove(struct pci_dev *pdev) | |||
| 323 | pci_disable_device(pdev); | 323 | pci_disable_device(pdev); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | static void aq_pci_shutdown(struct pci_dev *pdev) | ||
| 327 | { | ||
| 328 | struct aq_nic_s *self = pci_get_drvdata(pdev); | ||
| 329 | |||
| 330 | aq_nic_shutdown(self); | ||
| 331 | |||
| 332 | pci_disable_device(pdev); | ||
| 333 | |||
| 334 | if (system_state == SYSTEM_POWER_OFF) { | ||
| 335 | pci_wake_from_d3(pdev, false); | ||
| 336 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 326 | static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg) | 340 | static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg) |
| 327 | { | 341 | { |
| 328 | struct aq_nic_s *self = pci_get_drvdata(pdev); | 342 | struct aq_nic_s *self = pci_get_drvdata(pdev); |
| @@ -345,6 +359,7 @@ static struct pci_driver aq_pci_ops = { | |||
| 345 | .remove = aq_pci_remove, | 359 | .remove = aq_pci_remove, |
| 346 | .suspend = aq_pci_suspend, | 360 | .suspend = aq_pci_suspend, |
| 347 | .resume = aq_pci_resume, | 361 | .resume = aq_pci_resume, |
| 362 | .shutdown = aq_pci_shutdown, | ||
| 348 | }; | 363 | }; |
| 349 | 364 | ||
| 350 | module_pci_driver(aq_pci_ops); | 365 | module_pci_driver(aq_pci_ops); |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 0be6a11370bb..b5f1f62e8e25 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c | |||
| @@ -136,11 +136,12 @@ void aq_ring_queue_stop(struct aq_ring_s *ring) | |||
| 136 | netif_stop_subqueue(ndev, ring->idx); | 136 | netif_stop_subqueue(ndev, ring->idx); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | void aq_ring_tx_clean(struct aq_ring_s *self) | 139 | bool aq_ring_tx_clean(struct aq_ring_s *self) |
| 140 | { | 140 | { |
| 141 | struct device *dev = aq_nic_get_dev(self->aq_nic); | 141 | struct device *dev = aq_nic_get_dev(self->aq_nic); |
| 142 | unsigned int budget = AQ_CFG_TX_CLEAN_BUDGET; | ||
| 142 | 143 | ||
| 143 | for (; self->sw_head != self->hw_head; | 144 | for (; self->sw_head != self->hw_head && budget--; |
| 144 | self->sw_head = aq_ring_next_dx(self, self->sw_head)) { | 145 | self->sw_head = aq_ring_next_dx(self, self->sw_head)) { |
| 145 | struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; | 146 | struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; |
| 146 | 147 | ||
| @@ -167,6 +168,8 @@ void aq_ring_tx_clean(struct aq_ring_s *self) | |||
| 167 | buff->pa = 0U; | 168 | buff->pa = 0U; |
| 168 | buff->eop_index = 0xffffU; | 169 | buff->eop_index = 0xffffU; |
| 169 | } | 170 | } |
| 171 | |||
| 172 | return !!budget; | ||
| 170 | } | 173 | } |
| 171 | 174 | ||
| 172 | #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) | 175 | #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h index 965fae0fb6e0..ac1329f4051d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h | |||
| @@ -153,7 +153,7 @@ void aq_ring_free(struct aq_ring_s *self); | |||
| 153 | void aq_ring_update_queue_state(struct aq_ring_s *ring); | 153 | void aq_ring_update_queue_state(struct aq_ring_s *ring); |
| 154 | void aq_ring_queue_wake(struct aq_ring_s *ring); | 154 | void aq_ring_queue_wake(struct aq_ring_s *ring); |
| 155 | void aq_ring_queue_stop(struct aq_ring_s *ring); | 155 | void aq_ring_queue_stop(struct aq_ring_s *ring); |
| 156 | void aq_ring_tx_clean(struct aq_ring_s *self); | 156 | bool aq_ring_tx_clean(struct aq_ring_s *self); |
| 157 | int aq_ring_rx_clean(struct aq_ring_s *self, | 157 | int aq_ring_rx_clean(struct aq_ring_s *self, |
| 158 | struct napi_struct *napi, | 158 | struct napi_struct *napi, |
| 159 | int *work_done, | 159 | int *work_done, |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c index f890b8a5a862..d335c334fa56 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c | |||
| @@ -35,12 +35,12 @@ struct aq_vec_s { | |||
| 35 | static int aq_vec_poll(struct napi_struct *napi, int budget) | 35 | static int aq_vec_poll(struct napi_struct *napi, int budget) |
| 36 | { | 36 | { |
| 37 | struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi); | 37 | struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi); |
| 38 | unsigned int sw_tail_old = 0U; | ||
| 38 | struct aq_ring_s *ring = NULL; | 39 | struct aq_ring_s *ring = NULL; |
| 40 | bool was_tx_cleaned = true; | ||
| 41 | unsigned int i = 0U; | ||
| 39 | int work_done = 0; | 42 | int work_done = 0; |
| 40 | int err = 0; | 43 | int err = 0; |
| 41 | unsigned int i = 0U; | ||
| 42 | unsigned int sw_tail_old = 0U; | ||
| 43 | bool was_tx_cleaned = false; | ||
| 44 | 44 | ||
| 45 | if (!self) { | 45 | if (!self) { |
| 46 | err = -EINVAL; | 46 | err = -EINVAL; |
| @@ -57,9 +57,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) | |||
| 57 | 57 | ||
| 58 | if (ring[AQ_VEC_TX_ID].sw_head != | 58 | if (ring[AQ_VEC_TX_ID].sw_head != |
| 59 | ring[AQ_VEC_TX_ID].hw_head) { | 59 | ring[AQ_VEC_TX_ID].hw_head) { |
| 60 | aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); | 60 | was_tx_cleaned = aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); |
| 61 | aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); | 61 | aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]); |
| 62 | was_tx_cleaned = true; | ||
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw, | 64 | err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw, |
| @@ -90,7 +89,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget) | |||
| 90 | } | 89 | } |
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | if (was_tx_cleaned) | 92 | if (!was_tx_cleaned) |
| 94 | work_done = budget; | 93 | work_done = budget; |
| 95 | 94 | ||
| 96 | if (work_done < budget) { | 95 | if (work_done < budget) { |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c index 967f0fd07fcf..d3b847ec7465 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c | |||
| @@ -21,6 +21,10 @@ | |||
| 21 | 21 | ||
| 22 | #define HW_ATL_UCP_0X370_REG 0x0370U | 22 | #define HW_ATL_UCP_0X370_REG 0x0370U |
| 23 | 23 | ||
| 24 | #define HW_ATL_MIF_CMD 0x0200U | ||
| 25 | #define HW_ATL_MIF_ADDR 0x0208U | ||
| 26 | #define HW_ATL_MIF_VAL 0x020CU | ||
| 27 | |||
| 24 | #define HW_ATL_FW_SM_RAM 0x2U | 28 | #define HW_ATL_FW_SM_RAM 0x2U |
| 25 | #define HW_ATL_MPI_FW_VERSION 0x18 | 29 | #define HW_ATL_MPI_FW_VERSION 0x18 |
| 26 | #define HW_ATL_MPI_CONTROL_ADR 0x0368U | 30 | #define HW_ATL_MPI_CONTROL_ADR 0x0368U |
| @@ -79,16 +83,15 @@ int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) | |||
| 79 | 83 | ||
| 80 | static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) | 84 | static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) |
| 81 | { | 85 | { |
| 86 | u32 gsr, val; | ||
| 82 | int k = 0; | 87 | int k = 0; |
| 83 | u32 gsr; | ||
| 84 | 88 | ||
| 85 | aq_hw_write_reg(self, 0x404, 0x40e1); | 89 | aq_hw_write_reg(self, 0x404, 0x40e1); |
| 86 | AQ_HW_SLEEP(50); | 90 | AQ_HW_SLEEP(50); |
| 87 | 91 | ||
| 88 | /* Cleanup SPI */ | 92 | /* Cleanup SPI */ |
| 89 | aq_hw_write_reg(self, 0x534, 0xA0); | 93 | val = aq_hw_read_reg(self, 0x53C); |
| 90 | aq_hw_write_reg(self, 0x100, 0x9F); | 94 | aq_hw_write_reg(self, 0x53C, val | 0x10); |
| 91 | aq_hw_write_reg(self, 0x100, 0x809F); | ||
| 92 | 95 | ||
| 93 | gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); | 96 | gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); |
| 94 | aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); | 97 | aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); |
| @@ -97,7 +100,14 @@ static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) | |||
| 97 | aq_hw_write_reg(self, 0x404, 0x80e0); | 100 | aq_hw_write_reg(self, 0x404, 0x80e0); |
| 98 | aq_hw_write_reg(self, 0x32a8, 0x0); | 101 | aq_hw_write_reg(self, 0x32a8, 0x0); |
| 99 | aq_hw_write_reg(self, 0x520, 0x1); | 102 | aq_hw_write_reg(self, 0x520, 0x1); |
| 103 | |||
| 104 | /* Reset SPI again because of possible interrupted SPI burst */ | ||
| 105 | val = aq_hw_read_reg(self, 0x53C); | ||
| 106 | aq_hw_write_reg(self, 0x53C, val | 0x10); | ||
| 100 | AQ_HW_SLEEP(10); | 107 | AQ_HW_SLEEP(10); |
| 108 | /* Clear SPI reset state */ | ||
| 109 | aq_hw_write_reg(self, 0x53C, val & ~0x10); | ||
| 110 | |||
| 101 | aq_hw_write_reg(self, 0x404, 0x180e0); | 111 | aq_hw_write_reg(self, 0x404, 0x180e0); |
| 102 | 112 | ||
| 103 | for (k = 0; k < 1000; k++) { | 113 | for (k = 0; k < 1000; k++) { |
| @@ -141,13 +151,15 @@ static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self) | |||
| 141 | aq_pr_err("FW kickstart failed\n"); | 151 | aq_pr_err("FW kickstart failed\n"); |
| 142 | return -EIO; | 152 | return -EIO; |
| 143 | } | 153 | } |
| 154 | /* Old FW requires fixed delay after init */ | ||
| 155 | AQ_HW_SLEEP(15); | ||
| 144 | 156 | ||
| 145 | return 0; | 157 | return 0; |
| 146 | } | 158 | } |
| 147 | 159 | ||
| 148 | static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) | 160 | static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) |
| 149 | { | 161 | { |
| 150 | u32 gsr, rbl_status; | 162 | u32 gsr, val, rbl_status; |
| 151 | int k; | 163 | int k; |
| 152 | 164 | ||
| 153 | aq_hw_write_reg(self, 0x404, 0x40e1); | 165 | aq_hw_write_reg(self, 0x404, 0x40e1); |
| @@ -157,6 +169,10 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) | |||
| 157 | /* Alter RBL status */ | 169 | /* Alter RBL status */ |
| 158 | aq_hw_write_reg(self, 0x388, 0xDEAD); | 170 | aq_hw_write_reg(self, 0x388, 0xDEAD); |
| 159 | 171 | ||
| 172 | /* Cleanup SPI */ | ||
| 173 | val = aq_hw_read_reg(self, 0x53C); | ||
| 174 | aq_hw_write_reg(self, 0x53C, val | 0x10); | ||
| 175 | |||
| 160 | /* Global software reset*/ | 176 | /* Global software reset*/ |
| 161 | hw_atl_rx_rx_reg_res_dis_set(self, 0U); | 177 | hw_atl_rx_rx_reg_res_dis_set(self, 0U); |
| 162 | hw_atl_tx_tx_reg_res_dis_set(self, 0U); | 178 | hw_atl_tx_tx_reg_res_dis_set(self, 0U); |
| @@ -204,6 +220,8 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self) | |||
| 204 | aq_pr_err("FW kickstart failed\n"); | 220 | aq_pr_err("FW kickstart failed\n"); |
| 205 | return -EIO; | 221 | return -EIO; |
| 206 | } | 222 | } |
| 223 | /* Old FW requires fixed delay after init */ | ||
| 224 | AQ_HW_SLEEP(15); | ||
| 207 | 225 | ||
| 208 | return 0; | 226 | return 0; |
| 209 | } | 227 | } |
| @@ -255,18 +273,22 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a, | |||
| 255 | } | 273 | } |
| 256 | } | 274 | } |
| 257 | 275 | ||
| 258 | aq_hw_write_reg(self, 0x00000208U, a); | 276 | aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a); |
| 259 | |||
| 260 | for (++cnt; --cnt;) { | ||
| 261 | u32 i = 0U; | ||
| 262 | 277 | ||
| 263 | aq_hw_write_reg(self, 0x00000200U, 0x00008000U); | 278 | for (++cnt; --cnt && !err;) { |
| 279 | aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U); | ||
| 264 | 280 | ||
| 265 | for (i = 1024U; | 281 | if (IS_CHIP_FEATURE(REVISION_B1)) |
| 266 | (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) { | 282 | AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self, |
| 267 | } | 283 | HW_ATL_MIF_ADDR), |
| 284 | 1, 1000U); | ||
| 285 | else | ||
| 286 | AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self, | ||
| 287 | HW_ATL_MIF_CMD)), | ||
| 288 | 1, 1000U); | ||
| 268 | 289 | ||
| 269 | *(p++) = aq_hw_read_reg(self, 0x0000020CU); | 290 | *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL); |
| 291 | a += 4; | ||
| 270 | } | 292 | } |
| 271 | 293 | ||
| 272 | hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); | 294 | hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM); |
| @@ -662,14 +684,18 @@ void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p) | |||
| 662 | u32 val = hw_atl_reg_glb_mif_id_get(self); | 684 | u32 val = hw_atl_reg_glb_mif_id_get(self); |
| 663 | u32 mif_rev = val & 0xFFU; | 685 | u32 mif_rev = val & 0xFFU; |
| 664 | 686 | ||
| 665 | if ((3U & mif_rev) == 1U) { | 687 | if ((0xFU & mif_rev) == 1U) { |
| 666 | chip_features |= | 688 | chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 | |
| 667 | HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 | | ||
| 668 | HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | | 689 | HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | |
| 669 | HAL_ATLANTIC_UTILS_CHIP_MIPS; | 690 | HAL_ATLANTIC_UTILS_CHIP_MIPS; |
| 670 | } else if ((3U & mif_rev) == 2U) { | 691 | } else if ((0xFU & mif_rev) == 2U) { |
| 671 | chip_features |= | 692 | chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 | |
| 672 | HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 | | 693 | HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | |
| 694 | HAL_ATLANTIC_UTILS_CHIP_MIPS | | ||
| 695 | HAL_ATLANTIC_UTILS_CHIP_TPO2 | | ||
| 696 | HAL_ATLANTIC_UTILS_CHIP_RPF2; | ||
| 697 | } else if ((0xFU & mif_rev) == 0xAU) { | ||
| 698 | chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 | | ||
| 673 | HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | | 699 | HAL_ATLANTIC_UTILS_CHIP_MPI_AQ | |
| 674 | HAL_ATLANTIC_UTILS_CHIP_MIPS | | 700 | HAL_ATLANTIC_UTILS_CHIP_MIPS | |
| 675 | HAL_ATLANTIC_UTILS_CHIP_TPO2 | | 701 | HAL_ATLANTIC_UTILS_CHIP_TPO2 | |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h index 2c690947910a..cd8f18f39c61 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h | |||
| @@ -161,6 +161,7 @@ struct __packed hw_aq_atl_utils_mbox { | |||
| 161 | #define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ 0x00000010U | 161 | #define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ 0x00000010U |
| 162 | #define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 0x01000000U | 162 | #define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 0x01000000U |
| 163 | #define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 0x02000000U | 163 | #define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 0x02000000U |
| 164 | #define HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 0x04000000U | ||
| 164 | 165 | ||
| 165 | #define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \ | 166 | #define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \ |
| 166 | self->chip_features) | 167 | self->chip_features) |
diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h b/drivers/net/ethernet/aquantia/atlantic/ver.h index 5265b937677b..a445de6837a6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/ver.h +++ b/drivers/net/ethernet/aquantia/atlantic/ver.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #define NIC_MAJOR_DRIVER_VERSION 2 | 13 | #define NIC_MAJOR_DRIVER_VERSION 2 |
| 14 | #define NIC_MINOR_DRIVER_VERSION 0 | 14 | #define NIC_MINOR_DRIVER_VERSION 0 |
| 15 | #define NIC_BUILD_DRIVER_VERSION 2 | 15 | #define NIC_BUILD_DRIVER_VERSION 2 |
| 16 | #define NIC_REVISION_DRIVER_VERSION 0 | 16 | #define NIC_REVISION_DRIVER_VERSION 1 |
| 17 | 17 | ||
| 18 | #define AQ_CFG_DRV_VERSION_SUFFIX "-kern" | 18 | #define AQ_CFG_DRV_VERSION_SUFFIX "-kern" |
| 19 | 19 | ||
diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index 16f9bee992fe..0f6576802607 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c | |||
| @@ -169,8 +169,10 @@ static int emac_rockchip_probe(struct platform_device *pdev) | |||
| 169 | /* Optional regulator for PHY */ | 169 | /* Optional regulator for PHY */ |
| 170 | priv->regulator = devm_regulator_get_optional(dev, "phy"); | 170 | priv->regulator = devm_regulator_get_optional(dev, "phy"); |
| 171 | if (IS_ERR(priv->regulator)) { | 171 | if (IS_ERR(priv->regulator)) { |
| 172 | if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) | 172 | if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) { |
| 173 | return -EPROBE_DEFER; | 173 | err = -EPROBE_DEFER; |
| 174 | goto out_clk_disable; | ||
| 175 | } | ||
| 174 | dev_err(dev, "no regulator found\n"); | 176 | dev_err(dev, "no regulator found\n"); |
| 175 | priv->regulator = NULL; | 177 | priv->regulator = NULL; |
| 176 | } | 178 | } |
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index f15a8fc6dfc9..3fc549b88c43 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c | |||
| @@ -855,10 +855,12 @@ static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_tx_ring *ring, | |||
| 855 | static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, | 855 | static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, |
| 856 | struct bcm_sysport_tx_ring *ring) | 856 | struct bcm_sysport_tx_ring *ring) |
| 857 | { | 857 | { |
| 858 | unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs; | ||
| 859 | unsigned int pkts_compl = 0, bytes_compl = 0; | 858 | unsigned int pkts_compl = 0, bytes_compl = 0; |
| 860 | struct net_device *ndev = priv->netdev; | 859 | struct net_device *ndev = priv->netdev; |
| 860 | unsigned int txbds_processed = 0; | ||
| 861 | struct bcm_sysport_cb *cb; | 861 | struct bcm_sysport_cb *cb; |
| 862 | unsigned int txbds_ready; | ||
| 863 | unsigned int c_index; | ||
| 862 | u32 hw_ind; | 864 | u32 hw_ind; |
| 863 | 865 | ||
| 864 | /* Clear status before servicing to reduce spurious interrupts */ | 866 | /* Clear status before servicing to reduce spurious interrupts */ |
| @@ -871,29 +873,23 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, | |||
| 871 | /* Compute how many descriptors have been processed since last call */ | 873 | /* Compute how many descriptors have been processed since last call */ |
| 872 | hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index)); | 874 | hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index)); |
| 873 | c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK; | 875 | c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK; |
| 874 | ring->p_index = (hw_ind & RING_PROD_INDEX_MASK); | 876 | txbds_ready = (c_index - ring->c_index) & RING_CONS_INDEX_MASK; |
| 875 | |||
| 876 | last_c_index = ring->c_index; | ||
| 877 | num_tx_cbs = ring->size; | ||
| 878 | |||
| 879 | c_index &= (num_tx_cbs - 1); | ||
| 880 | |||
| 881 | if (c_index >= last_c_index) | ||
| 882 | last_tx_cn = c_index - last_c_index; | ||
| 883 | else | ||
| 884 | last_tx_cn = num_tx_cbs - last_c_index + c_index; | ||
| 885 | 877 | ||
| 886 | netif_dbg(priv, tx_done, ndev, | 878 | netif_dbg(priv, tx_done, ndev, |
| 887 | "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n", | 879 | "ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n", |
| 888 | ring->index, c_index, last_tx_cn, last_c_index); | 880 | ring->index, ring->c_index, c_index, txbds_ready); |
| 889 | 881 | ||
| 890 | while (last_tx_cn-- > 0) { | 882 | while (txbds_processed < txbds_ready) { |
| 891 | cb = ring->cbs + last_c_index; | 883 | cb = &ring->cbs[ring->clean_index]; |
| 892 | bcm_sysport_tx_reclaim_one(ring, cb, &bytes_compl, &pkts_compl); | 884 | bcm_sysport_tx_reclaim_one(ring, cb, &bytes_compl, &pkts_compl); |
| 893 | 885 | ||
| 894 | ring->desc_count++; | 886 | ring->desc_count++; |
| 895 | last_c_index++; | 887 | txbds_processed++; |
| 896 | last_c_index &= (num_tx_cbs - 1); | 888 | |
| 889 | if (likely(ring->clean_index < ring->size - 1)) | ||
| 890 | ring->clean_index++; | ||
| 891 | else | ||
| 892 | ring->clean_index = 0; | ||
| 897 | } | 893 | } |
| 898 | 894 | ||
| 899 | u64_stats_update_begin(&priv->syncp); | 895 | u64_stats_update_begin(&priv->syncp); |
| @@ -1394,6 +1390,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, | |||
| 1394 | netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64); | 1390 | netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64); |
| 1395 | ring->index = index; | 1391 | ring->index = index; |
| 1396 | ring->size = size; | 1392 | ring->size = size; |
| 1393 | ring->clean_index = 0; | ||
| 1397 | ring->alloc_size = ring->size; | 1394 | ring->alloc_size = ring->size; |
| 1398 | ring->desc_cpu = p; | 1395 | ring->desc_cpu = p; |
| 1399 | ring->desc_count = ring->size; | 1396 | ring->desc_count = ring->size; |
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index f5a984c1c986..19c91c76e327 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h | |||
| @@ -706,7 +706,7 @@ struct bcm_sysport_tx_ring { | |||
| 706 | unsigned int desc_count; /* Number of descriptors */ | 706 | unsigned int desc_count; /* Number of descriptors */ |
| 707 | unsigned int curr_desc; /* Current descriptor */ | 707 | unsigned int curr_desc; /* Current descriptor */ |
| 708 | unsigned int c_index; /* Last consumer index */ | 708 | unsigned int c_index; /* Last consumer index */ |
| 709 | unsigned int p_index; /* Current producer index */ | 709 | unsigned int clean_index; /* Current clean index */ |
| 710 | struct bcm_sysport_cb *cbs; /* Transmit control blocks */ | 710 | struct bcm_sysport_cb *cbs; /* Transmit control blocks */ |
| 711 | struct dma_desc *desc_cpu; /* CPU view of the descriptor */ | 711 | struct dma_desc *desc_cpu; /* CPU view of the descriptor */ |
| 712 | struct bcm_sysport_priv *priv; /* private context backpointer */ | 712 | struct bcm_sysport_priv *priv; /* private context backpointer */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 74fc9af4aadb..b8388e93520a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -13913,7 +13913,7 @@ static void bnx2x_register_phc(struct bnx2x *bp) | |||
| 13913 | bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev); | 13913 | bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev); |
| 13914 | if (IS_ERR(bp->ptp_clock)) { | 13914 | if (IS_ERR(bp->ptp_clock)) { |
| 13915 | bp->ptp_clock = NULL; | 13915 | bp->ptp_clock = NULL; |
| 13916 | BNX2X_ERR("PTP clock registeration failed\n"); | 13916 | BNX2X_ERR("PTP clock registration failed\n"); |
| 13917 | } | 13917 | } |
| 13918 | } | 13918 | } |
| 13919 | 13919 | ||
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1500243b9886..c7e5e6f09647 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -1439,7 +1439,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp, | |||
| 1439 | (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { | 1439 | (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { |
| 1440 | u16 vlan_proto = tpa_info->metadata >> | 1440 | u16 vlan_proto = tpa_info->metadata >> |
| 1441 | RX_CMP_FLAGS2_METADATA_TPID_SFT; | 1441 | RX_CMP_FLAGS2_METADATA_TPID_SFT; |
| 1442 | u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_VID_MASK; | 1442 | u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK; |
| 1443 | 1443 | ||
| 1444 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); | 1444 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); |
| 1445 | } | 1445 | } |
| @@ -1623,7 +1623,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, | |||
| 1623 | cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) && | 1623 | cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) && |
| 1624 | (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { | 1624 | (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { |
| 1625 | u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); | 1625 | u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); |
| 1626 | u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_VID_MASK; | 1626 | u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK; |
| 1627 | u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT; | 1627 | u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT; |
| 1628 | 1628 | ||
| 1629 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); | 1629 | __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); |
| @@ -3847,6 +3847,9 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) | |||
| 3847 | struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; | 3847 | struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; |
| 3848 | struct hwrm_vnic_tpa_cfg_input req = {0}; | 3848 | struct hwrm_vnic_tpa_cfg_input req = {0}; |
| 3849 | 3849 | ||
| 3850 | if (vnic->fw_vnic_id == INVALID_HW_RING_ID) | ||
| 3851 | return 0; | ||
| 3852 | |||
| 3850 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_TPA_CFG, -1, -1); | 3853 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_TPA_CFG, -1, -1); |
| 3851 | 3854 | ||
| 3852 | if (tpa_flags) { | 3855 | if (tpa_flags) { |
| @@ -4558,18 +4561,17 @@ int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings) | |||
| 4558 | return rc; | 4561 | return rc; |
| 4559 | } | 4562 | } |
| 4560 | 4563 | ||
| 4561 | static int | 4564 | static void |
| 4562 | bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | 4565 | __bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, struct hwrm_func_cfg_input *req, |
| 4563 | int ring_grps, int cp_rings, int vnics) | 4566 | int tx_rings, int rx_rings, int ring_grps, |
| 4567 | int cp_rings, int vnics) | ||
| 4564 | { | 4568 | { |
| 4565 | struct hwrm_func_cfg_input req = {0}; | ||
| 4566 | u32 enables = 0; | 4569 | u32 enables = 0; |
| 4567 | int rc; | ||
| 4568 | 4570 | ||
| 4569 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); | 4571 | bnxt_hwrm_cmd_hdr_init(bp, req, HWRM_FUNC_CFG, -1, -1); |
| 4570 | req.fid = cpu_to_le16(0xffff); | 4572 | req->fid = cpu_to_le16(0xffff); |
| 4571 | enables |= tx_rings ? FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; | 4573 | enables |= tx_rings ? FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; |
| 4572 | req.num_tx_rings = cpu_to_le16(tx_rings); | 4574 | req->num_tx_rings = cpu_to_le16(tx_rings); |
| 4573 | if (bp->flags & BNXT_FLAG_NEW_RM) { | 4575 | if (bp->flags & BNXT_FLAG_NEW_RM) { |
| 4574 | enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; | 4576 | enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; |
| 4575 | enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | 4577 | enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | |
| @@ -4578,16 +4580,53 @@ bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | |||
| 4578 | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; | 4580 | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; |
| 4579 | enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0; | 4581 | enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0; |
| 4580 | 4582 | ||
| 4581 | req.num_rx_rings = cpu_to_le16(rx_rings); | 4583 | req->num_rx_rings = cpu_to_le16(rx_rings); |
| 4582 | req.num_hw_ring_grps = cpu_to_le16(ring_grps); | 4584 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); |
| 4583 | req.num_cmpl_rings = cpu_to_le16(cp_rings); | 4585 | req->num_cmpl_rings = cpu_to_le16(cp_rings); |
| 4584 | req.num_stat_ctxs = req.num_cmpl_rings; | 4586 | req->num_stat_ctxs = req->num_cmpl_rings; |
| 4585 | req.num_vnics = cpu_to_le16(vnics); | 4587 | req->num_vnics = cpu_to_le16(vnics); |
| 4586 | } | 4588 | } |
| 4587 | if (!enables) | 4589 | req->enables = cpu_to_le32(enables); |
| 4590 | } | ||
| 4591 | |||
| 4592 | static void | ||
| 4593 | __bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, | ||
| 4594 | struct hwrm_func_vf_cfg_input *req, int tx_rings, | ||
| 4595 | int rx_rings, int ring_grps, int cp_rings, | ||
| 4596 | int vnics) | ||
| 4597 | { | ||
| 4598 | u32 enables = 0; | ||
| 4599 | |||
| 4600 | bnxt_hwrm_cmd_hdr_init(bp, req, HWRM_FUNC_VF_CFG, -1, -1); | ||
| 4601 | enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; | ||
| 4602 | enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; | ||
| 4603 | enables |= cp_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | ||
| 4604 | FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 4605 | enables |= ring_grps ? FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; | ||
| 4606 | enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0; | ||
| 4607 | |||
| 4608 | req->num_tx_rings = cpu_to_le16(tx_rings); | ||
| 4609 | req->num_rx_rings = cpu_to_le16(rx_rings); | ||
| 4610 | req->num_hw_ring_grps = cpu_to_le16(ring_grps); | ||
| 4611 | req->num_cmpl_rings = cpu_to_le16(cp_rings); | ||
| 4612 | req->num_stat_ctxs = req->num_cmpl_rings; | ||
| 4613 | req->num_vnics = cpu_to_le16(vnics); | ||
| 4614 | |||
| 4615 | req->enables = cpu_to_le32(enables); | ||
| 4616 | } | ||
| 4617 | |||
| 4618 | static int | ||
| 4619 | bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | ||
| 4620 | int ring_grps, int cp_rings, int vnics) | ||
| 4621 | { | ||
| 4622 | struct hwrm_func_cfg_input req = {0}; | ||
| 4623 | int rc; | ||
| 4624 | |||
| 4625 | __bnxt_hwrm_reserve_pf_rings(bp, &req, tx_rings, rx_rings, ring_grps, | ||
| 4626 | cp_rings, vnics); | ||
| 4627 | if (!req.enables) | ||
| 4588 | return 0; | 4628 | return 0; |
| 4589 | 4629 | ||
| 4590 | req.enables = cpu_to_le32(enables); | ||
| 4591 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 4630 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 4592 | if (rc) | 4631 | if (rc) |
| 4593 | return -ENOMEM; | 4632 | return -ENOMEM; |
| @@ -4604,7 +4643,6 @@ bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | |||
| 4604 | int ring_grps, int cp_rings, int vnics) | 4643 | int ring_grps, int cp_rings, int vnics) |
| 4605 | { | 4644 | { |
| 4606 | struct hwrm_func_vf_cfg_input req = {0}; | 4645 | struct hwrm_func_vf_cfg_input req = {0}; |
| 4607 | u32 enables = 0; | ||
| 4608 | int rc; | 4646 | int rc; |
| 4609 | 4647 | ||
| 4610 | if (!(bp->flags & BNXT_FLAG_NEW_RM)) { | 4648 | if (!(bp->flags & BNXT_FLAG_NEW_RM)) { |
| @@ -4612,22 +4650,8 @@ bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | |||
| 4612 | return 0; | 4650 | return 0; |
| 4613 | } | 4651 | } |
| 4614 | 4652 | ||
| 4615 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1); | 4653 | __bnxt_hwrm_reserve_vf_rings(bp, &req, tx_rings, rx_rings, ring_grps, |
| 4616 | enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; | 4654 | cp_rings, vnics); |
| 4617 | enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; | ||
| 4618 | enables |= cp_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | ||
| 4619 | FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 4620 | enables |= ring_grps ? FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; | ||
| 4621 | enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0; | ||
| 4622 | |||
| 4623 | req.num_tx_rings = cpu_to_le16(tx_rings); | ||
| 4624 | req.num_rx_rings = cpu_to_le16(rx_rings); | ||
| 4625 | req.num_hw_ring_grps = cpu_to_le16(ring_grps); | ||
| 4626 | req.num_cmpl_rings = cpu_to_le16(cp_rings); | ||
| 4627 | req.num_stat_ctxs = req.num_cmpl_rings; | ||
| 4628 | req.num_vnics = cpu_to_le16(vnics); | ||
| 4629 | |||
| 4630 | req.enables = cpu_to_le32(enables); | ||
| 4631 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 4655 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 4632 | if (rc) | 4656 | if (rc) |
| 4633 | return -ENOMEM; | 4657 | return -ENOMEM; |
| @@ -4743,39 +4767,25 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp) | |||
| 4743 | } | 4767 | } |
| 4744 | 4768 | ||
| 4745 | static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | 4769 | static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, |
| 4746 | int ring_grps, int cp_rings) | 4770 | int ring_grps, int cp_rings, int vnics) |
| 4747 | { | 4771 | { |
| 4748 | struct hwrm_func_vf_cfg_input req = {0}; | 4772 | struct hwrm_func_vf_cfg_input req = {0}; |
| 4749 | u32 flags, enables; | 4773 | u32 flags; |
| 4750 | int rc; | 4774 | int rc; |
| 4751 | 4775 | ||
| 4752 | if (!(bp->flags & BNXT_FLAG_NEW_RM)) | 4776 | if (!(bp->flags & BNXT_FLAG_NEW_RM)) |
| 4753 | return 0; | 4777 | return 0; |
| 4754 | 4778 | ||
| 4755 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1); | 4779 | __bnxt_hwrm_reserve_vf_rings(bp, &req, tx_rings, rx_rings, ring_grps, |
| 4780 | cp_rings, vnics); | ||
| 4756 | flags = FUNC_VF_CFG_REQ_FLAGS_TX_ASSETS_TEST | | 4781 | flags = FUNC_VF_CFG_REQ_FLAGS_TX_ASSETS_TEST | |
| 4757 | FUNC_VF_CFG_REQ_FLAGS_RX_ASSETS_TEST | | 4782 | FUNC_VF_CFG_REQ_FLAGS_RX_ASSETS_TEST | |
| 4758 | FUNC_VF_CFG_REQ_FLAGS_CMPL_ASSETS_TEST | | 4783 | FUNC_VF_CFG_REQ_FLAGS_CMPL_ASSETS_TEST | |
| 4759 | FUNC_VF_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST | | 4784 | FUNC_VF_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST | |
| 4760 | FUNC_VF_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST | | 4785 | FUNC_VF_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST | |
| 4761 | FUNC_VF_CFG_REQ_FLAGS_VNIC_ASSETS_TEST; | 4786 | FUNC_VF_CFG_REQ_FLAGS_VNIC_ASSETS_TEST; |
| 4762 | enables = FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS | | ||
| 4763 | FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS | | ||
| 4764 | FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | ||
| 4765 | FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS | | ||
| 4766 | FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS | | ||
| 4767 | FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS; | ||
| 4768 | 4787 | ||
| 4769 | req.flags = cpu_to_le32(flags); | 4788 | req.flags = cpu_to_le32(flags); |
| 4770 | req.enables = cpu_to_le32(enables); | ||
| 4771 | req.num_tx_rings = cpu_to_le16(tx_rings); | ||
| 4772 | req.num_rx_rings = cpu_to_le16(rx_rings); | ||
| 4773 | req.num_cmpl_rings = cpu_to_le16(cp_rings); | ||
| 4774 | req.num_hw_ring_grps = cpu_to_le16(ring_grps); | ||
| 4775 | req.num_stat_ctxs = cpu_to_le16(cp_rings); | ||
| 4776 | req.num_vnics = cpu_to_le16(1); | ||
| 4777 | if (bp->flags & BNXT_FLAG_RFS) | ||
| 4778 | req.num_vnics = cpu_to_le16(rx_rings + 1); | ||
| 4779 | rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 4789 | rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 4780 | if (rc) | 4790 | if (rc) |
| 4781 | return -ENOMEM; | 4791 | return -ENOMEM; |
| @@ -4783,38 +4793,23 @@ static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | |||
| 4783 | } | 4793 | } |
| 4784 | 4794 | ||
| 4785 | static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | 4795 | static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, |
| 4786 | int ring_grps, int cp_rings) | 4796 | int ring_grps, int cp_rings, int vnics) |
| 4787 | { | 4797 | { |
| 4788 | struct hwrm_func_cfg_input req = {0}; | 4798 | struct hwrm_func_cfg_input req = {0}; |
| 4789 | u32 flags, enables; | 4799 | u32 flags; |
| 4790 | int rc; | 4800 | int rc; |
| 4791 | 4801 | ||
| 4792 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); | 4802 | __bnxt_hwrm_reserve_pf_rings(bp, &req, tx_rings, rx_rings, ring_grps, |
| 4793 | req.fid = cpu_to_le16(0xffff); | 4803 | cp_rings, vnics); |
| 4794 | flags = FUNC_CFG_REQ_FLAGS_TX_ASSETS_TEST; | 4804 | flags = FUNC_CFG_REQ_FLAGS_TX_ASSETS_TEST; |
| 4795 | enables = FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS; | 4805 | if (bp->flags & BNXT_FLAG_NEW_RM) |
| 4796 | req.num_tx_rings = cpu_to_le16(tx_rings); | ||
| 4797 | if (bp->flags & BNXT_FLAG_NEW_RM) { | ||
| 4798 | flags |= FUNC_CFG_REQ_FLAGS_RX_ASSETS_TEST | | 4806 | flags |= FUNC_CFG_REQ_FLAGS_RX_ASSETS_TEST | |
| 4799 | FUNC_CFG_REQ_FLAGS_CMPL_ASSETS_TEST | | 4807 | FUNC_CFG_REQ_FLAGS_CMPL_ASSETS_TEST | |
| 4800 | FUNC_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST | | 4808 | FUNC_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST | |
| 4801 | FUNC_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST | | 4809 | FUNC_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST | |
| 4802 | FUNC_CFG_REQ_FLAGS_VNIC_ASSETS_TEST; | 4810 | FUNC_CFG_REQ_FLAGS_VNIC_ASSETS_TEST; |
| 4803 | enables |= FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS | | 4811 | |
| 4804 | FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | ||
| 4805 | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS | | ||
| 4806 | FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS | | ||
| 4807 | FUNC_CFG_REQ_ENABLES_NUM_VNICS; | ||
| 4808 | req.num_rx_rings = cpu_to_le16(rx_rings); | ||
| 4809 | req.num_cmpl_rings = cpu_to_le16(cp_rings); | ||
| 4810 | req.num_hw_ring_grps = cpu_to_le16(ring_grps); | ||
| 4811 | req.num_stat_ctxs = cpu_to_le16(cp_rings); | ||
| 4812 | req.num_vnics = cpu_to_le16(1); | ||
| 4813 | if (bp->flags & BNXT_FLAG_RFS) | ||
| 4814 | req.num_vnics = cpu_to_le16(rx_rings + 1); | ||
| 4815 | } | ||
| 4816 | req.flags = cpu_to_le32(flags); | 4812 | req.flags = cpu_to_le32(flags); |
| 4817 | req.enables = cpu_to_le32(enables); | ||
| 4818 | rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 4813 | rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 4819 | if (rc) | 4814 | if (rc) |
| 4820 | return -ENOMEM; | 4815 | return -ENOMEM; |
| @@ -4822,17 +4817,17 @@ static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings, | |||
| 4822 | } | 4817 | } |
| 4823 | 4818 | ||
| 4824 | static int bnxt_hwrm_check_rings(struct bnxt *bp, int tx_rings, int rx_rings, | 4819 | static int bnxt_hwrm_check_rings(struct bnxt *bp, int tx_rings, int rx_rings, |
| 4825 | int ring_grps, int cp_rings) | 4820 | int ring_grps, int cp_rings, int vnics) |
| 4826 | { | 4821 | { |
| 4827 | if (bp->hwrm_spec_code < 0x10801) | 4822 | if (bp->hwrm_spec_code < 0x10801) |
| 4828 | return 0; | 4823 | return 0; |
| 4829 | 4824 | ||
| 4830 | if (BNXT_PF(bp)) | 4825 | if (BNXT_PF(bp)) |
| 4831 | return bnxt_hwrm_check_pf_rings(bp, tx_rings, rx_rings, | 4826 | return bnxt_hwrm_check_pf_rings(bp, tx_rings, rx_rings, |
| 4832 | ring_grps, cp_rings); | 4827 | ring_grps, cp_rings, vnics); |
| 4833 | 4828 | ||
| 4834 | return bnxt_hwrm_check_vf_rings(bp, tx_rings, rx_rings, ring_grps, | 4829 | return bnxt_hwrm_check_vf_rings(bp, tx_rings, rx_rings, ring_grps, |
| 4835 | cp_rings); | 4830 | cp_rings, vnics); |
| 4836 | } | 4831 | } |
| 4837 | 4832 | ||
| 4838 | static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, | 4833 | static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, |
| @@ -5865,7 +5860,6 @@ static int bnxt_init_msix(struct bnxt *bp) | |||
| 5865 | if (rc) | 5860 | if (rc) |
| 5866 | goto msix_setup_exit; | 5861 | goto msix_setup_exit; |
| 5867 | 5862 | ||
| 5868 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | ||
| 5869 | bp->cp_nr_rings = (min == 1) ? | 5863 | bp->cp_nr_rings = (min == 1) ? |
| 5870 | max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) : | 5864 | max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) : |
| 5871 | bp->tx_nr_rings + bp->rx_nr_rings; | 5865 | bp->tx_nr_rings + bp->rx_nr_rings; |
| @@ -5897,7 +5891,6 @@ static int bnxt_init_inta(struct bnxt *bp) | |||
| 5897 | bp->rx_nr_rings = 1; | 5891 | bp->rx_nr_rings = 1; |
| 5898 | bp->tx_nr_rings = 1; | 5892 | bp->tx_nr_rings = 1; |
| 5899 | bp->cp_nr_rings = 1; | 5893 | bp->cp_nr_rings = 1; |
| 5900 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | ||
| 5901 | bp->flags |= BNXT_FLAG_SHARED_RINGS; | 5894 | bp->flags |= BNXT_FLAG_SHARED_RINGS; |
| 5902 | bp->irq_tbl[0].vector = bp->pdev->irq; | 5895 | bp->irq_tbl[0].vector = bp->pdev->irq; |
| 5903 | return 0; | 5896 | return 0; |
| @@ -7531,7 +7524,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs, | |||
| 7531 | int max_rx, max_tx, tx_sets = 1; | 7524 | int max_rx, max_tx, tx_sets = 1; |
| 7532 | int tx_rings_needed; | 7525 | int tx_rings_needed; |
| 7533 | int rx_rings = rx; | 7526 | int rx_rings = rx; |
| 7534 | int cp, rc; | 7527 | int cp, vnics, rc; |
| 7535 | 7528 | ||
| 7536 | if (tcs) | 7529 | if (tcs) |
| 7537 | tx_sets = tcs; | 7530 | tx_sets = tcs; |
| @@ -7547,10 +7540,15 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs, | |||
| 7547 | if (max_tx < tx_rings_needed) | 7540 | if (max_tx < tx_rings_needed) |
| 7548 | return -ENOMEM; | 7541 | return -ENOMEM; |
| 7549 | 7542 | ||
| 7543 | vnics = 1; | ||
| 7544 | if (bp->flags & BNXT_FLAG_RFS) | ||
| 7545 | vnics += rx_rings; | ||
| 7546 | |||
| 7550 | if (bp->flags & BNXT_FLAG_AGG_RINGS) | 7547 | if (bp->flags & BNXT_FLAG_AGG_RINGS) |
| 7551 | rx_rings <<= 1; | 7548 | rx_rings <<= 1; |
| 7552 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; | 7549 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; |
| 7553 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp); | 7550 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp, |
| 7551 | vnics); | ||
| 7554 | } | 7552 | } |
| 7555 | 7553 | ||
| 7556 | static void bnxt_unmap_bars(struct bnxt *bp, struct pci_dev *pdev) | 7554 | static void bnxt_unmap_bars(struct bnxt *bp, struct pci_dev *pdev) |
| @@ -8437,13 +8435,20 @@ int bnxt_restore_pf_fw_resources(struct bnxt *bp) | |||
| 8437 | return 0; | 8435 | return 0; |
| 8438 | 8436 | ||
| 8439 | bnxt_hwrm_func_qcaps(bp); | 8437 | bnxt_hwrm_func_qcaps(bp); |
| 8440 | __bnxt_close_nic(bp, true, false); | 8438 | |
| 8439 | if (netif_running(bp->dev)) | ||
| 8440 | __bnxt_close_nic(bp, true, false); | ||
| 8441 | |||
| 8441 | bnxt_clear_int_mode(bp); | 8442 | bnxt_clear_int_mode(bp); |
| 8442 | rc = bnxt_init_int_mode(bp); | 8443 | rc = bnxt_init_int_mode(bp); |
| 8443 | if (rc) | 8444 | |
| 8444 | dev_close(bp->dev); | 8445 | if (netif_running(bp->dev)) { |
| 8445 | else | 8446 | if (rc) |
| 8446 | rc = bnxt_open_nic(bp, true, false); | 8447 | dev_close(bp->dev); |
| 8448 | else | ||
| 8449 | rc = bnxt_open_nic(bp, true, false); | ||
| 8450 | } | ||
| 8451 | |||
| 8447 | return rc; | 8452 | return rc; |
| 8448 | } | 8453 | } |
| 8449 | 8454 | ||
| @@ -8664,6 +8669,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 8664 | if (rc) | 8669 | if (rc) |
| 8665 | goto init_err_pci_clean; | 8670 | goto init_err_pci_clean; |
| 8666 | 8671 | ||
| 8672 | /* No TC has been set yet and rings may have been trimmed due to | ||
| 8673 | * limited MSIX, so we re-initialize the TX rings per TC. | ||
| 8674 | */ | ||
| 8675 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | ||
| 8676 | |||
| 8667 | bnxt_get_wol_settings(bp); | 8677 | bnxt_get_wol_settings(bp); |
| 8668 | if (bp->flags & BNXT_FLAG_WOL_CAP) | 8678 | if (bp->flags & BNXT_FLAG_WOL_CAP) |
| 8669 | device_set_wakeup_enable(&pdev->dev, bp->wol); | 8679 | device_set_wakeup_enable(&pdev->dev, bp->wol); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 1989c470172c..5e3d62189cab 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
| @@ -189,6 +189,7 @@ struct rx_cmp_ext { | |||
| 189 | #define RX_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3) | 189 | #define RX_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3) |
| 190 | #define RX_CMP_FLAGS2_META_FORMAT_VLAN (0x1 << 4) | 190 | #define RX_CMP_FLAGS2_META_FORMAT_VLAN (0x1 << 4) |
| 191 | __le32 rx_cmp_meta_data; | 191 | __le32 rx_cmp_meta_data; |
| 192 | #define RX_CMP_FLAGS2_METADATA_TCI_MASK 0xffff | ||
| 192 | #define RX_CMP_FLAGS2_METADATA_VID_MASK 0xfff | 193 | #define RX_CMP_FLAGS2_METADATA_VID_MASK 0xfff |
| 193 | #define RX_CMP_FLAGS2_METADATA_TPID_MASK 0xffff0000 | 194 | #define RX_CMP_FLAGS2_METADATA_TPID_MASK 0xffff0000 |
| 194 | #define RX_CMP_FLAGS2_METADATA_TPID_SFT 16 | 195 | #define RX_CMP_FLAGS2_METADATA_TPID_SFT 16 |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index fbe6e208e17b..65c2cee35766 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
| @@ -349,6 +349,9 @@ static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, __le16 flow_handle) | |||
| 349 | if (rc) | 349 | if (rc) |
| 350 | netdev_info(bp->dev, "Error: %s: flow_handle=0x%x rc=%d", | 350 | netdev_info(bp->dev, "Error: %s: flow_handle=0x%x rc=%d", |
| 351 | __func__, flow_handle, rc); | 351 | __func__, flow_handle, rc); |
| 352 | |||
| 353 | if (rc) | ||
| 354 | rc = -EIO; | ||
| 352 | return rc; | 355 | return rc; |
| 353 | } | 356 | } |
| 354 | 357 | ||
| @@ -484,13 +487,15 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
| 484 | req.action_flags = cpu_to_le16(action_flags); | 487 | req.action_flags = cpu_to_le16(action_flags); |
| 485 | 488 | ||
| 486 | mutex_lock(&bp->hwrm_cmd_lock); | 489 | mutex_lock(&bp->hwrm_cmd_lock); |
| 487 | |||
| 488 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 490 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 489 | if (!rc) | 491 | if (!rc) |
| 490 | *flow_handle = resp->flow_handle; | 492 | *flow_handle = resp->flow_handle; |
| 491 | |||
| 492 | mutex_unlock(&bp->hwrm_cmd_lock); | 493 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 493 | 494 | ||
| 495 | if (rc == HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR) | ||
| 496 | rc = -ENOSPC; | ||
| 497 | else if (rc) | ||
| 498 | rc = -EIO; | ||
| 494 | return rc; | 499 | return rc; |
| 495 | } | 500 | } |
| 496 | 501 | ||
| @@ -561,6 +566,8 @@ static int hwrm_cfa_decap_filter_alloc(struct bnxt *bp, | |||
| 561 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | 566 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); |
| 562 | mutex_unlock(&bp->hwrm_cmd_lock); | 567 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 563 | 568 | ||
| 569 | if (rc) | ||
| 570 | rc = -EIO; | ||
| 564 | return rc; | 571 | return rc; |
| 565 | } | 572 | } |
| 566 | 573 | ||
| @@ -576,6 +583,9 @@ static int hwrm_cfa_decap_filter_free(struct bnxt *bp, | |||
| 576 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 583 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 577 | if (rc) | 584 | if (rc) |
| 578 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | 585 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); |
| 586 | |||
| 587 | if (rc) | ||
| 588 | rc = -EIO; | ||
| 579 | return rc; | 589 | return rc; |
| 580 | } | 590 | } |
| 581 | 591 | ||
| @@ -624,6 +634,8 @@ static int hwrm_cfa_encap_record_alloc(struct bnxt *bp, | |||
| 624 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | 634 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); |
| 625 | mutex_unlock(&bp->hwrm_cmd_lock); | 635 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 626 | 636 | ||
| 637 | if (rc) | ||
| 638 | rc = -EIO; | ||
| 627 | return rc; | 639 | return rc; |
| 628 | } | 640 | } |
| 629 | 641 | ||
| @@ -639,6 +651,9 @@ static int hwrm_cfa_encap_record_free(struct bnxt *bp, | |||
| 639 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 651 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 640 | if (rc) | 652 | if (rc) |
| 641 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | 653 | netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); |
| 654 | |||
| 655 | if (rc) | ||
| 656 | rc = -EIO; | ||
| 642 | return rc; | 657 | return rc; |
| 643 | } | 658 | } |
| 644 | 659 | ||
| @@ -1269,11 +1284,8 @@ static int bnxt_tc_del_flow(struct bnxt *bp, | |||
| 1269 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, | 1284 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, |
| 1270 | &tc_flow_cmd->cookie, | 1285 | &tc_flow_cmd->cookie, |
| 1271 | tc_info->flow_ht_params); | 1286 | tc_info->flow_ht_params); |
| 1272 | if (!flow_node) { | 1287 | if (!flow_node) |
| 1273 | netdev_info(bp->dev, "ERROR: no flow_node for cookie %lx", | ||
| 1274 | tc_flow_cmd->cookie); | ||
| 1275 | return -EINVAL; | 1288 | return -EINVAL; |
| 1276 | } | ||
| 1277 | 1289 | ||
| 1278 | return __bnxt_tc_del_flow(bp, flow_node); | 1290 | return __bnxt_tc_del_flow(bp, flow_node); |
| 1279 | } | 1291 | } |
| @@ -1290,11 +1302,8 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp, | |||
| 1290 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, | 1302 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, |
| 1291 | &tc_flow_cmd->cookie, | 1303 | &tc_flow_cmd->cookie, |
| 1292 | tc_info->flow_ht_params); | 1304 | tc_info->flow_ht_params); |
| 1293 | if (!flow_node) { | 1305 | if (!flow_node) |
| 1294 | netdev_info(bp->dev, "Error: no flow_node for cookie %lx", | ||
| 1295 | tc_flow_cmd->cookie); | ||
| 1296 | return -1; | 1306 | return -1; |
| 1297 | } | ||
| 1298 | 1307 | ||
| 1299 | flow = &flow_node->flow; | 1308 | flow = &flow_node->flow; |
| 1300 | curr_stats = &flow->stats; | 1309 | curr_stats = &flow->stats; |
| @@ -1344,8 +1353,10 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows, | |||
| 1344 | } else { | 1353 | } else { |
| 1345 | netdev_info(bp->dev, "error rc=%d", rc); | 1354 | netdev_info(bp->dev, "error rc=%d", rc); |
| 1346 | } | 1355 | } |
| 1347 | |||
| 1348 | mutex_unlock(&bp->hwrm_cmd_lock); | 1356 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 1357 | |||
| 1358 | if (rc) | ||
| 1359 | rc = -EIO; | ||
| 1349 | return rc; | 1360 | return rc; |
| 1350 | } | 1361 | } |
| 1351 | 1362 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index c1841db1b500..f2593978ae75 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -820,7 +820,7 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) | |||
| 820 | 820 | ||
| 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); | 821 | tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); |
| 822 | 822 | ||
| 823 | usleep_range(10, 20); | 823 | udelay(10); |
| 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; | 824 | timeout_us -= (timeout_us > 10) ? 10 : timeout_us; |
| 825 | } | 825 | } |
| 826 | 826 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 7b452e85de2a..61022b5f6743 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -4970,7 +4970,6 @@ static void cxgb4_mgmt_setup(struct net_device *dev) | |||
| 4970 | /* Initialize the device structure. */ | 4970 | /* Initialize the device structure. */ |
| 4971 | dev->netdev_ops = &cxgb4_mgmt_netdev_ops; | 4971 | dev->netdev_ops = &cxgb4_mgmt_netdev_ops; |
| 4972 | dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; | 4972 | dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; |
| 4973 | dev->needs_free_netdev = true; | ||
| 4974 | } | 4973 | } |
| 4975 | 4974 | ||
| 4976 | static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) | 4975 | static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) |
| @@ -5181,6 +5180,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5181 | adapter->name = pci_name(pdev); | 5180 | adapter->name = pci_name(pdev); |
| 5182 | adapter->mbox = func; | 5181 | adapter->mbox = func; |
| 5183 | adapter->pf = func; | 5182 | adapter->pf = func; |
| 5183 | adapter->params.chip = chip; | ||
| 5184 | adapter->adap_idx = adap_idx; | ||
| 5184 | adapter->msg_enable = DFLT_MSG_ENABLE; | 5185 | adapter->msg_enable = DFLT_MSG_ENABLE; |
| 5185 | adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) + | 5186 | adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) + |
| 5186 | (sizeof(struct mbox_cmd) * | 5187 | (sizeof(struct mbox_cmd) * |
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 5eb999af2c40..bd3f6e4d1341 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c | |||
| @@ -540,6 +540,7 @@ static int gmac_setup_txqs(struct net_device *netdev) | |||
| 540 | 540 | ||
| 541 | if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { | 541 | if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { |
| 542 | dev_warn(geth->dev, "TX queue base it not aligned\n"); | 542 | dev_warn(geth->dev, "TX queue base it not aligned\n"); |
| 543 | kfree(skb_tab); | ||
| 543 | return -ENOMEM; | 544 | return -ENOMEM; |
| 544 | } | 545 | } |
| 545 | 546 | ||
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 7caa8da48421..e4ec32a9ca15 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | |||
| @@ -2008,7 +2008,6 @@ static inline int dpaa_xmit(struct dpaa_priv *priv, | |||
| 2008 | } | 2008 | } |
| 2009 | 2009 | ||
| 2010 | if (unlikely(err < 0)) { | 2010 | if (unlikely(err < 0)) { |
| 2011 | percpu_stats->tx_errors++; | ||
| 2012 | percpu_stats->tx_fifo_errors++; | 2011 | percpu_stats->tx_fifo_errors++; |
| 2013 | return err; | 2012 | return err; |
| 2014 | } | 2013 | } |
| @@ -2278,7 +2277,6 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal, | |||
| 2278 | vaddr = phys_to_virt(addr); | 2277 | vaddr = phys_to_virt(addr); |
| 2279 | prefetch(vaddr + qm_fd_get_offset(fd)); | 2278 | prefetch(vaddr + qm_fd_get_offset(fd)); |
| 2280 | 2279 | ||
| 2281 | fd_format = qm_fd_get_format(fd); | ||
| 2282 | /* The only FD types that we may receive are contig and S/G */ | 2280 | /* The only FD types that we may receive are contig and S/G */ |
| 2283 | WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg)); | 2281 | WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg)); |
| 2284 | 2282 | ||
| @@ -2311,8 +2309,10 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal, | |||
| 2311 | 2309 | ||
| 2312 | skb_len = skb->len; | 2310 | skb_len = skb->len; |
| 2313 | 2311 | ||
| 2314 | if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) | 2312 | if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) { |
| 2313 | percpu_stats->rx_dropped++; | ||
| 2315 | return qman_cb_dqrr_consume; | 2314 | return qman_cb_dqrr_consume; |
| 2315 | } | ||
| 2316 | 2316 | ||
| 2317 | percpu_stats->rx_packets++; | 2317 | percpu_stats->rx_packets++; |
| 2318 | percpu_stats->rx_bytes += skb_len; | 2318 | percpu_stats->rx_bytes += skb_len; |
| @@ -2860,7 +2860,7 @@ static int dpaa_remove(struct platform_device *pdev) | |||
| 2860 | struct device *dev; | 2860 | struct device *dev; |
| 2861 | int err; | 2861 | int err; |
| 2862 | 2862 | ||
| 2863 | dev = &pdev->dev; | 2863 | dev = pdev->dev.parent; |
| 2864 | net_dev = dev_get_drvdata(dev); | 2864 | net_dev = dev_get_drvdata(dev); |
| 2865 | 2865 | ||
| 2866 | priv = netdev_priv(net_dev); | 2866 | priv = netdev_priv(net_dev); |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 7a7f3a42b2aa..d4604bc8eb5b 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -3600,6 +3600,8 @@ fec_drv_remove(struct platform_device *pdev) | |||
| 3600 | fec_enet_mii_remove(fep); | 3600 | fec_enet_mii_remove(fep); |
| 3601 | if (fep->reg_phy) | 3601 | if (fep->reg_phy) |
| 3602 | regulator_disable(fep->reg_phy); | 3602 | regulator_disable(fep->reg_phy); |
| 3603 | pm_runtime_put(&pdev->dev); | ||
| 3604 | pm_runtime_disable(&pdev->dev); | ||
| 3603 | if (of_phy_is_fixed_link(np)) | 3605 | if (of_phy_is_fixed_link(np)) |
| 3604 | of_phy_deregister_fixed_link(np); | 3606 | of_phy_deregister_fixed_link(np); |
| 3605 | of_node_put(fep->phy_node); | 3607 | of_node_put(fep->phy_node); |
diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c index ea43b4974149..7af31ddd093f 100644 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c | |||
| @@ -1100,7 +1100,7 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr) | |||
| 1100 | set_bucket(dtsec->regs, bucket, true); | 1100 | set_bucket(dtsec->regs, bucket, true); |
| 1101 | 1101 | ||
| 1102 | /* Create element to be added to the driver hash table */ | 1102 | /* Create element to be added to the driver hash table */ |
| 1103 | hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL); | 1103 | hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC); |
| 1104 | if (!hash_entry) | 1104 | if (!hash_entry) |
| 1105 | return -ENOMEM; | 1105 | return -ENOMEM; |
| 1106 | hash_entry->addr = addr; | 1106 | hash_entry->addr = addr; |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 86944bc3b273..74bd260ca02a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | |||
| @@ -666,7 +666,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data) | |||
| 666 | 666 | ||
| 667 | static int hns_gmac_get_sset_count(int stringset) | 667 | static int hns_gmac_get_sset_count(int stringset) |
| 668 | { | 668 | { |
| 669 | if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) | 669 | if (stringset == ETH_SS_STATS) |
| 670 | return ARRAY_SIZE(g_gmac_stats_string); | 670 | return ARRAY_SIZE(g_gmac_stats_string); |
| 671 | 671 | ||
| 672 | return 0; | 672 | return 0; |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index b62816c1574e..93e71e27401b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | |||
| @@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb) | |||
| 422 | 422 | ||
| 423 | int hns_ppe_get_sset_count(int stringset) | 423 | int hns_ppe_get_sset_count(int stringset) |
| 424 | { | 424 | { |
| 425 | if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) | 425 | if (stringset == ETH_SS_STATS) |
| 426 | return ETH_PPE_STATIC_NUM; | 426 | return ETH_PPE_STATIC_NUM; |
| 427 | return 0; | 427 | return 0; |
| 428 | } | 428 | } |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 6f3570cfb501..e2e28532e4dc 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | |||
| @@ -876,7 +876,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data) | |||
| 876 | */ | 876 | */ |
| 877 | int hns_rcb_get_ring_sset_count(int stringset) | 877 | int hns_rcb_get_ring_sset_count(int stringset) |
| 878 | { | 878 | { |
| 879 | if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) | 879 | if (stringset == ETH_SS_STATS) |
| 880 | return HNS_RING_STATIC_REG_NUM; | 880 | return HNS_RING_STATIC_REG_NUM; |
| 881 | 881 | ||
| 882 | return 0; | 882 | return 0; |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 7ea7f8a4aa2a..2e14a3ae1d8b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | |||
| @@ -993,8 +993,10 @@ int hns_get_sset_count(struct net_device *netdev, int stringset) | |||
| 993 | cnt--; | 993 | cnt--; |
| 994 | 994 | ||
| 995 | return cnt; | 995 | return cnt; |
| 996 | } else { | 996 | } else if (stringset == ETH_SS_STATS) { |
| 997 | return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset)); | 997 | return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset)); |
| 998 | } else { | ||
| 999 | return -EOPNOTSUPP; | ||
| 998 | } | 1000 | } |
| 999 | } | 1001 | } |
| 1000 | 1002 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index afb7ebe20b24..824fd44e25f0 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h | |||
| @@ -400,6 +400,10 @@ | |||
| 400 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ | 400 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ |
| 401 | #define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */ | 401 | #define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */ |
| 402 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ | 402 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ |
| 403 | #define E1000_ICR_MDAC 0x00000200 /* MDIO Access Complete */ | ||
| 404 | #define E1000_ICR_SRPD 0x00010000 /* Small Receive Packet Detected */ | ||
| 405 | #define E1000_ICR_ACK 0x00020000 /* Receive ACK Frame Detected */ | ||
| 406 | #define E1000_ICR_MNG 0x00040000 /* Manageability Event Detected */ | ||
| 403 | #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ | 407 | #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ |
| 404 | /* If this bit asserted, the driver should claim the interrupt */ | 408 | /* If this bit asserted, the driver should claim the interrupt */ |
| 405 | #define E1000_ICR_INT_ASSERTED 0x80000000 | 409 | #define E1000_ICR_INT_ASSERTED 0x80000000 |
| @@ -407,7 +411,7 @@ | |||
| 407 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ | 411 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ |
| 408 | #define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ | 412 | #define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ |
| 409 | #define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ | 413 | #define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ |
| 410 | #define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ | 414 | #define E1000_ICR_OTHER 0x01000000 /* Other Interrupt */ |
| 411 | 415 | ||
| 412 | /* PBA ECC Register */ | 416 | /* PBA ECC Register */ |
| 413 | #define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */ | 417 | #define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */ |
| @@ -431,12 +435,27 @@ | |||
| 431 | E1000_IMS_RXSEQ | \ | 435 | E1000_IMS_RXSEQ | \ |
| 432 | E1000_IMS_LSC) | 436 | E1000_IMS_LSC) |
| 433 | 437 | ||
| 438 | /* These are all of the events related to the OTHER interrupt. | ||
| 439 | */ | ||
| 440 | #define IMS_OTHER_MASK ( \ | ||
| 441 | E1000_IMS_LSC | \ | ||
| 442 | E1000_IMS_RXO | \ | ||
| 443 | E1000_IMS_MDAC | \ | ||
| 444 | E1000_IMS_SRPD | \ | ||
| 445 | E1000_IMS_ACK | \ | ||
| 446 | E1000_IMS_MNG) | ||
| 447 | |||
| 434 | /* Interrupt Mask Set */ | 448 | /* Interrupt Mask Set */ |
| 435 | #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ | 449 | #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ |
| 436 | #define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ | 450 | #define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ |
| 437 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ | 451 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ |
| 438 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ | 452 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ |
| 453 | #define E1000_IMS_RXO E1000_ICR_RXO /* Receiver Overrun */ | ||
| 439 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ | 454 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ |
| 455 | #define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO Access Complete */ | ||
| 456 | #define E1000_IMS_SRPD E1000_ICR_SRPD /* Small Receive Packet */ | ||
| 457 | #define E1000_IMS_ACK E1000_ICR_ACK /* Receive ACK Frame Detected */ | ||
| 458 | #define E1000_IMS_MNG E1000_ICR_MNG /* Manageability Event */ | ||
| 440 | #define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */ | 459 | #define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */ |
| 441 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ | 460 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ |
| 442 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ | 461 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 31277d3bb7dc..1dddfb7b2de6 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
| @@ -1367,9 +1367,6 @@ out: | |||
| 1367 | * Checks to see of the link status of the hardware has changed. If a | 1367 | * Checks to see of the link status of the hardware has changed. If a |
| 1368 | * change in link status has been detected, then we read the PHY registers | 1368 | * change in link status has been detected, then we read the PHY registers |
| 1369 | * to get the current speed/duplex if link exists. | 1369 | * to get the current speed/duplex if link exists. |
| 1370 | * | ||
| 1371 | * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link | ||
| 1372 | * up). | ||
| 1373 | **/ | 1370 | **/ |
| 1374 | static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | 1371 | static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) |
| 1375 | { | 1372 | { |
| @@ -1385,7 +1382,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1385 | * Change or Rx Sequence Error interrupt. | 1382 | * Change or Rx Sequence Error interrupt. |
| 1386 | */ | 1383 | */ |
| 1387 | if (!mac->get_link_status) | 1384 | if (!mac->get_link_status) |
| 1388 | return 1; | 1385 | return 0; |
| 1386 | mac->get_link_status = false; | ||
| 1389 | 1387 | ||
| 1390 | /* First we want to see if the MII Status Register reports | 1388 | /* First we want to see if the MII Status Register reports |
| 1391 | * link. If so, then we want to get the current speed/duplex | 1389 | * link. If so, then we want to get the current speed/duplex |
| @@ -1393,12 +1391,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1393 | */ | 1391 | */ |
| 1394 | ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); | 1392 | ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); |
| 1395 | if (ret_val) | 1393 | if (ret_val) |
| 1396 | return ret_val; | 1394 | goto out; |
| 1397 | 1395 | ||
| 1398 | if (hw->mac.type == e1000_pchlan) { | 1396 | if (hw->mac.type == e1000_pchlan) { |
| 1399 | ret_val = e1000_k1_gig_workaround_hv(hw, link); | 1397 | ret_val = e1000_k1_gig_workaround_hv(hw, link); |
| 1400 | if (ret_val) | 1398 | if (ret_val) |
| 1401 | return ret_val; | 1399 | goto out; |
| 1402 | } | 1400 | } |
| 1403 | 1401 | ||
| 1404 | /* When connected at 10Mbps half-duplex, some parts are excessively | 1402 | /* When connected at 10Mbps half-duplex, some parts are excessively |
| @@ -1431,7 +1429,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1431 | 1429 | ||
| 1432 | ret_val = hw->phy.ops.acquire(hw); | 1430 | ret_val = hw->phy.ops.acquire(hw); |
| 1433 | if (ret_val) | 1431 | if (ret_val) |
| 1434 | return ret_val; | 1432 | goto out; |
| 1435 | 1433 | ||
| 1436 | if (hw->mac.type == e1000_pch2lan) | 1434 | if (hw->mac.type == e1000_pch2lan) |
| 1437 | emi_addr = I82579_RX_CONFIG; | 1435 | emi_addr = I82579_RX_CONFIG; |
| @@ -1453,7 +1451,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1453 | hw->phy.ops.release(hw); | 1451 | hw->phy.ops.release(hw); |
| 1454 | 1452 | ||
| 1455 | if (ret_val) | 1453 | if (ret_val) |
| 1456 | return ret_val; | 1454 | goto out; |
| 1457 | 1455 | ||
| 1458 | if (hw->mac.type >= e1000_pch_spt) { | 1456 | if (hw->mac.type >= e1000_pch_spt) { |
| 1459 | u16 data; | 1457 | u16 data; |
| @@ -1462,14 +1460,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1462 | if (speed == SPEED_1000) { | 1460 | if (speed == SPEED_1000) { |
| 1463 | ret_val = hw->phy.ops.acquire(hw); | 1461 | ret_val = hw->phy.ops.acquire(hw); |
| 1464 | if (ret_val) | 1462 | if (ret_val) |
| 1465 | return ret_val; | 1463 | goto out; |
| 1466 | 1464 | ||
| 1467 | ret_val = e1e_rphy_locked(hw, | 1465 | ret_val = e1e_rphy_locked(hw, |
| 1468 | PHY_REG(776, 20), | 1466 | PHY_REG(776, 20), |
| 1469 | &data); | 1467 | &data); |
| 1470 | if (ret_val) { | 1468 | if (ret_val) { |
| 1471 | hw->phy.ops.release(hw); | 1469 | hw->phy.ops.release(hw); |
| 1472 | return ret_val; | 1470 | goto out; |
| 1473 | } | 1471 | } |
| 1474 | 1472 | ||
| 1475 | ptr_gap = (data & (0x3FF << 2)) >> 2; | 1473 | ptr_gap = (data & (0x3FF << 2)) >> 2; |
| @@ -1483,18 +1481,18 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1483 | } | 1481 | } |
| 1484 | hw->phy.ops.release(hw); | 1482 | hw->phy.ops.release(hw); |
| 1485 | if (ret_val) | 1483 | if (ret_val) |
| 1486 | return ret_val; | 1484 | goto out; |
| 1487 | } else { | 1485 | } else { |
| 1488 | ret_val = hw->phy.ops.acquire(hw); | 1486 | ret_val = hw->phy.ops.acquire(hw); |
| 1489 | if (ret_val) | 1487 | if (ret_val) |
| 1490 | return ret_val; | 1488 | goto out; |
| 1491 | 1489 | ||
| 1492 | ret_val = e1e_wphy_locked(hw, | 1490 | ret_val = e1e_wphy_locked(hw, |
| 1493 | PHY_REG(776, 20), | 1491 | PHY_REG(776, 20), |
| 1494 | 0xC023); | 1492 | 0xC023); |
| 1495 | hw->phy.ops.release(hw); | 1493 | hw->phy.ops.release(hw); |
| 1496 | if (ret_val) | 1494 | if (ret_val) |
| 1497 | return ret_val; | 1495 | goto out; |
| 1498 | 1496 | ||
| 1499 | } | 1497 | } |
| 1500 | } | 1498 | } |
| @@ -1521,7 +1519,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1521 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) { | 1519 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) { |
| 1522 | ret_val = e1000_k1_workaround_lpt_lp(hw, link); | 1520 | ret_val = e1000_k1_workaround_lpt_lp(hw, link); |
| 1523 | if (ret_val) | 1521 | if (ret_val) |
| 1524 | return ret_val; | 1522 | goto out; |
| 1525 | } | 1523 | } |
| 1526 | if (hw->mac.type >= e1000_pch_lpt) { | 1524 | if (hw->mac.type >= e1000_pch_lpt) { |
| 1527 | /* Set platform power management values for | 1525 | /* Set platform power management values for |
| @@ -1529,7 +1527,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1529 | */ | 1527 | */ |
| 1530 | ret_val = e1000_platform_pm_pch_lpt(hw, link); | 1528 | ret_val = e1000_platform_pm_pch_lpt(hw, link); |
| 1531 | if (ret_val) | 1529 | if (ret_val) |
| 1532 | return ret_val; | 1530 | goto out; |
| 1533 | } | 1531 | } |
| 1534 | 1532 | ||
| 1535 | /* Clear link partner's EEE ability */ | 1533 | /* Clear link partner's EEE ability */ |
| @@ -1552,9 +1550,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1552 | } | 1550 | } |
| 1553 | 1551 | ||
| 1554 | if (!link) | 1552 | if (!link) |
| 1555 | return 0; /* No link detected */ | 1553 | goto out; |
| 1556 | |||
| 1557 | mac->get_link_status = false; | ||
| 1558 | 1554 | ||
| 1559 | switch (hw->mac.type) { | 1555 | switch (hw->mac.type) { |
| 1560 | case e1000_pch2lan: | 1556 | case e1000_pch2lan: |
| @@ -1616,12 +1612,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
| 1616 | * different link partner. | 1612 | * different link partner. |
| 1617 | */ | 1613 | */ |
| 1618 | ret_val = e1000e_config_fc_after_link_up(hw); | 1614 | ret_val = e1000e_config_fc_after_link_up(hw); |
| 1619 | if (ret_val) { | 1615 | if (ret_val) |
| 1620 | e_dbg("Error configuring flow control\n"); | 1616 | e_dbg("Error configuring flow control\n"); |
| 1621 | return ret_val; | ||
| 1622 | } | ||
| 1623 | 1617 | ||
| 1624 | return 1; | 1618 | return ret_val; |
| 1619 | |||
| 1620 | out: | ||
| 1621 | mac->get_link_status = true; | ||
| 1622 | return ret_val; | ||
| 1625 | } | 1623 | } |
| 1626 | 1624 | ||
| 1627 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | 1625 | static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) |
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index f457c5703d0c..5bdc3a2d4fd7 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c | |||
| @@ -410,9 +410,6 @@ void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) | |||
| 410 | * Checks to see of the link status of the hardware has changed. If a | 410 | * Checks to see of the link status of the hardware has changed. If a |
| 411 | * change in link status has been detected, then we read the PHY registers | 411 | * change in link status has been detected, then we read the PHY registers |
| 412 | * to get the current speed/duplex if link exists. | 412 | * to get the current speed/duplex if link exists. |
| 413 | * | ||
| 414 | * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link | ||
| 415 | * up). | ||
| 416 | **/ | 413 | **/ |
| 417 | s32 e1000e_check_for_copper_link(struct e1000_hw *hw) | 414 | s32 e1000e_check_for_copper_link(struct e1000_hw *hw) |
| 418 | { | 415 | { |
| @@ -426,20 +423,16 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) | |||
| 426 | * Change or Rx Sequence Error interrupt. | 423 | * Change or Rx Sequence Error interrupt. |
| 427 | */ | 424 | */ |
| 428 | if (!mac->get_link_status) | 425 | if (!mac->get_link_status) |
| 429 | return 1; | 426 | return 0; |
| 427 | mac->get_link_status = false; | ||
| 430 | 428 | ||
| 431 | /* First we want to see if the MII Status Register reports | 429 | /* First we want to see if the MII Status Register reports |
| 432 | * link. If so, then we want to get the current speed/duplex | 430 | * link. If so, then we want to get the current speed/duplex |
| 433 | * of the PHY. | 431 | * of the PHY. |
| 434 | */ | 432 | */ |
| 435 | ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); | 433 | ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); |
| 436 | if (ret_val) | 434 | if (ret_val || !link) |
| 437 | return ret_val; | 435 | goto out; |
| 438 | |||
| 439 | if (!link) | ||
| 440 | return 0; /* No link detected */ | ||
| 441 | |||
| 442 | mac->get_link_status = false; | ||
| 443 | 436 | ||
| 444 | /* Check if there was DownShift, must be checked | 437 | /* Check if there was DownShift, must be checked |
| 445 | * immediately after link-up | 438 | * immediately after link-up |
| @@ -464,12 +457,14 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) | |||
| 464 | * different link partner. | 457 | * different link partner. |
| 465 | */ | 458 | */ |
| 466 | ret_val = e1000e_config_fc_after_link_up(hw); | 459 | ret_val = e1000e_config_fc_after_link_up(hw); |
| 467 | if (ret_val) { | 460 | if (ret_val) |
| 468 | e_dbg("Error configuring flow control\n"); | 461 | e_dbg("Error configuring flow control\n"); |
| 469 | return ret_val; | ||
| 470 | } | ||
| 471 | 462 | ||
| 472 | return 1; | 463 | return ret_val; |
| 464 | |||
| 465 | out: | ||
| 466 | mac->get_link_status = true; | ||
| 467 | return ret_val; | ||
| 473 | } | 468 | } |
| 474 | 469 | ||
| 475 | /** | 470 | /** |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 1298b69f990b..dc853b0863af 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
| @@ -1914,30 +1914,20 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data) | |||
| 1914 | struct net_device *netdev = data; | 1914 | struct net_device *netdev = data; |
| 1915 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1915 | struct e1000_adapter *adapter = netdev_priv(netdev); |
| 1916 | struct e1000_hw *hw = &adapter->hw; | 1916 | struct e1000_hw *hw = &adapter->hw; |
| 1917 | u32 icr; | 1917 | u32 icr = er32(ICR); |
| 1918 | bool enable = true; | 1918 | |
| 1919 | 1919 | if (icr & adapter->eiac_mask) | |
| 1920 | icr = er32(ICR); | 1920 | ew32(ICS, (icr & adapter->eiac_mask)); |
| 1921 | if (icr & E1000_ICR_RXO) { | 1921 | |
| 1922 | ew32(ICR, E1000_ICR_RXO); | ||
| 1923 | enable = false; | ||
| 1924 | /* napi poll will re-enable Other, make sure it runs */ | ||
| 1925 | if (napi_schedule_prep(&adapter->napi)) { | ||
| 1926 | adapter->total_rx_bytes = 0; | ||
| 1927 | adapter->total_rx_packets = 0; | ||
| 1928 | __napi_schedule(&adapter->napi); | ||
| 1929 | } | ||
| 1930 | } | ||
| 1931 | if (icr & E1000_ICR_LSC) { | 1922 | if (icr & E1000_ICR_LSC) { |
| 1932 | ew32(ICR, E1000_ICR_LSC); | ||
| 1933 | hw->mac.get_link_status = true; | 1923 | hw->mac.get_link_status = true; |
| 1934 | /* guard against interrupt when we're going down */ | 1924 | /* guard against interrupt when we're going down */ |
| 1935 | if (!test_bit(__E1000_DOWN, &adapter->state)) | 1925 | if (!test_bit(__E1000_DOWN, &adapter->state)) |
| 1936 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 1926 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
| 1937 | } | 1927 | } |
| 1938 | 1928 | ||
| 1939 | if (enable && !test_bit(__E1000_DOWN, &adapter->state)) | 1929 | if (!test_bit(__E1000_DOWN, &adapter->state)) |
| 1940 | ew32(IMS, E1000_IMS_OTHER); | 1930 | ew32(IMS, E1000_IMS_OTHER | IMS_OTHER_MASK); |
| 1941 | 1931 | ||
| 1942 | return IRQ_HANDLED; | 1932 | return IRQ_HANDLED; |
| 1943 | } | 1933 | } |
| @@ -2040,7 +2030,6 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) | |||
| 2040 | hw->hw_addr + E1000_EITR_82574(vector)); | 2030 | hw->hw_addr + E1000_EITR_82574(vector)); |
| 2041 | else | 2031 | else |
| 2042 | writel(1, hw->hw_addr + E1000_EITR_82574(vector)); | 2032 | writel(1, hw->hw_addr + E1000_EITR_82574(vector)); |
| 2043 | adapter->eiac_mask |= E1000_IMS_OTHER; | ||
| 2044 | 2033 | ||
| 2045 | /* Cause Tx interrupts on every write back */ | 2034 | /* Cause Tx interrupts on every write back */ |
| 2046 | ivar |= BIT(31); | 2035 | ivar |= BIT(31); |
| @@ -2265,7 +2254,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) | |||
| 2265 | 2254 | ||
| 2266 | if (adapter->msix_entries) { | 2255 | if (adapter->msix_entries) { |
| 2267 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); | 2256 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); |
| 2268 | ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC); | 2257 | ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | |
| 2258 | IMS_OTHER_MASK); | ||
| 2269 | } else if (hw->mac.type >= e1000_pch_lpt) { | 2259 | } else if (hw->mac.type >= e1000_pch_lpt) { |
| 2270 | ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); | 2260 | ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); |
| 2271 | } else { | 2261 | } else { |
| @@ -2333,8 +2323,8 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter, | |||
| 2333 | { | 2323 | { |
| 2334 | struct pci_dev *pdev = adapter->pdev; | 2324 | struct pci_dev *pdev = adapter->pdev; |
| 2335 | 2325 | ||
| 2336 | ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma, | 2326 | ring->desc = dma_zalloc_coherent(&pdev->dev, ring->size, &ring->dma, |
| 2337 | GFP_KERNEL); | 2327 | GFP_KERNEL); |
| 2338 | if (!ring->desc) | 2328 | if (!ring->desc) |
| 2339 | return -ENOMEM; | 2329 | return -ENOMEM; |
| 2340 | 2330 | ||
| @@ -2707,8 +2697,7 @@ static int e1000e_poll(struct napi_struct *napi, int weight) | |||
| 2707 | napi_complete_done(napi, work_done); | 2697 | napi_complete_done(napi, work_done); |
| 2708 | if (!test_bit(__E1000_DOWN, &adapter->state)) { | 2698 | if (!test_bit(__E1000_DOWN, &adapter->state)) { |
| 2709 | if (adapter->msix_entries) | 2699 | if (adapter->msix_entries) |
| 2710 | ew32(IMS, adapter->rx_ring->ims_val | | 2700 | ew32(IMS, adapter->rx_ring->ims_val); |
| 2711 | E1000_IMS_OTHER); | ||
| 2712 | else | 2701 | else |
| 2713 | e1000_irq_enable(adapter); | 2702 | e1000_irq_enable(adapter); |
| 2714 | } | 2703 | } |
| @@ -5101,7 +5090,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter) | |||
| 5101 | case e1000_media_type_copper: | 5090 | case e1000_media_type_copper: |
| 5102 | if (hw->mac.get_link_status) { | 5091 | if (hw->mac.get_link_status) { |
| 5103 | ret_val = hw->mac.ops.check_for_link(hw); | 5092 | ret_val = hw->mac.ops.check_for_link(hw); |
| 5104 | link_active = ret_val > 0; | 5093 | link_active = !hw->mac.get_link_status; |
| 5105 | } else { | 5094 | } else { |
| 5106 | link_active = true; | 5095 | link_active = true; |
| 5107 | } | 5096 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c index b698fb481b2e..996dc099cd58 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c | |||
| @@ -443,6 +443,17 @@ int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id) | |||
| 443 | } | 443 | } |
| 444 | EXPORT_SYMBOL(mlxsw_afa_block_jump); | 444 | EXPORT_SYMBOL(mlxsw_afa_block_jump); |
| 445 | 445 | ||
| 446 | int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block) | ||
| 447 | { | ||
| 448 | if (block->finished) | ||
| 449 | return -EINVAL; | ||
| 450 | mlxsw_afa_set_goto_set(block->cur_set, | ||
| 451 | MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0); | ||
| 452 | block->finished = true; | ||
| 453 | return 0; | ||
| 454 | } | ||
| 455 | EXPORT_SYMBOL(mlxsw_afa_block_terminate); | ||
| 456 | |||
| 446 | static struct mlxsw_afa_fwd_entry * | 457 | static struct mlxsw_afa_fwd_entry * |
| 447 | mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u8 local_port) | 458 | mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u8 local_port) |
| 448 | { | 459 | { |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h index 43132293475c..b91f2b0829b0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h | |||
| @@ -65,6 +65,7 @@ char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block); | |||
| 65 | u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block); | 65 | u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block); |
| 66 | int mlxsw_afa_block_continue(struct mlxsw_afa_block *block); | 66 | int mlxsw_afa_block_continue(struct mlxsw_afa_block *block); |
| 67 | int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id); | 67 | int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id); |
| 68 | int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block); | ||
| 68 | int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block); | 69 | int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block); |
| 69 | int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id); | 70 | int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id); |
| 70 | int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block, | 71 | int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block, |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index c7e941aecc2a..bf400c75fcc8 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
| @@ -655,13 +655,17 @@ static int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu) | |||
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | static struct mlxsw_sp_span_inspected_port * | 657 | static struct mlxsw_sp_span_inspected_port * |
| 658 | mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port, | 658 | mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry, |
| 659 | struct mlxsw_sp_span_entry *span_entry) | 659 | enum mlxsw_sp_span_type type, |
| 660 | struct mlxsw_sp_port *port, | ||
| 661 | bool bind) | ||
| 660 | { | 662 | { |
| 661 | struct mlxsw_sp_span_inspected_port *p; | 663 | struct mlxsw_sp_span_inspected_port *p; |
| 662 | 664 | ||
| 663 | list_for_each_entry(p, &span_entry->bound_ports_list, list) | 665 | list_for_each_entry(p, &span_entry->bound_ports_list, list) |
| 664 | if (port->local_port == p->local_port) | 666 | if (type == p->type && |
| 667 | port->local_port == p->local_port && | ||
| 668 | bind == p->bound) | ||
| 665 | return p; | 669 | return p; |
| 666 | return NULL; | 670 | return NULL; |
| 667 | } | 671 | } |
| @@ -691,8 +695,22 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port, | |||
| 691 | struct mlxsw_sp_span_inspected_port *inspected_port; | 695 | struct mlxsw_sp_span_inspected_port *inspected_port; |
| 692 | struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; | 696 | struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; |
| 693 | char sbib_pl[MLXSW_REG_SBIB_LEN]; | 697 | char sbib_pl[MLXSW_REG_SBIB_LEN]; |
| 698 | int i; | ||
| 694 | int err; | 699 | int err; |
| 695 | 700 | ||
| 701 | /* A given (source port, direction) can only be bound to one analyzer, | ||
| 702 | * so if a binding is requested, check for conflicts. | ||
| 703 | */ | ||
| 704 | if (bind) | ||
| 705 | for (i = 0; i < mlxsw_sp->span.entries_count; i++) { | ||
| 706 | struct mlxsw_sp_span_entry *curr = | ||
| 707 | &mlxsw_sp->span.entries[i]; | ||
| 708 | |||
| 709 | if (mlxsw_sp_span_entry_bound_port_find(curr, type, | ||
| 710 | port, bind)) | ||
| 711 | return -EEXIST; | ||
| 712 | } | ||
| 713 | |||
| 696 | /* if it is an egress SPAN, bind a shared buffer to it */ | 714 | /* if it is an egress SPAN, bind a shared buffer to it */ |
| 697 | if (type == MLXSW_SP_SPAN_EGRESS) { | 715 | if (type == MLXSW_SP_SPAN_EGRESS) { |
| 698 | u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, | 716 | u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, |
| @@ -720,6 +738,7 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port, | |||
| 720 | } | 738 | } |
| 721 | inspected_port->local_port = port->local_port; | 739 | inspected_port->local_port = port->local_port; |
| 722 | inspected_port->type = type; | 740 | inspected_port->type = type; |
| 741 | inspected_port->bound = bind; | ||
| 723 | list_add_tail(&inspected_port->list, &span_entry->bound_ports_list); | 742 | list_add_tail(&inspected_port->list, &span_entry->bound_ports_list); |
| 724 | 743 | ||
| 725 | return 0; | 744 | return 0; |
| @@ -746,7 +765,8 @@ mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port, | |||
| 746 | struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; | 765 | struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; |
| 747 | char sbib_pl[MLXSW_REG_SBIB_LEN]; | 766 | char sbib_pl[MLXSW_REG_SBIB_LEN]; |
| 748 | 767 | ||
| 749 | inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry); | 768 | inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type, |
| 769 | port, bind); | ||
| 750 | if (!inspected_port) | 770 | if (!inspected_port) |
| 751 | return; | 771 | return; |
| 752 | 772 | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 4ec1ca3c96c8..92064db2ae44 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h | |||
| @@ -120,6 +120,9 @@ struct mlxsw_sp_span_inspected_port { | |||
| 120 | struct list_head list; | 120 | struct list_head list; |
| 121 | enum mlxsw_sp_span_type type; | 121 | enum mlxsw_sp_span_type type; |
| 122 | u8 local_port; | 122 | u8 local_port; |
| 123 | |||
| 124 | /* Whether this is a directly bound mirror (port-to-port) or an ACL. */ | ||
| 125 | bool bound; | ||
| 123 | }; | 126 | }; |
| 124 | 127 | ||
| 125 | struct mlxsw_sp_span_entry { | 128 | struct mlxsw_sp_span_entry { |
| @@ -553,6 +556,7 @@ void mlxsw_sp_acl_rulei_keymask_buf(struct mlxsw_sp_acl_rule_info *rulei, | |||
| 553 | int mlxsw_sp_acl_rulei_act_continue(struct mlxsw_sp_acl_rule_info *rulei); | 556 | int mlxsw_sp_acl_rulei_act_continue(struct mlxsw_sp_acl_rule_info *rulei); |
| 554 | int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei, | 557 | int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei, |
| 555 | u16 group_id); | 558 | u16 group_id); |
| 559 | int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei); | ||
| 556 | int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei); | 560 | int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei); |
| 557 | int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei); | 561 | int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei); |
| 558 | int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp, | 562 | int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp, |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c index 0897a5435cc2..92d90ed7207e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | |||
| @@ -528,6 +528,11 @@ int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei, | |||
| 528 | return mlxsw_afa_block_jump(rulei->act_block, group_id); | 528 | return mlxsw_afa_block_jump(rulei->act_block, group_id); |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei) | ||
| 532 | { | ||
| 533 | return mlxsw_afa_block_terminate(rulei->act_block); | ||
| 534 | } | ||
| 535 | |||
| 531 | int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei) | 536 | int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei) |
| 532 | { | 537 | { |
| 533 | return mlxsw_afa_block_append_drop(rulei->act_block); | 538 | return mlxsw_afa_block_append_drop(rulei->act_block); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c index 93728c694e6d..0a9adc5962fb 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c | |||
| @@ -385,13 +385,13 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_egress[] = { | |||
| 385 | 385 | ||
| 386 | static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = { | 386 | static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = { |
| 387 | MLXSW_SP_CPU_PORT_SB_CM, | 387 | MLXSW_SP_CPU_PORT_SB_CM, |
| 388 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), | ||
| 389 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), | ||
| 390 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), | ||
| 391 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), | ||
| 392 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), | ||
| 388 | MLXSW_SP_CPU_PORT_SB_CM, | 393 | MLXSW_SP_CPU_PORT_SB_CM, |
| 389 | MLXSW_SP_CPU_PORT_SB_CM, | 394 | MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0), |
| 390 | MLXSW_SP_CPU_PORT_SB_CM, | ||
| 391 | MLXSW_SP_CPU_PORT_SB_CM, | ||
| 392 | MLXSW_SP_CPU_PORT_SB_CM, | ||
| 393 | MLXSW_SP_CPU_PORT_SB_CM, | ||
| 394 | MLXSW_SP_SB_CM(10000, 0, 0), | ||
| 395 | MLXSW_SP_CPU_PORT_SB_CM, | 395 | MLXSW_SP_CPU_PORT_SB_CM, |
| 396 | MLXSW_SP_CPU_PORT_SB_CM, | 396 | MLXSW_SP_CPU_PORT_SB_CM, |
| 397 | MLXSW_SP_CPU_PORT_SB_CM, | 397 | MLXSW_SP_CPU_PORT_SB_CM, |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 6ce00e28d4ea..89dbf569dff5 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | |||
| @@ -65,7 +65,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, | |||
| 65 | tcf_exts_to_list(exts, &actions); | 65 | tcf_exts_to_list(exts, &actions); |
| 66 | list_for_each_entry(a, &actions, list) { | 66 | list_for_each_entry(a, &actions, list) { |
| 67 | if (is_tcf_gact_ok(a)) { | 67 | if (is_tcf_gact_ok(a)) { |
| 68 | err = mlxsw_sp_acl_rulei_act_continue(rulei); | 68 | err = mlxsw_sp_acl_rulei_act_terminate(rulei); |
| 69 | if (err) | 69 | if (err) |
| 70 | return err; | 70 | return err; |
| 71 | } else if (is_tcf_gact_shot(a)) { | 71 | } else if (is_tcf_gact_shot(a)) { |
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig index a10ef50e4f12..017fb2322589 100644 --- a/drivers/net/ethernet/natsemi/Kconfig +++ b/drivers/net/ethernet/natsemi/Kconfig | |||
| @@ -1,16 +1,16 @@ | |||
| 1 | # | 1 | # |
| 2 | # National Semi-conductor device configuration | 2 | # National Semiconductor device configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | config NET_VENDOR_NATSEMI | 5 | config NET_VENDOR_NATSEMI |
| 6 | bool "National Semi-conductor devices" | 6 | bool "National Semiconductor devices" |
| 7 | default y | 7 | default y |
| 8 | ---help--- | 8 | ---help--- |
| 9 | If you have a network (Ethernet) card belonging to this class, say Y. | 9 | If you have a network (Ethernet) card belonging to this class, say Y. |
| 10 | 10 | ||
| 11 | Note that the answer to this question doesn't directly affect the | 11 | Note that the answer to this question doesn't directly affect the |
| 12 | kernel: saying N will just cause the configurator to skip all | 12 | kernel: saying N will just cause the configurator to skip all |
| 13 | the questions about National Semi-conductor devices. If you say Y, | 13 | the questions about National Semiconductor devices. If you say Y, |
| 14 | you will be asked for your specific card in the following questions. | 14 | you will be asked for your specific card in the following questions. |
| 15 | 15 | ||
| 16 | if NET_VENDOR_NATSEMI | 16 | if NET_VENDOR_NATSEMI |
diff --git a/drivers/net/ethernet/natsemi/Makefile b/drivers/net/ethernet/natsemi/Makefile index cc664977596e..a759aa09ef59 100644 --- a/drivers/net/ethernet/natsemi/Makefile +++ b/drivers/net/ethernet/natsemi/Makefile | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # | 2 | # |
| 3 | # Makefile for the National Semi-conductor Sonic devices. | 3 | # Makefile for the National Semiconductor Sonic devices. |
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_MACSONIC) += macsonic.o | 6 | obj-$(CONFIG_MACSONIC) += macsonic.o |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index 6f546e869d8d..00f41c145d4d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c | |||
| @@ -2480,7 +2480,10 @@ int qed_cxt_free_proto_ilt(struct qed_hwfn *p_hwfn, enum protocol_type proto) | |||
| 2480 | if (rc) | 2480 | if (rc) |
| 2481 | return rc; | 2481 | return rc; |
| 2482 | 2482 | ||
| 2483 | /* Free Task CXT */ | 2483 | /* Free Task CXT ( Intentionally RoCE as task-id is shared between |
| 2484 | * RoCE and iWARP ) | ||
| 2485 | */ | ||
| 2486 | proto = PROTOCOLID_ROCE; | ||
| 2484 | rc = qed_cxt_free_ilt_range(p_hwfn, QED_ELEM_TASK, 0, | 2487 | rc = qed_cxt_free_ilt_range(p_hwfn, QED_ELEM_TASK, 0, |
| 2485 | qed_cxt_get_proto_tid_count(p_hwfn, proto)); | 2488 | qed_cxt_get_proto_tid_count(p_hwfn, proto)); |
| 2486 | if (rc) | 2489 | if (rc) |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c index ca4a81dc1ace..d5d02be72947 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c | |||
| @@ -1703,6 +1703,13 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn, | |||
| 1703 | iph = (struct iphdr *)((u8 *)(ethh) + eth_hlen); | 1703 | iph = (struct iphdr *)((u8 *)(ethh) + eth_hlen); |
| 1704 | 1704 | ||
| 1705 | if (eth_type == ETH_P_IP) { | 1705 | if (eth_type == ETH_P_IP) { |
| 1706 | if (iph->protocol != IPPROTO_TCP) { | ||
| 1707 | DP_NOTICE(p_hwfn, | ||
| 1708 | "Unexpected ip protocol on ll2 %x\n", | ||
| 1709 | iph->protocol); | ||
| 1710 | return -EINVAL; | ||
| 1711 | } | ||
| 1712 | |||
| 1706 | cm_info->local_ip[0] = ntohl(iph->daddr); | 1713 | cm_info->local_ip[0] = ntohl(iph->daddr); |
| 1707 | cm_info->remote_ip[0] = ntohl(iph->saddr); | 1714 | cm_info->remote_ip[0] = ntohl(iph->saddr); |
| 1708 | cm_info->ip_version = TCP_IPV4; | 1715 | cm_info->ip_version = TCP_IPV4; |
| @@ -1711,6 +1718,14 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn, | |||
| 1711 | *payload_len = ntohs(iph->tot_len) - ip_hlen; | 1718 | *payload_len = ntohs(iph->tot_len) - ip_hlen; |
| 1712 | } else if (eth_type == ETH_P_IPV6) { | 1719 | } else if (eth_type == ETH_P_IPV6) { |
| 1713 | ip6h = (struct ipv6hdr *)iph; | 1720 | ip6h = (struct ipv6hdr *)iph; |
| 1721 | |||
| 1722 | if (ip6h->nexthdr != IPPROTO_TCP) { | ||
| 1723 | DP_NOTICE(p_hwfn, | ||
| 1724 | "Unexpected ip protocol on ll2 %x\n", | ||
| 1725 | iph->protocol); | ||
| 1726 | return -EINVAL; | ||
| 1727 | } | ||
| 1728 | |||
| 1714 | for (i = 0; i < 4; i++) { | 1729 | for (i = 0; i < 4; i++) { |
| 1715 | cm_info->local_ip[i] = | 1730 | cm_info->local_ip[i] = |
| 1716 | ntohl(ip6h->daddr.in6_u.u6_addr32[i]); | 1731 | ntohl(ip6h->daddr.in6_u.u6_addr32[i]); |
| @@ -1928,8 +1943,8 @@ qed_iwarp_update_fpdu_length(struct qed_hwfn *p_hwfn, | |||
| 1928 | /* Missing lower byte is now available */ | 1943 | /* Missing lower byte is now available */ |
| 1929 | mpa_len = fpdu->fpdu_length | *mpa_data; | 1944 | mpa_len = fpdu->fpdu_length | *mpa_data; |
| 1930 | fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len); | 1945 | fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len); |
| 1931 | fpdu->mpa_frag_len = fpdu->fpdu_length; | ||
| 1932 | /* one byte of hdr */ | 1946 | /* one byte of hdr */ |
| 1947 | fpdu->mpa_frag_len = 1; | ||
| 1933 | fpdu->incomplete_bytes = fpdu->fpdu_length - 1; | 1948 | fpdu->incomplete_bytes = fpdu->fpdu_length - 1; |
| 1934 | DP_VERBOSE(p_hwfn, | 1949 | DP_VERBOSE(p_hwfn, |
| 1935 | QED_MSG_RDMA, | 1950 | QED_MSG_RDMA, |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c index 5d040b873137..a411f9c702a1 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c | |||
| @@ -379,6 +379,7 @@ static void qed_rdma_free(struct qed_hwfn *p_hwfn) | |||
| 379 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Freeing RDMA\n"); | 379 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Freeing RDMA\n"); |
| 380 | 380 | ||
| 381 | qed_rdma_free_reserved_lkey(p_hwfn); | 381 | qed_rdma_free_reserved_lkey(p_hwfn); |
| 382 | qed_cxt_free_proto_ilt(p_hwfn, p_hwfn->p_rdma_info->proto); | ||
| 382 | qed_rdma_resc_free(p_hwfn); | 383 | qed_rdma_resc_free(p_hwfn); |
| 383 | } | 384 | } |
| 384 | 385 | ||
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 2db70eabddfe..a01e7d6e5442 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c | |||
| @@ -288,7 +288,7 @@ int __init qede_init(void) | |||
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | /* Must register notifier before pci ops, since we might miss | 290 | /* Must register notifier before pci ops, since we might miss |
| 291 | * interface rename after pci probe and netdev registeration. | 291 | * interface rename after pci probe and netdev registration. |
| 292 | */ | 292 | */ |
| 293 | ret = register_netdevice_notifier(&qede_netdev_notifier); | 293 | ret = register_netdevice_notifier(&qede_netdev_notifier); |
| 294 | if (ret) { | 294 | if (ret) { |
| @@ -988,7 +988,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, | |||
| 988 | if (rc) | 988 | if (rc) |
| 989 | goto err3; | 989 | goto err3; |
| 990 | 990 | ||
| 991 | /* Prepare the lock prior to the registeration of the netdev, | 991 | /* Prepare the lock prior to the registration of the netdev, |
| 992 | * as once it's registered we might reach flows requiring it | 992 | * as once it's registered we might reach flows requiring it |
| 993 | * [it's even possible to reach a flow needing it directly | 993 | * [it's even possible to reach a flow needing it directly |
| 994 | * from there, although it's unlikely]. | 994 | * from there, although it's unlikely]. |
| @@ -2067,8 +2067,6 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode, | |||
| 2067 | link_params.link_up = true; | 2067 | link_params.link_up = true; |
| 2068 | edev->ops->common->set_link(edev->cdev, &link_params); | 2068 | edev->ops->common->set_link(edev->cdev, &link_params); |
| 2069 | 2069 | ||
| 2070 | qede_rdma_dev_event_open(edev); | ||
| 2071 | |||
| 2072 | edev->state = QEDE_STATE_OPEN; | 2070 | edev->state = QEDE_STATE_OPEN; |
| 2073 | 2071 | ||
| 2074 | DP_INFO(edev, "Ending successfully qede load\n"); | 2072 | DP_INFO(edev, "Ending successfully qede load\n"); |
| @@ -2169,12 +2167,14 @@ static void qede_link_update(void *dev, struct qed_link_output *link) | |||
| 2169 | DP_NOTICE(edev, "Link is up\n"); | 2167 | DP_NOTICE(edev, "Link is up\n"); |
| 2170 | netif_tx_start_all_queues(edev->ndev); | 2168 | netif_tx_start_all_queues(edev->ndev); |
| 2171 | netif_carrier_on(edev->ndev); | 2169 | netif_carrier_on(edev->ndev); |
| 2170 | qede_rdma_dev_event_open(edev); | ||
| 2172 | } | 2171 | } |
| 2173 | } else { | 2172 | } else { |
| 2174 | if (netif_carrier_ok(edev->ndev)) { | 2173 | if (netif_carrier_ok(edev->ndev)) { |
| 2175 | DP_NOTICE(edev, "Link is down\n"); | 2174 | DP_NOTICE(edev, "Link is down\n"); |
| 2176 | netif_tx_disable(edev->ndev); | 2175 | netif_tx_disable(edev->ndev); |
| 2177 | netif_carrier_off(edev->ndev); | 2176 | netif_carrier_off(edev->ndev); |
| 2177 | qede_rdma_dev_event_close(edev); | ||
| 2178 | } | 2178 | } |
| 2179 | } | 2179 | } |
| 2180 | } | 2180 | } |
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 9b2280badaf7..02adb513f475 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c | |||
| @@ -485,7 +485,7 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc) | |||
| 485 | ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev); | 485 | ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev); |
| 486 | if (IS_ERR(ptp->clock)) { | 486 | if (IS_ERR(ptp->clock)) { |
| 487 | rc = -EINVAL; | 487 | rc = -EINVAL; |
| 488 | DP_ERR(edev, "PTP clock registeration failed\n"); | 488 | DP_ERR(edev, "PTP clock registration failed\n"); |
| 489 | goto err2; | 489 | goto err2; |
| 490 | } | 490 | } |
| 491 | 491 | ||
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c index 9cbb27263742..d5a32b7c7dc5 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c | |||
| @@ -1194,9 +1194,9 @@ void emac_mac_tx_process(struct emac_adapter *adpt, struct emac_tx_queue *tx_q) | |||
| 1194 | while (tx_q->tpd.consume_idx != hw_consume_idx) { | 1194 | while (tx_q->tpd.consume_idx != hw_consume_idx) { |
| 1195 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.consume_idx); | 1195 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.consume_idx); |
| 1196 | if (tpbuf->dma_addr) { | 1196 | if (tpbuf->dma_addr) { |
| 1197 | dma_unmap_single(adpt->netdev->dev.parent, | 1197 | dma_unmap_page(adpt->netdev->dev.parent, |
| 1198 | tpbuf->dma_addr, tpbuf->length, | 1198 | tpbuf->dma_addr, tpbuf->length, |
| 1199 | DMA_TO_DEVICE); | 1199 | DMA_TO_DEVICE); |
| 1200 | tpbuf->dma_addr = 0; | 1200 | tpbuf->dma_addr = 0; |
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| @@ -1353,9 +1353,11 @@ static void emac_tx_fill_tpd(struct emac_adapter *adpt, | |||
| 1353 | 1353 | ||
| 1354 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx); | 1354 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx); |
| 1355 | tpbuf->length = mapped_len; | 1355 | tpbuf->length = mapped_len; |
| 1356 | tpbuf->dma_addr = dma_map_single(adpt->netdev->dev.parent, | 1356 | tpbuf->dma_addr = dma_map_page(adpt->netdev->dev.parent, |
| 1357 | skb->data, tpbuf->length, | 1357 | virt_to_page(skb->data), |
| 1358 | DMA_TO_DEVICE); | 1358 | offset_in_page(skb->data), |
| 1359 | tpbuf->length, | ||
| 1360 | DMA_TO_DEVICE); | ||
| 1359 | ret = dma_mapping_error(adpt->netdev->dev.parent, | 1361 | ret = dma_mapping_error(adpt->netdev->dev.parent, |
| 1360 | tpbuf->dma_addr); | 1362 | tpbuf->dma_addr); |
| 1361 | if (ret) | 1363 | if (ret) |
| @@ -1371,9 +1373,12 @@ static void emac_tx_fill_tpd(struct emac_adapter *adpt, | |||
| 1371 | if (mapped_len < len) { | 1373 | if (mapped_len < len) { |
| 1372 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx); | 1374 | tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx); |
| 1373 | tpbuf->length = len - mapped_len; | 1375 | tpbuf->length = len - mapped_len; |
| 1374 | tpbuf->dma_addr = dma_map_single(adpt->netdev->dev.parent, | 1376 | tpbuf->dma_addr = dma_map_page(adpt->netdev->dev.parent, |
| 1375 | skb->data + mapped_len, | 1377 | virt_to_page(skb->data + |
| 1376 | tpbuf->length, DMA_TO_DEVICE); | 1378 | mapped_len), |
| 1379 | offset_in_page(skb->data + | ||
| 1380 | mapped_len), | ||
| 1381 | tpbuf->length, DMA_TO_DEVICE); | ||
| 1377 | ret = dma_mapping_error(adpt->netdev->dev.parent, | 1382 | ret = dma_mapping_error(adpt->netdev->dev.parent, |
| 1378 | tpbuf->dma_addr); | 1383 | tpbuf->dma_addr); |
| 1379 | if (ret) | 1384 | if (ret) |
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 012fb66eed8d..f0afb88d7bc2 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c | |||
| @@ -2335,14 +2335,14 @@ static int smsc911x_drv_remove(struct platform_device *pdev) | |||
| 2335 | pdata = netdev_priv(dev); | 2335 | pdata = netdev_priv(dev); |
| 2336 | BUG_ON(!pdata); | 2336 | BUG_ON(!pdata); |
| 2337 | BUG_ON(!pdata->ioaddr); | 2337 | BUG_ON(!pdata->ioaddr); |
| 2338 | WARN_ON(dev->phydev); | ||
| 2339 | 2338 | ||
| 2340 | SMSC_TRACE(pdata, ifdown, "Stopping driver"); | 2339 | SMSC_TRACE(pdata, ifdown, "Stopping driver"); |
| 2341 | 2340 | ||
| 2341 | unregister_netdev(dev); | ||
| 2342 | |||
| 2342 | mdiobus_unregister(pdata->mii_bus); | 2343 | mdiobus_unregister(pdata->mii_bus); |
| 2343 | mdiobus_free(pdata->mii_bus); | 2344 | mdiobus_free(pdata->mii_bus); |
| 2344 | 2345 | ||
| 2345 | unregister_netdev(dev); | ||
| 2346 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 2346 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| 2347 | "smsc911x-memory"); | 2347 | "smsc911x-memory"); |
| 2348 | if (!res) | 2348 | if (!res) |
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c index 111e7ca9df56..f5c5984afefb 100644 --- a/drivers/net/ethernet/socionext/sni_ave.c +++ b/drivers/net/ethernet/socionext/sni_ave.c | |||
| @@ -1295,7 +1295,7 @@ static int ave_open(struct net_device *ndev) | |||
| 1295 | val |= AVE_IIRQC_EN0 | (AVE_INTM_COUNT << 16); | 1295 | val |= AVE_IIRQC_EN0 | (AVE_INTM_COUNT << 16); |
| 1296 | writel(val, priv->base + AVE_IIRQC); | 1296 | writel(val, priv->base + AVE_IIRQC); |
| 1297 | 1297 | ||
| 1298 | val = AVE_GI_RXIINT | AVE_GI_RXOVF | AVE_GI_TX; | 1298 | val = AVE_GI_RXIINT | AVE_GI_RXOVF | AVE_GI_TX | AVE_GI_RXDROP; |
| 1299 | ave_irq_restore(ndev, val); | 1299 | ave_irq_restore(ndev, val); |
| 1300 | 1300 | ||
| 1301 | napi_enable(&priv->napi_rx); | 1301 | napi_enable(&priv->napi_rx); |
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 63d3d6b215f3..a94f50442613 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
| @@ -312,7 +312,7 @@ static struct vnet *vnet_new(const u64 *local_mac, | |||
| 312 | dev->ethtool_ops = &vnet_ethtool_ops; | 312 | dev->ethtool_ops = &vnet_ethtool_ops; |
| 313 | dev->watchdog_timeo = VNET_TX_TIMEOUT; | 313 | dev->watchdog_timeo = VNET_TX_TIMEOUT; |
| 314 | 314 | ||
| 315 | dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GSO_SOFTWARE | | 315 | dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_ALL_TSO | |
| 316 | NETIF_F_HW_CSUM | NETIF_F_SG; | 316 | NETIF_F_HW_CSUM | NETIF_F_SG; |
| 317 | dev->features = dev->hw_features; | 317 | dev->features = dev->hw_features; |
| 318 | 318 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 1b1b78fdc138..b2b30c9df037 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1014,7 +1014,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, | |||
| 1014 | /* set speed_in input in case RMII mode is used in 100Mbps */ | 1014 | /* set speed_in input in case RMII mode is used in 100Mbps */ |
| 1015 | if (phy->speed == 100) | 1015 | if (phy->speed == 100) |
| 1016 | mac_control |= BIT(15); | 1016 | mac_control |= BIT(15); |
| 1017 | else if (phy->speed == 10) | 1017 | /* in band mode only works in 10Mbps RGMII mode */ |
| 1018 | else if ((phy->speed == 10) && phy_interface_is_rgmii(phy)) | ||
| 1018 | mac_control |= BIT(18); /* In Band mode */ | 1019 | mac_control |= BIT(18); /* In Band mode */ |
| 1019 | 1020 | ||
| 1020 | if (priv->rx_pause) | 1021 | if (priv->rx_pause) |
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 0db3bd1ea06f..32861036c3fc 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
| @@ -173,6 +173,7 @@ struct rndis_device { | |||
| 173 | struct list_head req_list; | 173 | struct list_head req_list; |
| 174 | 174 | ||
| 175 | struct work_struct mcast_work; | 175 | struct work_struct mcast_work; |
| 176 | u32 filter; | ||
| 176 | 177 | ||
| 177 | bool link_state; /* 0 - link up, 1 - link down */ | 178 | bool link_state; /* 0 - link up, 1 - link down */ |
| 178 | 179 | ||
| @@ -211,7 +212,6 @@ void netvsc_channel_cb(void *context); | |||
| 211 | int netvsc_poll(struct napi_struct *napi, int budget); | 212 | int netvsc_poll(struct napi_struct *napi, int budget); |
| 212 | 213 | ||
| 213 | void rndis_set_subchannel(struct work_struct *w); | 214 | void rndis_set_subchannel(struct work_struct *w); |
| 214 | bool rndis_filter_opened(const struct netvsc_device *nvdev); | ||
| 215 | int rndis_filter_open(struct netvsc_device *nvdev); | 215 | int rndis_filter_open(struct netvsc_device *nvdev); |
| 216 | int rndis_filter_close(struct netvsc_device *nvdev); | 216 | int rndis_filter_close(struct netvsc_device *nvdev); |
| 217 | struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, | 217 | struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 0265d703eb03..7472172823f3 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
| @@ -90,6 +90,11 @@ static void free_netvsc_device(struct rcu_head *head) | |||
| 90 | = container_of(head, struct netvsc_device, rcu); | 90 | = container_of(head, struct netvsc_device, rcu); |
| 91 | int i; | 91 | int i; |
| 92 | 92 | ||
| 93 | kfree(nvdev->extension); | ||
| 94 | vfree(nvdev->recv_buf); | ||
| 95 | vfree(nvdev->send_buf); | ||
| 96 | kfree(nvdev->send_section_map); | ||
| 97 | |||
| 93 | for (i = 0; i < VRSS_CHANNEL_MAX; i++) | 98 | for (i = 0; i < VRSS_CHANNEL_MAX; i++) |
| 94 | vfree(nvdev->chan_table[i].mrc.slots); | 99 | vfree(nvdev->chan_table[i].mrc.slots); |
| 95 | 100 | ||
| @@ -211,12 +216,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device, | |||
| 211 | net_device->recv_buf_gpadl_handle = 0; | 216 | net_device->recv_buf_gpadl_handle = 0; |
| 212 | } | 217 | } |
| 213 | 218 | ||
| 214 | if (net_device->recv_buf) { | ||
| 215 | /* Free up the receive buffer */ | ||
| 216 | vfree(net_device->recv_buf); | ||
| 217 | net_device->recv_buf = NULL; | ||
| 218 | } | ||
| 219 | |||
| 220 | if (net_device->send_buf_gpadl_handle) { | 219 | if (net_device->send_buf_gpadl_handle) { |
| 221 | ret = vmbus_teardown_gpadl(device->channel, | 220 | ret = vmbus_teardown_gpadl(device->channel, |
| 222 | net_device->send_buf_gpadl_handle); | 221 | net_device->send_buf_gpadl_handle); |
| @@ -231,12 +230,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device, | |||
| 231 | } | 230 | } |
| 232 | net_device->send_buf_gpadl_handle = 0; | 231 | net_device->send_buf_gpadl_handle = 0; |
| 233 | } | 232 | } |
| 234 | if (net_device->send_buf) { | ||
| 235 | /* Free up the send buffer */ | ||
| 236 | vfree(net_device->send_buf); | ||
| 237 | net_device->send_buf = NULL; | ||
| 238 | } | ||
| 239 | kfree(net_device->send_section_map); | ||
| 240 | } | 233 | } |
| 241 | 234 | ||
| 242 | int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx) | 235 | int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx) |
| @@ -562,26 +555,29 @@ void netvsc_device_remove(struct hv_device *device) | |||
| 562 | = rtnl_dereference(net_device_ctx->nvdev); | 555 | = rtnl_dereference(net_device_ctx->nvdev); |
| 563 | int i; | 556 | int i; |
| 564 | 557 | ||
| 565 | cancel_work_sync(&net_device->subchan_work); | ||
| 566 | |||
| 567 | netvsc_revoke_buf(device, net_device); | 558 | netvsc_revoke_buf(device, net_device); |
| 568 | 559 | ||
| 569 | RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); | 560 | RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); |
| 570 | 561 | ||
| 562 | /* And disassociate NAPI context from device */ | ||
| 563 | for (i = 0; i < net_device->num_chn; i++) | ||
| 564 | netif_napi_del(&net_device->chan_table[i].napi); | ||
| 565 | |||
| 571 | /* | 566 | /* |
| 572 | * At this point, no one should be accessing net_device | 567 | * At this point, no one should be accessing net_device |
| 573 | * except in here | 568 | * except in here |
| 574 | */ | 569 | */ |
| 575 | netdev_dbg(ndev, "net device safe to remove\n"); | 570 | netdev_dbg(ndev, "net device safe to remove\n"); |
| 576 | 571 | ||
| 572 | /* older versions require that buffer be revoked before close */ | ||
| 573 | if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_4) | ||
| 574 | netvsc_teardown_gpadl(device, net_device); | ||
| 575 | |||
| 577 | /* Now, we can close the channel safely */ | 576 | /* Now, we can close the channel safely */ |
| 578 | vmbus_close(device->channel); | 577 | vmbus_close(device->channel); |
| 579 | 578 | ||
| 580 | netvsc_teardown_gpadl(device, net_device); | 579 | if (net_device->nvsp_version >= NVSP_PROTOCOL_VERSION_4) |
| 581 | 580 | netvsc_teardown_gpadl(device, net_device); | |
| 582 | /* And dissassociate NAPI context from device */ | ||
| 583 | for (i = 0; i < net_device->num_chn; i++) | ||
| 584 | netif_napi_del(&net_device->chan_table[i].napi); | ||
| 585 | 581 | ||
| 586 | /* Release all resources */ | 582 | /* Release all resources */ |
| 587 | free_netvsc_device_rcu(net_device); | 583 | free_netvsc_device_rcu(net_device); |
| @@ -645,14 +641,18 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device, | |||
| 645 | queue_sends = | 641 | queue_sends = |
| 646 | atomic_dec_return(&net_device->chan_table[q_idx].queue_sends); | 642 | atomic_dec_return(&net_device->chan_table[q_idx].queue_sends); |
| 647 | 643 | ||
| 648 | if (net_device->destroy && queue_sends == 0) | 644 | if (unlikely(net_device->destroy)) { |
| 649 | wake_up(&net_device->wait_drain); | 645 | if (queue_sends == 0) |
| 646 | wake_up(&net_device->wait_drain); | ||
| 647 | } else { | ||
| 648 | struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx); | ||
| 650 | 649 | ||
| 651 | if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) && | 650 | if (netif_tx_queue_stopped(txq) && |
| 652 | (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER || | 651 | (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER || |
| 653 | queue_sends < 1)) { | 652 | queue_sends < 1)) { |
| 654 | netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx)); | 653 | netif_tx_wake_queue(txq); |
| 655 | ndev_ctx->eth_stats.wake_queue++; | 654 | ndev_ctx->eth_stats.wake_queue++; |
| 655 | } | ||
| 656 | } | 656 | } |
| 657 | } | 657 | } |
| 658 | 658 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index cdb78eefab67..f28c85d212ce 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -46,7 +46,10 @@ | |||
| 46 | 46 | ||
| 47 | #include "hyperv_net.h" | 47 | #include "hyperv_net.h" |
| 48 | 48 | ||
| 49 | #define RING_SIZE_MIN 64 | 49 | #define RING_SIZE_MIN 64 |
| 50 | #define RETRY_US_LO 5000 | ||
| 51 | #define RETRY_US_HI 10000 | ||
| 52 | #define RETRY_MAX 2000 /* >10 sec */ | ||
| 50 | 53 | ||
| 51 | #define LINKCHANGE_INT (2 * HZ) | 54 | #define LINKCHANGE_INT (2 * HZ) |
| 52 | #define VF_TAKEOVER_INT (HZ / 10) | 55 | #define VF_TAKEOVER_INT (HZ / 10) |
| @@ -89,15 +92,20 @@ static void netvsc_change_rx_flags(struct net_device *net, int change) | |||
| 89 | static void netvsc_set_rx_mode(struct net_device *net) | 92 | static void netvsc_set_rx_mode(struct net_device *net) |
| 90 | { | 93 | { |
| 91 | struct net_device_context *ndev_ctx = netdev_priv(net); | 94 | struct net_device_context *ndev_ctx = netdev_priv(net); |
| 92 | struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); | 95 | struct net_device *vf_netdev; |
| 93 | struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev); | 96 | struct netvsc_device *nvdev; |
| 94 | 97 | ||
| 98 | rcu_read_lock(); | ||
| 99 | vf_netdev = rcu_dereference(ndev_ctx->vf_netdev); | ||
| 95 | if (vf_netdev) { | 100 | if (vf_netdev) { |
| 96 | dev_uc_sync(vf_netdev, net); | 101 | dev_uc_sync(vf_netdev, net); |
| 97 | dev_mc_sync(vf_netdev, net); | 102 | dev_mc_sync(vf_netdev, net); |
| 98 | } | 103 | } |
| 99 | 104 | ||
| 100 | rndis_filter_update(nvdev); | 105 | nvdev = rcu_dereference(ndev_ctx->nvdev); |
| 106 | if (nvdev) | ||
| 107 | rndis_filter_update(nvdev); | ||
| 108 | rcu_read_unlock(); | ||
| 101 | } | 109 | } |
| 102 | 110 | ||
| 103 | static int netvsc_open(struct net_device *net) | 111 | static int netvsc_open(struct net_device *net) |
| @@ -118,10 +126,8 @@ static int netvsc_open(struct net_device *net) | |||
| 118 | } | 126 | } |
| 119 | 127 | ||
| 120 | rdev = nvdev->extension; | 128 | rdev = nvdev->extension; |
| 121 | if (!rdev->link_state) { | 129 | if (!rdev->link_state) |
| 122 | netif_carrier_on(net); | 130 | netif_carrier_on(net); |
| 123 | netif_tx_wake_all_queues(net); | ||
| 124 | } | ||
| 125 | 131 | ||
| 126 | if (vf_netdev) { | 132 | if (vf_netdev) { |
| 127 | /* Setting synthetic device up transparently sets | 133 | /* Setting synthetic device up transparently sets |
| @@ -137,36 +143,25 @@ static int netvsc_open(struct net_device *net) | |||
| 137 | return 0; | 143 | return 0; |
| 138 | } | 144 | } |
| 139 | 145 | ||
| 140 | static int netvsc_close(struct net_device *net) | 146 | static int netvsc_wait_until_empty(struct netvsc_device *nvdev) |
| 141 | { | 147 | { |
| 142 | struct net_device_context *net_device_ctx = netdev_priv(net); | 148 | unsigned int retry = 0; |
| 143 | struct net_device *vf_netdev | 149 | int i; |
| 144 | = rtnl_dereference(net_device_ctx->vf_netdev); | ||
| 145 | struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); | ||
| 146 | int ret = 0; | ||
| 147 | u32 aread, i, msec = 10, retry = 0, retry_max = 20; | ||
| 148 | struct vmbus_channel *chn; | ||
| 149 | |||
| 150 | netif_tx_disable(net); | ||
| 151 | |||
| 152 | /* No need to close rndis filter if it is removed already */ | ||
| 153 | if (!nvdev) | ||
| 154 | goto out; | ||
| 155 | |||
| 156 | ret = rndis_filter_close(nvdev); | ||
| 157 | if (ret != 0) { | ||
| 158 | netdev_err(net, "unable to close device (ret %d).\n", ret); | ||
| 159 | return ret; | ||
| 160 | } | ||
| 161 | 150 | ||
| 162 | /* Ensure pending bytes in ring are read */ | 151 | /* Ensure pending bytes in ring are read */ |
| 163 | while (true) { | 152 | for (;;) { |
| 164 | aread = 0; | 153 | u32 aread = 0; |
| 154 | |||
| 165 | for (i = 0; i < nvdev->num_chn; i++) { | 155 | for (i = 0; i < nvdev->num_chn; i++) { |
| 166 | chn = nvdev->chan_table[i].channel; | 156 | struct vmbus_channel *chn |
| 157 | = nvdev->chan_table[i].channel; | ||
| 158 | |||
| 167 | if (!chn) | 159 | if (!chn) |
| 168 | continue; | 160 | continue; |
| 169 | 161 | ||
| 162 | /* make sure receive not running now */ | ||
| 163 | napi_synchronize(&nvdev->chan_table[i].napi); | ||
| 164 | |||
| 170 | aread = hv_get_bytes_to_read(&chn->inbound); | 165 | aread = hv_get_bytes_to_read(&chn->inbound); |
| 171 | if (aread) | 166 | if (aread) |
| 172 | break; | 167 | break; |
| @@ -176,22 +171,40 @@ static int netvsc_close(struct net_device *net) | |||
| 176 | break; | 171 | break; |
| 177 | } | 172 | } |
| 178 | 173 | ||
| 179 | retry++; | 174 | if (aread == 0) |
| 180 | if (retry > retry_max || aread == 0) | 175 | return 0; |
| 181 | break; | ||
| 182 | 176 | ||
| 183 | msleep(msec); | 177 | if (++retry > RETRY_MAX) |
| 178 | return -ETIMEDOUT; | ||
| 184 | 179 | ||
| 185 | if (msec < 1000) | 180 | usleep_range(RETRY_US_LO, RETRY_US_HI); |
| 186 | msec *= 2; | ||
| 187 | } | 181 | } |
| 182 | } | ||
| 188 | 183 | ||
| 189 | if (aread) { | 184 | static int netvsc_close(struct net_device *net) |
| 190 | netdev_err(net, "Ring buffer not empty after closing rndis\n"); | 185 | { |
| 191 | ret = -ETIMEDOUT; | 186 | struct net_device_context *net_device_ctx = netdev_priv(net); |
| 187 | struct net_device *vf_netdev | ||
| 188 | = rtnl_dereference(net_device_ctx->vf_netdev); | ||
| 189 | struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | netif_tx_disable(net); | ||
| 193 | |||
| 194 | /* No need to close rndis filter if it is removed already */ | ||
| 195 | if (!nvdev) | ||
| 196 | return 0; | ||
| 197 | |||
| 198 | ret = rndis_filter_close(nvdev); | ||
| 199 | if (ret != 0) { | ||
| 200 | netdev_err(net, "unable to close device (ret %d).\n", ret); | ||
| 201 | return ret; | ||
| 192 | } | 202 | } |
| 193 | 203 | ||
| 194 | out: | 204 | ret = netvsc_wait_until_empty(nvdev); |
| 205 | if (ret) | ||
| 206 | netdev_err(net, "Ring buffer not empty after closing rndis\n"); | ||
| 207 | |||
| 195 | if (vf_netdev) | 208 | if (vf_netdev) |
| 196 | dev_close(vf_netdev); | 209 | dev_close(vf_netdev); |
| 197 | 210 | ||
| @@ -840,16 +853,81 @@ static void netvsc_get_channels(struct net_device *net, | |||
| 840 | } | 853 | } |
| 841 | } | 854 | } |
| 842 | 855 | ||
| 856 | static int netvsc_detach(struct net_device *ndev, | ||
| 857 | struct netvsc_device *nvdev) | ||
| 858 | { | ||
| 859 | struct net_device_context *ndev_ctx = netdev_priv(ndev); | ||
| 860 | struct hv_device *hdev = ndev_ctx->device_ctx; | ||
| 861 | int ret; | ||
| 862 | |||
| 863 | /* Don't try continuing to try and setup sub channels */ | ||
| 864 | if (cancel_work_sync(&nvdev->subchan_work)) | ||
| 865 | nvdev->num_chn = 1; | ||
| 866 | |||
| 867 | /* If device was up (receiving) then shutdown */ | ||
| 868 | if (netif_running(ndev)) { | ||
| 869 | netif_tx_disable(ndev); | ||
| 870 | |||
| 871 | ret = rndis_filter_close(nvdev); | ||
| 872 | if (ret) { | ||
| 873 | netdev_err(ndev, | ||
| 874 | "unable to close device (ret %d).\n", ret); | ||
| 875 | return ret; | ||
| 876 | } | ||
| 877 | |||
| 878 | ret = netvsc_wait_until_empty(nvdev); | ||
| 879 | if (ret) { | ||
| 880 | netdev_err(ndev, | ||
| 881 | "Ring buffer not empty after closing rndis\n"); | ||
| 882 | return ret; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | netif_device_detach(ndev); | ||
| 887 | |||
| 888 | rndis_filter_device_remove(hdev, nvdev); | ||
| 889 | |||
| 890 | return 0; | ||
| 891 | } | ||
| 892 | |||
| 893 | static int netvsc_attach(struct net_device *ndev, | ||
| 894 | struct netvsc_device_info *dev_info) | ||
| 895 | { | ||
| 896 | struct net_device_context *ndev_ctx = netdev_priv(ndev); | ||
| 897 | struct hv_device *hdev = ndev_ctx->device_ctx; | ||
| 898 | struct netvsc_device *nvdev; | ||
| 899 | struct rndis_device *rdev; | ||
| 900 | int ret; | ||
| 901 | |||
| 902 | nvdev = rndis_filter_device_add(hdev, dev_info); | ||
| 903 | if (IS_ERR(nvdev)) | ||
| 904 | return PTR_ERR(nvdev); | ||
| 905 | |||
| 906 | /* Note: enable and attach happen when sub-channels setup */ | ||
| 907 | |||
| 908 | netif_carrier_off(ndev); | ||
| 909 | |||
| 910 | if (netif_running(ndev)) { | ||
| 911 | ret = rndis_filter_open(nvdev); | ||
| 912 | if (ret) | ||
| 913 | return ret; | ||
| 914 | |||
| 915 | rdev = nvdev->extension; | ||
| 916 | if (!rdev->link_state) | ||
| 917 | netif_carrier_on(ndev); | ||
| 918 | } | ||
| 919 | |||
| 920 | return 0; | ||
| 921 | } | ||
| 922 | |||
| 843 | static int netvsc_set_channels(struct net_device *net, | 923 | static int netvsc_set_channels(struct net_device *net, |
| 844 | struct ethtool_channels *channels) | 924 | struct ethtool_channels *channels) |
| 845 | { | 925 | { |
| 846 | struct net_device_context *net_device_ctx = netdev_priv(net); | 926 | struct net_device_context *net_device_ctx = netdev_priv(net); |
| 847 | struct hv_device *dev = net_device_ctx->device_ctx; | ||
| 848 | struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); | 927 | struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); |
| 849 | unsigned int orig, count = channels->combined_count; | 928 | unsigned int orig, count = channels->combined_count; |
| 850 | struct netvsc_device_info device_info; | 929 | struct netvsc_device_info device_info; |
| 851 | bool was_opened; | 930 | int ret; |
| 852 | int ret = 0; | ||
| 853 | 931 | ||
| 854 | /* We do not support separate count for rx, tx, or other */ | 932 | /* We do not support separate count for rx, tx, or other */ |
| 855 | if (count == 0 || | 933 | if (count == 0 || |
| @@ -866,9 +944,6 @@ static int netvsc_set_channels(struct net_device *net, | |||
| 866 | return -EINVAL; | 944 | return -EINVAL; |
| 867 | 945 | ||
| 868 | orig = nvdev->num_chn; | 946 | orig = nvdev->num_chn; |
| 869 | was_opened = rndis_filter_opened(nvdev); | ||
| 870 | if (was_opened) | ||
| 871 | rndis_filter_close(nvdev); | ||
| 872 | 947 | ||
| 873 | memset(&device_info, 0, sizeof(device_info)); | 948 | memset(&device_info, 0, sizeof(device_info)); |
| 874 | device_info.num_chn = count; | 949 | device_info.num_chn = count; |
| @@ -877,28 +952,17 @@ static int netvsc_set_channels(struct net_device *net, | |||
| 877 | device_info.recv_sections = nvdev->recv_section_cnt; | 952 | device_info.recv_sections = nvdev->recv_section_cnt; |
| 878 | device_info.recv_section_size = nvdev->recv_section_size; | 953 | device_info.recv_section_size = nvdev->recv_section_size; |
| 879 | 954 | ||
| 880 | rndis_filter_device_remove(dev, nvdev); | 955 | ret = netvsc_detach(net, nvdev); |
| 956 | if (ret) | ||
| 957 | return ret; | ||
| 881 | 958 | ||
| 882 | nvdev = rndis_filter_device_add(dev, &device_info); | 959 | ret = netvsc_attach(net, &device_info); |
| 883 | if (IS_ERR(nvdev)) { | 960 | if (ret) { |
| 884 | ret = PTR_ERR(nvdev); | ||
| 885 | device_info.num_chn = orig; | 961 | device_info.num_chn = orig; |
| 886 | nvdev = rndis_filter_device_add(dev, &device_info); | 962 | if (netvsc_attach(net, &device_info)) |
| 887 | 963 | netdev_err(net, "restoring channel setting failed\n"); | |
| 888 | if (IS_ERR(nvdev)) { | ||
| 889 | netdev_err(net, "restoring channel setting failed: %ld\n", | ||
| 890 | PTR_ERR(nvdev)); | ||
| 891 | return ret; | ||
| 892 | } | ||
| 893 | } | 964 | } |
| 894 | 965 | ||
| 895 | if (was_opened) | ||
| 896 | rndis_filter_open(nvdev); | ||
| 897 | |||
| 898 | /* We may have missed link change notifications */ | ||
| 899 | net_device_ctx->last_reconfig = 0; | ||
| 900 | schedule_delayed_work(&net_device_ctx->dwork, 0); | ||
| 901 | |||
| 902 | return ret; | 966 | return ret; |
| 903 | } | 967 | } |
| 904 | 968 | ||
| @@ -964,10 +1028,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
| 964 | struct net_device_context *ndevctx = netdev_priv(ndev); | 1028 | struct net_device_context *ndevctx = netdev_priv(ndev); |
| 965 | struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev); | 1029 | struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev); |
| 966 | struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); | 1030 | struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); |
| 967 | struct hv_device *hdev = ndevctx->device_ctx; | ||
| 968 | int orig_mtu = ndev->mtu; | 1031 | int orig_mtu = ndev->mtu; |
| 969 | struct netvsc_device_info device_info; | 1032 | struct netvsc_device_info device_info; |
| 970 | bool was_opened; | ||
| 971 | int ret = 0; | 1033 | int ret = 0; |
| 972 | 1034 | ||
| 973 | if (!nvdev || nvdev->destroy) | 1035 | if (!nvdev || nvdev->destroy) |
| @@ -980,11 +1042,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
| 980 | return ret; | 1042 | return ret; |
| 981 | } | 1043 | } |
| 982 | 1044 | ||
| 983 | netif_device_detach(ndev); | ||
| 984 | was_opened = rndis_filter_opened(nvdev); | ||
| 985 | if (was_opened) | ||
| 986 | rndis_filter_close(nvdev); | ||
| 987 | |||
| 988 | memset(&device_info, 0, sizeof(device_info)); | 1045 | memset(&device_info, 0, sizeof(device_info)); |
| 989 | device_info.num_chn = nvdev->num_chn; | 1046 | device_info.num_chn = nvdev->num_chn; |
| 990 | device_info.send_sections = nvdev->send_section_cnt; | 1047 | device_info.send_sections = nvdev->send_section_cnt; |
| @@ -992,35 +1049,27 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
| 992 | device_info.recv_sections = nvdev->recv_section_cnt; | 1049 | device_info.recv_sections = nvdev->recv_section_cnt; |
| 993 | device_info.recv_section_size = nvdev->recv_section_size; | 1050 | device_info.recv_section_size = nvdev->recv_section_size; |
| 994 | 1051 | ||
| 995 | rndis_filter_device_remove(hdev, nvdev); | 1052 | ret = netvsc_detach(ndev, nvdev); |
| 1053 | if (ret) | ||
| 1054 | goto rollback_vf; | ||
| 996 | 1055 | ||
| 997 | ndev->mtu = mtu; | 1056 | ndev->mtu = mtu; |
| 998 | 1057 | ||
| 999 | nvdev = rndis_filter_device_add(hdev, &device_info); | 1058 | ret = netvsc_attach(ndev, &device_info); |
| 1000 | if (IS_ERR(nvdev)) { | 1059 | if (ret) |
| 1001 | ret = PTR_ERR(nvdev); | 1060 | goto rollback; |
| 1002 | |||
| 1003 | /* Attempt rollback to original MTU */ | ||
| 1004 | ndev->mtu = orig_mtu; | ||
| 1005 | nvdev = rndis_filter_device_add(hdev, &device_info); | ||
| 1006 | |||
| 1007 | if (vf_netdev) | ||
| 1008 | dev_set_mtu(vf_netdev, orig_mtu); | ||
| 1009 | |||
| 1010 | if (IS_ERR(nvdev)) { | ||
| 1011 | netdev_err(ndev, "restoring mtu failed: %ld\n", | ||
| 1012 | PTR_ERR(nvdev)); | ||
| 1013 | return ret; | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | 1061 | ||
| 1017 | if (was_opened) | 1062 | return 0; |
| 1018 | rndis_filter_open(nvdev); | ||
| 1019 | 1063 | ||
| 1020 | netif_device_attach(ndev); | 1064 | rollback: |
| 1065 | /* Attempt rollback to original MTU */ | ||
| 1066 | ndev->mtu = orig_mtu; | ||
| 1021 | 1067 | ||
| 1022 | /* We may have missed link change notifications */ | 1068 | if (netvsc_attach(ndev, &device_info)) |
| 1023 | schedule_delayed_work(&ndevctx->dwork, 0); | 1069 | netdev_err(ndev, "restoring mtu failed\n"); |
| 1070 | rollback_vf: | ||
| 1071 | if (vf_netdev) | ||
| 1072 | dev_set_mtu(vf_netdev, orig_mtu); | ||
| 1024 | 1073 | ||
| 1025 | return ret; | 1074 | return ret; |
| 1026 | } | 1075 | } |
| @@ -1526,11 +1575,9 @@ static int netvsc_set_ringparam(struct net_device *ndev, | |||
| 1526 | { | 1575 | { |
| 1527 | struct net_device_context *ndevctx = netdev_priv(ndev); | 1576 | struct net_device_context *ndevctx = netdev_priv(ndev); |
| 1528 | struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); | 1577 | struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); |
| 1529 | struct hv_device *hdev = ndevctx->device_ctx; | ||
| 1530 | struct netvsc_device_info device_info; | 1578 | struct netvsc_device_info device_info; |
| 1531 | struct ethtool_ringparam orig; | 1579 | struct ethtool_ringparam orig; |
| 1532 | u32 new_tx, new_rx; | 1580 | u32 new_tx, new_rx; |
| 1533 | bool was_opened; | ||
| 1534 | int ret = 0; | 1581 | int ret = 0; |
| 1535 | 1582 | ||
| 1536 | if (!nvdev || nvdev->destroy) | 1583 | if (!nvdev || nvdev->destroy) |
| @@ -1555,34 +1602,18 @@ static int netvsc_set_ringparam(struct net_device *ndev, | |||
| 1555 | device_info.recv_sections = new_rx; | 1602 | device_info.recv_sections = new_rx; |
| 1556 | device_info.recv_section_size = nvdev->recv_section_size; | 1603 | device_info.recv_section_size = nvdev->recv_section_size; |
| 1557 | 1604 | ||
| 1558 | netif_device_detach(ndev); | 1605 | ret = netvsc_detach(ndev, nvdev); |
| 1559 | was_opened = rndis_filter_opened(nvdev); | 1606 | if (ret) |
| 1560 | if (was_opened) | 1607 | return ret; |
| 1561 | rndis_filter_close(nvdev); | ||
| 1562 | |||
| 1563 | rndis_filter_device_remove(hdev, nvdev); | ||
| 1564 | |||
| 1565 | nvdev = rndis_filter_device_add(hdev, &device_info); | ||
| 1566 | if (IS_ERR(nvdev)) { | ||
| 1567 | ret = PTR_ERR(nvdev); | ||
| 1568 | 1608 | ||
| 1609 | ret = netvsc_attach(ndev, &device_info); | ||
| 1610 | if (ret) { | ||
| 1569 | device_info.send_sections = orig.tx_pending; | 1611 | device_info.send_sections = orig.tx_pending; |
| 1570 | device_info.recv_sections = orig.rx_pending; | 1612 | device_info.recv_sections = orig.rx_pending; |
| 1571 | nvdev = rndis_filter_device_add(hdev, &device_info); | ||
| 1572 | if (IS_ERR(nvdev)) { | ||
| 1573 | netdev_err(ndev, "restoring ringparam failed: %ld\n", | ||
| 1574 | PTR_ERR(nvdev)); | ||
| 1575 | return ret; | ||
| 1576 | } | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | if (was_opened) | ||
| 1580 | rndis_filter_open(nvdev); | ||
| 1581 | netif_device_attach(ndev); | ||
| 1582 | 1613 | ||
| 1583 | /* We may have missed link change notifications */ | 1614 | if (netvsc_attach(ndev, &device_info)) |
| 1584 | ndevctx->last_reconfig = 0; | 1615 | netdev_err(ndev, "restoring ringparam failed"); |
| 1585 | schedule_delayed_work(&ndevctx->dwork, 0); | 1616 | } |
| 1586 | 1617 | ||
| 1587 | return ret; | 1618 | return ret; |
| 1588 | } | 1619 | } |
| @@ -1846,8 +1877,12 @@ static void __netvsc_vf_setup(struct net_device *ndev, | |||
| 1846 | 1877 | ||
| 1847 | /* set multicast etc flags on VF */ | 1878 | /* set multicast etc flags on VF */ |
| 1848 | dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE); | 1879 | dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE); |
| 1880 | |||
| 1881 | /* sync address list from ndev to VF */ | ||
| 1882 | netif_addr_lock_bh(ndev); | ||
| 1849 | dev_uc_sync(vf_netdev, ndev); | 1883 | dev_uc_sync(vf_netdev, ndev); |
| 1850 | dev_mc_sync(vf_netdev, ndev); | 1884 | dev_mc_sync(vf_netdev, ndev); |
| 1885 | netif_addr_unlock_bh(ndev); | ||
| 1851 | 1886 | ||
| 1852 | if (netif_running(ndev)) { | 1887 | if (netif_running(ndev)) { |
| 1853 | ret = dev_open(vf_netdev); | 1888 | ret = dev_open(vf_netdev); |
| @@ -2063,8 +2098,8 @@ no_net: | |||
| 2063 | static int netvsc_remove(struct hv_device *dev) | 2098 | static int netvsc_remove(struct hv_device *dev) |
| 2064 | { | 2099 | { |
| 2065 | struct net_device_context *ndev_ctx; | 2100 | struct net_device_context *ndev_ctx; |
| 2066 | struct net_device *vf_netdev; | 2101 | struct net_device *vf_netdev, *net; |
| 2067 | struct net_device *net; | 2102 | struct netvsc_device *nvdev; |
| 2068 | 2103 | ||
| 2069 | net = hv_get_drvdata(dev); | 2104 | net = hv_get_drvdata(dev); |
| 2070 | if (net == NULL) { | 2105 | if (net == NULL) { |
| @@ -2074,10 +2109,14 @@ static int netvsc_remove(struct hv_device *dev) | |||
| 2074 | 2109 | ||
| 2075 | ndev_ctx = netdev_priv(net); | 2110 | ndev_ctx = netdev_priv(net); |
| 2076 | 2111 | ||
| 2077 | netif_device_detach(net); | ||
| 2078 | |||
| 2079 | cancel_delayed_work_sync(&ndev_ctx->dwork); | 2112 | cancel_delayed_work_sync(&ndev_ctx->dwork); |
| 2080 | 2113 | ||
| 2114 | rcu_read_lock(); | ||
| 2115 | nvdev = rcu_dereference(ndev_ctx->nvdev); | ||
| 2116 | |||
| 2117 | if (nvdev) | ||
| 2118 | cancel_work_sync(&nvdev->subchan_work); | ||
| 2119 | |||
| 2081 | /* | 2120 | /* |
| 2082 | * Call to the vsc driver to let it know that the device is being | 2121 | * Call to the vsc driver to let it know that the device is being |
| 2083 | * removed. Also blocks mtu and channel changes. | 2122 | * removed. Also blocks mtu and channel changes. |
| @@ -2087,11 +2126,13 @@ static int netvsc_remove(struct hv_device *dev) | |||
| 2087 | if (vf_netdev) | 2126 | if (vf_netdev) |
| 2088 | netvsc_unregister_vf(vf_netdev); | 2127 | netvsc_unregister_vf(vf_netdev); |
| 2089 | 2128 | ||
| 2129 | if (nvdev) | ||
| 2130 | rndis_filter_device_remove(dev, nvdev); | ||
| 2131 | |||
| 2090 | unregister_netdevice(net); | 2132 | unregister_netdevice(net); |
| 2091 | 2133 | ||
| 2092 | rndis_filter_device_remove(dev, | ||
| 2093 | rtnl_dereference(ndev_ctx->nvdev)); | ||
| 2094 | rtnl_unlock(); | 2134 | rtnl_unlock(); |
| 2135 | rcu_read_unlock(); | ||
| 2095 | 2136 | ||
| 2096 | hv_set_drvdata(dev, NULL); | 2137 | hv_set_drvdata(dev, NULL); |
| 2097 | 2138 | ||
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 8927c483c217..a6ec41c399d6 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
| @@ -264,13 +264,23 @@ static void rndis_set_link_state(struct rndis_device *rdev, | |||
| 264 | } | 264 | } |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | static void rndis_filter_receive_response(struct rndis_device *dev, | 267 | static void rndis_filter_receive_response(struct net_device *ndev, |
| 268 | struct rndis_message *resp) | 268 | struct netvsc_device *nvdev, |
| 269 | const struct rndis_message *resp) | ||
| 269 | { | 270 | { |
| 271 | struct rndis_device *dev = nvdev->extension; | ||
| 270 | struct rndis_request *request = NULL; | 272 | struct rndis_request *request = NULL; |
| 271 | bool found = false; | 273 | bool found = false; |
| 272 | unsigned long flags; | 274 | unsigned long flags; |
| 273 | struct net_device *ndev = dev->ndev; | 275 | |
| 276 | /* This should never happen, it means control message | ||
| 277 | * response received after device removed. | ||
| 278 | */ | ||
| 279 | if (dev->state == RNDIS_DEV_UNINITIALIZED) { | ||
| 280 | netdev_err(ndev, | ||
| 281 | "got rndis message uninitialized\n"); | ||
| 282 | return; | ||
| 283 | } | ||
| 274 | 284 | ||
| 275 | spin_lock_irqsave(&dev->request_lock, flags); | 285 | spin_lock_irqsave(&dev->request_lock, flags); |
| 276 | list_for_each_entry(request, &dev->req_list, list_ent) { | 286 | list_for_each_entry(request, &dev->req_list, list_ent) { |
| @@ -352,7 +362,6 @@ static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type) | |||
| 352 | 362 | ||
| 353 | static int rndis_filter_receive_data(struct net_device *ndev, | 363 | static int rndis_filter_receive_data(struct net_device *ndev, |
| 354 | struct netvsc_device *nvdev, | 364 | struct netvsc_device *nvdev, |
| 355 | struct rndis_device *dev, | ||
| 356 | struct rndis_message *msg, | 365 | struct rndis_message *msg, |
| 357 | struct vmbus_channel *channel, | 366 | struct vmbus_channel *channel, |
| 358 | void *data, u32 data_buflen) | 367 | void *data, u32 data_buflen) |
| @@ -372,7 +381,7 @@ static int rndis_filter_receive_data(struct net_device *ndev, | |||
| 372 | * should be the data packet size plus the trailer padding size | 381 | * should be the data packet size plus the trailer padding size |
| 373 | */ | 382 | */ |
| 374 | if (unlikely(data_buflen < rndis_pkt->data_len)) { | 383 | if (unlikely(data_buflen < rndis_pkt->data_len)) { |
| 375 | netdev_err(dev->ndev, "rndis message buffer " | 384 | netdev_err(ndev, "rndis message buffer " |
| 376 | "overflow detected (got %u, min %u)" | 385 | "overflow detected (got %u, min %u)" |
| 377 | "...dropping this message!\n", | 386 | "...dropping this message!\n", |
| 378 | data_buflen, rndis_pkt->data_len); | 387 | data_buflen, rndis_pkt->data_len); |
| @@ -400,35 +409,20 @@ int rndis_filter_receive(struct net_device *ndev, | |||
| 400 | void *data, u32 buflen) | 409 | void *data, u32 buflen) |
| 401 | { | 410 | { |
| 402 | struct net_device_context *net_device_ctx = netdev_priv(ndev); | 411 | struct net_device_context *net_device_ctx = netdev_priv(ndev); |
| 403 | struct rndis_device *rndis_dev = net_dev->extension; | ||
| 404 | struct rndis_message *rndis_msg = data; | 412 | struct rndis_message *rndis_msg = data; |
| 405 | 413 | ||
| 406 | /* Make sure the rndis device state is initialized */ | ||
| 407 | if (unlikely(!rndis_dev)) { | ||
| 408 | netif_dbg(net_device_ctx, rx_err, ndev, | ||
| 409 | "got rndis message but no rndis device!\n"); | ||
| 410 | return NVSP_STAT_FAIL; | ||
| 411 | } | ||
| 412 | |||
| 413 | if (unlikely(rndis_dev->state == RNDIS_DEV_UNINITIALIZED)) { | ||
| 414 | netif_dbg(net_device_ctx, rx_err, ndev, | ||
| 415 | "got rndis message uninitialized\n"); | ||
| 416 | return NVSP_STAT_FAIL; | ||
| 417 | } | ||
| 418 | |||
| 419 | if (netif_msg_rx_status(net_device_ctx)) | 414 | if (netif_msg_rx_status(net_device_ctx)) |
| 420 | dump_rndis_message(ndev, rndis_msg); | 415 | dump_rndis_message(ndev, rndis_msg); |
| 421 | 416 | ||
| 422 | switch (rndis_msg->ndis_msg_type) { | 417 | switch (rndis_msg->ndis_msg_type) { |
| 423 | case RNDIS_MSG_PACKET: | 418 | case RNDIS_MSG_PACKET: |
| 424 | return rndis_filter_receive_data(ndev, net_dev, | 419 | return rndis_filter_receive_data(ndev, net_dev, rndis_msg, |
| 425 | rndis_dev, rndis_msg, | ||
| 426 | channel, data, buflen); | 420 | channel, data, buflen); |
| 427 | case RNDIS_MSG_INIT_C: | 421 | case RNDIS_MSG_INIT_C: |
| 428 | case RNDIS_MSG_QUERY_C: | 422 | case RNDIS_MSG_QUERY_C: |
| 429 | case RNDIS_MSG_SET_C: | 423 | case RNDIS_MSG_SET_C: |
| 430 | /* completion msgs */ | 424 | /* completion msgs */ |
| 431 | rndis_filter_receive_response(rndis_dev, rndis_msg); | 425 | rndis_filter_receive_response(ndev, net_dev, rndis_msg); |
| 432 | break; | 426 | break; |
| 433 | 427 | ||
| 434 | case RNDIS_MSG_INDICATE: | 428 | case RNDIS_MSG_INDICATE: |
| @@ -825,13 +819,15 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, | |||
| 825 | struct rndis_set_request *set; | 819 | struct rndis_set_request *set; |
| 826 | int ret; | 820 | int ret; |
| 827 | 821 | ||
| 822 | if (dev->filter == new_filter) | ||
| 823 | return 0; | ||
| 824 | |||
| 828 | request = get_rndis_request(dev, RNDIS_MSG_SET, | 825 | request = get_rndis_request(dev, RNDIS_MSG_SET, |
| 829 | RNDIS_MESSAGE_SIZE(struct rndis_set_request) + | 826 | RNDIS_MESSAGE_SIZE(struct rndis_set_request) + |
| 830 | sizeof(u32)); | 827 | sizeof(u32)); |
| 831 | if (!request) | 828 | if (!request) |
| 832 | return -ENOMEM; | 829 | return -ENOMEM; |
| 833 | 830 | ||
| 834 | |||
| 835 | /* Setup the rndis set */ | 831 | /* Setup the rndis set */ |
| 836 | set = &request->request_msg.msg.set_req; | 832 | set = &request->request_msg.msg.set_req; |
| 837 | set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; | 833 | set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; |
| @@ -842,8 +838,10 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, | |||
| 842 | &new_filter, sizeof(u32)); | 838 | &new_filter, sizeof(u32)); |
| 843 | 839 | ||
| 844 | ret = rndis_filter_send_request(dev, request); | 840 | ret = rndis_filter_send_request(dev, request); |
| 845 | if (ret == 0) | 841 | if (ret == 0) { |
| 846 | wait_for_completion(&request->wait_event); | 842 | wait_for_completion(&request->wait_event); |
| 843 | dev->filter = new_filter; | ||
| 844 | } | ||
| 847 | 845 | ||
| 848 | put_rndis_request(dev, request); | 846 | put_rndis_request(dev, request); |
| 849 | 847 | ||
| @@ -861,9 +859,9 @@ static void rndis_set_multicast(struct work_struct *w) | |||
| 861 | filter = NDIS_PACKET_TYPE_PROMISCUOUS; | 859 | filter = NDIS_PACKET_TYPE_PROMISCUOUS; |
| 862 | } else { | 860 | } else { |
| 863 | if (flags & IFF_ALLMULTI) | 861 | if (flags & IFF_ALLMULTI) |
| 864 | flags |= NDIS_PACKET_TYPE_ALL_MULTICAST; | 862 | filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; |
| 865 | if (flags & IFF_BROADCAST) | 863 | if (flags & IFF_BROADCAST) |
| 866 | flags |= NDIS_PACKET_TYPE_BROADCAST; | 864 | filter |= NDIS_PACKET_TYPE_BROADCAST; |
| 867 | } | 865 | } |
| 868 | 866 | ||
| 869 | rndis_filter_set_packet_filter(rdev, filter); | 867 | rndis_filter_set_packet_filter(rdev, filter); |
| @@ -1120,6 +1118,7 @@ void rndis_set_subchannel(struct work_struct *w) | |||
| 1120 | for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) | 1118 | for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) |
| 1121 | ndev_ctx->tx_table[i] = i % nvdev->num_chn; | 1119 | ndev_ctx->tx_table[i] = i % nvdev->num_chn; |
| 1122 | 1120 | ||
| 1121 | netif_device_attach(ndev); | ||
| 1123 | rtnl_unlock(); | 1122 | rtnl_unlock(); |
| 1124 | return; | 1123 | return; |
| 1125 | 1124 | ||
| @@ -1130,6 +1129,8 @@ failed: | |||
| 1130 | 1129 | ||
| 1131 | nvdev->max_chn = 1; | 1130 | nvdev->max_chn = 1; |
| 1132 | nvdev->num_chn = 1; | 1131 | nvdev->num_chn = 1; |
| 1132 | |||
| 1133 | netif_device_attach(ndev); | ||
| 1133 | unlock: | 1134 | unlock: |
| 1134 | rtnl_unlock(); | 1135 | rtnl_unlock(); |
| 1135 | } | 1136 | } |
| @@ -1332,6 +1333,10 @@ out: | |||
| 1332 | net_device->num_chn = 1; | 1333 | net_device->num_chn = 1; |
| 1333 | } | 1334 | } |
| 1334 | 1335 | ||
| 1336 | /* No sub channels, device is ready */ | ||
| 1337 | if (net_device->num_chn == 1) | ||
| 1338 | netif_device_attach(net); | ||
| 1339 | |||
| 1335 | return net_device; | 1340 | return net_device; |
| 1336 | 1341 | ||
| 1337 | err_dev_remv: | 1342 | err_dev_remv: |
| @@ -1344,16 +1349,12 @@ void rndis_filter_device_remove(struct hv_device *dev, | |||
| 1344 | { | 1349 | { |
| 1345 | struct rndis_device *rndis_dev = net_dev->extension; | 1350 | struct rndis_device *rndis_dev = net_dev->extension; |
| 1346 | 1351 | ||
| 1347 | /* Don't try and setup sub channels if about to halt */ | ||
| 1348 | cancel_work_sync(&net_dev->subchan_work); | ||
| 1349 | |||
| 1350 | /* Halt and release the rndis device */ | 1352 | /* Halt and release the rndis device */ |
| 1351 | rndis_filter_halt_device(rndis_dev); | 1353 | rndis_filter_halt_device(rndis_dev); |
| 1352 | 1354 | ||
| 1353 | net_dev->extension = NULL; | 1355 | net_dev->extension = NULL; |
| 1354 | 1356 | ||
| 1355 | netvsc_device_remove(dev); | 1357 | netvsc_device_remove(dev); |
| 1356 | kfree(rndis_dev); | ||
| 1357 | } | 1358 | } |
| 1358 | 1359 | ||
| 1359 | int rndis_filter_open(struct netvsc_device *nvdev) | 1360 | int rndis_filter_open(struct netvsc_device *nvdev) |
| @@ -1371,10 +1372,3 @@ int rndis_filter_close(struct netvsc_device *nvdev) | |||
| 1371 | 1372 | ||
| 1372 | return rndis_filter_close_device(nvdev->extension); | 1373 | return rndis_filter_close_device(nvdev->extension); |
| 1373 | } | 1374 | } |
| 1374 | |||
| 1375 | bool rndis_filter_opened(const struct netvsc_device *nvdev) | ||
| 1376 | { | ||
| 1377 | const struct rndis_device *dev = nvdev->extension; | ||
| 1378 | |||
| 1379 | return dev->state == RNDIS_DEV_DATAINITIALIZED; | ||
| 1380 | } | ||
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 7de88b33d5b9..9cbb0c8a896a 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
| @@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev, | |||
| 3277 | 3277 | ||
| 3278 | err = netdev_upper_dev_link(real_dev, dev, extack); | 3278 | err = netdev_upper_dev_link(real_dev, dev, extack); |
| 3279 | if (err < 0) | 3279 | if (err < 0) |
| 3280 | goto unregister; | 3280 | goto put_dev; |
| 3281 | 3281 | ||
| 3282 | /* need to be already registered so that ->init has run and | 3282 | /* need to be already registered so that ->init has run and |
| 3283 | * the MAC addr is set | 3283 | * the MAC addr is set |
| @@ -3316,7 +3316,8 @@ del_dev: | |||
| 3316 | macsec_del_dev(macsec); | 3316 | macsec_del_dev(macsec); |
| 3317 | unlink: | 3317 | unlink: |
| 3318 | netdev_upper_dev_unlink(real_dev, dev); | 3318 | netdev_upper_dev_unlink(real_dev, dev); |
| 3319 | unregister: | 3319 | put_dev: |
| 3320 | dev_put(real_dev); | ||
| 3320 | unregister_netdevice(dev); | 3321 | unregister_netdevice(dev); |
| 3321 | return err; | 3322 | return err; |
| 3322 | } | 3323 | } |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 8fc02d9db3d0..725f4b4afc6d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
| @@ -1036,7 +1036,7 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev, | |||
| 1036 | lowerdev_features &= (features | ~NETIF_F_LRO); | 1036 | lowerdev_features &= (features | ~NETIF_F_LRO); |
| 1037 | features = netdev_increment_features(lowerdev_features, features, mask); | 1037 | features = netdev_increment_features(lowerdev_features, features, mask); |
| 1038 | features |= ALWAYS_ON_FEATURES; | 1038 | features |= ALWAYS_ON_FEATURES; |
| 1039 | features &= ~NETIF_F_NETNS_LOCAL; | 1039 | features &= (ALWAYS_ON_FEATURES | MACVLAN_FEATURES); |
| 1040 | 1040 | ||
| 1041 | return features; | 1041 | return features; |
| 1042 | } | 1042 | } |
diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c index 171010eb4d9c..5ad130c3da43 100644 --- a/drivers/net/phy/bcm-phy-lib.c +++ b/drivers/net/phy/bcm-phy-lib.c | |||
| @@ -341,8 +341,8 @@ void bcm_phy_get_strings(struct phy_device *phydev, u8 *data) | |||
| 341 | unsigned int i; | 341 | unsigned int i; |
| 342 | 342 | ||
| 343 | for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++) | 343 | for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++) |
| 344 | memcpy(data + i * ETH_GSTRING_LEN, | 344 | strlcpy(data + i * ETH_GSTRING_LEN, |
| 345 | bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN); | 345 | bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN); |
| 346 | } | 346 | } |
| 347 | EXPORT_SYMBOL_GPL(bcm_phy_get_strings); | 347 | EXPORT_SYMBOL_GPL(bcm_phy_get_strings); |
| 348 | 348 | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 22d9bc9c33a4..0e0978d8a0eb 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
| @@ -1452,8 +1452,8 @@ static void marvell_get_strings(struct phy_device *phydev, u8 *data) | |||
| 1452 | int i; | 1452 | int i; |
| 1453 | 1453 | ||
| 1454 | for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { | 1454 | for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { |
| 1455 | memcpy(data + i * ETH_GSTRING_LEN, | 1455 | strlcpy(data + i * ETH_GSTRING_LEN, |
| 1456 | marvell_hw_stats[i].string, ETH_GSTRING_LEN); | 1456 | marvell_hw_stats[i].string, ETH_GSTRING_LEN); |
| 1457 | } | 1457 | } |
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 0f45310300f6..f41b224a9cdb 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -635,25 +635,6 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev) | |||
| 635 | return 0; | 635 | return 0; |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | /* This routine returns -1 as an indication to the caller that the | ||
| 639 | * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE | ||
| 640 | * MMD extended PHY registers. | ||
| 641 | */ | ||
| 642 | static int | ||
| 643 | ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum) | ||
| 644 | { | ||
| 645 | return -1; | ||
| 646 | } | ||
| 647 | |||
| 648 | /* This routine does nothing since the Micrel ksz9021 does not support | ||
| 649 | * standard IEEE MMD extended PHY registers. | ||
| 650 | */ | ||
| 651 | static int | ||
| 652 | ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum, u16 val) | ||
| 653 | { | ||
| 654 | return -1; | ||
| 655 | } | ||
| 656 | |||
| 657 | static int kszphy_get_sset_count(struct phy_device *phydev) | 638 | static int kszphy_get_sset_count(struct phy_device *phydev) |
| 658 | { | 639 | { |
| 659 | return ARRAY_SIZE(kszphy_hw_stats); | 640 | return ARRAY_SIZE(kszphy_hw_stats); |
| @@ -664,8 +645,8 @@ static void kszphy_get_strings(struct phy_device *phydev, u8 *data) | |||
| 664 | int i; | 645 | int i; |
| 665 | 646 | ||
| 666 | for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) { | 647 | for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) { |
| 667 | memcpy(data + i * ETH_GSTRING_LEN, | 648 | strlcpy(data + i * ETH_GSTRING_LEN, |
| 668 | kszphy_hw_stats[i].string, ETH_GSTRING_LEN); | 649 | kszphy_hw_stats[i].string, ETH_GSTRING_LEN); |
| 669 | } | 650 | } |
| 670 | } | 651 | } |
| 671 | 652 | ||
| @@ -946,8 +927,8 @@ static struct phy_driver ksphy_driver[] = { | |||
| 946 | .get_stats = kszphy_get_stats, | 927 | .get_stats = kszphy_get_stats, |
| 947 | .suspend = genphy_suspend, | 928 | .suspend = genphy_suspend, |
| 948 | .resume = genphy_resume, | 929 | .resume = genphy_resume, |
| 949 | .read_mmd = ksz9021_rd_mmd_phyreg, | 930 | .read_mmd = genphy_read_mmd_unsupported, |
| 950 | .write_mmd = ksz9021_wr_mmd_phyreg, | 931 | .write_mmd = genphy_write_mmd_unsupported, |
| 951 | }, { | 932 | }, { |
| 952 | .phy_id = PHY_ID_KSZ9031, | 933 | .phy_id = PHY_ID_KSZ9031, |
| 953 | .phy_id_mask = MICREL_PHY_ID_MASK, | 934 | .phy_id_mask = MICREL_PHY_ID_MASK, |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a6f924fee584..9aabfa1a455a 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -618,6 +618,77 @@ static void phy_error(struct phy_device *phydev) | |||
| 618 | } | 618 | } |
| 619 | 619 | ||
| 620 | /** | 620 | /** |
| 621 | * phy_disable_interrupts - Disable the PHY interrupts from the PHY side | ||
| 622 | * @phydev: target phy_device struct | ||
| 623 | */ | ||
| 624 | static int phy_disable_interrupts(struct phy_device *phydev) | ||
| 625 | { | ||
| 626 | int err; | ||
| 627 | |||
| 628 | /* Disable PHY interrupts */ | ||
| 629 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
| 630 | if (err) | ||
| 631 | goto phy_err; | ||
| 632 | |||
| 633 | /* Clear the interrupt */ | ||
| 634 | err = phy_clear_interrupt(phydev); | ||
| 635 | if (err) | ||
| 636 | goto phy_err; | ||
| 637 | |||
| 638 | return 0; | ||
| 639 | |||
| 640 | phy_err: | ||
| 641 | phy_error(phydev); | ||
| 642 | |||
| 643 | return err; | ||
| 644 | } | ||
| 645 | |||
| 646 | /** | ||
| 647 | * phy_change - Called by the phy_interrupt to handle PHY changes | ||
| 648 | * @phydev: phy_device struct that interrupted | ||
| 649 | */ | ||
| 650 | static irqreturn_t phy_change(struct phy_device *phydev) | ||
| 651 | { | ||
| 652 | if (phy_interrupt_is_valid(phydev)) { | ||
| 653 | if (phydev->drv->did_interrupt && | ||
| 654 | !phydev->drv->did_interrupt(phydev)) | ||
| 655 | return IRQ_NONE; | ||
| 656 | |||
| 657 | if (phydev->state == PHY_HALTED) | ||
| 658 | if (phy_disable_interrupts(phydev)) | ||
| 659 | goto phy_err; | ||
| 660 | } | ||
| 661 | |||
| 662 | mutex_lock(&phydev->lock); | ||
| 663 | if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) | ||
| 664 | phydev->state = PHY_CHANGELINK; | ||
| 665 | mutex_unlock(&phydev->lock); | ||
| 666 | |||
| 667 | /* reschedule state queue work to run as soon as possible */ | ||
| 668 | phy_trigger_machine(phydev, true); | ||
| 669 | |||
| 670 | if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev)) | ||
| 671 | goto phy_err; | ||
| 672 | return IRQ_HANDLED; | ||
| 673 | |||
| 674 | phy_err: | ||
| 675 | phy_error(phydev); | ||
| 676 | return IRQ_NONE; | ||
| 677 | } | ||
| 678 | |||
| 679 | /** | ||
| 680 | * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes | ||
| 681 | * @work: work_struct that describes the work to be done | ||
| 682 | */ | ||
| 683 | void phy_change_work(struct work_struct *work) | ||
| 684 | { | ||
| 685 | struct phy_device *phydev = | ||
| 686 | container_of(work, struct phy_device, phy_queue); | ||
| 687 | |||
| 688 | phy_change(phydev); | ||
| 689 | } | ||
| 690 | |||
| 691 | /** | ||
| 621 | * phy_interrupt - PHY interrupt handler | 692 | * phy_interrupt - PHY interrupt handler |
| 622 | * @irq: interrupt line | 693 | * @irq: interrupt line |
| 623 | * @phy_dat: phy_device pointer | 694 | * @phy_dat: phy_device pointer |
| @@ -632,9 +703,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat) | |||
| 632 | if (PHY_HALTED == phydev->state) | 703 | if (PHY_HALTED == phydev->state) |
| 633 | return IRQ_NONE; /* It can't be ours. */ | 704 | return IRQ_NONE; /* It can't be ours. */ |
| 634 | 705 | ||
| 635 | phy_change(phydev); | 706 | return phy_change(phydev); |
| 636 | |||
| 637 | return IRQ_HANDLED; | ||
| 638 | } | 707 | } |
| 639 | 708 | ||
| 640 | /** | 709 | /** |
| @@ -652,32 +721,6 @@ static int phy_enable_interrupts(struct phy_device *phydev) | |||
| 652 | } | 721 | } |
| 653 | 722 | ||
| 654 | /** | 723 | /** |
| 655 | * phy_disable_interrupts - Disable the PHY interrupts from the PHY side | ||
| 656 | * @phydev: target phy_device struct | ||
| 657 | */ | ||
| 658 | static int phy_disable_interrupts(struct phy_device *phydev) | ||
| 659 | { | ||
| 660 | int err; | ||
| 661 | |||
| 662 | /* Disable PHY interrupts */ | ||
| 663 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
| 664 | if (err) | ||
| 665 | goto phy_err; | ||
| 666 | |||
| 667 | /* Clear the interrupt */ | ||
| 668 | err = phy_clear_interrupt(phydev); | ||
| 669 | if (err) | ||
| 670 | goto phy_err; | ||
| 671 | |||
| 672 | return 0; | ||
| 673 | |||
| 674 | phy_err: | ||
| 675 | phy_error(phydev); | ||
| 676 | |||
| 677 | return err; | ||
| 678 | } | ||
| 679 | |||
| 680 | /** | ||
| 681 | * phy_start_interrupts - request and enable interrupts for a PHY device | 724 | * phy_start_interrupts - request and enable interrupts for a PHY device |
| 682 | * @phydev: target phy_device struct | 725 | * @phydev: target phy_device struct |
| 683 | * | 726 | * |
| @@ -720,50 +763,6 @@ int phy_stop_interrupts(struct phy_device *phydev) | |||
| 720 | EXPORT_SYMBOL(phy_stop_interrupts); | 763 | EXPORT_SYMBOL(phy_stop_interrupts); |
| 721 | 764 | ||
| 722 | /** | 765 | /** |
| 723 | * phy_change - Called by the phy_interrupt to handle PHY changes | ||
| 724 | * @phydev: phy_device struct that interrupted | ||
| 725 | */ | ||
| 726 | void phy_change(struct phy_device *phydev) | ||
| 727 | { | ||
| 728 | if (phy_interrupt_is_valid(phydev)) { | ||
| 729 | if (phydev->drv->did_interrupt && | ||
| 730 | !phydev->drv->did_interrupt(phydev)) | ||
| 731 | return; | ||
| 732 | |||
| 733 | if (phydev->state == PHY_HALTED) | ||
| 734 | if (phy_disable_interrupts(phydev)) | ||
| 735 | goto phy_err; | ||
| 736 | } | ||
| 737 | |||
| 738 | mutex_lock(&phydev->lock); | ||
| 739 | if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) | ||
| 740 | phydev->state = PHY_CHANGELINK; | ||
| 741 | mutex_unlock(&phydev->lock); | ||
| 742 | |||
| 743 | /* reschedule state queue work to run as soon as possible */ | ||
| 744 | phy_trigger_machine(phydev, true); | ||
| 745 | |||
| 746 | if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev)) | ||
| 747 | goto phy_err; | ||
| 748 | return; | ||
| 749 | |||
| 750 | phy_err: | ||
| 751 | phy_error(phydev); | ||
| 752 | } | ||
| 753 | |||
| 754 | /** | ||
| 755 | * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes | ||
| 756 | * @work: work_struct that describes the work to be done | ||
| 757 | */ | ||
| 758 | void phy_change_work(struct work_struct *work) | ||
| 759 | { | ||
| 760 | struct phy_device *phydev = | ||
| 761 | container_of(work, struct phy_device, phy_queue); | ||
| 762 | |||
| 763 | phy_change(phydev); | ||
| 764 | } | ||
| 765 | |||
| 766 | /** | ||
| 767 | * phy_stop - Bring down the PHY link, and stop checking the status | 766 | * phy_stop - Bring down the PHY link, and stop checking the status |
| 768 | * @phydev: target phy_device struct | 767 | * @phydev: target phy_device struct |
| 769 | */ | 768 | */ |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 478405e544cc..74664a6c0cdc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -1012,10 +1012,17 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
| 1012 | err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj, | 1012 | err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj, |
| 1013 | "attached_dev"); | 1013 | "attached_dev"); |
| 1014 | if (!err) { | 1014 | if (!err) { |
| 1015 | err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj, | 1015 | err = sysfs_create_link_nowarn(&dev->dev.kobj, |
| 1016 | "phydev"); | 1016 | &phydev->mdio.dev.kobj, |
| 1017 | if (err) | 1017 | "phydev"); |
| 1018 | goto error; | 1018 | if (err) { |
| 1019 | dev_err(&dev->dev, "could not add device link to %s err %d\n", | ||
| 1020 | kobject_name(&phydev->mdio.dev.kobj), | ||
| 1021 | err); | ||
| 1022 | /* non-fatal - some net drivers can use one netdevice | ||
| 1023 | * with more then one phy | ||
| 1024 | */ | ||
| 1025 | } | ||
| 1019 | 1026 | ||
| 1020 | phydev->sysfs_links = true; | 1027 | phydev->sysfs_links = true; |
| 1021 | } | 1028 | } |
| @@ -1666,6 +1673,23 @@ int genphy_config_init(struct phy_device *phydev) | |||
| 1666 | } | 1673 | } |
| 1667 | EXPORT_SYMBOL(genphy_config_init); | 1674 | EXPORT_SYMBOL(genphy_config_init); |
| 1668 | 1675 | ||
| 1676 | /* This is used for the phy device which doesn't support the MMD extended | ||
| 1677 | * register access, but it does have side effect when we are trying to access | ||
| 1678 | * the MMD register via indirect method. | ||
| 1679 | */ | ||
| 1680 | int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum) | ||
| 1681 | { | ||
| 1682 | return -EOPNOTSUPP; | ||
| 1683 | } | ||
| 1684 | EXPORT_SYMBOL(genphy_read_mmd_unsupported); | ||
| 1685 | |||
| 1686 | int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum, | ||
| 1687 | u16 regnum, u16 val) | ||
| 1688 | { | ||
| 1689 | return -EOPNOTSUPP; | ||
| 1690 | } | ||
| 1691 | EXPORT_SYMBOL(genphy_write_mmd_unsupported); | ||
| 1692 | |||
| 1669 | int genphy_suspend(struct phy_device *phydev) | 1693 | int genphy_suspend(struct phy_device *phydev) |
| 1670 | { | 1694 | { |
| 1671 | return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); | 1695 | return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); |
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index ee3ca4a2f12b..9f48ecf9c627 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c | |||
| @@ -172,6 +172,8 @@ static struct phy_driver realtek_drvs[] = { | |||
| 172 | .flags = PHY_HAS_INTERRUPT, | 172 | .flags = PHY_HAS_INTERRUPT, |
| 173 | .ack_interrupt = &rtl821x_ack_interrupt, | 173 | .ack_interrupt = &rtl821x_ack_interrupt, |
| 174 | .config_intr = &rtl8211b_config_intr, | 174 | .config_intr = &rtl8211b_config_intr, |
| 175 | .read_mmd = &genphy_read_mmd_unsupported, | ||
| 176 | .write_mmd = &genphy_write_mmd_unsupported, | ||
| 175 | }, { | 177 | }, { |
| 176 | .phy_id = 0x001cc914, | 178 | .phy_id = 0x001cc914, |
| 177 | .name = "RTL8211DN Gigabit Ethernet", | 179 | .name = "RTL8211DN Gigabit Ethernet", |
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index fa2a9bdd1866..da1937832c99 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
| @@ -257,7 +257,7 @@ struct ppp_net { | |||
| 257 | /* Prototypes. */ | 257 | /* Prototypes. */ |
| 258 | static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, | 258 | static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, |
| 259 | struct file *file, unsigned int cmd, unsigned long arg); | 259 | struct file *file, unsigned int cmd, unsigned long arg); |
| 260 | static void ppp_xmit_process(struct ppp *ppp); | 260 | static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb); |
| 261 | static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); | 261 | static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); |
| 262 | static void ppp_push(struct ppp *ppp); | 262 | static void ppp_push(struct ppp *ppp); |
| 263 | static void ppp_channel_push(struct channel *pch); | 263 | static void ppp_channel_push(struct channel *pch); |
| @@ -513,13 +513,12 @@ static ssize_t ppp_write(struct file *file, const char __user *buf, | |||
| 513 | goto out; | 513 | goto out; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | skb_queue_tail(&pf->xq, skb); | ||
| 517 | |||
| 518 | switch (pf->kind) { | 516 | switch (pf->kind) { |
| 519 | case INTERFACE: | 517 | case INTERFACE: |
| 520 | ppp_xmit_process(PF_TO_PPP(pf)); | 518 | ppp_xmit_process(PF_TO_PPP(pf), skb); |
| 521 | break; | 519 | break; |
| 522 | case CHANNEL: | 520 | case CHANNEL: |
| 521 | skb_queue_tail(&pf->xq, skb); | ||
| 523 | ppp_channel_push(PF_TO_CHANNEL(pf)); | 522 | ppp_channel_push(PF_TO_CHANNEL(pf)); |
| 524 | break; | 523 | break; |
| 525 | } | 524 | } |
| @@ -1267,8 +1266,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1267 | put_unaligned_be16(proto, pp); | 1266 | put_unaligned_be16(proto, pp); |
| 1268 | 1267 | ||
| 1269 | skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev))); | 1268 | skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev))); |
| 1270 | skb_queue_tail(&ppp->file.xq, skb); | 1269 | ppp_xmit_process(ppp, skb); |
| 1271 | ppp_xmit_process(ppp); | 1270 | |
| 1272 | return NETDEV_TX_OK; | 1271 | return NETDEV_TX_OK; |
| 1273 | 1272 | ||
| 1274 | outf: | 1273 | outf: |
| @@ -1420,13 +1419,14 @@ static void ppp_setup(struct net_device *dev) | |||
| 1420 | */ | 1419 | */ |
| 1421 | 1420 | ||
| 1422 | /* Called to do any work queued up on the transmit side that can now be done */ | 1421 | /* Called to do any work queued up on the transmit side that can now be done */ |
| 1423 | static void __ppp_xmit_process(struct ppp *ppp) | 1422 | static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb) |
| 1424 | { | 1423 | { |
| 1425 | struct sk_buff *skb; | ||
| 1426 | |||
| 1427 | ppp_xmit_lock(ppp); | 1424 | ppp_xmit_lock(ppp); |
| 1428 | if (!ppp->closing) { | 1425 | if (!ppp->closing) { |
| 1429 | ppp_push(ppp); | 1426 | ppp_push(ppp); |
| 1427 | |||
| 1428 | if (skb) | ||
| 1429 | skb_queue_tail(&ppp->file.xq, skb); | ||
| 1430 | while (!ppp->xmit_pending && | 1430 | while (!ppp->xmit_pending && |
| 1431 | (skb = skb_dequeue(&ppp->file.xq))) | 1431 | (skb = skb_dequeue(&ppp->file.xq))) |
| 1432 | ppp_send_frame(ppp, skb); | 1432 | ppp_send_frame(ppp, skb); |
| @@ -1440,7 +1440,7 @@ static void __ppp_xmit_process(struct ppp *ppp) | |||
| 1440 | ppp_xmit_unlock(ppp); | 1440 | ppp_xmit_unlock(ppp); |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| 1443 | static void ppp_xmit_process(struct ppp *ppp) | 1443 | static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb) |
| 1444 | { | 1444 | { |
| 1445 | local_bh_disable(); | 1445 | local_bh_disable(); |
| 1446 | 1446 | ||
| @@ -1448,7 +1448,7 @@ static void ppp_xmit_process(struct ppp *ppp) | |||
| 1448 | goto err; | 1448 | goto err; |
| 1449 | 1449 | ||
| 1450 | (*this_cpu_ptr(ppp->xmit_recursion))++; | 1450 | (*this_cpu_ptr(ppp->xmit_recursion))++; |
| 1451 | __ppp_xmit_process(ppp); | 1451 | __ppp_xmit_process(ppp, skb); |
| 1452 | (*this_cpu_ptr(ppp->xmit_recursion))--; | 1452 | (*this_cpu_ptr(ppp->xmit_recursion))--; |
| 1453 | 1453 | ||
| 1454 | local_bh_enable(); | 1454 | local_bh_enable(); |
| @@ -1458,6 +1458,8 @@ static void ppp_xmit_process(struct ppp *ppp) | |||
| 1458 | err: | 1458 | err: |
| 1459 | local_bh_enable(); | 1459 | local_bh_enable(); |
| 1460 | 1460 | ||
| 1461 | kfree_skb(skb); | ||
| 1462 | |||
| 1461 | if (net_ratelimit()) | 1463 | if (net_ratelimit()) |
| 1462 | netdev_err(ppp->dev, "recursion detected\n"); | 1464 | netdev_err(ppp->dev, "recursion detected\n"); |
| 1463 | } | 1465 | } |
| @@ -1942,7 +1944,7 @@ static void __ppp_channel_push(struct channel *pch) | |||
| 1942 | if (skb_queue_empty(&pch->file.xq)) { | 1944 | if (skb_queue_empty(&pch->file.xq)) { |
| 1943 | ppp = pch->ppp; | 1945 | ppp = pch->ppp; |
| 1944 | if (ppp) | 1946 | if (ppp) |
| 1945 | __ppp_xmit_process(ppp); | 1947 | __ppp_xmit_process(ppp, NULL); |
| 1946 | } | 1948 | } |
| 1947 | } | 1949 | } |
| 1948 | 1950 | ||
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index a468439969df..56c701b73c12 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
| @@ -2395,7 +2395,7 @@ send_done: | |||
| 2395 | if (!nlh) { | 2395 | if (!nlh) { |
| 2396 | err = __send_and_alloc_skb(&skb, team, portid, send_func); | 2396 | err = __send_and_alloc_skb(&skb, team, portid, send_func); |
| 2397 | if (err) | 2397 | if (err) |
| 2398 | goto errout; | 2398 | return err; |
| 2399 | goto send_done; | 2399 | goto send_done; |
| 2400 | } | 2400 | } |
| 2401 | 2401 | ||
| @@ -2681,7 +2681,7 @@ send_done: | |||
| 2681 | if (!nlh) { | 2681 | if (!nlh) { |
| 2682 | err = __send_and_alloc_skb(&skb, team, portid, send_func); | 2682 | err = __send_and_alloc_skb(&skb, team, portid, send_func); |
| 2683 | if (err) | 2683 | if (err) |
| 2684 | goto errout; | 2684 | return err; |
| 2685 | goto send_done; | 2685 | goto send_done; |
| 2686 | } | 2686 | } |
| 2687 | 2687 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7433bb2e4451..28cfa642e39a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -655,7 +655,7 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile) | |||
| 655 | return tun; | 655 | return tun; |
| 656 | } | 656 | } |
| 657 | 657 | ||
| 658 | static void tun_ptr_free(void *ptr) | 658 | void tun_ptr_free(void *ptr) |
| 659 | { | 659 | { |
| 660 | if (!ptr) | 660 | if (!ptr) |
| 661 | return; | 661 | return; |
| @@ -667,6 +667,7 @@ static void tun_ptr_free(void *ptr) | |||
| 667 | __skb_array_destroy_skb(ptr); | 667 | __skb_array_destroy_skb(ptr); |
| 668 | } | 668 | } |
| 669 | } | 669 | } |
| 670 | EXPORT_SYMBOL_GPL(tun_ptr_free); | ||
| 670 | 671 | ||
| 671 | static void tun_queue_purge(struct tun_file *tfile) | 672 | static void tun_queue_purge(struct tun_file *tfile) |
| 672 | { | 673 | { |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8a22ff67b026..d9eea8cfe6cb 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -315,6 +315,7 @@ static void __usbnet_status_stop_force(struct usbnet *dev) | |||
| 315 | void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) | 315 | void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) |
| 316 | { | 316 | { |
| 317 | struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); | 317 | struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); |
| 318 | unsigned long flags; | ||
| 318 | int status; | 319 | int status; |
| 319 | 320 | ||
| 320 | if (test_bit(EVENT_RX_PAUSED, &dev->flags)) { | 321 | if (test_bit(EVENT_RX_PAUSED, &dev->flags)) { |
| @@ -326,10 +327,10 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) | |||
| 326 | if (skb->protocol == 0) | 327 | if (skb->protocol == 0) |
| 327 | skb->protocol = eth_type_trans (skb, dev->net); | 328 | skb->protocol = eth_type_trans (skb, dev->net); |
| 328 | 329 | ||
| 329 | u64_stats_update_begin(&stats64->syncp); | 330 | flags = u64_stats_update_begin_irqsave(&stats64->syncp); |
| 330 | stats64->rx_packets++; | 331 | stats64->rx_packets++; |
| 331 | stats64->rx_bytes += skb->len; | 332 | stats64->rx_bytes += skb->len; |
| 332 | u64_stats_update_end(&stats64->syncp); | 333 | u64_stats_update_end_irqrestore(&stats64->syncp, flags); |
| 333 | 334 | ||
| 334 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", | 335 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", |
| 335 | skb->len + sizeof (struct ethhdr), skb->protocol); | 336 | skb->len + sizeof (struct ethhdr), skb->protocol); |
| @@ -1248,11 +1249,12 @@ static void tx_complete (struct urb *urb) | |||
| 1248 | 1249 | ||
| 1249 | if (urb->status == 0) { | 1250 | if (urb->status == 0) { |
| 1250 | struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); | 1251 | struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64); |
| 1252 | unsigned long flags; | ||
| 1251 | 1253 | ||
| 1252 | u64_stats_update_begin(&stats64->syncp); | 1254 | flags = u64_stats_update_begin_irqsave(&stats64->syncp); |
| 1253 | stats64->tx_packets += entry->packets; | 1255 | stats64->tx_packets += entry->packets; |
| 1254 | stats64->tx_bytes += entry->length; | 1256 | stats64->tx_bytes += entry->length; |
| 1255 | u64_stats_update_end(&stats64->syncp); | 1257 | u64_stats_update_end_irqrestore(&stats64->syncp, flags); |
| 1256 | } else { | 1258 | } else { |
| 1257 | dev->net->stats.tx_errors++; | 1259 | dev->net->stats.tx_errors++; |
| 1258 | 1260 | ||
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 8b39c160743d..e04937f44f33 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
| @@ -977,6 +977,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 977 | { | 977 | { |
| 978 | int ret; | 978 | int ret; |
| 979 | u32 count; | 979 | u32 count; |
| 980 | int num_pkts; | ||
| 981 | int tx_num_deferred; | ||
| 980 | unsigned long flags; | 982 | unsigned long flags; |
| 981 | struct vmxnet3_tx_ctx ctx; | 983 | struct vmxnet3_tx_ctx ctx; |
| 982 | union Vmxnet3_GenericDesc *gdesc; | 984 | union Vmxnet3_GenericDesc *gdesc; |
| @@ -1075,12 +1077,12 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 1075 | #else | 1077 | #else |
| 1076 | gdesc = ctx.sop_txd; | 1078 | gdesc = ctx.sop_txd; |
| 1077 | #endif | 1079 | #endif |
| 1080 | tx_num_deferred = le32_to_cpu(tq->shared->txNumDeferred); | ||
| 1078 | if (ctx.mss) { | 1081 | if (ctx.mss) { |
| 1079 | gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size; | 1082 | gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size; |
| 1080 | gdesc->txd.om = VMXNET3_OM_TSO; | 1083 | gdesc->txd.om = VMXNET3_OM_TSO; |
| 1081 | gdesc->txd.msscof = ctx.mss; | 1084 | gdesc->txd.msscof = ctx.mss; |
| 1082 | le32_add_cpu(&tq->shared->txNumDeferred, (skb->len - | 1085 | num_pkts = (skb->len - gdesc->txd.hlen + ctx.mss - 1) / ctx.mss; |
| 1083 | gdesc->txd.hlen + ctx.mss - 1) / ctx.mss); | ||
| 1084 | } else { | 1086 | } else { |
| 1085 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1087 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1086 | gdesc->txd.hlen = ctx.eth_ip_hdr_size; | 1088 | gdesc->txd.hlen = ctx.eth_ip_hdr_size; |
| @@ -1091,8 +1093,10 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 1091 | gdesc->txd.om = 0; | 1093 | gdesc->txd.om = 0; |
| 1092 | gdesc->txd.msscof = 0; | 1094 | gdesc->txd.msscof = 0; |
| 1093 | } | 1095 | } |
| 1094 | le32_add_cpu(&tq->shared->txNumDeferred, 1); | 1096 | num_pkts = 1; |
| 1095 | } | 1097 | } |
| 1098 | le32_add_cpu(&tq->shared->txNumDeferred, num_pkts); | ||
| 1099 | tx_num_deferred += num_pkts; | ||
| 1096 | 1100 | ||
| 1097 | if (skb_vlan_tag_present(skb)) { | 1101 | if (skb_vlan_tag_present(skb)) { |
| 1098 | gdesc->txd.ti = 1; | 1102 | gdesc->txd.ti = 1; |
| @@ -1118,8 +1122,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
| 1118 | 1122 | ||
| 1119 | spin_unlock_irqrestore(&tq->tx_lock, flags); | 1123 | spin_unlock_irqrestore(&tq->tx_lock, flags); |
| 1120 | 1124 | ||
| 1121 | if (le32_to_cpu(tq->shared->txNumDeferred) >= | 1125 | if (tx_num_deferred >= le32_to_cpu(tq->shared->txThreshold)) { |
| 1122 | le32_to_cpu(tq->shared->txThreshold)) { | ||
| 1123 | tq->shared->txNumDeferred = 0; | 1126 | tq->shared->txNumDeferred = 0; |
| 1124 | VMXNET3_WRITE_BAR0_REG(adapter, | 1127 | VMXNET3_WRITE_BAR0_REG(adapter, |
| 1125 | VMXNET3_REG_TXPROD + tq->qid * 8, | 1128 | VMXNET3_REG_TXPROD + tq->qid * 8, |
| @@ -1470,7 +1473,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
| 1470 | vmxnet3_rx_csum(adapter, skb, | 1473 | vmxnet3_rx_csum(adapter, skb, |
| 1471 | (union Vmxnet3_GenericDesc *)rcd); | 1474 | (union Vmxnet3_GenericDesc *)rcd); |
| 1472 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 1475 | skb->protocol = eth_type_trans(skb, adapter->netdev); |
| 1473 | if (!rcd->tcp || !adapter->lro) | 1476 | if (!rcd->tcp || |
| 1477 | !(adapter->netdev->features & NETIF_F_LRO)) | ||
| 1474 | goto not_lro; | 1478 | goto not_lro; |
| 1475 | 1479 | ||
| 1476 | if (segCnt != 0 && mss != 0) { | 1480 | if (segCnt != 0 && mss != 0) { |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 5ba222920e80..59ec34052a65 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
| @@ -69,10 +69,10 @@ | |||
| 69 | /* | 69 | /* |
| 70 | * Version numbers | 70 | * Version numbers |
| 71 | */ | 71 | */ |
| 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.4.11.0-k" | 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.4.13.0-k" |
| 73 | 73 | ||
| 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ | 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
| 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01040b00 | 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01040d00 |
| 76 | 76 | ||
| 77 | #if defined(CONFIG_PCI_MSI) | 77 | #if defined(CONFIG_PCI_MSI) |
| 78 | /* RSS only makes sense if MSI-X is supported. */ | 78 | /* RSS only makes sense if MSI-X is supported. */ |
| @@ -342,9 +342,6 @@ struct vmxnet3_adapter { | |||
| 342 | u8 __iomem *hw_addr1; /* for BAR 1 */ | 342 | u8 __iomem *hw_addr1; /* for BAR 1 */ |
| 343 | u8 version; | 343 | u8 version; |
| 344 | 344 | ||
| 345 | bool rxcsum; | ||
| 346 | bool lro; | ||
| 347 | |||
| 348 | #ifdef VMXNET3_RSS | 345 | #ifdef VMXNET3_RSS |
| 349 | struct UPT1_RSSConf *rss_conf; | 346 | struct UPT1_RSSConf *rss_conf; |
| 350 | bool rss; | 347 | bool rss; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index e89e5ef2c2a4..f246e9ed4a81 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -729,6 +729,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
| 729 | ieee80211_hw_set(hw, SPECTRUM_MGMT); | 729 | ieee80211_hw_set(hw, SPECTRUM_MGMT); |
| 730 | ieee80211_hw_set(hw, SIGNAL_DBM); | 730 | ieee80211_hw_set(hw, SIGNAL_DBM); |
| 731 | ieee80211_hw_set(hw, AMPDU_AGGREGATION); | 731 | ieee80211_hw_set(hw, AMPDU_AGGREGATION); |
| 732 | ieee80211_hw_set(hw, DOESNT_SUPPORT_QOS_NDP); | ||
| 732 | 733 | ||
| 733 | if (ath9k_ps_enable) | 734 | if (ath9k_ps_enable) |
| 734 | ieee80211_hw_set(hw, SUPPORTS_PS); | 735 | ieee80211_hw_set(hw, SUPPORTS_PS); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index df8a1ecb9924..232dcbb83311 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | |||
| @@ -181,6 +181,7 @@ enum brcmf_netif_stop_reason { | |||
| 181 | * @netif_stop_lock: spinlock for update netif_stop from multiple sources. | 181 | * @netif_stop_lock: spinlock for update netif_stop from multiple sources. |
| 182 | * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. | 182 | * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. |
| 183 | * @pend_8021x_wait: used for signalling change in count. | 183 | * @pend_8021x_wait: used for signalling change in count. |
| 184 | * @fwil_fwerr: flag indicating fwil layer should return firmware error codes. | ||
| 184 | */ | 185 | */ |
| 185 | struct brcmf_if { | 186 | struct brcmf_if { |
| 186 | struct brcmf_pub *drvr; | 187 | struct brcmf_pub *drvr; |
| @@ -198,6 +199,7 @@ struct brcmf_if { | |||
| 198 | wait_queue_head_t pend_8021x_wait; | 199 | wait_queue_head_t pend_8021x_wait; |
| 199 | struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; | 200 | struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; |
| 200 | u8 ipv6addr_idx; | 201 | u8 ipv6addr_idx; |
| 202 | bool fwil_fwerr; | ||
| 201 | }; | 203 | }; |
| 202 | 204 | ||
| 203 | int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); | 205 | int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index 47de35a33853..bede7b7fd996 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | |||
| @@ -104,6 +104,9 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp, | |||
| 104 | u32 data; | 104 | u32 data; |
| 105 | int err; | 105 | int err; |
| 106 | 106 | ||
| 107 | /* we need to know firmware error */ | ||
| 108 | ifp->fwil_fwerr = true; | ||
| 109 | |||
| 107 | err = brcmf_fil_iovar_int_get(ifp, name, &data); | 110 | err = brcmf_fil_iovar_int_get(ifp, name, &data); |
| 108 | if (err == 0) { | 111 | if (err == 0) { |
| 109 | brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); | 112 | brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); |
| @@ -112,6 +115,8 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp, | |||
| 112 | brcmf_dbg(TRACE, "%s feature check failed: %d\n", | 115 | brcmf_dbg(TRACE, "%s feature check failed: %d\n", |
| 113 | brcmf_feat_names[id], err); | 116 | brcmf_feat_names[id], err); |
| 114 | } | 117 | } |
| 118 | |||
| 119 | ifp->fwil_fwerr = false; | ||
| 115 | } | 120 | } |
| 116 | 121 | ||
| 117 | static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, | 122 | static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, |
| @@ -120,6 +125,9 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, | |||
| 120 | { | 125 | { |
| 121 | int err; | 126 | int err; |
| 122 | 127 | ||
| 128 | /* we need to know firmware error */ | ||
| 129 | ifp->fwil_fwerr = true; | ||
| 130 | |||
| 123 | err = brcmf_fil_iovar_data_set(ifp, name, data, len); | 131 | err = brcmf_fil_iovar_data_set(ifp, name, data, len); |
| 124 | if (err != -BRCMF_FW_UNSUPPORTED) { | 132 | if (err != -BRCMF_FW_UNSUPPORTED) { |
| 125 | brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); | 133 | brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); |
| @@ -128,6 +136,8 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, | |||
| 128 | brcmf_dbg(TRACE, "%s feature check failed: %d\n", | 136 | brcmf_dbg(TRACE, "%s feature check failed: %d\n", |
| 129 | brcmf_feat_names[id], err); | 137 | brcmf_feat_names[id], err); |
| 130 | } | 138 | } |
| 139 | |||
| 140 | ifp->fwil_fwerr = false; | ||
| 131 | } | 141 | } |
| 132 | 142 | ||
| 133 | #define MAX_CAPS_BUFFER_SIZE 512 | 143 | #define MAX_CAPS_BUFFER_SIZE 512 |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c index f2cfdd3b2bf1..fc5751116d99 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | |||
| @@ -131,6 +131,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | |||
| 131 | brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); | 131 | brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); |
| 132 | err = -EBADE; | 132 | err = -EBADE; |
| 133 | } | 133 | } |
| 134 | if (ifp->fwil_fwerr) | ||
| 135 | return fwerr; | ||
| 136 | |||
| 134 | return err; | 137 | return err; |
| 135 | } | 138 | } |
| 136 | 139 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 2ee54133efa1..82064e909784 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | |||
| @@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac) | |||
| 462 | * @dev_addr: optional device address. | 462 | * @dev_addr: optional device address. |
| 463 | * | 463 | * |
| 464 | * P2P needs mac addresses for P2P device and interface. If no device | 464 | * P2P needs mac addresses for P2P device and interface. If no device |
| 465 | * address it specified, these are derived from the primary net device, ie. | 465 | * address it specified, these are derived from a random ethernet |
| 466 | * the permanent ethernet address of the device. | 466 | * address. |
| 467 | */ | 467 | */ |
| 468 | static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) | 468 | static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) |
| 469 | { | 469 | { |
| 470 | struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; | 470 | bool random_addr = false; |
| 471 | bool local_admin = false; | ||
| 472 | 471 | ||
| 473 | if (!dev_addr || is_zero_ether_addr(dev_addr)) { | 472 | if (!dev_addr || is_zero_ether_addr(dev_addr)) |
| 474 | dev_addr = pri_ifp->mac_addr; | 473 | random_addr = true; |
| 475 | local_admin = true; | ||
| 476 | } | ||
| 477 | 474 | ||
| 478 | /* Generate the P2P Device Address. This consists of the device's | 475 | /* Generate the P2P Device Address obtaining a random ethernet |
| 479 | * primary MAC address with the locally administered bit set. | 476 | * address with the locally administered bit set. |
| 480 | */ | 477 | */ |
| 481 | memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); | 478 | if (random_addr) |
| 482 | if (local_admin) | 479 | eth_random_addr(p2p->dev_addr); |
| 483 | p2p->dev_addr[0] |= 0x02; | 480 | else |
| 481 | memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); | ||
| 484 | 482 | ||
| 485 | /* Generate the P2P Interface Address. If the discovery and connection | 483 | /* Generate the P2P Interface Address. If the discovery and connection |
| 486 | * BSSCFGs need to simultaneously co-exist, then this address must be | 484 | * BSSCFGs need to simultaneously co-exist, then this address must be |
diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig index c5f2ddf9b0fe..e5a2fc738ac3 100644 --- a/drivers/net/wireless/intel/iwlwifi/Kconfig +++ b/drivers/net/wireless/intel/iwlwifi/Kconfig | |||
| @@ -91,7 +91,6 @@ config IWLWIFI_BCAST_FILTERING | |||
| 91 | config IWLWIFI_PCIE_RTPM | 91 | config IWLWIFI_PCIE_RTPM |
| 92 | bool "Enable runtime power management mode for PCIe devices" | 92 | bool "Enable runtime power management mode for PCIe devices" |
| 93 | depends on IWLMVM && PM && EXPERT | 93 | depends on IWLMVM && PM && EXPERT |
| 94 | default false | ||
| 95 | help | 94 | help |
| 96 | Say Y here to enable runtime power management for PCIe | 95 | Say Y here to enable runtime power management for PCIe |
| 97 | devices. If enabled, the device will go into low power mode | 96 | devices. If enabled, the device will go into low power mode |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h index 3721a3ed358b..f824bebceb06 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h | |||
| @@ -211,7 +211,7 @@ enum { | |||
| 211 | * @TE_V2_NOTIF_HOST_FRAG_END:request/receive notification on frag end | 211 | * @TE_V2_NOTIF_HOST_FRAG_END:request/receive notification on frag end |
| 212 | * @TE_V2_NOTIF_INTERNAL_FRAG_START: internal FW use. | 212 | * @TE_V2_NOTIF_INTERNAL_FRAG_START: internal FW use. |
| 213 | * @TE_V2_NOTIF_INTERNAL_FRAG_END: internal FW use. | 213 | * @TE_V2_NOTIF_INTERNAL_FRAG_END: internal FW use. |
| 214 | * @T2_V2_START_IMMEDIATELY: start time event immediately | 214 | * @TE_V2_START_IMMEDIATELY: start time event immediately |
| 215 | * @TE_V2_DEP_OTHER: depends on another time event | 215 | * @TE_V2_DEP_OTHER: depends on another time event |
| 216 | * @TE_V2_DEP_TSF: depends on a specific time | 216 | * @TE_V2_DEP_TSF: depends on a specific time |
| 217 | * @TE_V2_EVENT_SOCIOPATHIC: can't co-exist with other events of tha same MAC | 217 | * @TE_V2_EVENT_SOCIOPATHIC: can't co-exist with other events of tha same MAC |
| @@ -230,7 +230,7 @@ enum iwl_time_event_policy { | |||
| 230 | TE_V2_NOTIF_HOST_FRAG_END = BIT(5), | 230 | TE_V2_NOTIF_HOST_FRAG_END = BIT(5), |
| 231 | TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6), | 231 | TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6), |
| 232 | TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7), | 232 | TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7), |
| 233 | T2_V2_START_IMMEDIATELY = BIT(11), | 233 | TE_V2_START_IMMEDIATELY = BIT(11), |
| 234 | 234 | ||
| 235 | /* placement characteristics */ | 235 | /* placement characteristics */ |
| 236 | TE_V2_DEP_OTHER = BIT(TE_V2_PLACEMENT_POS), | 236 | TE_V2_DEP_OTHER = BIT(TE_V2_PLACEMENT_POS), |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 67aefc8fc9ac..7bd704a3e640 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -33,6 +34,7 @@ | |||
| 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
| 34 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 35 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 36 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 37 | * Copyright(c) 2018 Intel Corporation | ||
| 36 | * All rights reserved. | 38 | * All rights reserved. |
| 37 | * | 39 | * |
| 38 | * Redistribution and use in source and binary forms, with or without | 40 | * Redistribution and use in source and binary forms, with or without |
| @@ -942,7 +944,6 @@ dump_trans_data: | |||
| 942 | 944 | ||
| 943 | out: | 945 | out: |
| 944 | iwl_fw_free_dump_desc(fwrt); | 946 | iwl_fw_free_dump_desc(fwrt); |
| 945 | fwrt->dump.trig = NULL; | ||
| 946 | clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status); | 947 | clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status); |
| 947 | IWL_DEBUG_INFO(fwrt, "WRT dump done\n"); | 948 | IWL_DEBUG_INFO(fwrt, "WRT dump done\n"); |
| 948 | } | 949 | } |
| @@ -1112,6 +1113,14 @@ void iwl_fw_error_dump_wk(struct work_struct *work) | |||
| 1112 | fwrt->ops->dump_start(fwrt->ops_ctx)) | 1113 | fwrt->ops->dump_start(fwrt->ops_ctx)) |
| 1113 | return; | 1114 | return; |
| 1114 | 1115 | ||
| 1116 | if (fwrt->ops && fwrt->ops->fw_running && | ||
| 1117 | !fwrt->ops->fw_running(fwrt->ops_ctx)) { | ||
| 1118 | IWL_ERR(fwrt, "Firmware not running - cannot dump error\n"); | ||
| 1119 | iwl_fw_free_dump_desc(fwrt); | ||
| 1120 | clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status); | ||
| 1121 | goto out; | ||
| 1122 | } | ||
| 1123 | |||
| 1115 | if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { | 1124 | if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { |
| 1116 | /* stop recording */ | 1125 | /* stop recording */ |
| 1117 | iwl_fw_dbg_stop_recording(fwrt); | 1126 | iwl_fw_dbg_stop_recording(fwrt); |
| @@ -1145,7 +1154,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) | |||
| 1145 | iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, out_ctrl); | 1154 | iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, out_ctrl); |
| 1146 | } | 1155 | } |
| 1147 | } | 1156 | } |
| 1148 | 1157 | out: | |
| 1149 | if (fwrt->ops && fwrt->ops->dump_end) | 1158 | if (fwrt->ops && fwrt->ops->dump_end) |
| 1150 | fwrt->ops->dump_end(fwrt->ops_ctx); | 1159 | fwrt->ops->dump_end(fwrt->ops_ctx); |
| 1151 | } | 1160 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 223fb77a3aa9..72259bff9922 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -33,6 +34,7 @@ | |||
| 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
| 34 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 35 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 35 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH | 36 | * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |
| 37 | * Copyright(c) 2018 Intel Corporation | ||
| 36 | * All rights reserved. | 38 | * All rights reserved. |
| 37 | * | 39 | * |
| 38 | * Redistribution and use in source and binary forms, with or without | 40 | * Redistribution and use in source and binary forms, with or without |
| @@ -91,6 +93,7 @@ static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt) | |||
| 91 | if (fwrt->dump.desc != &iwl_dump_desc_assert) | 93 | if (fwrt->dump.desc != &iwl_dump_desc_assert) |
| 92 | kfree(fwrt->dump.desc); | 94 | kfree(fwrt->dump.desc); |
| 93 | fwrt->dump.desc = NULL; | 95 | fwrt->dump.desc = NULL; |
| 96 | fwrt->dump.trig = NULL; | ||
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt); | 99 | void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt); |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h index e57ff92a68ae..3da468d2cc92 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h | |||
| @@ -75,6 +75,20 @@ static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) | |||
| 75 | cancel_delayed_work_sync(&fwrt->timestamp.wk); | 75 | cancel_delayed_work_sync(&fwrt->timestamp.wk); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) | ||
| 79 | { | ||
| 80 | cancel_delayed_work_sync(&fwrt->timestamp.wk); | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) | ||
| 84 | { | ||
| 85 | if (!fwrt->timestamp.delay) | ||
| 86 | return; | ||
| 87 | |||
| 88 | schedule_delayed_work(&fwrt->timestamp.wk, | ||
| 89 | round_jiffies_relative(fwrt->timestamp.delay)); | ||
| 90 | } | ||
| 91 | |||
| 78 | #else | 92 | #else |
| 79 | static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, | 93 | static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, |
| 80 | struct dentry *dbgfs_dir) | 94 | struct dentry *dbgfs_dir) |
| @@ -84,4 +98,8 @@ static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, | |||
| 84 | 98 | ||
| 85 | static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {} | 99 | static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {} |
| 86 | 100 | ||
| 101 | static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) {} | ||
| 102 | |||
| 103 | static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} | ||
| 104 | |||
| 87 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 105 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index c39fe84bb4c4..2efac307909e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c | |||
| @@ -77,8 +77,14 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, | |||
| 77 | } | 77 | } |
| 78 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); | 78 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); |
| 79 | 79 | ||
| 80 | void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt) | 80 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) |
| 81 | { | 81 | { |
| 82 | iwl_fw_cancel_timestamp(fwrt); | 82 | iwl_fw_suspend_timestamp(fwrt); |
| 83 | } | 83 | } |
| 84 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_exit); | 84 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); |
| 85 | |||
| 86 | void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt) | ||
| 87 | { | ||
| 88 | iwl_fw_resume_timestamp(fwrt); | ||
| 89 | } | ||
| 90 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume); | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index e25c049f980f..3fb940ebd74a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
| 7 | * | 7 | * |
| 8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 9 | * Copyright(c) 2018 Intel Corporation | ||
| 9 | * | 10 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -26,6 +27,7 @@ | |||
| 26 | * BSD LICENSE | 27 | * BSD LICENSE |
| 27 | * | 28 | * |
| 28 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
| 30 | * Copyright(c) 2018 Intel Corporation | ||
| 29 | * All rights reserved. | 31 | * All rights reserved. |
| 30 | * | 32 | * |
| 31 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
| @@ -68,6 +70,7 @@ | |||
| 68 | struct iwl_fw_runtime_ops { | 70 | struct iwl_fw_runtime_ops { |
| 69 | int (*dump_start)(void *ctx); | 71 | int (*dump_start)(void *ctx); |
| 70 | void (*dump_end)(void *ctx); | 72 | void (*dump_end)(void *ctx); |
| 73 | bool (*fw_running)(void *ctx); | ||
| 71 | }; | 74 | }; |
| 72 | 75 | ||
| 73 | #define MAX_NUM_LMAC 2 | 76 | #define MAX_NUM_LMAC 2 |
| @@ -150,6 +153,10 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, | |||
| 150 | 153 | ||
| 151 | void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); | 154 | void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); |
| 152 | 155 | ||
| 156 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); | ||
| 157 | |||
| 158 | void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt); | ||
| 159 | |||
| 153 | static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt, | 160 | static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt, |
| 154 | enum iwl_ucode_type cur_fw_img) | 161 | enum iwl_ucode_type cur_fw_img) |
| 155 | { | 162 | { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 0e6cf39285f4..2efe9b099556 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c | |||
| @@ -1098,6 +1098,8 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 1098 | /* make sure the d0i3 exit work is not pending */ | 1098 | /* make sure the d0i3 exit work is not pending */ |
| 1099 | flush_work(&mvm->d0i3_exit_work); | 1099 | flush_work(&mvm->d0i3_exit_work); |
| 1100 | 1100 | ||
| 1101 | iwl_fw_runtime_suspend(&mvm->fwrt); | ||
| 1102 | |||
| 1101 | ret = iwl_trans_suspend(trans); | 1103 | ret = iwl_trans_suspend(trans); |
| 1102 | if (ret) | 1104 | if (ret) |
| 1103 | return ret; | 1105 | return ret; |
| @@ -2012,6 +2014,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw) | |||
| 2012 | 2014 | ||
| 2013 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; | 2015 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; |
| 2014 | 2016 | ||
| 2017 | iwl_fw_runtime_resume(&mvm->fwrt); | ||
| 2018 | |||
| 2015 | return ret; | 2019 | return ret; |
| 2016 | } | 2020 | } |
| 2017 | 2021 | ||
| @@ -2038,6 +2042,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file) | |||
| 2038 | 2042 | ||
| 2039 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; | 2043 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; |
| 2040 | 2044 | ||
| 2045 | iwl_fw_runtime_suspend(&mvm->fwrt); | ||
| 2046 | |||
| 2041 | /* start pseudo D3 */ | 2047 | /* start pseudo D3 */ |
| 2042 | rtnl_lock(); | 2048 | rtnl_lock(); |
| 2043 | err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); | 2049 | err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); |
| @@ -2098,6 +2104,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) | |||
| 2098 | __iwl_mvm_resume(mvm, true); | 2104 | __iwl_mvm_resume(mvm, true); |
| 2099 | rtnl_unlock(); | 2105 | rtnl_unlock(); |
| 2100 | 2106 | ||
| 2107 | iwl_fw_runtime_resume(&mvm->fwrt); | ||
| 2108 | |||
| 2101 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; | 2109 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; |
| 2102 | 2110 | ||
| 2103 | iwl_abort_notification_waits(&mvm->notif_wait); | 2111 | iwl_abort_notification_waits(&mvm->notif_wait); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index a7892c1254a2..9c436d8d001d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -35,6 +36,7 @@ | |||
| 35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 36 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 37 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 37 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 38 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 39 | * Copyright(c) 2018 Intel Corporation | ||
| 38 | * All rights reserved. | 40 | * All rights reserved. |
| 39 | * | 41 | * |
| 40 | * Redistribution and use in source and binary forms, with or without | 42 | * Redistribution and use in source and binary forms, with or without |
| @@ -1281,9 +1283,6 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, | |||
| 1281 | { | 1283 | { |
| 1282 | int ret; | 1284 | int ret; |
| 1283 | 1285 | ||
| 1284 | if (!iwl_mvm_firmware_running(mvm)) | ||
| 1285 | return -EIO; | ||
| 1286 | |||
| 1287 | ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE); | 1286 | ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE); |
| 1288 | if (ret) | 1287 | if (ret) |
| 1289 | return ret; | 1288 | return ret; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 2f22e14e00fe..8ba16fc24e3a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | |||
| @@ -438,7 +438,8 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 438 | } | 438 | } |
| 439 | 439 | ||
| 440 | /* Allocate the CAB queue for softAP and GO interfaces */ | 440 | /* Allocate the CAB queue for softAP and GO interfaces */ |
| 441 | if (vif->type == NL80211_IFTYPE_AP) { | 441 | if (vif->type == NL80211_IFTYPE_AP || |
| 442 | vif->type == NL80211_IFTYPE_ADHOC) { | ||
| 442 | /* | 443 | /* |
| 443 | * For TVQM this will be overwritten later with the FW assigned | 444 | * For TVQM this will be overwritten later with the FW assigned |
| 444 | * queue value (when queue is enabled). | 445 | * queue value (when queue is enabled). |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 8aed40a8bc38..ebf511150f4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -2106,15 +2107,40 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
| 2106 | if (ret) | 2107 | if (ret) |
| 2107 | goto out_remove; | 2108 | goto out_remove; |
| 2108 | 2109 | ||
| 2109 | ret = iwl_mvm_add_mcast_sta(mvm, vif); | 2110 | /* |
| 2110 | if (ret) | 2111 | * This is not very nice, but the simplest: |
| 2111 | goto out_unbind; | 2112 | * For older FWs adding the mcast sta before the bcast station may |
| 2112 | 2113 | * cause assert 0x2b00. | |
| 2113 | /* Send the bcast station. At this stage the TBTT and DTIM time events | 2114 | * This is fixed in later FW so make the order of removal depend on |
| 2114 | * are added and applied to the scheduler */ | 2115 | * the TLV |
| 2115 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); | 2116 | */ |
| 2116 | if (ret) | 2117 | if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) { |
| 2117 | goto out_rm_mcast; | 2118 | ret = iwl_mvm_add_mcast_sta(mvm, vif); |
| 2119 | if (ret) | ||
| 2120 | goto out_unbind; | ||
| 2121 | /* | ||
| 2122 | * Send the bcast station. At this stage the TBTT and DTIM time | ||
| 2123 | * events are added and applied to the scheduler | ||
| 2124 | */ | ||
| 2125 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); | ||
| 2126 | if (ret) { | ||
| 2127 | iwl_mvm_rm_mcast_sta(mvm, vif); | ||
| 2128 | goto out_unbind; | ||
| 2129 | } | ||
| 2130 | } else { | ||
| 2131 | /* | ||
| 2132 | * Send the bcast station. At this stage the TBTT and DTIM time | ||
| 2133 | * events are added and applied to the scheduler | ||
| 2134 | */ | ||
| 2135 | iwl_mvm_send_add_bcast_sta(mvm, vif); | ||
| 2136 | if (ret) | ||
| 2137 | goto out_unbind; | ||
| 2138 | iwl_mvm_add_mcast_sta(mvm, vif); | ||
| 2139 | if (ret) { | ||
| 2140 | iwl_mvm_send_rm_bcast_sta(mvm, vif); | ||
| 2141 | goto out_unbind; | ||
| 2142 | } | ||
| 2143 | } | ||
| 2118 | 2144 | ||
| 2119 | /* must be set before quota calculations */ | 2145 | /* must be set before quota calculations */ |
| 2120 | mvmvif->ap_ibss_active = true; | 2146 | mvmvif->ap_ibss_active = true; |
| @@ -2144,7 +2170,6 @@ out_quota_failed: | |||
| 2144 | iwl_mvm_power_update_mac(mvm); | 2170 | iwl_mvm_power_update_mac(mvm); |
| 2145 | mvmvif->ap_ibss_active = false; | 2171 | mvmvif->ap_ibss_active = false; |
| 2146 | iwl_mvm_send_rm_bcast_sta(mvm, vif); | 2172 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
| 2147 | out_rm_mcast: | ||
| 2148 | iwl_mvm_rm_mcast_sta(mvm, vif); | 2173 | iwl_mvm_rm_mcast_sta(mvm, vif); |
| 2149 | out_unbind: | 2174 | out_unbind: |
| 2150 | iwl_mvm_binding_remove_vif(mvm, vif); | 2175 | iwl_mvm_binding_remove_vif(mvm, vif); |
| @@ -2682,6 +2707,10 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | |||
| 2682 | 2707 | ||
| 2683 | /* enable beacon filtering */ | 2708 | /* enable beacon filtering */ |
| 2684 | WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); | 2709 | WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); |
| 2710 | |||
| 2711 | iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, | ||
| 2712 | false); | ||
| 2713 | |||
| 2685 | ret = 0; | 2714 | ret = 0; |
| 2686 | } else if (old_state == IEEE80211_STA_AUTHORIZED && | 2715 | } else if (old_state == IEEE80211_STA_AUTHORIZED && |
| 2687 | new_state == IEEE80211_STA_ASSOC) { | 2716 | new_state == IEEE80211_STA_ASSOC) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 2d28e0804218..89ff02d7c876 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
| @@ -90,6 +90,7 @@ | |||
| 90 | #include "fw/runtime.h" | 90 | #include "fw/runtime.h" |
| 91 | #include "fw/dbg.h" | 91 | #include "fw/dbg.h" |
| 92 | #include "fw/acpi.h" | 92 | #include "fw/acpi.h" |
| 93 | #include "fw/debugfs.h" | ||
| 93 | 94 | ||
| 94 | #define IWL_MVM_MAX_ADDRESSES 5 | 95 | #define IWL_MVM_MAX_ADDRESSES 5 |
| 95 | /* RSSI offset for WkP */ | 96 | /* RSSI offset for WkP */ |
| @@ -1783,6 +1784,7 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) | |||
| 1783 | 1784 | ||
| 1784 | static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) | 1785 | static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) |
| 1785 | { | 1786 | { |
| 1787 | iwl_fw_cancel_timestamp(&mvm->fwrt); | ||
| 1786 | iwl_free_fw_paging(&mvm->fwrt); | 1788 | iwl_free_fw_paging(&mvm->fwrt); |
| 1787 | clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); | 1789 | clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); |
| 1788 | iwl_fw_dump_conf_clear(&mvm->fwrt); | 1790 | iwl_fw_dump_conf_clear(&mvm->fwrt); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5d525a0023dc..ab7fb5aad984 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | * Copyright(c) 2018 Intel Corporation | ||
| 11 | * | 12 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of version 2 of the GNU General Public License as | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -35,6 +36,7 @@ | |||
| 35 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 36 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 36 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 37 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 37 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH | 38 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 39 | * Copyright(c) 2018 Intel Corporation | ||
| 38 | * All rights reserved. | 40 | * All rights reserved. |
| 39 | * | 41 | * |
| 40 | * Redistribution and use in source and binary forms, with or without | 42 | * Redistribution and use in source and binary forms, with or without |
| @@ -552,9 +554,15 @@ static void iwl_mvm_fwrt_dump_end(void *ctx) | |||
| 552 | iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT); | 554 | iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT); |
| 553 | } | 555 | } |
| 554 | 556 | ||
| 557 | static bool iwl_mvm_fwrt_fw_running(void *ctx) | ||
| 558 | { | ||
| 559 | return iwl_mvm_firmware_running(ctx); | ||
| 560 | } | ||
| 561 | |||
| 555 | static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { | 562 | static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { |
| 556 | .dump_start = iwl_mvm_fwrt_dump_start, | 563 | .dump_start = iwl_mvm_fwrt_dump_start, |
| 557 | .dump_end = iwl_mvm_fwrt_dump_end, | 564 | .dump_end = iwl_mvm_fwrt_dump_end, |
| 565 | .fw_running = iwl_mvm_fwrt_fw_running, | ||
| 558 | }; | 566 | }; |
| 559 | 567 | ||
| 560 | static struct iwl_op_mode * | 568 | static struct iwl_op_mode * |
| @@ -802,7 +810,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
| 802 | iwl_mvm_leds_exit(mvm); | 810 | iwl_mvm_leds_exit(mvm); |
| 803 | iwl_mvm_thermal_exit(mvm); | 811 | iwl_mvm_thermal_exit(mvm); |
| 804 | out_free: | 812 | out_free: |
| 805 | iwl_fw_runtime_exit(&mvm->fwrt); | ||
| 806 | iwl_fw_flush_dump(&mvm->fwrt); | 813 | iwl_fw_flush_dump(&mvm->fwrt); |
| 807 | 814 | ||
| 808 | if (iwlmvm_mod_params.init_dbg) | 815 | if (iwlmvm_mod_params.init_dbg) |
| @@ -843,7 +850,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) | |||
| 843 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) | 850 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) |
| 844 | kfree(mvm->d3_resume_sram); | 851 | kfree(mvm->d3_resume_sram); |
| 845 | #endif | 852 | #endif |
| 846 | iwl_fw_runtime_exit(&mvm->fwrt); | ||
| 847 | iwl_trans_op_mode_leave(mvm->trans); | 853 | iwl_trans_op_mode_leave(mvm->trans); |
| 848 | 854 | ||
| 849 | iwl_phy_db_free(mvm->phy_db); | 855 | iwl_phy_db_free(mvm->phy_db); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 60abb0084ee5..47f4c7a1d80d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c | |||
| @@ -2684,7 +2684,8 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, | |||
| 2684 | struct ieee80211_sta *sta, | 2684 | struct ieee80211_sta *sta, |
| 2685 | struct iwl_lq_sta *lq_sta, | 2685 | struct iwl_lq_sta *lq_sta, |
| 2686 | enum nl80211_band band, | 2686 | enum nl80211_band band, |
| 2687 | struct rs_rate *rate) | 2687 | struct rs_rate *rate, |
| 2688 | bool init) | ||
| 2688 | { | 2689 | { |
| 2689 | int i, nentries; | 2690 | int i, nentries; |
| 2690 | unsigned long active_rate; | 2691 | unsigned long active_rate; |
| @@ -2738,14 +2739,25 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, | |||
| 2738 | */ | 2739 | */ |
| 2739 | if (sta->vht_cap.vht_supported && | 2740 | if (sta->vht_cap.vht_supported && |
| 2740 | best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { | 2741 | best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { |
| 2741 | switch (sta->bandwidth) { | 2742 | /* |
| 2742 | case IEEE80211_STA_RX_BW_160: | 2743 | * In AP mode, when a new station associates, rs is initialized |
| 2743 | case IEEE80211_STA_RX_BW_80: | 2744 | * immediately upon association completion, before the phy |
| 2744 | case IEEE80211_STA_RX_BW_40: | 2745 | * context is updated with the association parameters, so the |
| 2746 | * sta bandwidth might be wider than the phy context allows. | ||
| 2747 | * To avoid this issue, always initialize rs with 20mhz | ||
| 2748 | * bandwidth rate, and after authorization, when the phy context | ||
| 2749 | * is already up-to-date, re-init rs with the correct bw. | ||
| 2750 | */ | ||
| 2751 | u32 bw = init ? RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta); | ||
| 2752 | |||
| 2753 | switch (bw) { | ||
| 2754 | case RATE_MCS_CHAN_WIDTH_40: | ||
| 2755 | case RATE_MCS_CHAN_WIDTH_80: | ||
| 2756 | case RATE_MCS_CHAN_WIDTH_160: | ||
| 2745 | initial_rates = rs_optimal_rates_vht; | 2757 | initial_rates = rs_optimal_rates_vht; |
| 2746 | nentries = ARRAY_SIZE(rs_optimal_rates_vht); | 2758 | nentries = ARRAY_SIZE(rs_optimal_rates_vht); |
| 2747 | break; | 2759 | break; |
| 2748 | case IEEE80211_STA_RX_BW_20: | 2760 | case RATE_MCS_CHAN_WIDTH_20: |
| 2749 | initial_rates = rs_optimal_rates_vht_20mhz; | 2761 | initial_rates = rs_optimal_rates_vht_20mhz; |
| 2750 | nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); | 2762 | nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz); |
| 2751 | break; | 2763 | break; |
| @@ -2756,7 +2768,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, | |||
| 2756 | 2768 | ||
| 2757 | active_rate = lq_sta->active_siso_rate; | 2769 | active_rate = lq_sta->active_siso_rate; |
| 2758 | rate->type = LQ_VHT_SISO; | 2770 | rate->type = LQ_VHT_SISO; |
| 2759 | rate->bw = rs_bw_from_sta_bw(sta); | 2771 | rate->bw = bw; |
| 2760 | } else if (sta->ht_cap.ht_supported && | 2772 | } else if (sta->ht_cap.ht_supported && |
| 2761 | best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { | 2773 | best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) { |
| 2762 | initial_rates = rs_optimal_rates_ht; | 2774 | initial_rates = rs_optimal_rates_ht; |
| @@ -2839,7 +2851,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
| 2839 | tbl = &(lq_sta->lq_info[active_tbl]); | 2851 | tbl = &(lq_sta->lq_info[active_tbl]); |
| 2840 | rate = &tbl->rate; | 2852 | rate = &tbl->rate; |
| 2841 | 2853 | ||
| 2842 | rs_get_initial_rate(mvm, sta, lq_sta, band, rate); | 2854 | rs_get_initial_rate(mvm, sta, lq_sta, band, rate, init); |
| 2843 | rs_init_optimal_rate(mvm, sta, lq_sta); | 2855 | rs_init_optimal_rate(mvm, sta, lq_sta); |
| 2844 | 2856 | ||
| 2845 | WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B, | 2857 | WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B, |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index a3f7c1bf3cc8..580de5851fc7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |||
| @@ -71,6 +71,7 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 71 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 71 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 72 | struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb); | 72 | struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb); |
| 73 | struct iwl_mvm_key_pn *ptk_pn; | 73 | struct iwl_mvm_key_pn *ptk_pn; |
| 74 | int res; | ||
| 74 | u8 tid, keyidx; | 75 | u8 tid, keyidx; |
| 75 | u8 pn[IEEE80211_CCMP_PN_LEN]; | 76 | u8 pn[IEEE80211_CCMP_PN_LEN]; |
| 76 | u8 *extiv; | 77 | u8 *extiv; |
| @@ -127,12 +128,13 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 127 | pn[4] = extiv[1]; | 128 | pn[4] = extiv[1]; |
| 128 | pn[5] = extiv[0]; | 129 | pn[5] = extiv[0]; |
| 129 | 130 | ||
| 130 | if (memcmp(pn, ptk_pn->q[queue].pn[tid], | 131 | res = memcmp(pn, ptk_pn->q[queue].pn[tid], IEEE80211_CCMP_PN_LEN); |
| 131 | IEEE80211_CCMP_PN_LEN) <= 0) | 132 | if (res < 0) |
| 133 | return -1; | ||
| 134 | if (!res && !(stats->flag & RX_FLAG_ALLOW_SAME_PN)) | ||
| 132 | return -1; | 135 | return -1; |
| 133 | 136 | ||
| 134 | if (!(stats->flag & RX_FLAG_AMSDU_MORE)) | 137 | memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN); |
| 135 | memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN); | ||
| 136 | stats->flag |= RX_FLAG_PN_VALIDATED; | 138 | stats->flag |= RX_FLAG_PN_VALIDATED; |
| 137 | 139 | ||
| 138 | return 0; | 140 | return 0; |
| @@ -314,28 +316,21 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta, | |||
| 314 | } | 316 | } |
| 315 | 317 | ||
| 316 | /* | 318 | /* |
| 317 | * returns true if a packet outside BA session is a duplicate and | 319 | * returns true if a packet is a duplicate and should be dropped. |
| 318 | * should be dropped | 320 | * Updates AMSDU PN tracking info |
| 319 | */ | 321 | */ |
| 320 | static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue, | 322 | static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue, |
| 321 | struct ieee80211_rx_status *rx_status, | 323 | struct ieee80211_rx_status *rx_status, |
| 322 | struct ieee80211_hdr *hdr, | 324 | struct ieee80211_hdr *hdr, |
| 323 | struct iwl_rx_mpdu_desc *desc) | 325 | struct iwl_rx_mpdu_desc *desc) |
| 324 | { | 326 | { |
| 325 | struct iwl_mvm_sta *mvm_sta; | 327 | struct iwl_mvm_sta *mvm_sta; |
| 326 | struct iwl_mvm_rxq_dup_data *dup_data; | 328 | struct iwl_mvm_rxq_dup_data *dup_data; |
| 327 | u8 baid, tid, sub_frame_idx; | 329 | u8 tid, sub_frame_idx; |
| 328 | 330 | ||
| 329 | if (WARN_ON(IS_ERR_OR_NULL(sta))) | 331 | if (WARN_ON(IS_ERR_OR_NULL(sta))) |
| 330 | return false; | 332 | return false; |
| 331 | 333 | ||
| 332 | baid = (le32_to_cpu(desc->reorder_data) & | ||
| 333 | IWL_RX_MPDU_REORDER_BAID_MASK) >> | ||
| 334 | IWL_RX_MPDU_REORDER_BAID_SHIFT; | ||
| 335 | |||
| 336 | if (baid != IWL_RX_REORDER_DATA_INVALID_BAID) | ||
| 337 | return false; | ||
| 338 | |||
| 339 | mvm_sta = iwl_mvm_sta_from_mac80211(sta); | 334 | mvm_sta = iwl_mvm_sta_from_mac80211(sta); |
| 340 | dup_data = &mvm_sta->dup_data[queue]; | 335 | dup_data = &mvm_sta->dup_data[queue]; |
| 341 | 336 | ||
| @@ -365,6 +360,12 @@ static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue, | |||
| 365 | dup_data->last_sub_frame[tid] >= sub_frame_idx)) | 360 | dup_data->last_sub_frame[tid] >= sub_frame_idx)) |
| 366 | return true; | 361 | return true; |
| 367 | 362 | ||
| 363 | /* Allow same PN as the first subframe for following sub frames */ | ||
| 364 | if (dup_data->last_seq[tid] == hdr->seq_ctrl && | ||
| 365 | sub_frame_idx > dup_data->last_sub_frame[tid] && | ||
| 366 | desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU) | ||
| 367 | rx_status->flag |= RX_FLAG_ALLOW_SAME_PN; | ||
| 368 | |||
| 368 | dup_data->last_seq[tid] = hdr->seq_ctrl; | 369 | dup_data->last_seq[tid] = hdr->seq_ctrl; |
| 369 | dup_data->last_sub_frame[tid] = sub_frame_idx; | 370 | dup_data->last_sub_frame[tid] = sub_frame_idx; |
| 370 | 371 | ||
| @@ -971,7 +972,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
| 971 | if (ieee80211_is_data(hdr->frame_control)) | 972 | if (ieee80211_is_data(hdr->frame_control)) |
| 972 | iwl_mvm_rx_csum(sta, skb, desc); | 973 | iwl_mvm_rx_csum(sta, skb, desc); |
| 973 | 974 | ||
| 974 | if (iwl_mvm_is_nonagg_dup(sta, queue, rx_status, hdr, desc)) { | 975 | if (iwl_mvm_is_dup(sta, queue, rx_status, hdr, desc)) { |
| 975 | kfree_skb(skb); | 976 | kfree_skb(skb); |
| 976 | goto out; | 977 | goto out; |
| 977 | } | 978 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 6b2674e02606..630e23cb0ffb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c | |||
| @@ -2039,7 +2039,7 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 2039 | struct iwl_trans_txq_scd_cfg cfg = { | 2039 | struct iwl_trans_txq_scd_cfg cfg = { |
| 2040 | .fifo = IWL_MVM_TX_FIFO_MCAST, | 2040 | .fifo = IWL_MVM_TX_FIFO_MCAST, |
| 2041 | .sta_id = msta->sta_id, | 2041 | .sta_id = msta->sta_id, |
| 2042 | .tid = IWL_MAX_TID_COUNT, | 2042 | .tid = 0, |
| 2043 | .aggregate = false, | 2043 | .aggregate = false, |
| 2044 | .frame_limit = IWL_FRAME_LIMIT, | 2044 | .frame_limit = IWL_FRAME_LIMIT, |
| 2045 | }; | 2045 | }; |
| @@ -2053,6 +2053,17 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 2053 | return -ENOTSUPP; | 2053 | return -ENOTSUPP; |
| 2054 | 2054 | ||
| 2055 | /* | 2055 | /* |
| 2056 | * In IBSS, ieee80211_check_queues() sets the cab_queue to be | ||
| 2057 | * invalid, so make sure we use the queue we want. | ||
| 2058 | * Note that this is done here as we want to avoid making DQA | ||
| 2059 | * changes in mac80211 layer. | ||
| 2060 | */ | ||
| 2061 | if (vif->type == NL80211_IFTYPE_ADHOC) { | ||
| 2062 | vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE; | ||
| 2063 | mvmvif->cab_queue = vif->cab_queue; | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | /* | ||
| 2056 | * While in previous FWs we had to exclude cab queue from TFD queue | 2067 | * While in previous FWs we had to exclude cab queue from TFD queue |
| 2057 | * mask, now it is needed as any other queue. | 2068 | * mask, now it is needed as any other queue. |
| 2058 | */ | 2069 | */ |
| @@ -2079,24 +2090,13 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 2079 | if (iwl_mvm_has_new_tx_api(mvm)) { | 2090 | if (iwl_mvm_has_new_tx_api(mvm)) { |
| 2080 | int queue = iwl_mvm_tvqm_enable_txq(mvm, vif->cab_queue, | 2091 | int queue = iwl_mvm_tvqm_enable_txq(mvm, vif->cab_queue, |
| 2081 | msta->sta_id, | 2092 | msta->sta_id, |
| 2082 | IWL_MAX_TID_COUNT, | 2093 | 0, |
| 2083 | timeout); | 2094 | timeout); |
| 2084 | mvmvif->cab_queue = queue; | 2095 | mvmvif->cab_queue = queue; |
| 2085 | } else if (!fw_has_api(&mvm->fw->ucode_capa, | 2096 | } else if (!fw_has_api(&mvm->fw->ucode_capa, |
| 2086 | IWL_UCODE_TLV_API_STA_TYPE)) { | 2097 | IWL_UCODE_TLV_API_STA_TYPE)) |
| 2087 | /* | ||
| 2088 | * In IBSS, ieee80211_check_queues() sets the cab_queue to be | ||
| 2089 | * invalid, so make sure we use the queue we want. | ||
| 2090 | * Note that this is done here as we want to avoid making DQA | ||
| 2091 | * changes in mac80211 layer. | ||
| 2092 | */ | ||
| 2093 | if (vif->type == NL80211_IFTYPE_ADHOC) { | ||
| 2094 | vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE; | ||
| 2095 | mvmvif->cab_queue = vif->cab_queue; | ||
| 2096 | } | ||
| 2097 | iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0, | 2098 | iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0, |
| 2098 | &cfg, timeout); | 2099 | &cfg, timeout); |
| 2099 | } | ||
| 2100 | 2100 | ||
| 2101 | return 0; | 2101 | return 0; |
| 2102 | } | 2102 | } |
| @@ -2115,7 +2115,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 2115 | iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true, 0); | 2115 | iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true, 0); |
| 2116 | 2116 | ||
| 2117 | iwl_mvm_disable_txq(mvm, mvmvif->cab_queue, vif->cab_queue, | 2117 | iwl_mvm_disable_txq(mvm, mvmvif->cab_queue, vif->cab_queue, |
| 2118 | IWL_MAX_TID_COUNT, 0); | 2118 | 0, 0); |
| 2119 | 2119 | ||
| 2120 | ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); | 2120 | ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); |
| 2121 | if (ret) | 2121 | if (ret) |
| @@ -3170,8 +3170,9 @@ static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, | |||
| 3170 | int ret, size; | 3170 | int ret, size; |
| 3171 | u32 status; | 3171 | u32 status; |
| 3172 | 3172 | ||
| 3173 | /* This is a valid situation for GTK removal */ | ||
| 3173 | if (sta_id == IWL_MVM_INVALID_STA) | 3174 | if (sta_id == IWL_MVM_INVALID_STA) |
| 3174 | return -EINVAL; | 3175 | return 0; |
| 3175 | 3176 | ||
| 3176 | key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & | 3177 | key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & |
| 3177 | STA_KEY_FLG_KEYID_MSK); | 3178 | STA_KEY_FLG_KEYID_MSK); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 200ab50ec86b..acb217e666db 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | |||
| @@ -616,7 +616,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
| 616 | time_cmd.repeat = 1; | 616 | time_cmd.repeat = 1; |
| 617 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | | 617 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | |
| 618 | TE_V2_NOTIF_HOST_EVENT_END | | 618 | TE_V2_NOTIF_HOST_EVENT_END | |
| 619 | T2_V2_START_IMMEDIATELY); | 619 | TE_V2_START_IMMEDIATELY); |
| 620 | 620 | ||
| 621 | if (!wait_for_notif) { | 621 | if (!wait_for_notif) { |
| 622 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 622 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
| @@ -803,7 +803,7 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 803 | time_cmd.repeat = 1; | 803 | time_cmd.repeat = 1; |
| 804 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | | 804 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | |
| 805 | TE_V2_NOTIF_HOST_EVENT_END | | 805 | TE_V2_NOTIF_HOST_EVENT_END | |
| 806 | T2_V2_START_IMMEDIATELY); | 806 | TE_V2_START_IMMEDIATELY); |
| 807 | 807 | ||
| 808 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 808 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
| 809 | } | 809 | } |
| @@ -913,6 +913,8 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, | |||
| 913 | time_cmd.interval = cpu_to_le32(1); | 913 | time_cmd.interval = cpu_to_le32(1); |
| 914 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | | 914 | time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START | |
| 915 | TE_V2_ABSENCE); | 915 | TE_V2_ABSENCE); |
| 916 | if (!apply_time) | ||
| 917 | time_cmd.policy |= cpu_to_le16(TE_V2_START_IMMEDIATELY); | ||
| 916 | 918 | ||
| 917 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 919 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
| 918 | } | 920 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index dda77b327c98..af6dfceab6b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
| @@ -419,11 +419,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, | |||
| 419 | { | 419 | { |
| 420 | struct ieee80211_key_conf *keyconf = info->control.hw_key; | 420 | struct ieee80211_key_conf *keyconf = info->control.hw_key; |
| 421 | u8 *crypto_hdr = skb_frag->data + hdrlen; | 421 | u8 *crypto_hdr = skb_frag->data + hdrlen; |
| 422 | enum iwl_tx_cmd_sec_ctrl type = TX_CMD_SEC_CCM; | ||
| 422 | u64 pn; | 423 | u64 pn; |
| 423 | 424 | ||
| 424 | switch (keyconf->cipher) { | 425 | switch (keyconf->cipher) { |
| 425 | case WLAN_CIPHER_SUITE_CCMP: | 426 | case WLAN_CIPHER_SUITE_CCMP: |
| 426 | case WLAN_CIPHER_SUITE_CCMP_256: | ||
| 427 | iwl_mvm_set_tx_cmd_ccmp(info, tx_cmd); | 427 | iwl_mvm_set_tx_cmd_ccmp(info, tx_cmd); |
| 428 | iwl_mvm_set_tx_cmd_pn(info, crypto_hdr); | 428 | iwl_mvm_set_tx_cmd_pn(info, crypto_hdr); |
| 429 | break; | 429 | break; |
| @@ -447,13 +447,16 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, | |||
| 447 | break; | 447 | break; |
| 448 | case WLAN_CIPHER_SUITE_GCMP: | 448 | case WLAN_CIPHER_SUITE_GCMP: |
| 449 | case WLAN_CIPHER_SUITE_GCMP_256: | 449 | case WLAN_CIPHER_SUITE_GCMP_256: |
| 450 | type = TX_CMD_SEC_GCMP; | ||
| 451 | /* Fall through */ | ||
| 452 | case WLAN_CIPHER_SUITE_CCMP_256: | ||
| 450 | /* TODO: Taking the key from the table might introduce a race | 453 | /* TODO: Taking the key from the table might introduce a race |
| 451 | * when PTK rekeying is done, having an old packets with a PN | 454 | * when PTK rekeying is done, having an old packets with a PN |
| 452 | * based on the old key but the message encrypted with a new | 455 | * based on the old key but the message encrypted with a new |
| 453 | * one. | 456 | * one. |
| 454 | * Need to handle this. | 457 | * Need to handle this. |
| 455 | */ | 458 | */ |
| 456 | tx_cmd->sec_ctl |= TX_CMD_SEC_GCMP | TX_CMD_SEC_KEY_FROM_TABLE; | 459 | tx_cmd->sec_ctl |= type | TX_CMD_SEC_KEY_FROM_TABLE; |
| 457 | tx_cmd->key[0] = keyconf->hw_key_idx; | 460 | tx_cmd->key[0] = keyconf->hw_key_idx; |
| 458 | iwl_mvm_set_tx_cmd_pn(info, crypto_hdr); | 461 | iwl_mvm_set_tx_cmd_pn(info, crypto_hdr); |
| 459 | break; | 462 | break; |
| @@ -645,7 +648,11 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
| 645 | if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE || | 648 | if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE || |
| 646 | info.control.vif->type == NL80211_IFTYPE_AP || | 649 | info.control.vif->type == NL80211_IFTYPE_AP || |
| 647 | info.control.vif->type == NL80211_IFTYPE_ADHOC) { | 650 | info.control.vif->type == NL80211_IFTYPE_ADHOC) { |
| 648 | sta_id = mvmvif->bcast_sta.sta_id; | 651 | if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE) |
| 652 | sta_id = mvmvif->bcast_sta.sta_id; | ||
| 653 | else | ||
| 654 | sta_id = mvmvif->mcast_sta.sta_id; | ||
| 655 | |||
| 649 | queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, | 656 | queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, |
| 650 | hdr->frame_control); | 657 | hdr->frame_control); |
| 651 | if (queue < 0) | 658 | if (queue < 0) |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 6d0a907d5ba5..fabae0f60683 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | |||
| @@ -147,7 +147,7 @@ static void iwl_pcie_gen2_tfd_unmap(struct iwl_trans *trans, | |||
| 147 | /* Sanity check on number of chunks */ | 147 | /* Sanity check on number of chunks */ |
| 148 | num_tbs = iwl_pcie_gen2_get_num_tbs(trans, tfd); | 148 | num_tbs = iwl_pcie_gen2_get_num_tbs(trans, tfd); |
| 149 | 149 | ||
| 150 | if (num_tbs >= trans_pcie->max_tbs) { | 150 | if (num_tbs > trans_pcie->max_tbs) { |
| 151 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); | 151 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); |
| 152 | return; | 152 | return; |
| 153 | } | 153 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 3f85713c41dc..1a566287993d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c | |||
| @@ -378,7 +378,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, | |||
| 378 | /* Sanity check on number of chunks */ | 378 | /* Sanity check on number of chunks */ |
| 379 | num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd); | 379 | num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd); |
| 380 | 380 | ||
| 381 | if (num_tbs >= trans_pcie->max_tbs) { | 381 | if (num_tbs > trans_pcie->max_tbs) { |
| 382 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); | 382 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); |
| 383 | /* @todo issue fatal error, it is quite serious situation */ | 383 | /* @todo issue fatal error, it is quite serious situation */ |
| 384 | return; | 384 | return; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6e0af815f25e..35b21f8152bb 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -2727,6 +2727,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, | |||
| 2727 | mutex_init(&data->mutex); | 2727 | mutex_init(&data->mutex); |
| 2728 | 2728 | ||
| 2729 | data->netgroup = hwsim_net_get_netgroup(net); | 2729 | data->netgroup = hwsim_net_get_netgroup(net); |
| 2730 | data->wmediumd = hwsim_net_get_wmediumd(net); | ||
| 2730 | 2731 | ||
| 2731 | /* Enable frame retransmissions for lossy channels */ | 2732 | /* Enable frame retransmissions for lossy channels */ |
| 2732 | hw->max_rates = 4; | 2733 | hw->max_rates = 4; |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index f9ccd13c79f9..e7bbbc95cdb1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | |||
| @@ -1125,7 +1125,8 @@ static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw) | |||
| 1125 | 1125 | ||
| 1126 | /* Configuration Space offset 0x70f BIT7 is used to control L0S */ | 1126 | /* Configuration Space offset 0x70f BIT7 is used to control L0S */ |
| 1127 | tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f); | 1127 | tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f); |
| 1128 | _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7)); | 1128 | _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) | |
| 1129 | ASPM_L1_LATENCY << 3); | ||
| 1129 | 1130 | ||
| 1130 | /* Configuration Space offset 0x719 Bit3 is for L1 | 1131 | /* Configuration Space offset 0x719 Bit3 is for L1 |
| 1131 | * BIT4 is for clock request | 1132 | * BIT4 is for clock request |
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c index 345acca576b3..1bd7b3734751 100644 --- a/drivers/nvdimm/blk.c +++ b/drivers/nvdimm/blk.c | |||
| @@ -278,8 +278,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) | |||
| 278 | disk->queue = q; | 278 | disk->queue = q; |
| 279 | disk->flags = GENHD_FL_EXT_DEVT; | 279 | disk->flags = GENHD_FL_EXT_DEVT; |
| 280 | nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name); | 280 | nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name); |
| 281 | set_capacity(disk, 0); | ||
| 282 | device_add_disk(dev, disk); | ||
| 283 | 281 | ||
| 284 | if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk)) | 282 | if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk)) |
| 285 | return -ENOMEM; | 283 | return -ENOMEM; |
| @@ -292,6 +290,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) | |||
| 292 | } | 290 | } |
| 293 | 291 | ||
| 294 | set_capacity(disk, available_disk_size >> SECTOR_SHIFT); | 292 | set_capacity(disk, available_disk_size >> SECTOR_SHIFT); |
| 293 | device_add_disk(dev, disk); | ||
| 295 | revalidate_disk(disk); | 294 | revalidate_disk(disk); |
| 296 | return 0; | 295 | return 0; |
| 297 | } | 296 | } |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 2ef544f10ec8..4b95ac513de2 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
| @@ -1545,8 +1545,6 @@ static int btt_blk_init(struct btt *btt) | |||
| 1545 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue); | 1545 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue); |
| 1546 | btt->btt_queue->queuedata = btt; | 1546 | btt->btt_queue->queuedata = btt; |
| 1547 | 1547 | ||
| 1548 | set_capacity(btt->btt_disk, 0); | ||
| 1549 | device_add_disk(&btt->nd_btt->dev, btt->btt_disk); | ||
| 1550 | if (btt_meta_size(btt)) { | 1548 | if (btt_meta_size(btt)) { |
| 1551 | int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt)); | 1549 | int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt)); |
| 1552 | 1550 | ||
| @@ -1558,6 +1556,7 @@ static int btt_blk_init(struct btt *btt) | |||
| 1558 | } | 1556 | } |
| 1559 | } | 1557 | } |
| 1560 | set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9); | 1558 | set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9); |
| 1559 | device_add_disk(&btt->nd_btt->dev, btt->btt_disk); | ||
| 1561 | btt->nd_btt->size = btt->nlba * (u64)btt->sector_size; | 1560 | btt->nd_btt->size = btt->nlba * (u64)btt->sector_size; |
| 1562 | revalidate_disk(btt->btt_disk); | 1561 | revalidate_disk(btt->btt_disk); |
| 1563 | 1562 | ||
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index f5c4e8c6e29d..2f4d18752c97 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c | |||
| @@ -304,7 +304,7 @@ static const struct attribute_group *nd_pfn_attribute_groups[] = { | |||
| 304 | struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn, | 304 | struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn, |
| 305 | struct nd_namespace_common *ndns) | 305 | struct nd_namespace_common *ndns) |
| 306 | { | 306 | { |
| 307 | struct device *dev = &nd_pfn->dev; | 307 | struct device *dev; |
| 308 | 308 | ||
| 309 | if (!nd_pfn) | 309 | if (!nd_pfn) |
| 310 | return NULL; | 310 | return NULL; |
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index e6d01911e092..1593e1806b16 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c | |||
| @@ -532,11 +532,13 @@ static ssize_t persistence_domain_show(struct device *dev, | |||
| 532 | struct device_attribute *attr, char *buf) | 532 | struct device_attribute *attr, char *buf) |
| 533 | { | 533 | { |
| 534 | struct nd_region *nd_region = to_nd_region(dev); | 534 | struct nd_region *nd_region = to_nd_region(dev); |
| 535 | unsigned long flags = nd_region->flags; | ||
| 536 | 535 | ||
| 537 | return sprintf(buf, "%s%s\n", | 536 | if (test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags)) |
| 538 | flags & BIT(ND_REGION_PERSIST_CACHE) ? "cpu_cache " : "", | 537 | return sprintf(buf, "cpu_cache\n"); |
| 539 | flags & BIT(ND_REGION_PERSIST_MEMCTRL) ? "memory_controller " : ""); | 538 | else if (test_bit(ND_REGION_PERSIST_MEMCTRL, &nd_region->flags)) |
| 539 | return sprintf(buf, "memory_controller\n"); | ||
| 540 | else | ||
| 541 | return sprintf(buf, "\n"); | ||
| 540 | } | 542 | } |
| 541 | static DEVICE_ATTR_RO(persistence_domain); | 543 | static DEVICE_ATTR_RO(persistence_domain); |
| 542 | 544 | ||
| @@ -593,6 +595,13 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n) | |||
| 593 | return 0; | 595 | return 0; |
| 594 | } | 596 | } |
| 595 | 597 | ||
| 598 | if (a == &dev_attr_persistence_domain.attr) { | ||
| 599 | if ((nd_region->flags & (BIT(ND_REGION_PERSIST_CACHE) | ||
| 600 | | BIT(ND_REGION_PERSIST_MEMCTRL))) == 0) | ||
| 601 | return 0; | ||
| 602 | return a->mode; | ||
| 603 | } | ||
| 604 | |||
| 596 | if (a != &dev_attr_set_cookie.attr | 605 | if (a != &dev_attr_set_cookie.attr |
| 597 | && a != &dev_attr_available_size.attr) | 606 | && a != &dev_attr_available_size.attr) |
| 598 | return a->mode; | 607 | return a->mode; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8b14bd326d4a..46d47bd6ca1f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -3908,6 +3908,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230, | |||
| 3908 | quirk_dma_func1_alias); | 3908 | quirk_dma_func1_alias); |
| 3909 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, | 3909 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, |
| 3910 | quirk_dma_func1_alias); | 3910 | quirk_dma_func1_alias); |
| 3911 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645, | ||
| 3912 | quirk_dma_func1_alias); | ||
| 3911 | /* https://bugs.gentoo.org/show_bug.cgi?id=497630 */ | 3913 | /* https://bugs.gentoo.org/show_bug.cgi?id=497630 */ |
| 3912 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON, | 3914 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON, |
| 3913 | PCI_DEVICE_ID_JMICRON_JMB388_ESD, | 3915 | PCI_DEVICE_ID_JMICRON_JMB388_ESD, |
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm.c index c32399faff57..90c274490181 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm.c | |||
| @@ -124,7 +124,7 @@ static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = { | |||
| 124 | EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c), | 124 | EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c), |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { | 127 | static const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { |
| 128 | { | 128 | { |
| 129 | /* pin-controller instance 0 data */ | 129 | /* pin-controller instance 0 data */ |
| 130 | .pin_banks = s5pv210_pin_bank, | 130 | .pin_banks = s5pv210_pin_bank, |
| @@ -137,6 +137,11 @@ const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { | |||
| 137 | }, | 137 | }, |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | const struct samsung_pinctrl_of_match_data s5pv210_of_data __initconst = { | ||
| 141 | .ctrl = s5pv210_pin_ctrl, | ||
| 142 | .num_ctrl = ARRAY_SIZE(s5pv210_pin_ctrl), | ||
| 143 | }; | ||
| 144 | |||
| 140 | /* Pad retention control code for accessing PMU regmap */ | 145 | /* Pad retention control code for accessing PMU regmap */ |
| 141 | static atomic_t exynos_shared_retention_refcnt; | 146 | static atomic_t exynos_shared_retention_refcnt; |
| 142 | 147 | ||
| @@ -199,7 +204,7 @@ static const struct samsung_retention_data exynos3250_retention_data __initconst | |||
| 199 | * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes | 204 | * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes |
| 200 | * two gpio/pin-mux/pinconfig controllers. | 205 | * two gpio/pin-mux/pinconfig controllers. |
| 201 | */ | 206 | */ |
| 202 | const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { | 207 | static const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { |
| 203 | { | 208 | { |
| 204 | /* pin-controller instance 0 data */ | 209 | /* pin-controller instance 0 data */ |
| 205 | .pin_banks = exynos3250_pin_banks0, | 210 | .pin_banks = exynos3250_pin_banks0, |
| @@ -220,6 +225,11 @@ const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { | |||
| 220 | }, | 225 | }, |
| 221 | }; | 226 | }; |
| 222 | 227 | ||
| 228 | const struct samsung_pinctrl_of_match_data exynos3250_of_data __initconst = { | ||
| 229 | .ctrl = exynos3250_pin_ctrl, | ||
| 230 | .num_ctrl = ARRAY_SIZE(exynos3250_pin_ctrl), | ||
| 231 | }; | ||
| 232 | |||
| 223 | /* pin banks of exynos4210 pin-controller 0 */ | 233 | /* pin banks of exynos4210 pin-controller 0 */ |
| 224 | static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = { | 234 | static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = { |
| 225 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 235 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
| @@ -303,7 +313,7 @@ static const struct samsung_retention_data exynos4_audio_retention_data __initco | |||
| 303 | * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes | 313 | * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes |
| 304 | * three gpio/pin-mux/pinconfig controllers. | 314 | * three gpio/pin-mux/pinconfig controllers. |
| 305 | */ | 315 | */ |
| 306 | const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { | 316 | static const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { |
| 307 | { | 317 | { |
| 308 | /* pin-controller instance 0 data */ | 318 | /* pin-controller instance 0 data */ |
| 309 | .pin_banks = exynos4210_pin_banks0, | 319 | .pin_banks = exynos4210_pin_banks0, |
| @@ -329,6 +339,11 @@ const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { | |||
| 329 | }, | 339 | }, |
| 330 | }; | 340 | }; |
| 331 | 341 | ||
| 342 | const struct samsung_pinctrl_of_match_data exynos4210_of_data __initconst = { | ||
| 343 | .ctrl = exynos4210_pin_ctrl, | ||
| 344 | .num_ctrl = ARRAY_SIZE(exynos4210_pin_ctrl), | ||
| 345 | }; | ||
| 346 | |||
| 332 | /* pin banks of exynos4x12 pin-controller 0 */ | 347 | /* pin banks of exynos4x12 pin-controller 0 */ |
| 333 | static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = { | 348 | static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = { |
| 334 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 349 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
| @@ -391,7 +406,7 @@ static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst = | |||
| 391 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes | 406 | * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes |
| 392 | * four gpio/pin-mux/pinconfig controllers. | 407 | * four gpio/pin-mux/pinconfig controllers. |
| 393 | */ | 408 | */ |
| 394 | const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { | 409 | static const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { |
| 395 | { | 410 | { |
| 396 | /* pin-controller instance 0 data */ | 411 | /* pin-controller instance 0 data */ |
| 397 | .pin_banks = exynos4x12_pin_banks0, | 412 | .pin_banks = exynos4x12_pin_banks0, |
| @@ -427,6 +442,11 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { | |||
| 427 | }, | 442 | }, |
| 428 | }; | 443 | }; |
| 429 | 444 | ||
| 445 | const struct samsung_pinctrl_of_match_data exynos4x12_of_data __initconst = { | ||
| 446 | .ctrl = exynos4x12_pin_ctrl, | ||
| 447 | .num_ctrl = ARRAY_SIZE(exynos4x12_pin_ctrl), | ||
| 448 | }; | ||
| 449 | |||
| 430 | /* pin banks of exynos5250 pin-controller 0 */ | 450 | /* pin banks of exynos5250 pin-controller 0 */ |
| 431 | static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = { | 451 | static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = { |
| 432 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 452 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
| @@ -487,7 +507,7 @@ static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst = | |||
| 487 | * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes | 507 | * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes |
| 488 | * four gpio/pin-mux/pinconfig controllers. | 508 | * four gpio/pin-mux/pinconfig controllers. |
| 489 | */ | 509 | */ |
| 490 | const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { | 510 | static const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { |
| 491 | { | 511 | { |
| 492 | /* pin-controller instance 0 data */ | 512 | /* pin-controller instance 0 data */ |
| 493 | .pin_banks = exynos5250_pin_banks0, | 513 | .pin_banks = exynos5250_pin_banks0, |
| @@ -523,6 +543,11 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { | |||
| 523 | }, | 543 | }, |
| 524 | }; | 544 | }; |
| 525 | 545 | ||
| 546 | const struct samsung_pinctrl_of_match_data exynos5250_of_data __initconst = { | ||
| 547 | .ctrl = exynos5250_pin_ctrl, | ||
| 548 | .num_ctrl = ARRAY_SIZE(exynos5250_pin_ctrl), | ||
| 549 | }; | ||
| 550 | |||
| 526 | /* pin banks of exynos5260 pin-controller 0 */ | 551 | /* pin banks of exynos5260 pin-controller 0 */ |
| 527 | static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = { | 552 | static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = { |
| 528 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00), | 553 | EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00), |
| @@ -567,7 +592,7 @@ static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst = | |||
| 567 | * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes | 592 | * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes |
| 568 | * three gpio/pin-mux/pinconfig controllers. | 593 | * three gpio/pin-mux/pinconfig controllers. |
| 569 | */ | 594 | */ |
| 570 | const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { | 595 | static const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { |
| 571 | { | 596 | { |
| 572 | /* pin-controller instance 0 data */ | 597 | /* pin-controller instance 0 data */ |
| 573 | .pin_banks = exynos5260_pin_banks0, | 598 | .pin_banks = exynos5260_pin_banks0, |
| @@ -587,6 +612,11 @@ const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { | |||
| 587 | }, | 612 | }, |
| 588 | }; | 613 | }; |
| 589 | 614 | ||
| 615 | const struct samsung_pinctrl_of_match_data exynos5260_of_data __initconst = { | ||
| 616 | .ctrl = exynos5260_pin_ctrl, | ||
| 617 | .num_ctrl = ARRAY_SIZE(exynos5260_pin_ctrl), | ||
| 618 | }; | ||
| 619 | |||
| 590 | /* pin banks of exynos5410 pin-controller 0 */ | 620 | /* pin banks of exynos5410 pin-controller 0 */ |
| 591 | static const struct samsung_pin_bank_data exynos5410_pin_banks0[] __initconst = { | 621 | static const struct samsung_pin_bank_data exynos5410_pin_banks0[] __initconst = { |
| 592 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), | 622 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), |
| @@ -657,7 +687,7 @@ static const struct samsung_pin_bank_data exynos5410_pin_banks3[] __initconst = | |||
| 657 | * Samsung pinctrl driver data for Exynos5410 SoC. Exynos5410 SoC includes | 687 | * Samsung pinctrl driver data for Exynos5410 SoC. Exynos5410 SoC includes |
| 658 | * four gpio/pin-mux/pinconfig controllers. | 688 | * four gpio/pin-mux/pinconfig controllers. |
| 659 | */ | 689 | */ |
| 660 | const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = { | 690 | static const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = { |
| 661 | { | 691 | { |
| 662 | /* pin-controller instance 0 data */ | 692 | /* pin-controller instance 0 data */ |
| 663 | .pin_banks = exynos5410_pin_banks0, | 693 | .pin_banks = exynos5410_pin_banks0, |
| @@ -690,6 +720,11 @@ const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = { | |||
| 690 | }, | 720 | }, |
| 691 | }; | 721 | }; |
| 692 | 722 | ||
| 723 | const struct samsung_pinctrl_of_match_data exynos5410_of_data __initconst = { | ||
| 724 | .ctrl = exynos5410_pin_ctrl, | ||
| 725 | .num_ctrl = ARRAY_SIZE(exynos5410_pin_ctrl), | ||
| 726 | }; | ||
| 727 | |||
| 693 | /* pin banks of exynos5420 pin-controller 0 */ | 728 | /* pin banks of exynos5420 pin-controller 0 */ |
| 694 | static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = { | 729 | static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = { |
| 695 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00), | 730 | EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00), |
| @@ -774,7 +809,7 @@ static const struct samsung_retention_data exynos5420_retention_data __initconst | |||
| 774 | * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes | 809 | * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes |
| 775 | * four gpio/pin-mux/pinconfig controllers. | 810 | * four gpio/pin-mux/pinconfig controllers. |
| 776 | */ | 811 | */ |
| 777 | const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { | 812 | static const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { |
| 778 | { | 813 | { |
| 779 | /* pin-controller instance 0 data */ | 814 | /* pin-controller instance 0 data */ |
| 780 | .pin_banks = exynos5420_pin_banks0, | 815 | .pin_banks = exynos5420_pin_banks0, |
| @@ -808,3 +843,8 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { | |||
| 808 | .retention_data = &exynos4_audio_retention_data, | 843 | .retention_data = &exynos4_audio_retention_data, |
| 809 | }, | 844 | }, |
| 810 | }; | 845 | }; |
| 846 | |||
| 847 | const struct samsung_pinctrl_of_match_data exynos5420_of_data __initconst = { | ||
| 848 | .ctrl = exynos5420_pin_ctrl, | ||
| 849 | .num_ctrl = ARRAY_SIZE(exynos5420_pin_ctrl), | ||
| 850 | }; | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c index fc8f7833bec0..71c9d1d9f345 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c | |||
| @@ -175,7 +175,7 @@ static const struct samsung_retention_data exynos5433_fsys_retention_data __init | |||
| 175 | * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes | 175 | * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes |
| 176 | * ten gpio/pin-mux/pinconfig controllers. | 176 | * ten gpio/pin-mux/pinconfig controllers. |
| 177 | */ | 177 | */ |
| 178 | const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { | 178 | static const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { |
| 179 | { | 179 | { |
| 180 | /* pin-controller instance 0 data */ | 180 | /* pin-controller instance 0 data */ |
| 181 | .pin_banks = exynos5433_pin_banks0, | 181 | .pin_banks = exynos5433_pin_banks0, |
| @@ -260,6 +260,11 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { | |||
| 260 | }, | 260 | }, |
| 261 | }; | 261 | }; |
| 262 | 262 | ||
| 263 | const struct samsung_pinctrl_of_match_data exynos5433_of_data __initconst = { | ||
| 264 | .ctrl = exynos5433_pin_ctrl, | ||
| 265 | .num_ctrl = ARRAY_SIZE(exynos5433_pin_ctrl), | ||
| 266 | }; | ||
| 267 | |||
| 263 | /* pin banks of exynos7 pin-controller - ALIVE */ | 268 | /* pin banks of exynos7 pin-controller - ALIVE */ |
| 264 | static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { | 269 | static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { |
| 265 | EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), | 270 | EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), |
| @@ -339,7 +344,7 @@ static const struct samsung_pin_bank_data exynos7_pin_banks9[] __initconst = { | |||
| 339 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), | 344 | EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), |
| 340 | }; | 345 | }; |
| 341 | 346 | ||
| 342 | const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { | 347 | static const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { |
| 343 | { | 348 | { |
| 344 | /* pin-controller instance 0 Alive data */ | 349 | /* pin-controller instance 0 Alive data */ |
| 345 | .pin_banks = exynos7_pin_banks0, | 350 | .pin_banks = exynos7_pin_banks0, |
| @@ -392,3 +397,8 @@ const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { | |||
| 392 | .eint_gpio_init = exynos_eint_gpio_init, | 397 | .eint_gpio_init = exynos_eint_gpio_init, |
| 393 | }, | 398 | }, |
| 394 | }; | 399 | }; |
| 400 | |||
| 401 | const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = { | ||
| 402 | .ctrl = exynos7_pin_ctrl, | ||
| 403 | .num_ctrl = ARRAY_SIZE(exynos7_pin_ctrl), | ||
| 404 | }; | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 10187cb0e9b9..7e824e4d20f4 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c | |||
| @@ -565,7 +565,7 @@ static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = { | |||
| 565 | PIN_BANK_2BIT(13, 0x080, "gpj"), | 565 | PIN_BANK_2BIT(13, 0x080, "gpj"), |
| 566 | }; | 566 | }; |
| 567 | 567 | ||
| 568 | const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { | 568 | static const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { |
| 569 | { | 569 | { |
| 570 | .pin_banks = s3c2412_pin_banks, | 570 | .pin_banks = s3c2412_pin_banks, |
| 571 | .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), | 571 | .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), |
| @@ -573,6 +573,11 @@ const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { | |||
| 573 | }, | 573 | }, |
| 574 | }; | 574 | }; |
| 575 | 575 | ||
| 576 | const struct samsung_pinctrl_of_match_data s3c2412_of_data __initconst = { | ||
| 577 | .ctrl = s3c2412_pin_ctrl, | ||
| 578 | .num_ctrl = ARRAY_SIZE(s3c2412_pin_ctrl), | ||
| 579 | }; | ||
| 580 | |||
| 576 | static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { | 581 | static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { |
| 577 | PIN_BANK_A(27, 0x000, "gpa"), | 582 | PIN_BANK_A(27, 0x000, "gpa"), |
| 578 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 583 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
| @@ -587,7 +592,7 @@ static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { | |||
| 587 | PIN_BANK_2BIT(2, 0x100, "gpm"), | 592 | PIN_BANK_2BIT(2, 0x100, "gpm"), |
| 588 | }; | 593 | }; |
| 589 | 594 | ||
| 590 | const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { | 595 | static const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { |
| 591 | { | 596 | { |
| 592 | .pin_banks = s3c2416_pin_banks, | 597 | .pin_banks = s3c2416_pin_banks, |
| 593 | .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), | 598 | .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), |
| @@ -595,6 +600,11 @@ const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { | |||
| 595 | }, | 600 | }, |
| 596 | }; | 601 | }; |
| 597 | 602 | ||
| 603 | const struct samsung_pinctrl_of_match_data s3c2416_of_data __initconst = { | ||
| 604 | .ctrl = s3c2416_pin_ctrl, | ||
| 605 | .num_ctrl = ARRAY_SIZE(s3c2416_pin_ctrl), | ||
| 606 | }; | ||
| 607 | |||
| 598 | static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { | 608 | static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { |
| 599 | PIN_BANK_A(25, 0x000, "gpa"), | 609 | PIN_BANK_A(25, 0x000, "gpa"), |
| 600 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 610 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
| @@ -607,7 +617,7 @@ static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { | |||
| 607 | PIN_BANK_2BIT(13, 0x0d0, "gpj"), | 617 | PIN_BANK_2BIT(13, 0x0d0, "gpj"), |
| 608 | }; | 618 | }; |
| 609 | 619 | ||
| 610 | const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { | 620 | static const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { |
| 611 | { | 621 | { |
| 612 | .pin_banks = s3c2440_pin_banks, | 622 | .pin_banks = s3c2440_pin_banks, |
| 613 | .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), | 623 | .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), |
| @@ -615,6 +625,11 @@ const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { | |||
| 615 | }, | 625 | }, |
| 616 | }; | 626 | }; |
| 617 | 627 | ||
| 628 | const struct samsung_pinctrl_of_match_data s3c2440_of_data __initconst = { | ||
| 629 | .ctrl = s3c2440_pin_ctrl, | ||
| 630 | .num_ctrl = ARRAY_SIZE(s3c2440_pin_ctrl), | ||
| 631 | }; | ||
| 632 | |||
| 618 | static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { | 633 | static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { |
| 619 | PIN_BANK_A(28, 0x000, "gpa"), | 634 | PIN_BANK_A(28, 0x000, "gpa"), |
| 620 | PIN_BANK_2BIT(11, 0x010, "gpb"), | 635 | PIN_BANK_2BIT(11, 0x010, "gpb"), |
| @@ -630,10 +645,15 @@ static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { | |||
| 630 | PIN_BANK_2BIT(2, 0x100, "gpm"), | 645 | PIN_BANK_2BIT(2, 0x100, "gpm"), |
| 631 | }; | 646 | }; |
| 632 | 647 | ||
| 633 | const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = { | 648 | static const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = { |
| 634 | { | 649 | { |
| 635 | .pin_banks = s3c2450_pin_banks, | 650 | .pin_banks = s3c2450_pin_banks, |
| 636 | .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), | 651 | .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), |
| 637 | .eint_wkup_init = s3c24xx_eint_init, | 652 | .eint_wkup_init = s3c24xx_eint_init, |
| 638 | }, | 653 | }, |
| 639 | }; | 654 | }; |
| 655 | |||
| 656 | const struct samsung_pinctrl_of_match_data s3c2450_of_data __initconst = { | ||
| 657 | .ctrl = s3c2450_pin_ctrl, | ||
| 658 | .num_ctrl = ARRAY_SIZE(s3c2450_pin_ctrl), | ||
| 659 | }; | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 679628ac4b31..288e6567ceb1 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c | |||
| @@ -789,7 +789,7 @@ static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = { | |||
| 789 | * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes | 789 | * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes |
| 790 | * one gpio/pin-mux/pinconfig controller. | 790 | * one gpio/pin-mux/pinconfig controller. |
| 791 | */ | 791 | */ |
| 792 | const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = { | 792 | static const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = { |
| 793 | { | 793 | { |
| 794 | /* pin-controller instance 1 data */ | 794 | /* pin-controller instance 1 data */ |
| 795 | .pin_banks = s3c64xx_pin_banks0, | 795 | .pin_banks = s3c64xx_pin_banks0, |
| @@ -798,3 +798,8 @@ const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = { | |||
| 798 | .eint_wkup_init = s3c64xx_eint_eint0_init, | 798 | .eint_wkup_init = s3c64xx_eint_eint0_init, |
| 799 | }, | 799 | }, |
| 800 | }; | 800 | }; |
| 801 | |||
| 802 | const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = { | ||
| 803 | .ctrl = s3c64xx_pin_ctrl, | ||
| 804 | .num_ctrl = ARRAY_SIZE(s3c64xx_pin_ctrl), | ||
| 805 | }; | ||
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index da58e4554137..336e88d7bdb9 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c | |||
| @@ -942,12 +942,33 @@ static int samsung_gpiolib_register(struct platform_device *pdev, | |||
| 942 | return 0; | 942 | return 0; |
| 943 | } | 943 | } |
| 944 | 944 | ||
| 945 | static const struct samsung_pin_ctrl * | ||
| 946 | samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev) | ||
| 947 | { | ||
| 948 | struct device_node *node = pdev->dev.of_node; | ||
| 949 | const struct samsung_pinctrl_of_match_data *of_data; | ||
| 950 | int id; | ||
| 951 | |||
| 952 | id = of_alias_get_id(node, "pinctrl"); | ||
| 953 | if (id < 0) { | ||
| 954 | dev_err(&pdev->dev, "failed to get alias id\n"); | ||
| 955 | return NULL; | ||
| 956 | } | ||
| 957 | |||
| 958 | of_data = of_device_get_match_data(&pdev->dev); | ||
| 959 | if (id >= of_data->num_ctrl) { | ||
| 960 | dev_err(&pdev->dev, "invalid alias id %d\n", id); | ||
| 961 | return NULL; | ||
| 962 | } | ||
| 963 | |||
| 964 | return &(of_data->ctrl[id]); | ||
| 965 | } | ||
| 966 | |||
| 945 | /* retrieve the soc specific data */ | 967 | /* retrieve the soc specific data */ |
| 946 | static const struct samsung_pin_ctrl * | 968 | static const struct samsung_pin_ctrl * |
| 947 | samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, | 969 | samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, |
| 948 | struct platform_device *pdev) | 970 | struct platform_device *pdev) |
| 949 | { | 971 | { |
| 950 | int id; | ||
| 951 | struct device_node *node = pdev->dev.of_node; | 972 | struct device_node *node = pdev->dev.of_node; |
| 952 | struct device_node *np; | 973 | struct device_node *np; |
| 953 | const struct samsung_pin_bank_data *bdata; | 974 | const struct samsung_pin_bank_data *bdata; |
| @@ -957,13 +978,9 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, | |||
| 957 | void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES]; | 978 | void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES]; |
| 958 | unsigned int i; | 979 | unsigned int i; |
| 959 | 980 | ||
| 960 | id = of_alias_get_id(node, "pinctrl"); | 981 | ctrl = samsung_pinctrl_get_soc_data_for_of_alias(pdev); |
| 961 | if (id < 0) { | 982 | if (!ctrl) |
| 962 | dev_err(&pdev->dev, "failed to get alias id\n"); | ||
| 963 | return ERR_PTR(-ENOENT); | 983 | return ERR_PTR(-ENOENT); |
| 964 | } | ||
| 965 | ctrl = of_device_get_match_data(&pdev->dev); | ||
| 966 | ctrl += id; | ||
| 967 | 984 | ||
| 968 | d->suspend = ctrl->suspend; | 985 | d->suspend = ctrl->suspend; |
| 969 | d->resume = ctrl->resume; | 986 | d->resume = ctrl->resume; |
| @@ -1188,41 +1205,41 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev) | |||
| 1188 | static const struct of_device_id samsung_pinctrl_dt_match[] = { | 1205 | static const struct of_device_id samsung_pinctrl_dt_match[] = { |
| 1189 | #ifdef CONFIG_PINCTRL_EXYNOS_ARM | 1206 | #ifdef CONFIG_PINCTRL_EXYNOS_ARM |
| 1190 | { .compatible = "samsung,exynos3250-pinctrl", | 1207 | { .compatible = "samsung,exynos3250-pinctrl", |
| 1191 | .data = exynos3250_pin_ctrl }, | 1208 | .data = &exynos3250_of_data }, |
| 1192 | { .compatible = "samsung,exynos4210-pinctrl", | 1209 | { .compatible = "samsung,exynos4210-pinctrl", |
| 1193 | .data = exynos4210_pin_ctrl }, | 1210 | .data = &exynos4210_of_data }, |
| 1194 | { .compatible = "samsung,exynos4x12-pinctrl", | 1211 | { .compatible = "samsung,exynos4x12-pinctrl", |
| 1195 | .data = exynos4x12_pin_ctrl }, | 1212 | .data = &exynos4x12_of_data }, |
| 1196 | { .compatible = "samsung,exynos5250-pinctrl", | 1213 | { .compatible = "samsung,exynos5250-pinctrl", |
| 1197 | .data = exynos5250_pin_ctrl }, | 1214 | .data = &exynos5250_of_data }, |
| 1198 | { .compatible = "samsung,exynos5260-pinctrl", | 1215 | { .compatible = "samsung,exynos5260-pinctrl", |
| 1199 | .data = exynos5260_pin_ctrl }, | 1216 | .data = &exynos5260_of_data }, |
| 1200 | { .compatible = "samsung,exynos5410-pinctrl", | 1217 | { .compatible = "samsung,exynos5410-pinctrl", |
| 1201 | .data = exynos5410_pin_ctrl }, | 1218 | .data = &exynos5410_of_data }, |
| 1202 | { .compatible = "samsung,exynos5420-pinctrl", | 1219 | { .compatible = "samsung,exynos5420-pinctrl", |
| 1203 | .data = exynos5420_pin_ctrl }, | 1220 | .data = &exynos5420_of_data }, |
| 1204 | { .compatible = "samsung,s5pv210-pinctrl", | 1221 | { .compatible = "samsung,s5pv210-pinctrl", |
| 1205 | .data = s5pv210_pin_ctrl }, | 1222 | .data = &s5pv210_of_data }, |
| 1206 | #endif | 1223 | #endif |
| 1207 | #ifdef CONFIG_PINCTRL_EXYNOS_ARM64 | 1224 | #ifdef CONFIG_PINCTRL_EXYNOS_ARM64 |
| 1208 | { .compatible = "samsung,exynos5433-pinctrl", | 1225 | { .compatible = "samsung,exynos5433-pinctrl", |
| 1209 | .data = exynos5433_pin_ctrl }, | 1226 | .data = &exynos5433_of_data }, |
| 1210 | { .compatible = "samsung,exynos7-pinctrl", | 1227 | { .compatible = "samsung,exynos7-pinctrl", |
| 1211 | .data = exynos7_pin_ctrl }, | 1228 | .data = &exynos7_of_data }, |
| 1212 | #endif | 1229 | #endif |
| 1213 | #ifdef CONFIG_PINCTRL_S3C64XX | 1230 | #ifdef CONFIG_PINCTRL_S3C64XX |
| 1214 | { .compatible = "samsung,s3c64xx-pinctrl", | 1231 | { .compatible = "samsung,s3c64xx-pinctrl", |
| 1215 | .data = s3c64xx_pin_ctrl }, | 1232 | .data = &s3c64xx_of_data }, |
| 1216 | #endif | 1233 | #endif |
| 1217 | #ifdef CONFIG_PINCTRL_S3C24XX | 1234 | #ifdef CONFIG_PINCTRL_S3C24XX |
| 1218 | { .compatible = "samsung,s3c2412-pinctrl", | 1235 | { .compatible = "samsung,s3c2412-pinctrl", |
| 1219 | .data = s3c2412_pin_ctrl }, | 1236 | .data = &s3c2412_of_data }, |
| 1220 | { .compatible = "samsung,s3c2416-pinctrl", | 1237 | { .compatible = "samsung,s3c2416-pinctrl", |
| 1221 | .data = s3c2416_pin_ctrl }, | 1238 | .data = &s3c2416_of_data }, |
| 1222 | { .compatible = "samsung,s3c2440-pinctrl", | 1239 | { .compatible = "samsung,s3c2440-pinctrl", |
| 1223 | .data = s3c2440_pin_ctrl }, | 1240 | .data = &s3c2440_of_data }, |
| 1224 | { .compatible = "samsung,s3c2450-pinctrl", | 1241 | { .compatible = "samsung,s3c2450-pinctrl", |
| 1225 | .data = s3c2450_pin_ctrl }, | 1242 | .data = &s3c2450_of_data }, |
| 1226 | #endif | 1243 | #endif |
| 1227 | {}, | 1244 | {}, |
| 1228 | }; | 1245 | }; |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index e204f609823b..f0cda9424dfe 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h | |||
| @@ -282,6 +282,16 @@ struct samsung_pinctrl_drv_data { | |||
| 282 | }; | 282 | }; |
| 283 | 283 | ||
| 284 | /** | 284 | /** |
| 285 | * struct samsung_pinctrl_of_match_data: OF match device specific configuration data. | ||
| 286 | * @ctrl: array of pin controller data. | ||
| 287 | * @num_ctrl: size of array @ctrl. | ||
| 288 | */ | ||
| 289 | struct samsung_pinctrl_of_match_data { | ||
| 290 | const struct samsung_pin_ctrl *ctrl; | ||
| 291 | unsigned int num_ctrl; | ||
| 292 | }; | ||
| 293 | |||
| 294 | /** | ||
| 285 | * struct samsung_pin_group: represent group of pins of a pinmux function. | 295 | * struct samsung_pin_group: represent group of pins of a pinmux function. |
| 286 | * @name: name of the pin group, used to lookup the group. | 296 | * @name: name of the pin group, used to lookup the group. |
| 287 | * @pins: the pins included in this group. | 297 | * @pins: the pins included in this group. |
| @@ -309,20 +319,20 @@ struct samsung_pmx_func { | |||
| 309 | }; | 319 | }; |
| 310 | 320 | ||
| 311 | /* list of all exported SoC specific data */ | 321 | /* list of all exported SoC specific data */ |
| 312 | extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[]; | 322 | extern const struct samsung_pinctrl_of_match_data exynos3250_of_data; |
| 313 | extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[]; | 323 | extern const struct samsung_pinctrl_of_match_data exynos4210_of_data; |
| 314 | extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; | 324 | extern const struct samsung_pinctrl_of_match_data exynos4x12_of_data; |
| 315 | extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; | 325 | extern const struct samsung_pinctrl_of_match_data exynos5250_of_data; |
| 316 | extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; | 326 | extern const struct samsung_pinctrl_of_match_data exynos5260_of_data; |
| 317 | extern const struct samsung_pin_ctrl exynos5410_pin_ctrl[]; | 327 | extern const struct samsung_pinctrl_of_match_data exynos5410_of_data; |
| 318 | extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; | 328 | extern const struct samsung_pinctrl_of_match_data exynos5420_of_data; |
| 319 | extern const struct samsung_pin_ctrl exynos5433_pin_ctrl[]; | 329 | extern const struct samsung_pinctrl_of_match_data exynos5433_of_data; |
| 320 | extern const struct samsung_pin_ctrl exynos7_pin_ctrl[]; | 330 | extern const struct samsung_pinctrl_of_match_data exynos7_of_data; |
| 321 | extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; | 331 | extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data; |
| 322 | extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; | 332 | extern const struct samsung_pinctrl_of_match_data s3c2412_of_data; |
| 323 | extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[]; | 333 | extern const struct samsung_pinctrl_of_match_data s3c2416_of_data; |
| 324 | extern const struct samsung_pin_ctrl s3c2440_pin_ctrl[]; | 334 | extern const struct samsung_pinctrl_of_match_data s3c2440_of_data; |
| 325 | extern const struct samsung_pin_ctrl s3c2450_pin_ctrl[]; | 335 | extern const struct samsung_pinctrl_of_match_data s3c2450_of_data; |
| 326 | extern const struct samsung_pin_ctrl s5pv210_pin_ctrl[]; | 336 | extern const struct samsung_pinctrl_of_match_data s5pv210_of_data; |
| 327 | 337 | ||
| 328 | #endif /* __PINCTRL_SAMSUNG_H */ | 338 | #endif /* __PINCTRL_SAMSUNG_H */ |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index 18aeee592fdc..35951e7b89d2 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c | |||
| @@ -1538,7 +1538,6 @@ static const struct sh_pfc_pin pinmux_pins[] = { | |||
| 1538 | SH_PFC_PIN_NAMED_CFG('B', 18, AVB_TD1, CFG_FLAGS), | 1538 | SH_PFC_PIN_NAMED_CFG('B', 18, AVB_TD1, CFG_FLAGS), |
| 1539 | SH_PFC_PIN_NAMED_CFG('B', 19, AVB_RXC, CFG_FLAGS), | 1539 | SH_PFC_PIN_NAMED_CFG('B', 19, AVB_RXC, CFG_FLAGS), |
| 1540 | SH_PFC_PIN_NAMED_CFG('C', 1, PRESETOUT#, CFG_FLAGS), | 1540 | SH_PFC_PIN_NAMED_CFG('C', 1, PRESETOUT#, CFG_FLAGS), |
| 1541 | SH_PFC_PIN_NAMED_CFG('F', 1, CLKOUT, CFG_FLAGS), | ||
| 1542 | SH_PFC_PIN_NAMED_CFG('H', 37, MLB_REF, CFG_FLAGS), | 1541 | SH_PFC_PIN_NAMED_CFG('H', 37, MLB_REF, CFG_FLAGS), |
| 1543 | SH_PFC_PIN_NAMED_CFG('V', 3, QSPI1_SPCLK, CFG_FLAGS), | 1542 | SH_PFC_PIN_NAMED_CFG('V', 3, QSPI1_SPCLK, CFG_FLAGS), |
| 1544 | SH_PFC_PIN_NAMED_CFG('V', 5, QSPI1_SSL, CFG_FLAGS), | 1543 | SH_PFC_PIN_NAMED_CFG('V', 5, QSPI1_SSL, CFG_FLAGS), |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c8b308cfabf1..3653bea38470 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -527,8 +527,7 @@ static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue) | |||
| 527 | queue == card->qdio.no_in_queues - 1; | 527 | queue == card->qdio.no_in_queues - 1; |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | 530 | static int __qeth_issue_next_read(struct qeth_card *card) | |
| 531 | static int qeth_issue_next_read(struct qeth_card *card) | ||
| 532 | { | 531 | { |
| 533 | int rc; | 532 | int rc; |
| 534 | struct qeth_cmd_buffer *iob; | 533 | struct qeth_cmd_buffer *iob; |
| @@ -559,6 +558,17 @@ static int qeth_issue_next_read(struct qeth_card *card) | |||
| 559 | return rc; | 558 | return rc; |
| 560 | } | 559 | } |
| 561 | 560 | ||
| 561 | static int qeth_issue_next_read(struct qeth_card *card) | ||
| 562 | { | ||
| 563 | int ret; | ||
| 564 | |||
| 565 | spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card))); | ||
| 566 | ret = __qeth_issue_next_read(card); | ||
| 567 | spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card))); | ||
| 568 | |||
| 569 | return ret; | ||
| 570 | } | ||
| 571 | |||
| 562 | static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) | 572 | static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) |
| 563 | { | 573 | { |
| 564 | struct qeth_reply *reply; | 574 | struct qeth_reply *reply; |
| @@ -960,7 +970,7 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread) | |||
| 960 | spin_lock_irqsave(&card->thread_mask_lock, flags); | 970 | spin_lock_irqsave(&card->thread_mask_lock, flags); |
| 961 | card->thread_running_mask &= ~thread; | 971 | card->thread_running_mask &= ~thread; |
| 962 | spin_unlock_irqrestore(&card->thread_mask_lock, flags); | 972 | spin_unlock_irqrestore(&card->thread_mask_lock, flags); |
| 963 | wake_up(&card->wait_q); | 973 | wake_up_all(&card->wait_q); |
| 964 | } | 974 | } |
| 965 | EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit); | 975 | EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit); |
| 966 | 976 | ||
| @@ -1164,6 +1174,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, | |||
| 1164 | } | 1174 | } |
| 1165 | rc = qeth_get_problem(cdev, irb); | 1175 | rc = qeth_get_problem(cdev, irb); |
| 1166 | if (rc) { | 1176 | if (rc) { |
| 1177 | card->read_or_write_problem = 1; | ||
| 1167 | qeth_clear_ipacmd_list(card); | 1178 | qeth_clear_ipacmd_list(card); |
| 1168 | qeth_schedule_recovery(card); | 1179 | qeth_schedule_recovery(card); |
| 1169 | goto out; | 1180 | goto out; |
| @@ -1182,7 +1193,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, | |||
| 1182 | return; | 1193 | return; |
| 1183 | if (channel == &card->read && | 1194 | if (channel == &card->read && |
| 1184 | channel->state == CH_STATE_UP) | 1195 | channel->state == CH_STATE_UP) |
| 1185 | qeth_issue_next_read(card); | 1196 | __qeth_issue_next_read(card); |
| 1186 | 1197 | ||
| 1187 | iob = channel->iob; | 1198 | iob = channel->iob; |
| 1188 | index = channel->buf_no; | 1199 | index = channel->buf_no; |
| @@ -5087,8 +5098,6 @@ static void qeth_core_free_card(struct qeth_card *card) | |||
| 5087 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 5098 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
| 5088 | qeth_clean_channel(&card->read); | 5099 | qeth_clean_channel(&card->read); |
| 5089 | qeth_clean_channel(&card->write); | 5100 | qeth_clean_channel(&card->write); |
| 5090 | if (card->dev) | ||
| 5091 | free_netdev(card->dev); | ||
| 5092 | qeth_free_qdio_buffers(card); | 5101 | qeth_free_qdio_buffers(card); |
| 5093 | unregister_service_level(&card->qeth_service_level); | 5102 | unregister_service_level(&card->qeth_service_level); |
| 5094 | kfree(card); | 5103 | kfree(card); |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7f236440483f..5ef4c978ad19 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
| @@ -915,8 +915,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) | |||
| 915 | qeth_l2_set_offline(cgdev); | 915 | qeth_l2_set_offline(cgdev); |
| 916 | 916 | ||
| 917 | if (card->dev) { | 917 | if (card->dev) { |
| 918 | netif_napi_del(&card->napi); | ||
| 919 | unregister_netdev(card->dev); | 918 | unregister_netdev(card->dev); |
| 919 | free_netdev(card->dev); | ||
| 920 | card->dev = NULL; | 920 | card->dev = NULL; |
| 921 | } | 921 | } |
| 922 | return; | 922 | return; |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 962a04b68dd2..b6b12220da71 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
| @@ -2865,8 +2865,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |||
| 2865 | qeth_l3_set_offline(cgdev); | 2865 | qeth_l3_set_offline(cgdev); |
| 2866 | 2866 | ||
| 2867 | if (card->dev) { | 2867 | if (card->dev) { |
| 2868 | netif_napi_del(&card->napi); | ||
| 2869 | unregister_netdev(card->dev); | 2868 | unregister_netdev(card->dev); |
| 2869 | free_netdev(card->dev); | ||
| 2870 | card->dev = NULL; | 2870 | card->dev = NULL; |
| 2871 | } | 2871 | } |
| 2872 | 2872 | ||
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 6de9681ace82..ceab5e5c41c2 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
| @@ -223,6 +223,7 @@ out_done: | |||
| 223 | static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | 223 | static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) |
| 224 | { | 224 | { |
| 225 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); | 225 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); |
| 226 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
| 226 | struct sas_task *task = TO_SAS_TASK(cmd); | 227 | struct sas_task *task = TO_SAS_TASK(cmd); |
| 227 | 228 | ||
| 228 | /* At this point, we only get called following an actual abort | 229 | /* At this point, we only get called following an actual abort |
| @@ -231,6 +232,14 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | |||
| 231 | */ | 232 | */ |
| 232 | sas_end_task(cmd, task); | 233 | sas_end_task(cmd, task); |
| 233 | 234 | ||
| 235 | if (dev_is_sata(dev)) { | ||
| 236 | /* defer commands to libata so that libata EH can | ||
| 237 | * handle ata qcs correctly | ||
| 238 | */ | ||
| 239 | list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q); | ||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 234 | /* now finish the command and move it on to the error | 243 | /* now finish the command and move it on to the error |
| 235 | * handler done list, this also takes it off the | 244 | * handler done list, this also takes it off the |
| 236 | * error handler pending list. | 245 | * error handler pending list. |
| @@ -238,22 +247,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) | |||
| 238 | scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); | 247 | scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); |
| 239 | } | 248 | } |
| 240 | 249 | ||
| 241 | static void sas_eh_defer_cmd(struct scsi_cmnd *cmd) | ||
| 242 | { | ||
| 243 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
| 244 | struct sas_ha_struct *ha = dev->port->ha; | ||
| 245 | struct sas_task *task = TO_SAS_TASK(cmd); | ||
| 246 | |||
| 247 | if (!dev_is_sata(dev)) { | ||
| 248 | sas_eh_finish_cmd(cmd); | ||
| 249 | return; | ||
| 250 | } | ||
| 251 | |||
| 252 | /* report the timeout to libata */ | ||
| 253 | sas_end_task(cmd, task); | ||
| 254 | list_move_tail(&cmd->eh_entry, &ha->eh_ata_q); | ||
| 255 | } | ||
| 256 | |||
| 257 | static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) | 250 | static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) |
| 258 | { | 251 | { |
| 259 | struct scsi_cmnd *cmd, *n; | 252 | struct scsi_cmnd *cmd, *n; |
| @@ -261,7 +254,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd | |||
| 261 | list_for_each_entry_safe(cmd, n, error_q, eh_entry) { | 254 | list_for_each_entry_safe(cmd, n, error_q, eh_entry) { |
| 262 | if (cmd->device->sdev_target == my_cmd->device->sdev_target && | 255 | if (cmd->device->sdev_target == my_cmd->device->sdev_target && |
| 263 | cmd->device->lun == my_cmd->device->lun) | 256 | cmd->device->lun == my_cmd->device->lun) |
| 264 | sas_eh_defer_cmd(cmd); | 257 | sas_eh_finish_cmd(cmd); |
| 265 | } | 258 | } |
| 266 | } | 259 | } |
| 267 | 260 | ||
| @@ -631,12 +624,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * | |||
| 631 | case TASK_IS_DONE: | 624 | case TASK_IS_DONE: |
| 632 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, | 625 | SAS_DPRINTK("%s: task 0x%p is done\n", __func__, |
| 633 | task); | 626 | task); |
| 634 | sas_eh_defer_cmd(cmd); | 627 | sas_eh_finish_cmd(cmd); |
| 635 | continue; | 628 | continue; |
| 636 | case TASK_IS_ABORTED: | 629 | case TASK_IS_ABORTED: |
| 637 | SAS_DPRINTK("%s: task 0x%p is aborted\n", | 630 | SAS_DPRINTK("%s: task 0x%p is aborted\n", |
| 638 | __func__, task); | 631 | __func__, task); |
| 639 | sas_eh_defer_cmd(cmd); | 632 | sas_eh_finish_cmd(cmd); |
| 640 | continue; | 633 | continue; |
| 641 | case TASK_IS_AT_LU: | 634 | case TASK_IS_AT_LU: |
| 642 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); | 635 | SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); |
| @@ -647,7 +640,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * | |||
| 647 | "recovered\n", | 640 | "recovered\n", |
| 648 | SAS_ADDR(task->dev), | 641 | SAS_ADDR(task->dev), |
| 649 | cmd->device->lun); | 642 | cmd->device->lun); |
| 650 | sas_eh_defer_cmd(cmd); | 643 | sas_eh_finish_cmd(cmd); |
| 651 | sas_scsi_clear_queue_lu(work_q, cmd); | 644 | sas_scsi_clear_queue_lu(work_q, cmd); |
| 652 | goto Again; | 645 | goto Again; |
| 653 | } | 646 | } |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 00329dda6179..8d7fab3cd01d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -1719,7 +1719,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | |||
| 1719 | 1719 | ||
| 1720 | set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); | 1720 | set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); |
| 1721 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 1721 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); |
| 1722 | ea->fcport->loop_id = FC_NO_LOOP_ID; | ||
| 1723 | ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; | 1722 | ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; |
| 1724 | ea->fcport->logout_on_delete = 1; | 1723 | ea->fcport->logout_on_delete = 1; |
| 1725 | ea->fcport->send_els_logo = 0; | 1724 | ea->fcport->send_els_logo = 0; |
diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index e4f5bb056fd2..ba3cfa8e279b 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c | |||
| @@ -2443,39 +2443,21 @@ struct cgr_comp { | |||
| 2443 | struct completion completion; | 2443 | struct completion completion; |
| 2444 | }; | 2444 | }; |
| 2445 | 2445 | ||
| 2446 | static int qman_delete_cgr_thread(void *p) | 2446 | static void qman_delete_cgr_smp_call(void *p) |
| 2447 | { | 2447 | { |
| 2448 | struct cgr_comp *cgr_comp = (struct cgr_comp *)p; | 2448 | qman_delete_cgr((struct qman_cgr *)p); |
| 2449 | int ret; | ||
| 2450 | |||
| 2451 | ret = qman_delete_cgr(cgr_comp->cgr); | ||
| 2452 | complete(&cgr_comp->completion); | ||
| 2453 | |||
| 2454 | return ret; | ||
| 2455 | } | 2449 | } |
| 2456 | 2450 | ||
| 2457 | void qman_delete_cgr_safe(struct qman_cgr *cgr) | 2451 | void qman_delete_cgr_safe(struct qman_cgr *cgr) |
| 2458 | { | 2452 | { |
| 2459 | struct task_struct *thread; | ||
| 2460 | struct cgr_comp cgr_comp; | ||
| 2461 | |||
| 2462 | preempt_disable(); | 2453 | preempt_disable(); |
| 2463 | if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { | 2454 | if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { |
| 2464 | init_completion(&cgr_comp.completion); | 2455 | smp_call_function_single(qman_cgr_cpus[cgr->cgrid], |
| 2465 | cgr_comp.cgr = cgr; | 2456 | qman_delete_cgr_smp_call, cgr, true); |
| 2466 | thread = kthread_create(qman_delete_cgr_thread, &cgr_comp, | ||
| 2467 | "cgr_del"); | ||
| 2468 | |||
| 2469 | if (IS_ERR(thread)) | ||
| 2470 | goto out; | ||
| 2471 | |||
| 2472 | kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]); | ||
| 2473 | wake_up_process(thread); | ||
| 2474 | wait_for_completion(&cgr_comp.completion); | ||
| 2475 | preempt_enable(); | 2457 | preempt_enable(); |
| 2476 | return; | 2458 | return; |
| 2477 | } | 2459 | } |
| 2478 | out: | 2460 | |
| 2479 | qman_delete_cgr(cgr); | 2461 | qman_delete_cgr(cgr); |
| 2480 | preempt_enable(); | 2462 | preempt_enable(); |
| 2481 | } | 2463 | } |
diff --git a/drivers/staging/ncpfs/ncplib_kernel.c b/drivers/staging/ncpfs/ncplib_kernel.c index 804adfebba2f..3e047eb4cc7c 100644 --- a/drivers/staging/ncpfs/ncplib_kernel.c +++ b/drivers/staging/ncpfs/ncplib_kernel.c | |||
| @@ -981,6 +981,10 @@ ncp_read_kernel(struct ncp_server *server, const char *file_id, | |||
| 981 | goto out; | 981 | goto out; |
| 982 | } | 982 | } |
| 983 | *bytes_read = ncp_reply_be16(server, 0); | 983 | *bytes_read = ncp_reply_be16(server, 0); |
| 984 | if (*bytes_read > to_read) { | ||
| 985 | result = -EINVAL; | ||
| 986 | goto out; | ||
| 987 | } | ||
| 984 | source = ncp_reply_data(server, 2 + (offset & 1)); | 988 | source = ncp_reply_data(server, 2 + (offset & 1)); |
| 985 | 989 | ||
| 986 | memcpy(target, source, *bytes_read); | 990 | memcpy(target, source, *bytes_read); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 88b902c525d7..b4e57c5a8bba 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -1727,7 +1727,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
| 1727 | default_attr(vc); | 1727 | default_attr(vc); |
| 1728 | update_attr(vc); | 1728 | update_attr(vc); |
| 1729 | 1729 | ||
| 1730 | vc->vc_tab_stop[0] = 0x01010100; | 1730 | vc->vc_tab_stop[0] = |
| 1731 | vc->vc_tab_stop[1] = | 1731 | vc->vc_tab_stop[1] = |
| 1732 | vc->vc_tab_stop[2] = | 1732 | vc->vc_tab_stop[2] = |
| 1733 | vc->vc_tab_stop[3] = | 1733 | vc->vc_tab_stop[3] = |
| @@ -1771,7 +1771,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
| 1771 | vc->vc_pos -= (vc->vc_x << 1); | 1771 | vc->vc_pos -= (vc->vc_x << 1); |
| 1772 | while (vc->vc_x < vc->vc_cols - 1) { | 1772 | while (vc->vc_x < vc->vc_cols - 1) { |
| 1773 | vc->vc_x++; | 1773 | vc->vc_x++; |
| 1774 | if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31))) | 1774 | if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31))) |
| 1775 | break; | 1775 | break; |
| 1776 | } | 1776 | } |
| 1777 | vc->vc_pos += (vc->vc_x << 1); | 1777 | vc->vc_pos += (vc->vc_x << 1); |
| @@ -1831,7 +1831,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
| 1831 | lf(vc); | 1831 | lf(vc); |
| 1832 | return; | 1832 | return; |
| 1833 | case 'H': | 1833 | case 'H': |
| 1834 | vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31)); | 1834 | vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31)); |
| 1835 | return; | 1835 | return; |
| 1836 | case 'Z': | 1836 | case 'Z': |
| 1837 | respond_ID(tty); | 1837 | respond_ID(tty); |
| @@ -2024,7 +2024,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
| 2024 | return; | 2024 | return; |
| 2025 | case 'g': | 2025 | case 'g': |
| 2026 | if (!vc->vc_par[0]) | 2026 | if (!vc->vc_par[0]) |
| 2027 | vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31)); | 2027 | vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31)); |
| 2028 | else if (vc->vc_par[0] == 3) { | 2028 | else if (vc->vc_par[0] == 3) { |
| 2029 | vc->vc_tab_stop[0] = | 2029 | vc->vc_tab_stop[0] = |
| 2030 | vc->vc_tab_stop[1] = | 2030 | vc->vc_tab_stop[1] = |
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index b0f759476900..8a1508a8e481 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
| @@ -207,9 +207,6 @@ static bool vfio_pci_nointx(struct pci_dev *pdev) | |||
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | if (!pdev->irq) | ||
| 211 | return true; | ||
| 212 | |||
| 213 | return false; | 210 | return false; |
| 214 | } | 211 | } |
| 215 | 212 | ||
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 610cba276d47..8139bc70ad7d 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
| @@ -170,7 +170,7 @@ static void vhost_net_buf_unproduce(struct vhost_net_virtqueue *nvq) | |||
| 170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { | 170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { |
| 171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, | 171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, |
| 172 | vhost_net_buf_get_size(rxq), | 172 | vhost_net_buf_get_size(rxq), |
| 173 | __skb_array_destroy_skb); | 173 | tun_ptr_free); |
| 174 | rxq->head = rxq->tail = 0; | 174 | rxq->head = rxq->tail = 0; |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| @@ -948,6 +948,7 @@ static int vhost_net_open(struct inode *inode, struct file *f) | |||
| 948 | n->vqs[i].done_idx = 0; | 948 | n->vqs[i].done_idx = 0; |
| 949 | n->vqs[i].vhost_hlen = 0; | 949 | n->vqs[i].vhost_hlen = 0; |
| 950 | n->vqs[i].sock_hlen = 0; | 950 | n->vqs[i].sock_hlen = 0; |
| 951 | n->vqs[i].rx_ring = NULL; | ||
| 951 | vhost_net_buf_init(&n->vqs[i].rxq); | 952 | vhost_net_buf_init(&n->vqs[i].rxq); |
| 952 | } | 953 | } |
| 953 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX); | 954 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX); |
| @@ -972,6 +973,7 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n, | |||
| 972 | vhost_net_disable_vq(n, vq); | 973 | vhost_net_disable_vq(n, vq); |
| 973 | vq->private_data = NULL; | 974 | vq->private_data = NULL; |
| 974 | vhost_net_buf_unproduce(nvq); | 975 | vhost_net_buf_unproduce(nvq); |
| 976 | nvq->rx_ring = NULL; | ||
| 975 | mutex_unlock(&vq->mutex); | 977 | mutex_unlock(&vq->mutex); |
| 976 | return sock; | 978 | return sock; |
| 977 | } | 979 | } |
| @@ -1161,14 +1163,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
| 1161 | vhost_net_disable_vq(n, vq); | 1163 | vhost_net_disable_vq(n, vq); |
| 1162 | vq->private_data = sock; | 1164 | vq->private_data = sock; |
| 1163 | vhost_net_buf_unproduce(nvq); | 1165 | vhost_net_buf_unproduce(nvq); |
| 1164 | if (index == VHOST_NET_VQ_RX) | ||
| 1165 | nvq->rx_ring = get_tap_ptr_ring(fd); | ||
| 1166 | r = vhost_vq_init_access(vq); | 1166 | r = vhost_vq_init_access(vq); |
| 1167 | if (r) | 1167 | if (r) |
| 1168 | goto err_used; | 1168 | goto err_used; |
| 1169 | r = vhost_net_enable_vq(n, vq); | 1169 | r = vhost_net_enable_vq(n, vq); |
| 1170 | if (r) | 1170 | if (r) |
| 1171 | goto err_used; | 1171 | goto err_used; |
| 1172 | if (index == VHOST_NET_VQ_RX) | ||
| 1173 | nvq->rx_ring = get_tap_ptr_ring(fd); | ||
| 1172 | 1174 | ||
| 1173 | oldubufs = nvq->ubufs; | 1175 | oldubufs = nvq->ubufs; |
| 1174 | nvq->ubufs = ubufs; | 1176 | nvq->ubufs = ubufs; |
diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c index 6d1fbda0f461..0da9943d405f 100644 --- a/drivers/watchdog/wdat_wdt.c +++ b/drivers/watchdog/wdat_wdt.c | |||
| @@ -392,7 +392,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) | |||
| 392 | 392 | ||
| 393 | memset(&r, 0, sizeof(r)); | 393 | memset(&r, 0, sizeof(r)); |
| 394 | r.start = gas->address; | 394 | r.start = gas->address; |
| 395 | r.end = r.start + gas->access_width; | 395 | r.end = r.start + gas->access_width - 1; |
| 396 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 396 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
| 397 | r.flags = IORESOURCE_MEM; | 397 | r.flags = IORESOURCE_MEM; |
| 398 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { | 398 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8fe1b0aa2896..b9a254dcc0e7 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
| @@ -108,6 +108,16 @@ static void huge_pagevec_release(struct pagevec *pvec) | |||
| 108 | pagevec_reinit(pvec); | 108 | pagevec_reinit(pvec); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /* | ||
| 112 | * Mask used when checking the page offset value passed in via system | ||
| 113 | * calls. This value will be converted to a loff_t which is signed. | ||
| 114 | * Therefore, we want to check the upper PAGE_SHIFT + 1 bits of the | ||
| 115 | * value. The extra bit (- 1 in the shift value) is to take the sign | ||
| 116 | * bit into account. | ||
| 117 | */ | ||
| 118 | #define PGOFF_LOFFT_MAX \ | ||
| 119 | (((1UL << (PAGE_SHIFT + 1)) - 1) << (BITS_PER_LONG - (PAGE_SHIFT + 1))) | ||
| 120 | |||
| 111 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 121 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
| 112 | { | 122 | { |
| 113 | struct inode *inode = file_inode(file); | 123 | struct inode *inode = file_inode(file); |
| @@ -127,12 +137,13 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 127 | vma->vm_ops = &hugetlb_vm_ops; | 137 | vma->vm_ops = &hugetlb_vm_ops; |
| 128 | 138 | ||
| 129 | /* | 139 | /* |
| 130 | * Offset passed to mmap (before page shift) could have been | 140 | * page based offset in vm_pgoff could be sufficiently large to |
| 131 | * negative when represented as a (l)off_t. | 141 | * overflow a (l)off_t when converted to byte offset. |
| 132 | */ | 142 | */ |
| 133 | if (((loff_t)vma->vm_pgoff << PAGE_SHIFT) < 0) | 143 | if (vma->vm_pgoff & PGOFF_LOFFT_MAX) |
| 134 | return -EINVAL; | 144 | return -EINVAL; |
| 135 | 145 | ||
| 146 | /* must be huge page aligned */ | ||
| 136 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) | 147 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) |
| 137 | return -EINVAL; | 148 | return -EINVAL; |
| 138 | 149 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 150521c9671b..61b770e39809 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -268,6 +268,35 @@ free_blocked_lock(struct nfsd4_blocked_lock *nbl) | |||
| 268 | kfree(nbl); | 268 | kfree(nbl); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static void | ||
| 272 | remove_blocked_locks(struct nfs4_lockowner *lo) | ||
| 273 | { | ||
| 274 | struct nfs4_client *clp = lo->lo_owner.so_client; | ||
| 275 | struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); | ||
| 276 | struct nfsd4_blocked_lock *nbl; | ||
| 277 | LIST_HEAD(reaplist); | ||
| 278 | |||
| 279 | /* Dequeue all blocked locks */ | ||
| 280 | spin_lock(&nn->blocked_locks_lock); | ||
| 281 | while (!list_empty(&lo->lo_blocked)) { | ||
| 282 | nbl = list_first_entry(&lo->lo_blocked, | ||
| 283 | struct nfsd4_blocked_lock, | ||
| 284 | nbl_list); | ||
| 285 | list_del_init(&nbl->nbl_list); | ||
| 286 | list_move(&nbl->nbl_lru, &reaplist); | ||
| 287 | } | ||
| 288 | spin_unlock(&nn->blocked_locks_lock); | ||
| 289 | |||
| 290 | /* Now free them */ | ||
| 291 | while (!list_empty(&reaplist)) { | ||
| 292 | nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock, | ||
| 293 | nbl_lru); | ||
| 294 | list_del_init(&nbl->nbl_lru); | ||
| 295 | posix_unblock_lock(&nbl->nbl_lock); | ||
| 296 | free_blocked_lock(nbl); | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 271 | static int | 300 | static int |
| 272 | nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task) | 301 | nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task) |
| 273 | { | 302 | { |
| @@ -1866,6 +1895,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp) | |||
| 1866 | static void | 1895 | static void |
| 1867 | __destroy_client(struct nfs4_client *clp) | 1896 | __destroy_client(struct nfs4_client *clp) |
| 1868 | { | 1897 | { |
| 1898 | int i; | ||
| 1869 | struct nfs4_openowner *oo; | 1899 | struct nfs4_openowner *oo; |
| 1870 | struct nfs4_delegation *dp; | 1900 | struct nfs4_delegation *dp; |
| 1871 | struct list_head reaplist; | 1901 | struct list_head reaplist; |
| @@ -1895,6 +1925,16 @@ __destroy_client(struct nfs4_client *clp) | |||
| 1895 | nfs4_get_stateowner(&oo->oo_owner); | 1925 | nfs4_get_stateowner(&oo->oo_owner); |
| 1896 | release_openowner(oo); | 1926 | release_openowner(oo); |
| 1897 | } | 1927 | } |
| 1928 | for (i = 0; i < OWNER_HASH_SIZE; i++) { | ||
| 1929 | struct nfs4_stateowner *so, *tmp; | ||
| 1930 | |||
| 1931 | list_for_each_entry_safe(so, tmp, &clp->cl_ownerstr_hashtbl[i], | ||
| 1932 | so_strhash) { | ||
| 1933 | /* Should be no openowners at this point */ | ||
| 1934 | WARN_ON_ONCE(so->so_is_open_owner); | ||
| 1935 | remove_blocked_locks(lockowner(so)); | ||
| 1936 | } | ||
| 1937 | } | ||
| 1898 | nfsd4_return_all_client_layouts(clp); | 1938 | nfsd4_return_all_client_layouts(clp); |
| 1899 | nfsd4_shutdown_callback(clp); | 1939 | nfsd4_shutdown_callback(clp); |
| 1900 | if (clp->cl_cb_conn.cb_xprt) | 1940 | if (clp->cl_cb_conn.cb_xprt) |
| @@ -6355,6 +6395,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, | |||
| 6355 | } | 6395 | } |
| 6356 | spin_unlock(&clp->cl_lock); | 6396 | spin_unlock(&clp->cl_lock); |
| 6357 | free_ol_stateid_reaplist(&reaplist); | 6397 | free_ol_stateid_reaplist(&reaplist); |
| 6398 | remove_blocked_locks(lo); | ||
| 6358 | nfs4_put_stateowner(&lo->lo_owner); | 6399 | nfs4_put_stateowner(&lo->lo_owner); |
| 6359 | 6400 | ||
| 6360 | return status; | 6401 | return status; |
| @@ -7140,6 +7181,8 @@ nfs4_state_destroy_net(struct net *net) | |||
| 7140 | } | 7181 | } |
| 7141 | } | 7182 | } |
| 7142 | 7183 | ||
| 7184 | WARN_ON(!list_empty(&nn->blocked_locks_lru)); | ||
| 7185 | |||
| 7143 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 7186 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
| 7144 | while (!list_empty(&nn->unconf_id_hashtbl[i])) { | 7187 | while (!list_empty(&nn->unconf_id_hashtbl[i])) { |
| 7145 | clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); | 7188 | clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); |
| @@ -7206,7 +7249,6 @@ nfs4_state_shutdown_net(struct net *net) | |||
| 7206 | struct nfs4_delegation *dp = NULL; | 7249 | struct nfs4_delegation *dp = NULL; |
| 7207 | struct list_head *pos, *next, reaplist; | 7250 | struct list_head *pos, *next, reaplist; |
| 7208 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | 7251 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
| 7209 | struct nfsd4_blocked_lock *nbl; | ||
| 7210 | 7252 | ||
| 7211 | cancel_delayed_work_sync(&nn->laundromat_work); | 7253 | cancel_delayed_work_sync(&nn->laundromat_work); |
| 7212 | locks_end_grace(&nn->nfsd4_manager); | 7254 | locks_end_grace(&nn->nfsd4_manager); |
| @@ -7227,24 +7269,6 @@ nfs4_state_shutdown_net(struct net *net) | |||
| 7227 | nfs4_put_stid(&dp->dl_stid); | 7269 | nfs4_put_stid(&dp->dl_stid); |
| 7228 | } | 7270 | } |
| 7229 | 7271 | ||
| 7230 | BUG_ON(!list_empty(&reaplist)); | ||
| 7231 | spin_lock(&nn->blocked_locks_lock); | ||
| 7232 | while (!list_empty(&nn->blocked_locks_lru)) { | ||
| 7233 | nbl = list_first_entry(&nn->blocked_locks_lru, | ||
| 7234 | struct nfsd4_blocked_lock, nbl_lru); | ||
| 7235 | list_move(&nbl->nbl_lru, &reaplist); | ||
| 7236 | list_del_init(&nbl->nbl_list); | ||
| 7237 | } | ||
| 7238 | spin_unlock(&nn->blocked_locks_lock); | ||
| 7239 | |||
| 7240 | while (!list_empty(&reaplist)) { | ||
| 7241 | nbl = list_first_entry(&reaplist, | ||
| 7242 | struct nfsd4_blocked_lock, nbl_lru); | ||
| 7243 | list_del_init(&nbl->nbl_lru); | ||
| 7244 | posix_unblock_lock(&nbl->nbl_lock); | ||
| 7245 | free_blocked_lock(nbl); | ||
| 7246 | } | ||
| 7247 | |||
| 7248 | nfsd4_client_tracking_exit(net); | 7272 | nfsd4_client_tracking_exit(net); |
| 7249 | nfs4_state_destroy_net(net); | 7273 | nfs4_state_destroy_net(net); |
| 7250 | } | 7274 | } |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 8664db25a9a6..215c225b2ca1 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -106,6 +106,7 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, | |||
| 106 | { | 106 | { |
| 107 | return sysfs_do_create_link(kobj, target, name, 0); | 107 | return sysfs_do_create_link(kobj, target, name, 0); |
| 108 | } | 108 | } |
| 109 | EXPORT_SYMBOL_GPL(sysfs_create_link_nowarn); | ||
| 109 | 110 | ||
| 110 | /** | 111 | /** |
| 111 | * sysfs_delete_link - remove symlink in object's directory. | 112 | * sysfs_delete_link - remove symlink in object's directory. |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 2cfa3075d148..bfbb44a5ad38 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -983,6 +983,8 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot); | |||
| 983 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); | 983 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); |
| 984 | int pud_clear_huge(pud_t *pud); | 984 | int pud_clear_huge(pud_t *pud); |
| 985 | int pmd_clear_huge(pmd_t *pmd); | 985 | int pmd_clear_huge(pmd_t *pmd); |
| 986 | int pud_free_pmd_page(pud_t *pud); | ||
| 987 | int pmd_free_pte_page(pmd_t *pmd); | ||
| 986 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ | 988 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ |
| 987 | static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) | 989 | static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) |
| 988 | { | 990 | { |
| @@ -1008,6 +1010,14 @@ static inline int pmd_clear_huge(pmd_t *pmd) | |||
| 1008 | { | 1010 | { |
| 1009 | return 0; | 1011 | return 0; |
| 1010 | } | 1012 | } |
| 1013 | static inline int pud_free_pmd_page(pud_t *pud) | ||
| 1014 | { | ||
| 1015 | return 0; | ||
| 1016 | } | ||
| 1017 | static inline int pmd_free_pte_page(pmd_t *pmd) | ||
| 1018 | { | ||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1011 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ | 1021 | #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ |
| 1012 | 1022 | ||
| 1013 | #ifndef __HAVE_ARCH_FLUSH_PMD_TLB_RANGE | 1023 | #ifndef __HAVE_ARCH_FLUSH_PMD_TLB_RANGE |
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 9f242b876fde..f8e76d01a5ad 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h | |||
| @@ -755,13 +755,13 @@ struct sock_cgroup_data { | |||
| 755 | * updaters and return part of the previous pointer as the prioidx or | 755 | * updaters and return part of the previous pointer as the prioidx or |
| 756 | * classid. Such races are short-lived and the result isn't critical. | 756 | * classid. Such races are short-lived and the result isn't critical. |
| 757 | */ | 757 | */ |
| 758 | static inline u16 sock_cgroup_prioidx(struct sock_cgroup_data *skcd) | 758 | static inline u16 sock_cgroup_prioidx(const struct sock_cgroup_data *skcd) |
| 759 | { | 759 | { |
| 760 | /* fallback to 1 which is always the ID of the root cgroup */ | 760 | /* fallback to 1 which is always the ID of the root cgroup */ |
| 761 | return (skcd->is_data & 1) ? skcd->prioidx : 1; | 761 | return (skcd->is_data & 1) ? skcd->prioidx : 1; |
| 762 | } | 762 | } |
| 763 | 763 | ||
| 764 | static inline u32 sock_cgroup_classid(struct sock_cgroup_data *skcd) | 764 | static inline u32 sock_cgroup_classid(const struct sock_cgroup_data *skcd) |
| 765 | { | 765 | { |
| 766 | /* fallback to 0 which is the unconfigured default classid */ | 766 | /* fallback to 0 which is the unconfigured default classid */ |
| 767 | return (skcd->is_data & 1) ? skcd->classid : 0; | 767 | return (skcd->is_data & 1) ? skcd->classid : 0; |
diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h index c332f0a45607..3fdfede2f0f3 100644 --- a/include/linux/fsl_ifc.h +++ b/include/linux/fsl_ifc.h | |||
| @@ -734,11 +734,7 @@ struct fsl_ifc_nand { | |||
| 734 | u32 res19[0x10]; | 734 | u32 res19[0x10]; |
| 735 | __be32 nand_fsr; | 735 | __be32 nand_fsr; |
| 736 | u32 res20; | 736 | u32 res20; |
| 737 | /* The V1 nand_eccstat is actually 4 words that overlaps the | 737 | __be32 nand_eccstat[8]; |
| 738 | * V2 nand_eccstat. | ||
| 739 | */ | ||
| 740 | __be32 v1_nand_eccstat[2]; | ||
| 741 | __be32 v2_nand_eccstat[6]; | ||
| 742 | u32 res21[0x1c]; | 738 | u32 res21[0x1c]; |
| 743 | __be32 nanndcr; | 739 | __be32 nanndcr; |
| 744 | u32 res22[0x2]; | 740 | u32 res22[0x2]; |
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index c5b0a75a7812..fd00170b494f 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h | |||
| @@ -25,6 +25,7 @@ struct ptr_ring *tun_get_tx_ring(struct file *file); | |||
| 25 | bool tun_is_xdp_buff(void *ptr); | 25 | bool tun_is_xdp_buff(void *ptr); |
| 26 | void *tun_xdp_to_ptr(void *ptr); | 26 | void *tun_xdp_to_ptr(void *ptr); |
| 27 | void *tun_ptr_to_xdp(void *ptr); | 27 | void *tun_ptr_to_xdp(void *ptr); |
| 28 | void tun_ptr_free(void *ptr); | ||
| 28 | #else | 29 | #else |
| 29 | #include <linux/err.h> | 30 | #include <linux/err.h> |
| 30 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
| @@ -50,5 +51,8 @@ static inline void *tun_ptr_to_xdp(void *ptr) | |||
| 50 | { | 51 | { |
| 51 | return NULL; | 52 | return NULL; |
| 52 | } | 53 | } |
| 54 | static inline void tun_ptr_free(void *ptr) | ||
| 55 | { | ||
| 56 | } | ||
| 53 | #endif /* CONFIG_TUN */ | 57 | #endif /* CONFIG_TUN */ |
| 54 | #endif /* __IF_TUN_H */ | 58 | #endif /* __IF_TUN_H */ |
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 5e6a2d4dc366..c4a1cff9c768 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
| @@ -300,30 +300,34 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features, | |||
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | /** | 302 | /** |
| 303 | * __vlan_insert_tag - regular VLAN tag inserting | 303 | * __vlan_insert_inner_tag - inner VLAN tag inserting |
| 304 | * @skb: skbuff to tag | 304 | * @skb: skbuff to tag |
| 305 | * @vlan_proto: VLAN encapsulation protocol | 305 | * @vlan_proto: VLAN encapsulation protocol |
| 306 | * @vlan_tci: VLAN TCI to insert | 306 | * @vlan_tci: VLAN TCI to insert |
| 307 | * @mac_len: MAC header length including outer vlan headers | ||
| 307 | * | 308 | * |
| 308 | * Inserts the VLAN tag into @skb as part of the payload | 309 | * Inserts the VLAN tag into @skb as part of the payload at offset mac_len |
| 309 | * Returns error if skb_cow_head failes. | 310 | * Returns error if skb_cow_head failes. |
| 310 | * | 311 | * |
| 311 | * Does not change skb->protocol so this function can be used during receive. | 312 | * Does not change skb->protocol so this function can be used during receive. |
| 312 | */ | 313 | */ |
| 313 | static inline int __vlan_insert_tag(struct sk_buff *skb, | 314 | static inline int __vlan_insert_inner_tag(struct sk_buff *skb, |
| 314 | __be16 vlan_proto, u16 vlan_tci) | 315 | __be16 vlan_proto, u16 vlan_tci, |
| 316 | unsigned int mac_len) | ||
| 315 | { | 317 | { |
| 316 | struct vlan_ethhdr *veth; | 318 | struct vlan_ethhdr *veth; |
| 317 | 319 | ||
| 318 | if (skb_cow_head(skb, VLAN_HLEN) < 0) | 320 | if (skb_cow_head(skb, VLAN_HLEN) < 0) |
| 319 | return -ENOMEM; | 321 | return -ENOMEM; |
| 320 | 322 | ||
| 321 | veth = skb_push(skb, VLAN_HLEN); | 323 | skb_push(skb, VLAN_HLEN); |
| 322 | 324 | ||
| 323 | /* Move the mac addresses to the beginning of the new header. */ | 325 | /* Move the mac header sans proto to the beginning of the new header. */ |
| 324 | memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN); | 326 | memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN); |
| 325 | skb->mac_header -= VLAN_HLEN; | 327 | skb->mac_header -= VLAN_HLEN; |
| 326 | 328 | ||
| 329 | veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN); | ||
| 330 | |||
| 327 | /* first, the ethernet type */ | 331 | /* first, the ethernet type */ |
| 328 | veth->h_vlan_proto = vlan_proto; | 332 | veth->h_vlan_proto = vlan_proto; |
| 329 | 333 | ||
| @@ -334,12 +338,30 @@ static inline int __vlan_insert_tag(struct sk_buff *skb, | |||
| 334 | } | 338 | } |
| 335 | 339 | ||
| 336 | /** | 340 | /** |
| 337 | * vlan_insert_tag - regular VLAN tag inserting | 341 | * __vlan_insert_tag - regular VLAN tag inserting |
| 338 | * @skb: skbuff to tag | 342 | * @skb: skbuff to tag |
| 339 | * @vlan_proto: VLAN encapsulation protocol | 343 | * @vlan_proto: VLAN encapsulation protocol |
| 340 | * @vlan_tci: VLAN TCI to insert | 344 | * @vlan_tci: VLAN TCI to insert |
| 341 | * | 345 | * |
| 342 | * Inserts the VLAN tag into @skb as part of the payload | 346 | * Inserts the VLAN tag into @skb as part of the payload |
| 347 | * Returns error if skb_cow_head failes. | ||
| 348 | * | ||
| 349 | * Does not change skb->protocol so this function can be used during receive. | ||
| 350 | */ | ||
| 351 | static inline int __vlan_insert_tag(struct sk_buff *skb, | ||
| 352 | __be16 vlan_proto, u16 vlan_tci) | ||
| 353 | { | ||
| 354 | return __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); | ||
| 355 | } | ||
| 356 | |||
| 357 | /** | ||
| 358 | * vlan_insert_inner_tag - inner VLAN tag inserting | ||
| 359 | * @skb: skbuff to tag | ||
| 360 | * @vlan_proto: VLAN encapsulation protocol | ||
| 361 | * @vlan_tci: VLAN TCI to insert | ||
| 362 | * @mac_len: MAC header length including outer vlan headers | ||
| 363 | * | ||
| 364 | * Inserts the VLAN tag into @skb as part of the payload at offset mac_len | ||
| 343 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. | 365 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. |
| 344 | * | 366 | * |
| 345 | * Following the skb_unshare() example, in case of error, the calling function | 367 | * Following the skb_unshare() example, in case of error, the calling function |
| @@ -347,12 +369,14 @@ static inline int __vlan_insert_tag(struct sk_buff *skb, | |||
| 347 | * | 369 | * |
| 348 | * Does not change skb->protocol so this function can be used during receive. | 370 | * Does not change skb->protocol so this function can be used during receive. |
| 349 | */ | 371 | */ |
| 350 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | 372 | static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb, |
| 351 | __be16 vlan_proto, u16 vlan_tci) | 373 | __be16 vlan_proto, |
| 374 | u16 vlan_tci, | ||
| 375 | unsigned int mac_len) | ||
| 352 | { | 376 | { |
| 353 | int err; | 377 | int err; |
| 354 | 378 | ||
| 355 | err = __vlan_insert_tag(skb, vlan_proto, vlan_tci); | 379 | err = __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, mac_len); |
| 356 | if (err) { | 380 | if (err) { |
| 357 | dev_kfree_skb_any(skb); | 381 | dev_kfree_skb_any(skb); |
| 358 | return NULL; | 382 | return NULL; |
| @@ -361,6 +385,26 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | |||
| 361 | } | 385 | } |
| 362 | 386 | ||
| 363 | /** | 387 | /** |
| 388 | * vlan_insert_tag - regular VLAN tag inserting | ||
| 389 | * @skb: skbuff to tag | ||
| 390 | * @vlan_proto: VLAN encapsulation protocol | ||
| 391 | * @vlan_tci: VLAN TCI to insert | ||
| 392 | * | ||
| 393 | * Inserts the VLAN tag into @skb as part of the payload | ||
| 394 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. | ||
| 395 | * | ||
| 396 | * Following the skb_unshare() example, in case of error, the calling function | ||
| 397 | * doesn't have to worry about freeing the original skb. | ||
| 398 | * | ||
| 399 | * Does not change skb->protocol so this function can be used during receive. | ||
| 400 | */ | ||
| 401 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | ||
| 402 | __be16 vlan_proto, u16 vlan_tci) | ||
| 403 | { | ||
| 404 | return vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | ||
| 364 | * vlan_insert_tag_set_proto - regular VLAN tag inserting | 408 | * vlan_insert_tag_set_proto - regular VLAN tag inserting |
| 365 | * @skb: skbuff to tag | 409 | * @skb: skbuff to tag |
| 366 | * @vlan_proto: VLAN encapsulation protocol | 410 | * @vlan_proto: VLAN encapsulation protocol |
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 2168cc6b8b30..b46b541c67c4 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h | |||
| @@ -151,7 +151,7 @@ extern struct jump_entry __start___jump_table[]; | |||
| 151 | extern struct jump_entry __stop___jump_table[]; | 151 | extern struct jump_entry __stop___jump_table[]; |
| 152 | 152 | ||
| 153 | extern void jump_label_init(void); | 153 | extern void jump_label_init(void); |
| 154 | extern void jump_label_invalidate_init(void); | 154 | extern void jump_label_invalidate_initmem(void); |
| 155 | extern void jump_label_lock(void); | 155 | extern void jump_label_lock(void); |
| 156 | extern void jump_label_unlock(void); | 156 | extern void jump_label_unlock(void); |
| 157 | extern void arch_jump_label_transform(struct jump_entry *entry, | 157 | extern void arch_jump_label_transform(struct jump_entry *entry, |
| @@ -199,7 +199,7 @@ static __always_inline void jump_label_init(void) | |||
| 199 | static_key_initialized = true; | 199 | static_key_initialized = true; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static inline void jump_label_invalidate_init(void) {} | 202 | static inline void jump_label_invalidate_initmem(void) {} |
| 203 | 203 | ||
| 204 | static __always_inline bool static_key_false(struct static_key *key) | 204 | static __always_inline bool static_key_false(struct static_key *key) |
| 205 | { | 205 | { |
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 8be5077efb5f..f92ea7783652 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
| @@ -187,7 +187,6 @@ int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, | |||
| 187 | unsigned long *end_pfn); | 187 | unsigned long *end_pfn); |
| 188 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, | 188 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, |
| 189 | unsigned long *out_end_pfn, int *out_nid); | 189 | unsigned long *out_end_pfn, int *out_nid); |
| 190 | unsigned long memblock_next_valid_pfn(unsigned long pfn, unsigned long max_pfn); | ||
| 191 | 190 | ||
| 192 | /** | 191 | /** |
| 193 | * for_each_mem_pfn_range - early memory pfn range iterator | 192 | * for_each_mem_pfn_range - early memory pfn range iterator |
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 6ed79a8a8318..9d3a03364e6e 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
| @@ -453,8 +453,8 @@ struct mlx5_core_srq { | |||
| 453 | struct mlx5_core_rsc_common common; /* must be first */ | 453 | struct mlx5_core_rsc_common common; /* must be first */ |
| 454 | u32 srqn; | 454 | u32 srqn; |
| 455 | int max; | 455 | int max; |
| 456 | int max_gs; | 456 | size_t max_gs; |
| 457 | int max_avail_gather; | 457 | size_t max_avail_gather; |
| 458 | int wqe_shift; | 458 | int wqe_shift; |
| 459 | void (*event) (struct mlx5_core_srq *, enum mlx5_event); | 459 | void (*event) (struct mlx5_core_srq *, enum mlx5_event); |
| 460 | 460 | ||
diff --git a/include/linux/net.h b/include/linux/net.h index 91216b16feb7..2a0391eea05c 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
| @@ -222,6 +222,7 @@ enum { | |||
| 222 | int sock_wake_async(struct socket_wq *sk_wq, int how, int band); | 222 | int sock_wake_async(struct socket_wq *sk_wq, int how, int band); |
| 223 | int sock_register(const struct net_proto_family *fam); | 223 | int sock_register(const struct net_proto_family *fam); |
| 224 | void sock_unregister(int family); | 224 | void sock_unregister(int family); |
| 225 | bool sock_is_registered(int family); | ||
| 225 | int __sock_create(struct net *net, int family, int type, int proto, | 226 | int __sock_create(struct net *net, int family, int type, int proto, |
| 226 | struct socket **res, int kern); | 227 | struct socket **res, int kern); |
| 227 | int sock_create(int family, int type, int proto, struct socket **res); | 228 | int sock_create(int family, int type, int proto, struct socket **res); |
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 1313b35c3ab7..14529511c4b8 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
| @@ -285,6 +285,8 @@ unsigned int *xt_alloc_entry_offsets(unsigned int size); | |||
| 285 | bool xt_find_jump_offset(const unsigned int *offsets, | 285 | bool xt_find_jump_offset(const unsigned int *offsets, |
| 286 | unsigned int target, unsigned int size); | 286 | unsigned int target, unsigned int size); |
| 287 | 287 | ||
| 288 | int xt_check_proc_name(const char *name, unsigned int size); | ||
| 289 | |||
| 288 | int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, | 290 | int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, |
| 289 | bool inv_proto); | 291 | bool inv_proto); |
| 290 | int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, | 292 | int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, |
diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index 864d167a1073..009cdf3d65b6 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h | |||
| @@ -30,10 +30,14 @@ | |||
| 30 | * calls io_destroy() or the process exits. | 30 | * calls io_destroy() or the process exits. |
| 31 | * | 31 | * |
| 32 | * In the aio code, kill_ioctx() is called when we wish to destroy a kioctx; it | 32 | * In the aio code, kill_ioctx() is called when we wish to destroy a kioctx; it |
| 33 | * calls percpu_ref_kill(), then hlist_del_rcu() and synchronize_rcu() to remove | 33 | * removes the kioctx from the proccess's table of kioctxs and kills percpu_ref. |
| 34 | * the kioctx from the proccess's list of kioctxs - after that, there can't be | 34 | * After that, there can't be any new users of the kioctx (from lookup_ioctx()) |
| 35 | * any new users of the kioctx (from lookup_ioctx()) and it's then safe to drop | 35 | * and it's then safe to drop the initial ref with percpu_ref_put(). |
| 36 | * the initial ref with percpu_ref_put(). | 36 | * |
| 37 | * Note that the free path, free_ioctx(), needs to go through explicit call_rcu() | ||
| 38 | * to synchronize with RCU protected lookup_ioctx(). percpu_ref operations don't | ||
| 39 | * imply RCU grace periods of any kind and if a user wants to combine percpu_ref | ||
| 40 | * with RCU protection, it must be done explicitly. | ||
| 37 | * | 41 | * |
| 38 | * Code that does a two stage shutdown like this often needs some kind of | 42 | * Code that does a two stage shutdown like this often needs some kind of |
| 39 | * explicit synchronization to ensure the initial refcount can only be dropped | 43 | * explicit synchronization to ensure the initial refcount can only be dropped |
| @@ -113,8 +117,10 @@ void percpu_ref_reinit(struct percpu_ref *ref); | |||
| 113 | * Must be used to drop the initial ref on a percpu refcount; must be called | 117 | * Must be used to drop the initial ref on a percpu refcount; must be called |
| 114 | * precisely once before shutdown. | 118 | * precisely once before shutdown. |
| 115 | * | 119 | * |
| 116 | * Puts @ref in non percpu mode, then does a call_rcu() before gathering up the | 120 | * Switches @ref into atomic mode before gathering up the percpu counters |
| 117 | * percpu counters and dropping the initial ref. | 121 | * and dropping the initial ref. |
| 122 | * | ||
| 123 | * There are no implied RCU grace periods between kill and release. | ||
| 118 | */ | 124 | */ |
| 119 | static inline void percpu_ref_kill(struct percpu_ref *ref) | 125 | static inline void percpu_ref_kill(struct percpu_ref *ref) |
| 120 | { | 126 | { |
diff --git a/include/linux/phy.h b/include/linux/phy.h index d7069539f351..7c4c2379e010 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h | |||
| @@ -984,6 +984,10 @@ static inline int genphy_no_soft_reset(struct phy_device *phydev) | |||
| 984 | { | 984 | { |
| 985 | return 0; | 985 | return 0; |
| 986 | } | 986 | } |
| 987 | int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, | ||
| 988 | u16 regnum); | ||
| 989 | int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum, | ||
| 990 | u16 regnum, u16 val); | ||
| 987 | 991 | ||
| 988 | /* Clause 45 PHY */ | 992 | /* Clause 45 PHY */ |
| 989 | int genphy_c45_restart_aneg(struct phy_device *phydev); | 993 | int genphy_c45_restart_aneg(struct phy_device *phydev); |
| @@ -1012,7 +1016,6 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner); | |||
| 1012 | int phy_drivers_register(struct phy_driver *new_driver, int n, | 1016 | int phy_drivers_register(struct phy_driver *new_driver, int n, |
| 1013 | struct module *owner); | 1017 | struct module *owner); |
| 1014 | void phy_state_machine(struct work_struct *work); | 1018 | void phy_state_machine(struct work_struct *work); |
| 1015 | void phy_change(struct phy_device *phydev); | ||
| 1016 | void phy_change_work(struct work_struct *work); | 1019 | void phy_change_work(struct work_struct *work); |
| 1017 | void phy_mac_interrupt(struct phy_device *phydev); | 1020 | void phy_mac_interrupt(struct phy_device *phydev); |
| 1018 | void phy_start_machine(struct phy_device *phydev); | 1021 | void phy_start_machine(struct phy_device *phydev); |
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index c9df2527e0cd..668a21f04b09 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h | |||
| @@ -766,8 +766,10 @@ slow_path: | |||
| 766 | if (!key || | 766 | if (!key || |
| 767 | (params.obj_cmpfn ? | 767 | (params.obj_cmpfn ? |
| 768 | params.obj_cmpfn(&arg, rht_obj(ht, head)) : | 768 | params.obj_cmpfn(&arg, rht_obj(ht, head)) : |
| 769 | rhashtable_compare(&arg, rht_obj(ht, head)))) | 769 | rhashtable_compare(&arg, rht_obj(ht, head)))) { |
| 770 | pprev = &head->next; | ||
| 770 | continue; | 771 | continue; |
| 772 | } | ||
| 771 | 773 | ||
| 772 | data = rht_obj(ht, head); | 774 | data = rht_obj(ht, head); |
| 773 | 775 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index ddf77cf4ff2d..99df17109e1b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -4037,6 +4037,12 @@ static inline bool skb_is_gso_v6(const struct sk_buff *skb) | |||
| 4037 | return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6; | 4037 | return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6; |
| 4038 | } | 4038 | } |
| 4039 | 4039 | ||
| 4040 | /* Note: Should be called only if skb_is_gso(skb) is true */ | ||
| 4041 | static inline bool skb_is_gso_sctp(const struct sk_buff *skb) | ||
| 4042 | { | ||
| 4043 | return skb_shinfo(skb)->gso_type & SKB_GSO_SCTP; | ||
| 4044 | } | ||
| 4045 | |||
| 4040 | static inline void skb_gso_reset(struct sk_buff *skb) | 4046 | static inline void skb_gso_reset(struct sk_buff *skb) |
| 4041 | { | 4047 | { |
| 4042 | skb_shinfo(skb)->gso_size = 0; | 4048 | skb_shinfo(skb)->gso_size = 0; |
| @@ -4044,6 +4050,22 @@ static inline void skb_gso_reset(struct sk_buff *skb) | |||
| 4044 | skb_shinfo(skb)->gso_type = 0; | 4050 | skb_shinfo(skb)->gso_type = 0; |
| 4045 | } | 4051 | } |
| 4046 | 4052 | ||
| 4053 | static inline void skb_increase_gso_size(struct skb_shared_info *shinfo, | ||
| 4054 | u16 increment) | ||
| 4055 | { | ||
| 4056 | if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS)) | ||
| 4057 | return; | ||
| 4058 | shinfo->gso_size += increment; | ||
| 4059 | } | ||
| 4060 | |||
| 4061 | static inline void skb_decrease_gso_size(struct skb_shared_info *shinfo, | ||
| 4062 | u16 decrement) | ||
| 4063 | { | ||
| 4064 | if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS)) | ||
| 4065 | return; | ||
| 4066 | shinfo->gso_size -= decrement; | ||
| 4067 | } | ||
| 4068 | |||
| 4047 | void __skb_warn_lro_forwarding(const struct sk_buff *skb); | 4069 | void __skb_warn_lro_forwarding(const struct sk_buff *skb); |
| 4048 | 4070 | ||
| 4049 | static inline bool skb_warn_if_lro(const struct sk_buff *skb) | 4071 | static inline bool skb_warn_if_lro(const struct sk_buff *skb) |
diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h index 5bdbd9f49395..07ee0f84a46c 100644 --- a/include/linux/u64_stats_sync.h +++ b/include/linux/u64_stats_sync.h | |||
| @@ -90,6 +90,28 @@ static inline void u64_stats_update_end(struct u64_stats_sync *syncp) | |||
| 90 | #endif | 90 | #endif |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static inline unsigned long | ||
| 94 | u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp) | ||
| 95 | { | ||
| 96 | unsigned long flags = 0; | ||
| 97 | |||
| 98 | #if BITS_PER_LONG==32 && defined(CONFIG_SMP) | ||
| 99 | local_irq_save(flags); | ||
| 100 | write_seqcount_begin(&syncp->seq); | ||
| 101 | #endif | ||
| 102 | return flags; | ||
| 103 | } | ||
| 104 | |||
| 105 | static inline void | ||
| 106 | u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp, | ||
| 107 | unsigned long flags) | ||
| 108 | { | ||
| 109 | #if BITS_PER_LONG==32 && defined(CONFIG_SMP) | ||
| 110 | write_seqcount_end(&syncp->seq); | ||
| 111 | local_irq_restore(flags); | ||
| 112 | #endif | ||
| 113 | } | ||
| 114 | |||
| 93 | static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp) | 115 | static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp) |
| 94 | { | 116 | { |
| 95 | #if BITS_PER_LONG==32 && defined(CONFIG_SMP) | 117 | #if BITS_PER_LONG==32 && defined(CONFIG_SMP) |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index bc0cda180c8b..0c3301421c57 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
| @@ -456,7 +456,6 @@ extern int schedule_on_each_cpu(work_func_t func); | |||
| 456 | int execute_in_process_context(work_func_t fn, struct execute_work *); | 456 | int execute_in_process_context(work_func_t fn, struct execute_work *); |
| 457 | 457 | ||
| 458 | extern bool flush_work(struct work_struct *work); | 458 | extern bool flush_work(struct work_struct *work); |
| 459 | extern bool cancel_work(struct work_struct *work); | ||
| 460 | extern bool cancel_work_sync(struct work_struct *work); | 459 | extern bool cancel_work_sync(struct work_struct *work); |
| 461 | 460 | ||
| 462 | extern bool flush_delayed_work(struct delayed_work *dwork); | 461 | extern bool flush_delayed_work(struct delayed_work *dwork); |
diff --git a/include/net/ip.h b/include/net/ip.h index 746abff9ce51..f49b3a576bec 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -328,6 +328,13 @@ int ip_decrease_ttl(struct iphdr *iph) | |||
| 328 | return --iph->ttl; | 328 | return --iph->ttl; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | static inline int ip_mtu_locked(const struct dst_entry *dst) | ||
| 332 | { | ||
| 333 | const struct rtable *rt = (const struct rtable *)dst; | ||
| 334 | |||
| 335 | return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU); | ||
| 336 | } | ||
| 337 | |||
| 331 | static inline | 338 | static inline |
| 332 | int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) | 339 | int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) |
| 333 | { | 340 | { |
| @@ -335,7 +342,7 @@ int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) | |||
| 335 | 342 | ||
| 336 | return pmtudisc == IP_PMTUDISC_DO || | 343 | return pmtudisc == IP_PMTUDISC_DO || |
| 337 | (pmtudisc == IP_PMTUDISC_WANT && | 344 | (pmtudisc == IP_PMTUDISC_WANT && |
| 338 | !(dst_metric_locked(dst, RTAX_MTU))); | 345 | !ip_mtu_locked(dst)); |
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | static inline bool ip_sk_accept_pmtu(const struct sock *sk) | 348 | static inline bool ip_sk_accept_pmtu(const struct sock *sk) |
| @@ -361,7 +368,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, | |||
| 361 | struct net *net = dev_net(dst->dev); | 368 | struct net *net = dev_net(dst->dev); |
| 362 | 369 | ||
| 363 | if (net->ipv4.sysctl_ip_fwd_use_pmtu || | 370 | if (net->ipv4.sysctl_ip_fwd_use_pmtu || |
| 364 | dst_metric_locked(dst, RTAX_MTU) || | 371 | ip_mtu_locked(dst) || |
| 365 | !forwarding) | 372 | !forwarding) |
| 366 | return dst_mtu(dst); | 373 | return dst_mtu(dst); |
| 367 | 374 | ||
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 27d23a65f3cd..ac0866bb9e93 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
| @@ -179,6 +179,9 @@ void rt6_disable_ip(struct net_device *dev, unsigned long event); | |||
| 179 | void rt6_sync_down_dev(struct net_device *dev, unsigned long event); | 179 | void rt6_sync_down_dev(struct net_device *dev, unsigned long event); |
| 180 | void rt6_multipath_rebalance(struct rt6_info *rt); | 180 | void rt6_multipath_rebalance(struct rt6_info *rt); |
| 181 | 181 | ||
| 182 | void rt6_uncached_list_add(struct rt6_info *rt); | ||
| 183 | void rt6_uncached_list_del(struct rt6_info *rt); | ||
| 184 | |||
| 182 | static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) | 185 | static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) |
| 183 | { | 186 | { |
| 184 | const struct dst_entry *dst = skb_dst(skb); | 187 | const struct dst_entry *dst = skb_dst(skb); |
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index f80524396c06..77d0a78cf7d2 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
| @@ -59,6 +59,7 @@ struct fib_nh_exception { | |||
| 59 | int fnhe_genid; | 59 | int fnhe_genid; |
| 60 | __be32 fnhe_daddr; | 60 | __be32 fnhe_daddr; |
| 61 | u32 fnhe_pmtu; | 61 | u32 fnhe_pmtu; |
| 62 | bool fnhe_mtu_locked; | ||
| 62 | __be32 fnhe_gw; | 63 | __be32 fnhe_gw; |
| 63 | unsigned long fnhe_expires; | 64 | unsigned long fnhe_expires; |
| 64 | struct rtable __rcu *fnhe_rth_input; | 65 | struct rtable __rcu *fnhe_rth_input; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c96511fa9198..2b581bd93812 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -2063,6 +2063,9 @@ struct ieee80211_txq { | |||
| 2063 | * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on | 2063 | * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on |
| 2064 | * TDLS links. | 2064 | * TDLS links. |
| 2065 | * | 2065 | * |
| 2066 | * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't | ||
| 2067 | * support QoS NDP for AP probing - that's most likely a driver bug. | ||
| 2068 | * | ||
| 2066 | * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays | 2069 | * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays |
| 2067 | */ | 2070 | */ |
| 2068 | enum ieee80211_hw_flags { | 2071 | enum ieee80211_hw_flags { |
| @@ -2106,6 +2109,7 @@ enum ieee80211_hw_flags { | |||
| 2106 | IEEE80211_HW_REPORTS_LOW_ACK, | 2109 | IEEE80211_HW_REPORTS_LOW_ACK, |
| 2107 | IEEE80211_HW_SUPPORTS_TX_FRAG, | 2110 | IEEE80211_HW_SUPPORTS_TX_FRAG, |
| 2108 | IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, | 2111 | IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, |
| 2112 | IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, | ||
| 2109 | 2113 | ||
| 2110 | /* keep last, obviously */ | 2114 | /* keep last, obviously */ |
| 2111 | NUM_IEEE80211_HW_FLAGS | 2115 | NUM_IEEE80211_HW_FLAGS |
diff --git a/include/net/route.h b/include/net/route.h index 1eb9ce470e25..20a92ca9e115 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
| @@ -63,7 +63,8 @@ struct rtable { | |||
| 63 | __be32 rt_gateway; | 63 | __be32 rt_gateway; |
| 64 | 64 | ||
| 65 | /* Miscellaneous cached information */ | 65 | /* Miscellaneous cached information */ |
| 66 | u32 rt_pmtu; | 66 | u32 rt_mtu_locked:1, |
| 67 | rt_pmtu:31; | ||
| 67 | 68 | ||
| 68 | u32 rt_table_id; | 69 | u32 rt_table_id; |
| 69 | 70 | ||
| @@ -227,6 +228,9 @@ struct in_ifaddr; | |||
| 227 | void fib_add_ifaddr(struct in_ifaddr *); | 228 | void fib_add_ifaddr(struct in_ifaddr *); |
| 228 | void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); | 229 | void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); |
| 229 | 230 | ||
| 231 | void rt_add_uncached_list(struct rtable *rt); | ||
| 232 | void rt_del_uncached_list(struct rtable *rt); | ||
| 233 | |||
| 230 | static inline void ip_rt_put(struct rtable *rt) | 234 | static inline void ip_rt_put(struct rtable *rt) |
| 231 | { | 235 | { |
| 232 | /* dst_release() accepts a NULL parameter. | 236 | /* dst_release() accepts a NULL parameter. |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index e2ab13687fb9..2092d33194dd 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
| @@ -824,6 +824,16 @@ static inline void __qdisc_drop(struct sk_buff *skb, struct sk_buff **to_free) | |||
| 824 | *to_free = skb; | 824 | *to_free = skb; |
| 825 | } | 825 | } |
| 826 | 826 | ||
| 827 | static inline void __qdisc_drop_all(struct sk_buff *skb, | ||
| 828 | struct sk_buff **to_free) | ||
| 829 | { | ||
| 830 | if (skb->prev) | ||
| 831 | skb->prev->next = *to_free; | ||
| 832 | else | ||
| 833 | skb->next = *to_free; | ||
| 834 | *to_free = skb; | ||
| 835 | } | ||
| 836 | |||
| 827 | static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch, | 837 | static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch, |
| 828 | struct qdisc_skb_head *qh, | 838 | struct qdisc_skb_head *qh, |
| 829 | struct sk_buff **to_free) | 839 | struct sk_buff **to_free) |
| @@ -956,6 +966,15 @@ static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch, | |||
| 956 | return NET_XMIT_DROP; | 966 | return NET_XMIT_DROP; |
| 957 | } | 967 | } |
| 958 | 968 | ||
| 969 | static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch, | ||
| 970 | struct sk_buff **to_free) | ||
| 971 | { | ||
| 972 | __qdisc_drop_all(skb, to_free); | ||
| 973 | qdisc_qstats_drop(sch); | ||
| 974 | |||
| 975 | return NET_XMIT_DROP; | ||
| 976 | } | ||
| 977 | |||
| 959 | /* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how | 978 | /* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how |
| 960 | long it will take to send a packet given its size. | 979 | long it will take to send a packet given its size. |
| 961 | */ | 980 | */ |
diff --git a/include/net/sock.h b/include/net/sock.h index 169c92afcafa..ae23f3b389ca 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1137,6 +1137,7 @@ struct proto { | |||
| 1137 | 1137 | ||
| 1138 | int proto_register(struct proto *prot, int alloc_slab); | 1138 | int proto_register(struct proto *prot, int alloc_slab); |
| 1139 | void proto_unregister(struct proto *prot); | 1139 | void proto_unregister(struct proto *prot); |
| 1140 | int sock_load_diag_module(int family, int protocol); | ||
| 1140 | 1141 | ||
| 1141 | #ifdef SOCK_REFCNT_DEBUG | 1142 | #ifdef SOCK_REFCNT_DEBUG |
| 1142 | static inline void sk_refcnt_debug_inc(struct sock *sk) | 1143 | static inline void sk_refcnt_debug_inc(struct sock *sk) |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 73b2387e3f74..ff3ed435701f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
| @@ -1537,10 +1537,6 @@ struct ib_xrcd { | |||
| 1537 | 1537 | ||
| 1538 | struct mutex tgt_qp_mutex; | 1538 | struct mutex tgt_qp_mutex; |
| 1539 | struct list_head tgt_qp_list; | 1539 | struct list_head tgt_qp_list; |
| 1540 | /* | ||
| 1541 | * Implementation details of the RDMA core, don't use in drivers: | ||
| 1542 | */ | ||
| 1543 | struct rdma_restrack_entry res; | ||
| 1544 | }; | 1540 | }; |
| 1545 | 1541 | ||
| 1546 | struct ib_ah { | 1542 | struct ib_ah { |
diff --git a/include/trace/events/mmc.h b/include/trace/events/mmc.h index 200f731be557..7b706ff21335 100644 --- a/include/trace/events/mmc.h +++ b/include/trace/events/mmc.h | |||
| @@ -86,8 +86,8 @@ TRACE_EVENT(mmc_request_start, | |||
| 86 | __entry->stop_flags, __entry->stop_retries, | 86 | __entry->stop_flags, __entry->stop_retries, |
| 87 | __entry->sbc_opcode, __entry->sbc_arg, | 87 | __entry->sbc_opcode, __entry->sbc_arg, |
| 88 | __entry->sbc_flags, __entry->sbc_retries, | 88 | __entry->sbc_flags, __entry->sbc_retries, |
| 89 | __entry->blocks, __entry->blk_addr, | 89 | __entry->blocks, __entry->blksz, |
| 90 | __entry->blksz, __entry->data_flags, __entry->tag, | 90 | __entry->blk_addr, __entry->data_flags, __entry->tag, |
| 91 | __entry->can_retune, __entry->doing_retune, | 91 | __entry->can_retune, __entry->doing_retune, |
| 92 | __entry->retune_now, __entry->need_retune, | 92 | __entry->retune_now, __entry->need_retune, |
| 93 | __entry->hold_retune, __entry->retune_period) | 93 | __entry->hold_retune, __entry->retune_period) |
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 8bbbcb5cd94b..820de5d222d2 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #define ETH_ALEN 6 /* Octets in one ethernet addr */ | 32 | #define ETH_ALEN 6 /* Octets in one ethernet addr */ |
| 33 | #define ETH_TLEN 2 /* Octets in ethernet type field */ | ||
| 33 | #define ETH_HLEN 14 /* Total octets in header. */ | 34 | #define ETH_HLEN 14 /* Total octets in header. */ |
| 34 | #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ | 35 | #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ |
| 35 | #define ETH_DATA_LEN 1500 /* Max. octets in payload */ | 36 | #define ETH_DATA_LEN 1500 /* Max. octets in payload */ |
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index 4fe580d36e41..f5bf06ecd87d 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h | |||
| @@ -54,7 +54,6 @@ | |||
| 54 | #define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) | 54 | #define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) |
| 55 | #define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) | 55 | #define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) |
| 56 | #define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) | 56 | #define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) |
| 57 | #define LIRC_CAN_SEND_SCANCODE LIRC_MODE2SEND(LIRC_MODE_SCANCODE) | ||
| 58 | #define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) | 57 | #define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) |
| 59 | 58 | ||
| 60 | #define LIRC_CAN_SEND_MASK 0x0000003f | 59 | #define LIRC_CAN_SEND_MASK 0x0000003f |
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h index 17a022c5b414..da3315ed1bcd 100644 --- a/include/uapi/linux/usb/audio.h +++ b/include/uapi/linux/usb/audio.h | |||
| @@ -370,7 +370,7 @@ static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_d | |||
| 370 | { | 370 | { |
| 371 | return (protocol == UAC_VERSION_1) ? | 371 | return (protocol == UAC_VERSION_1) ? |
| 372 | desc->baSourceID[desc->bNrInPins + 4] : | 372 | desc->baSourceID[desc->bNrInPins + 4] : |
| 373 | desc->baSourceID[desc->bNrInPins + 6]; | 373 | 2; /* in UAC2, this value is constant */ |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc, | 376 | static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc, |
| @@ -378,7 +378,7 @@ static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_de | |||
| 378 | { | 378 | { |
| 379 | return (protocol == UAC_VERSION_1) ? | 379 | return (protocol == UAC_VERSION_1) ? |
| 380 | &desc->baSourceID[desc->bNrInPins + 5] : | 380 | &desc->baSourceID[desc->bNrInPins + 5] : |
| 381 | &desc->baSourceID[desc->bNrInPins + 7]; | 381 | &desc->baSourceID[desc->bNrInPins + 6]; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc, | 384 | static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc, |
diff --git a/init/main.c b/init/main.c index 969eaf140ef0..21efbf6ace93 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -1001,7 +1001,7 @@ static int __ref kernel_init(void *unused) | |||
| 1001 | /* need to finish all async __init code before freeing the memory */ | 1001 | /* need to finish all async __init code before freeing the memory */ |
| 1002 | async_synchronize_full(); | 1002 | async_synchronize_full(); |
| 1003 | ftrace_free_init_mem(); | 1003 | ftrace_free_init_mem(); |
| 1004 | jump_label_invalidate_init(); | 1004 | jump_label_invalidate_initmem(); |
| 1005 | free_initmem(); | 1005 | free_initmem(); |
| 1006 | mark_readonly(); | 1006 | mark_readonly(); |
| 1007 | system_state = SYSTEM_RUNNING; | 1007 | system_state = SYSTEM_RUNNING; |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index d7f309f74dec..a808f29d4c5a 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -325,9 +325,8 @@ err: | |||
| 325 | static int mqueue_fill_super(struct super_block *sb, void *data, int silent) | 325 | static int mqueue_fill_super(struct super_block *sb, void *data, int silent) |
| 326 | { | 326 | { |
| 327 | struct inode *inode; | 327 | struct inode *inode; |
| 328 | struct ipc_namespace *ns = data; | 328 | struct ipc_namespace *ns = sb->s_fs_info; |
| 329 | 329 | ||
| 330 | sb->s_fs_info = ns; | ||
| 331 | sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV; | 330 | sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV; |
| 332 | sb->s_blocksize = PAGE_SIZE; | 331 | sb->s_blocksize = PAGE_SIZE; |
| 333 | sb->s_blocksize_bits = PAGE_SHIFT; | 332 | sb->s_blocksize_bits = PAGE_SHIFT; |
| @@ -344,44 +343,18 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent) | |||
| 344 | return 0; | 343 | return 0; |
| 345 | } | 344 | } |
| 346 | 345 | ||
| 347 | static struct file_system_type mqueue_fs_type; | ||
| 348 | /* | ||
| 349 | * Return value is pinned only by reference in ->mq_mnt; it will | ||
| 350 | * live until ipcns dies. Caller does not need to drop it. | ||
| 351 | */ | ||
| 352 | static struct vfsmount *mq_internal_mount(void) | ||
| 353 | { | ||
| 354 | struct ipc_namespace *ns = current->nsproxy->ipc_ns; | ||
| 355 | struct vfsmount *m = ns->mq_mnt; | ||
| 356 | if (m) | ||
| 357 | return m; | ||
| 358 | m = kern_mount_data(&mqueue_fs_type, ns); | ||
| 359 | spin_lock(&mq_lock); | ||
| 360 | if (unlikely(ns->mq_mnt)) { | ||
| 361 | spin_unlock(&mq_lock); | ||
| 362 | if (!IS_ERR(m)) | ||
| 363 | kern_unmount(m); | ||
| 364 | return ns->mq_mnt; | ||
| 365 | } | ||
| 366 | if (!IS_ERR(m)) | ||
| 367 | ns->mq_mnt = m; | ||
| 368 | spin_unlock(&mq_lock); | ||
| 369 | return m; | ||
| 370 | } | ||
| 371 | |||
| 372 | static struct dentry *mqueue_mount(struct file_system_type *fs_type, | 346 | static struct dentry *mqueue_mount(struct file_system_type *fs_type, |
| 373 | int flags, const char *dev_name, | 347 | int flags, const char *dev_name, |
| 374 | void *data) | 348 | void *data) |
| 375 | { | 349 | { |
| 376 | struct vfsmount *m; | 350 | struct ipc_namespace *ns; |
| 377 | if (flags & SB_KERNMOUNT) | 351 | if (flags & SB_KERNMOUNT) { |
| 378 | return mount_nodev(fs_type, flags, data, mqueue_fill_super); | 352 | ns = data; |
| 379 | m = mq_internal_mount(); | 353 | data = NULL; |
| 380 | if (IS_ERR(m)) | 354 | } else { |
| 381 | return ERR_CAST(m); | 355 | ns = current->nsproxy->ipc_ns; |
| 382 | atomic_inc(&m->mnt_sb->s_active); | 356 | } |
| 383 | down_write(&m->mnt_sb->s_umount); | 357 | return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super); |
| 384 | return dget(m->mnt_root); | ||
| 385 | } | 358 | } |
| 386 | 359 | ||
| 387 | static void init_once(void *foo) | 360 | static void init_once(void *foo) |
| @@ -771,16 +744,13 @@ static int prepare_open(struct dentry *dentry, int oflag, int ro, | |||
| 771 | static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, | 744 | static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, |
| 772 | struct mq_attr *attr) | 745 | struct mq_attr *attr) |
| 773 | { | 746 | { |
| 774 | struct vfsmount *mnt = mq_internal_mount(); | 747 | struct vfsmount *mnt = current->nsproxy->ipc_ns->mq_mnt; |
| 775 | struct dentry *root; | 748 | struct dentry *root = mnt->mnt_root; |
| 776 | struct filename *name; | 749 | struct filename *name; |
| 777 | struct path path; | 750 | struct path path; |
| 778 | int fd, error; | 751 | int fd, error; |
| 779 | int ro; | 752 | int ro; |
| 780 | 753 | ||
| 781 | if (IS_ERR(mnt)) | ||
| 782 | return PTR_ERR(mnt); | ||
| 783 | |||
| 784 | audit_mq_open(oflag, mode, attr); | 754 | audit_mq_open(oflag, mode, attr); |
| 785 | 755 | ||
| 786 | if (IS_ERR(name = getname(u_name))) | 756 | if (IS_ERR(name = getname(u_name))) |
| @@ -791,7 +761,6 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, | |||
| 791 | goto out_putname; | 761 | goto out_putname; |
| 792 | 762 | ||
| 793 | ro = mnt_want_write(mnt); /* we'll drop it in any case */ | 763 | ro = mnt_want_write(mnt); /* we'll drop it in any case */ |
| 794 | root = mnt->mnt_root; | ||
| 795 | inode_lock(d_inode(root)); | 764 | inode_lock(d_inode(root)); |
| 796 | path.dentry = lookup_one_len(name->name, root, strlen(name->name)); | 765 | path.dentry = lookup_one_len(name->name, root, strlen(name->name)); |
| 797 | if (IS_ERR(path.dentry)) { | 766 | if (IS_ERR(path.dentry)) { |
| @@ -840,9 +809,6 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) | |||
| 840 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; | 809 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; |
| 841 | struct vfsmount *mnt = ipc_ns->mq_mnt; | 810 | struct vfsmount *mnt = ipc_ns->mq_mnt; |
| 842 | 811 | ||
| 843 | if (!mnt) | ||
| 844 | return -ENOENT; | ||
| 845 | |||
| 846 | name = getname(u_name); | 812 | name = getname(u_name); |
| 847 | if (IS_ERR(name)) | 813 | if (IS_ERR(name)) |
| 848 | return PTR_ERR(name); | 814 | return PTR_ERR(name); |
| @@ -1569,26 +1535,28 @@ int mq_init_ns(struct ipc_namespace *ns) | |||
| 1569 | ns->mq_msgsize_max = DFLT_MSGSIZEMAX; | 1535 | ns->mq_msgsize_max = DFLT_MSGSIZEMAX; |
| 1570 | ns->mq_msg_default = DFLT_MSG; | 1536 | ns->mq_msg_default = DFLT_MSG; |
| 1571 | ns->mq_msgsize_default = DFLT_MSGSIZE; | 1537 | ns->mq_msgsize_default = DFLT_MSGSIZE; |
| 1572 | ns->mq_mnt = NULL; | ||
| 1573 | 1538 | ||
| 1539 | ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns); | ||
| 1540 | if (IS_ERR(ns->mq_mnt)) { | ||
| 1541 | int err = PTR_ERR(ns->mq_mnt); | ||
| 1542 | ns->mq_mnt = NULL; | ||
| 1543 | return err; | ||
| 1544 | } | ||
| 1574 | return 0; | 1545 | return 0; |
| 1575 | } | 1546 | } |
| 1576 | 1547 | ||
| 1577 | void mq_clear_sbinfo(struct ipc_namespace *ns) | 1548 | void mq_clear_sbinfo(struct ipc_namespace *ns) |
| 1578 | { | 1549 | { |
| 1579 | if (ns->mq_mnt) | 1550 | ns->mq_mnt->mnt_sb->s_fs_info = NULL; |
| 1580 | ns->mq_mnt->mnt_sb->s_fs_info = NULL; | ||
| 1581 | } | 1551 | } |
| 1582 | 1552 | ||
| 1583 | void mq_put_mnt(struct ipc_namespace *ns) | 1553 | void mq_put_mnt(struct ipc_namespace *ns) |
| 1584 | { | 1554 | { |
| 1585 | if (ns->mq_mnt) | 1555 | kern_unmount(ns->mq_mnt); |
| 1586 | kern_unmount(ns->mq_mnt); | ||
| 1587 | } | 1556 | } |
| 1588 | 1557 | ||
| 1589 | static int __init init_mqueue_fs(void) | 1558 | static int __init init_mqueue_fs(void) |
| 1590 | { | 1559 | { |
| 1591 | struct vfsmount *m; | ||
| 1592 | int error; | 1560 | int error; |
| 1593 | 1561 | ||
| 1594 | mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache", | 1562 | mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache", |
| @@ -1610,10 +1578,6 @@ static int __init init_mqueue_fs(void) | |||
| 1610 | if (error) | 1578 | if (error) |
| 1611 | goto out_filesystem; | 1579 | goto out_filesystem; |
| 1612 | 1580 | ||
| 1613 | m = kern_mount_data(&mqueue_fs_type, &init_ipc_ns); | ||
| 1614 | if (IS_ERR(m)) | ||
| 1615 | goto out_filesystem; | ||
| 1616 | init_ipc_ns.mq_mnt = m; | ||
| 1617 | return 0; | 1581 | return 0; |
| 1618 | 1582 | ||
| 1619 | out_filesystem: | 1583 | out_filesystem: |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e24aa3241387..43f95d190eea 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -1845,7 +1845,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz | |||
| 1845 | union bpf_attr attr = {}; | 1845 | union bpf_attr attr = {}; |
| 1846 | int err; | 1846 | int err; |
| 1847 | 1847 | ||
| 1848 | if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled) | 1848 | if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN)) |
| 1849 | return -EPERM; | 1849 | return -EPERM; |
| 1850 | 1850 | ||
| 1851 | err = check_uarg_tail_zero(uattr, sizeof(attr), size); | 1851 | err = check_uarg_tail_zero(uattr, sizeof(attr), size); |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 8cda3bc3ae22..4bfb2908ec15 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
| @@ -3183,6 +3183,16 @@ static int cgroup_enable_threaded(struct cgroup *cgrp) | |||
| 3183 | if (cgroup_is_threaded(cgrp)) | 3183 | if (cgroup_is_threaded(cgrp)) |
| 3184 | return 0; | 3184 | return 0; |
| 3185 | 3185 | ||
| 3186 | /* | ||
| 3187 | * If @cgroup is populated or has domain controllers enabled, it | ||
| 3188 | * can't be switched. While the below cgroup_can_be_thread_root() | ||
| 3189 | * test can catch the same conditions, that's only when @parent is | ||
| 3190 | * not mixable, so let's check it explicitly. | ||
| 3191 | */ | ||
| 3192 | if (cgroup_is_populated(cgrp) || | ||
| 3193 | cgrp->subtree_control & ~cgrp_dfl_threaded_ss_mask) | ||
| 3194 | return -EOPNOTSUPP; | ||
| 3195 | |||
| 3186 | /* we're joining the parent's domain, ensure its validity */ | 3196 | /* we're joining the parent's domain, ensure its validity */ |
| 3187 | if (!cgroup_is_valid_domain(dom_cgrp) || | 3197 | if (!cgroup_is_valid_domain(dom_cgrp) || |
| 3188 | !cgroup_can_be_thread_root(dom_cgrp)) | 3198 | !cgroup_can_be_thread_root(dom_cgrp)) |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 4b838470fac4..709a55b9ad97 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -724,9 +724,15 @@ static inline void __update_cgrp_time(struct perf_cgroup *cgrp) | |||
| 724 | 724 | ||
| 725 | static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx) | 725 | static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx) |
| 726 | { | 726 | { |
| 727 | struct perf_cgroup *cgrp_out = cpuctx->cgrp; | 727 | struct perf_cgroup *cgrp = cpuctx->cgrp; |
| 728 | if (cgrp_out) | 728 | struct cgroup_subsys_state *css; |
| 729 | __update_cgrp_time(cgrp_out); | 729 | |
| 730 | if (cgrp) { | ||
| 731 | for (css = &cgrp->css; css; css = css->parent) { | ||
| 732 | cgrp = container_of(css, struct perf_cgroup, css); | ||
| 733 | __update_cgrp_time(cgrp); | ||
| 734 | } | ||
| 735 | } | ||
| 730 | } | 736 | } |
| 731 | 737 | ||
| 732 | static inline void update_cgrp_time_from_event(struct perf_event *event) | 738 | static inline void update_cgrp_time_from_event(struct perf_event *event) |
| @@ -754,6 +760,7 @@ perf_cgroup_set_timestamp(struct task_struct *task, | |||
| 754 | { | 760 | { |
| 755 | struct perf_cgroup *cgrp; | 761 | struct perf_cgroup *cgrp; |
| 756 | struct perf_cgroup_info *info; | 762 | struct perf_cgroup_info *info; |
| 763 | struct cgroup_subsys_state *css; | ||
| 757 | 764 | ||
| 758 | /* | 765 | /* |
| 759 | * ctx->lock held by caller | 766 | * ctx->lock held by caller |
| @@ -764,8 +771,12 @@ perf_cgroup_set_timestamp(struct task_struct *task, | |||
| 764 | return; | 771 | return; |
| 765 | 772 | ||
| 766 | cgrp = perf_cgroup_from_task(task, ctx); | 773 | cgrp = perf_cgroup_from_task(task, ctx); |
| 767 | info = this_cpu_ptr(cgrp->info); | 774 | |
| 768 | info->timestamp = ctx->timestamp; | 775 | for (css = &cgrp->css; css; css = css->parent) { |
| 776 | cgrp = container_of(css, struct perf_cgroup, css); | ||
| 777 | info = this_cpu_ptr(cgrp->info); | ||
| 778 | info->timestamp = ctx->timestamp; | ||
| 779 | } | ||
| 769 | } | 780 | } |
| 770 | 781 | ||
| 771 | static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list); | 782 | static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list); |
diff --git a/kernel/fail_function.c b/kernel/fail_function.c index 21b0122cb39c..1d5632d8bbcc 100644 --- a/kernel/fail_function.c +++ b/kernel/fail_function.c | |||
| @@ -14,6 +14,15 @@ | |||
| 14 | 14 | ||
| 15 | static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs); | 15 | static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs); |
| 16 | 16 | ||
| 17 | static void fei_post_handler(struct kprobe *kp, struct pt_regs *regs, | ||
| 18 | unsigned long flags) | ||
| 19 | { | ||
| 20 | /* | ||
| 21 | * A dummy post handler is required to prohibit optimizing, because | ||
| 22 | * jump optimization does not support execution path overriding. | ||
| 23 | */ | ||
| 24 | } | ||
| 25 | |||
| 17 | struct fei_attr { | 26 | struct fei_attr { |
| 18 | struct list_head list; | 27 | struct list_head list; |
| 19 | struct kprobe kp; | 28 | struct kprobe kp; |
| @@ -56,6 +65,7 @@ static struct fei_attr *fei_attr_new(const char *sym, unsigned long addr) | |||
| 56 | return NULL; | 65 | return NULL; |
| 57 | } | 66 | } |
| 58 | attr->kp.pre_handler = fei_kprobe_handler; | 67 | attr->kp.pre_handler = fei_kprobe_handler; |
| 68 | attr->kp.post_handler = fei_post_handler; | ||
| 59 | attr->retval = adjust_error_retval(addr, 0); | 69 | attr->retval = adjust_error_retval(addr, 0); |
| 60 | INIT_LIST_HEAD(&attr->list); | 70 | INIT_LIST_HEAD(&attr->list); |
| 61 | } | 71 | } |
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index e7214093dcd1..01ebdf1f9f40 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/jump_label_ratelimit.h> | 16 | #include <linux/jump_label_ratelimit.h> |
| 17 | #include <linux/bug.h> | 17 | #include <linux/bug.h> |
| 18 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
| 19 | #include <asm/sections.h> | ||
| 19 | 20 | ||
| 20 | #ifdef HAVE_JUMP_LABEL | 21 | #ifdef HAVE_JUMP_LABEL |
| 21 | 22 | ||
| @@ -421,15 +422,15 @@ void __init jump_label_init(void) | |||
| 421 | cpus_read_unlock(); | 422 | cpus_read_unlock(); |
| 422 | } | 423 | } |
| 423 | 424 | ||
| 424 | /* Disable any jump label entries in __init code */ | 425 | /* Disable any jump label entries in __init/__exit code */ |
| 425 | void __init jump_label_invalidate_init(void) | 426 | void __init jump_label_invalidate_initmem(void) |
| 426 | { | 427 | { |
| 427 | struct jump_entry *iter_start = __start___jump_table; | 428 | struct jump_entry *iter_start = __start___jump_table; |
| 428 | struct jump_entry *iter_stop = __stop___jump_table; | 429 | struct jump_entry *iter_stop = __stop___jump_table; |
| 429 | struct jump_entry *iter; | 430 | struct jump_entry *iter; |
| 430 | 431 | ||
| 431 | for (iter = iter_start; iter < iter_stop; iter++) { | 432 | for (iter = iter_start; iter < iter_stop; iter++) { |
| 432 | if (init_kernel_text(iter->code)) | 433 | if (init_section_contains((void *)(unsigned long)iter->code, 1)) |
| 433 | iter->code = 0; | 434 | iter->code = 0; |
| 434 | } | 435 | } |
| 435 | } | 436 | } |
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 858a07590e39..2048359f33d2 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c | |||
| @@ -1082,15 +1082,16 @@ static noinline int __sched | |||
| 1082 | __mutex_lock_interruptible_slowpath(struct mutex *lock); | 1082 | __mutex_lock_interruptible_slowpath(struct mutex *lock); |
| 1083 | 1083 | ||
| 1084 | /** | 1084 | /** |
| 1085 | * mutex_lock_interruptible - acquire the mutex, interruptible | 1085 | * mutex_lock_interruptible() - Acquire the mutex, interruptible by signals. |
| 1086 | * @lock: the mutex to be acquired | 1086 | * @lock: The mutex to be acquired. |
| 1087 | * | 1087 | * |
| 1088 | * Lock the mutex like mutex_lock(), and return 0 if the mutex has | 1088 | * Lock the mutex like mutex_lock(). If a signal is delivered while the |
| 1089 | * been acquired or sleep until the mutex becomes available. If a | 1089 | * process is sleeping, this function will return without acquiring the |
| 1090 | * signal arrives while waiting for the lock then this function | 1090 | * mutex. |
| 1091 | * returns -EINTR. | ||
| 1092 | * | 1091 | * |
| 1093 | * This function is similar to (but not equivalent to) down_interruptible(). | 1092 | * Context: Process context. |
| 1093 | * Return: 0 if the lock was successfully acquired or %-EINTR if a | ||
| 1094 | * signal arrived. | ||
| 1094 | */ | 1095 | */ |
| 1095 | int __sched mutex_lock_interruptible(struct mutex *lock) | 1096 | int __sched mutex_lock_interruptible(struct mutex *lock) |
| 1096 | { | 1097 | { |
| @@ -1104,6 +1105,18 @@ int __sched mutex_lock_interruptible(struct mutex *lock) | |||
| 1104 | 1105 | ||
| 1105 | EXPORT_SYMBOL(mutex_lock_interruptible); | 1106 | EXPORT_SYMBOL(mutex_lock_interruptible); |
| 1106 | 1107 | ||
| 1108 | /** | ||
| 1109 | * mutex_lock_killable() - Acquire the mutex, interruptible by fatal signals. | ||
| 1110 | * @lock: The mutex to be acquired. | ||
| 1111 | * | ||
| 1112 | * Lock the mutex like mutex_lock(). If a signal which will be fatal to | ||
| 1113 | * the current process is delivered while the process is sleeping, this | ||
| 1114 | * function will return without acquiring the mutex. | ||
| 1115 | * | ||
| 1116 | * Context: Process context. | ||
| 1117 | * Return: 0 if the lock was successfully acquired or %-EINTR if a | ||
| 1118 | * fatal signal arrived. | ||
| 1119 | */ | ||
| 1107 | int __sched mutex_lock_killable(struct mutex *lock) | 1120 | int __sched mutex_lock_killable(struct mutex *lock) |
| 1108 | { | 1121 | { |
| 1109 | might_sleep(); | 1122 | might_sleep(); |
| @@ -1115,6 +1128,16 @@ int __sched mutex_lock_killable(struct mutex *lock) | |||
| 1115 | } | 1128 | } |
| 1116 | EXPORT_SYMBOL(mutex_lock_killable); | 1129 | EXPORT_SYMBOL(mutex_lock_killable); |
| 1117 | 1130 | ||
| 1131 | /** | ||
| 1132 | * mutex_lock_io() - Acquire the mutex and mark the process as waiting for I/O | ||
| 1133 | * @lock: The mutex to be acquired. | ||
| 1134 | * | ||
| 1135 | * Lock the mutex like mutex_lock(). While the task is waiting for this | ||
| 1136 | * mutex, it will be accounted as being in the IO wait state by the | ||
| 1137 | * scheduler. | ||
| 1138 | * | ||
| 1139 | * Context: Process context. | ||
| 1140 | */ | ||
| 1118 | void __sched mutex_lock_io(struct mutex *lock) | 1141 | void __sched mutex_lock_io(struct mutex *lock) |
| 1119 | { | 1142 | { |
| 1120 | int token; | 1143 | int token; |
diff --git a/kernel/memremap.c b/kernel/memremap.c index 4dd4274cabe2..895e6b76b25e 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c | |||
| @@ -427,7 +427,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) | |||
| 427 | err_pfn_remap: | 427 | err_pfn_remap: |
| 428 | err_radix: | 428 | err_radix: |
| 429 | pgmap_radix_release(res, pgoff); | 429 | pgmap_radix_release(res, pgoff); |
| 430 | devres_free(pgmap); | ||
| 431 | return ERR_PTR(error); | 430 | return ERR_PTR(error); |
| 432 | } | 431 | } |
| 433 | EXPORT_SYMBOL(devm_memremap_pages); | 432 | EXPORT_SYMBOL(devm_memremap_pages); |
diff --git a/kernel/module.c b/kernel/module.c index ad2d420024f6..e42764acedb4 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -4228,7 +4228,7 @@ static int modules_open(struct inode *inode, struct file *file) | |||
| 4228 | m->private = kallsyms_show_value() ? NULL : (void *)8ul; | 4228 | m->private = kallsyms_show_value() ? NULL : (void *)8ul; |
| 4229 | } | 4229 | } |
| 4230 | 4230 | ||
| 4231 | return 0; | 4231 | return err; |
| 4232 | } | 4232 | } |
| 4233 | 4233 | ||
| 4234 | static const struct file_operations proc_modules_operations = { | 4234 | static const struct file_operations proc_modules_operations = { |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e7c535eee0a6..c94895bc5a2c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -6683,13 +6683,18 @@ static int tg_cfs_schedulable_down(struct task_group *tg, void *data) | |||
| 6683 | parent_quota = parent_b->hierarchical_quota; | 6683 | parent_quota = parent_b->hierarchical_quota; |
| 6684 | 6684 | ||
| 6685 | /* | 6685 | /* |
| 6686 | * Ensure max(child_quota) <= parent_quota, inherit when no | 6686 | * Ensure max(child_quota) <= parent_quota. On cgroup2, |
| 6687 | * always take the min. On cgroup1, only inherit when no | ||
| 6687 | * limit is set: | 6688 | * limit is set: |
| 6688 | */ | 6689 | */ |
| 6689 | if (quota == RUNTIME_INF) | 6690 | if (cgroup_subsys_on_dfl(cpu_cgrp_subsys)) { |
| 6690 | quota = parent_quota; | 6691 | quota = min(quota, parent_quota); |
| 6691 | else if (parent_quota != RUNTIME_INF && quota > parent_quota) | 6692 | } else { |
| 6692 | return -EINVAL; | 6693 | if (quota == RUNTIME_INF) |
| 6694 | quota = parent_quota; | ||
| 6695 | else if (parent_quota != RUNTIME_INF && quota > parent_quota) | ||
| 6696 | return -EINVAL; | ||
| 6697 | } | ||
| 6693 | } | 6698 | } |
| 6694 | cfs_b->hierarchical_quota = quota; | 6699 | cfs_b->hierarchical_quota = quota; |
| 6695 | 6700 | ||
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index c0a9e310d715..01e6b3a38871 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c | |||
| @@ -661,7 +661,41 @@ static const struct bpf_func_proto bpf_get_stackid_proto_tp = { | |||
| 661 | .arg3_type = ARG_ANYTHING, | 661 | .arg3_type = ARG_ANYTHING, |
| 662 | }; | 662 | }; |
| 663 | 663 | ||
| 664 | BPF_CALL_3(bpf_perf_prog_read_value_tp, struct bpf_perf_event_data_kern *, ctx, | 664 | static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) |
| 665 | { | ||
| 666 | switch (func_id) { | ||
| 667 | case BPF_FUNC_perf_event_output: | ||
| 668 | return &bpf_perf_event_output_proto_tp; | ||
| 669 | case BPF_FUNC_get_stackid: | ||
| 670 | return &bpf_get_stackid_proto_tp; | ||
| 671 | default: | ||
| 672 | return tracing_func_proto(func_id); | ||
| 673 | } | ||
| 674 | } | ||
| 675 | |||
| 676 | static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, | ||
| 677 | struct bpf_insn_access_aux *info) | ||
| 678 | { | ||
| 679 | if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) | ||
| 680 | return false; | ||
| 681 | if (type != BPF_READ) | ||
| 682 | return false; | ||
| 683 | if (off % size != 0) | ||
| 684 | return false; | ||
| 685 | |||
| 686 | BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64)); | ||
| 687 | return true; | ||
| 688 | } | ||
| 689 | |||
| 690 | const struct bpf_verifier_ops tracepoint_verifier_ops = { | ||
| 691 | .get_func_proto = tp_prog_func_proto, | ||
| 692 | .is_valid_access = tp_prog_is_valid_access, | ||
| 693 | }; | ||
| 694 | |||
| 695 | const struct bpf_prog_ops tracepoint_prog_ops = { | ||
| 696 | }; | ||
| 697 | |||
| 698 | BPF_CALL_3(bpf_perf_prog_read_value, struct bpf_perf_event_data_kern *, ctx, | ||
| 665 | struct bpf_perf_event_value *, buf, u32, size) | 699 | struct bpf_perf_event_value *, buf, u32, size) |
| 666 | { | 700 | { |
| 667 | int err = -EINVAL; | 701 | int err = -EINVAL; |
| @@ -678,8 +712,8 @@ clear: | |||
| 678 | return err; | 712 | return err; |
| 679 | } | 713 | } |
| 680 | 714 | ||
| 681 | static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = { | 715 | static const struct bpf_func_proto bpf_perf_prog_read_value_proto = { |
| 682 | .func = bpf_perf_prog_read_value_tp, | 716 | .func = bpf_perf_prog_read_value, |
| 683 | .gpl_only = true, | 717 | .gpl_only = true, |
| 684 | .ret_type = RET_INTEGER, | 718 | .ret_type = RET_INTEGER, |
| 685 | .arg1_type = ARG_PTR_TO_CTX, | 719 | .arg1_type = ARG_PTR_TO_CTX, |
| @@ -687,7 +721,7 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = { | |||
| 687 | .arg3_type = ARG_CONST_SIZE, | 721 | .arg3_type = ARG_CONST_SIZE, |
| 688 | }; | 722 | }; |
| 689 | 723 | ||
| 690 | static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) | 724 | static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id) |
| 691 | { | 725 | { |
| 692 | switch (func_id) { | 726 | switch (func_id) { |
| 693 | case BPF_FUNC_perf_event_output: | 727 | case BPF_FUNC_perf_event_output: |
| @@ -695,34 +729,12 @@ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) | |||
| 695 | case BPF_FUNC_get_stackid: | 729 | case BPF_FUNC_get_stackid: |
| 696 | return &bpf_get_stackid_proto_tp; | 730 | return &bpf_get_stackid_proto_tp; |
| 697 | case BPF_FUNC_perf_prog_read_value: | 731 | case BPF_FUNC_perf_prog_read_value: |
| 698 | return &bpf_perf_prog_read_value_proto_tp; | 732 | return &bpf_perf_prog_read_value_proto; |
| 699 | default: | 733 | default: |
| 700 | return tracing_func_proto(func_id); | 734 | return tracing_func_proto(func_id); |
| 701 | } | 735 | } |
| 702 | } | 736 | } |
| 703 | 737 | ||
| 704 | static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, | ||
| 705 | struct bpf_insn_access_aux *info) | ||
| 706 | { | ||
| 707 | if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) | ||
| 708 | return false; | ||
| 709 | if (type != BPF_READ) | ||
| 710 | return false; | ||
| 711 | if (off % size != 0) | ||
| 712 | return false; | ||
| 713 | |||
| 714 | BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64)); | ||
| 715 | return true; | ||
| 716 | } | ||
| 717 | |||
| 718 | const struct bpf_verifier_ops tracepoint_verifier_ops = { | ||
| 719 | .get_func_proto = tp_prog_func_proto, | ||
| 720 | .is_valid_access = tp_prog_is_valid_access, | ||
| 721 | }; | ||
| 722 | |||
| 723 | const struct bpf_prog_ops tracepoint_prog_ops = { | ||
| 724 | }; | ||
| 725 | |||
| 726 | static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, | 738 | static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, |
| 727 | struct bpf_insn_access_aux *info) | 739 | struct bpf_insn_access_aux *info) |
| 728 | { | 740 | { |
| @@ -779,7 +791,7 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type, | |||
| 779 | } | 791 | } |
| 780 | 792 | ||
| 781 | const struct bpf_verifier_ops perf_event_verifier_ops = { | 793 | const struct bpf_verifier_ops perf_event_verifier_ops = { |
| 782 | .get_func_proto = tp_prog_func_proto, | 794 | .get_func_proto = pe_prog_func_proto, |
| 783 | .is_valid_access = pe_prog_is_valid_access, | 795 | .is_valid_access = pe_prog_is_valid_access, |
| 784 | .convert_ctx_access = pe_prog_convert_ctx_access, | 796 | .convert_ctx_access = pe_prog_convert_ctx_access, |
| 785 | }; | 797 | }; |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1fad24acd444..ae4147eaebd4 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -659,7 +659,7 @@ static int create_trace_kprobe(int argc, char **argv) | |||
| 659 | char *symbol = NULL, *event = NULL, *group = NULL; | 659 | char *symbol = NULL, *event = NULL, *group = NULL; |
| 660 | int maxactive = 0; | 660 | int maxactive = 0; |
| 661 | char *arg; | 661 | char *arg; |
| 662 | unsigned long offset = 0; | 662 | long offset = 0; |
| 663 | void *addr = NULL; | 663 | void *addr = NULL; |
| 664 | char buf[MAX_EVENT_NAME_LEN]; | 664 | char buf[MAX_EVENT_NAME_LEN]; |
| 665 | 665 | ||
| @@ -747,7 +747,7 @@ static int create_trace_kprobe(int argc, char **argv) | |||
| 747 | symbol = argv[1]; | 747 | symbol = argv[1]; |
| 748 | /* TODO: support .init module functions */ | 748 | /* TODO: support .init module functions */ |
| 749 | ret = traceprobe_split_symbol_offset(symbol, &offset); | 749 | ret = traceprobe_split_symbol_offset(symbol, &offset); |
| 750 | if (ret) { | 750 | if (ret || offset < 0 || offset > UINT_MAX) { |
| 751 | pr_info("Failed to parse either an address or a symbol.\n"); | 751 | pr_info("Failed to parse either an address or a symbol.\n"); |
| 752 | return ret; | 752 | return ret; |
| 753 | } | 753 | } |
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d59357308677..daf54bda4dc8 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
| @@ -320,7 +320,7 @@ static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | /* Split symbol and offset. */ | 322 | /* Split symbol and offset. */ |
| 323 | int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) | 323 | int traceprobe_split_symbol_offset(char *symbol, long *offset) |
| 324 | { | 324 | { |
| 325 | char *tmp; | 325 | char *tmp; |
| 326 | int ret; | 326 | int ret; |
| @@ -328,13 +328,11 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) | |||
| 328 | if (!offset) | 328 | if (!offset) |
| 329 | return -EINVAL; | 329 | return -EINVAL; |
| 330 | 330 | ||
| 331 | tmp = strchr(symbol, '+'); | 331 | tmp = strpbrk(symbol, "+-"); |
| 332 | if (tmp) { | 332 | if (tmp) { |
| 333 | /* skip sign because kstrtoul doesn't accept '+' */ | 333 | ret = kstrtol(tmp, 0, offset); |
| 334 | ret = kstrtoul(tmp + 1, 0, offset); | ||
| 335 | if (ret) | 334 | if (ret) |
| 336 | return ret; | 335 | return ret; |
| 337 | |||
| 338 | *tmp = '\0'; | 336 | *tmp = '\0'; |
| 339 | } else | 337 | } else |
| 340 | *offset = 0; | 338 | *offset = 0; |
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index e101c5bb9eda..6a4d3fa94042 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h | |||
| @@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name, | |||
| 365 | extern void traceprobe_update_arg(struct probe_arg *arg); | 365 | extern void traceprobe_update_arg(struct probe_arg *arg); |
| 366 | extern void traceprobe_free_probe_arg(struct probe_arg *arg); | 366 | extern void traceprobe_free_probe_arg(struct probe_arg *arg); |
| 367 | 367 | ||
| 368 | extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset); | 368 | extern int traceprobe_split_symbol_offset(char *symbol, long *offset); |
| 369 | 369 | ||
| 370 | /* Sum up total data length for dynamic arraies (strings) */ | 370 | /* Sum up total data length for dynamic arraies (strings) */ |
| 371 | static nokprobe_inline int | 371 | static nokprobe_inline int |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index bb9a519cbf50..6ec6ba65127b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -3018,14 +3018,6 @@ static bool __cancel_work(struct work_struct *work, bool is_dwork) | |||
| 3018 | return ret; | 3018 | return ret; |
| 3019 | } | 3019 | } |
| 3020 | 3020 | ||
| 3021 | /* | ||
| 3022 | * See cancel_delayed_work() | ||
| 3023 | */ | ||
| 3024 | bool cancel_work(struct work_struct *work) | ||
| 3025 | { | ||
| 3026 | return __cancel_work(work, false); | ||
| 3027 | } | ||
| 3028 | |||
| 3029 | /** | 3021 | /** |
| 3030 | * cancel_delayed_work - cancel a delayed work | 3022 | * cancel_delayed_work - cancel a delayed work |
| 3031 | * @dwork: delayed_work to cancel | 3023 | * @dwork: delayed_work to cancel |
| @@ -5337,7 +5329,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq) | |||
| 5337 | 5329 | ||
| 5338 | ret = device_register(&wq_dev->dev); | 5330 | ret = device_register(&wq_dev->dev); |
| 5339 | if (ret) { | 5331 | if (ret) { |
| 5340 | kfree(wq_dev); | 5332 | put_device(&wq_dev->dev); |
| 5341 | wq->wq_dev = NULL; | 5333 | wq->wq_dev = NULL; |
| 5342 | return ret; | 5334 | return ret; |
| 5343 | } | 5335 | } |
diff --git a/lib/ioremap.c b/lib/ioremap.c index b808a390e4c3..54e5bbaa3200 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c | |||
| @@ -91,7 +91,8 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, | |||
| 91 | 91 | ||
| 92 | if (ioremap_pmd_enabled() && | 92 | if (ioremap_pmd_enabled() && |
| 93 | ((next - addr) == PMD_SIZE) && | 93 | ((next - addr) == PMD_SIZE) && |
| 94 | IS_ALIGNED(phys_addr + addr, PMD_SIZE)) { | 94 | IS_ALIGNED(phys_addr + addr, PMD_SIZE) && |
| 95 | pmd_free_pte_page(pmd)) { | ||
| 95 | if (pmd_set_huge(pmd, phys_addr + addr, prot)) | 96 | if (pmd_set_huge(pmd, phys_addr + addr, prot)) |
| 96 | continue; | 97 | continue; |
| 97 | } | 98 | } |
| @@ -117,7 +118,8 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr, | |||
| 117 | 118 | ||
| 118 | if (ioremap_pud_enabled() && | 119 | if (ioremap_pud_enabled() && |
| 119 | ((next - addr) == PUD_SIZE) && | 120 | ((next - addr) == PUD_SIZE) && |
| 120 | IS_ALIGNED(phys_addr + addr, PUD_SIZE)) { | 121 | IS_ALIGNED(phys_addr + addr, PUD_SIZE) && |
| 122 | pud_free_pmd_page(pud)) { | ||
| 121 | if (pud_set_huge(pud, phys_addr + addr, prot)) | 123 | if (pud_set_huge(pud, phys_addr + addr, prot)) |
| 122 | continue; | 124 | continue; |
| 123 | } | 125 | } |
diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index 30e7dd88148b..9f96fa7bc000 100644 --- a/lib/percpu-refcount.c +++ b/lib/percpu-refcount.c | |||
| @@ -322,6 +322,8 @@ EXPORT_SYMBOL_GPL(percpu_ref_switch_to_percpu); | |||
| 322 | * This function normally doesn't block and can be called from any context | 322 | * This function normally doesn't block and can be called from any context |
| 323 | * but it may block if @confirm_kill is specified and @ref is in the | 323 | * but it may block if @confirm_kill is specified and @ref is in the |
| 324 | * process of switching to atomic mode by percpu_ref_switch_to_atomic(). | 324 | * process of switching to atomic mode by percpu_ref_switch_to_atomic(). |
| 325 | * | ||
| 326 | * There are no implied RCU grace periods between kill and release. | ||
| 325 | */ | 327 | */ |
| 326 | void percpu_ref_kill_and_confirm(struct percpu_ref *ref, | 328 | void percpu_ref_kill_and_confirm(struct percpu_ref *ref, |
| 327 | percpu_ref_func_t *confirm_kill) | 329 | percpu_ref_func_t *confirm_kill) |
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 3825c30aaa36..47de025b6245 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
| @@ -506,8 +506,10 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, | |||
| 506 | if (!key || | 506 | if (!key || |
| 507 | (ht->p.obj_cmpfn ? | 507 | (ht->p.obj_cmpfn ? |
| 508 | ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) : | 508 | ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) : |
| 509 | rhashtable_compare(&arg, rht_obj(ht, head)))) | 509 | rhashtable_compare(&arg, rht_obj(ht, head)))) { |
| 510 | pprev = &head->next; | ||
| 510 | continue; | 511 | continue; |
| 512 | } | ||
| 511 | 513 | ||
| 512 | if (!ht->rhlist) | 514 | if (!ht->rhlist) |
| 513 | return rht_obj(ht, head); | 515 | return rht_obj(ht, head); |
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 2efb213716fa..3e9335493fe4 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c | |||
| @@ -5467,7 +5467,7 @@ static struct bpf_test tests[] = { | |||
| 5467 | { | 5467 | { |
| 5468 | "BPF_MAXINSNS: Jump, gap, jump, ...", | 5468 | "BPF_MAXINSNS: Jump, gap, jump, ...", |
| 5469 | { }, | 5469 | { }, |
| 5470 | #ifdef CONFIG_BPF_JIT_ALWAYS_ON | 5470 | #if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_X86) |
| 5471 | CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, | 5471 | CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, |
| 5472 | #else | 5472 | #else |
| 5473 | CLASSIC | FLAG_NO_DATA, | 5473 | CLASSIC | FLAG_NO_DATA, |
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index 76d3667fdea2..f4000c137dbe 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c | |||
| @@ -79,6 +79,21 @@ struct thread_data { | |||
| 79 | struct test_obj *objs; | 79 | struct test_obj *objs; |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | static u32 my_hashfn(const void *data, u32 len, u32 seed) | ||
| 83 | { | ||
| 84 | const struct test_obj_rhl *obj = data; | ||
| 85 | |||
| 86 | return (obj->value.id % 10) << RHT_HASH_RESERVED_SPACE; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) | ||
| 90 | { | ||
| 91 | const struct test_obj_rhl *test_obj = obj; | ||
| 92 | const struct test_obj_val *val = arg->key; | ||
| 93 | |||
| 94 | return test_obj->value.id - val->id; | ||
| 95 | } | ||
| 96 | |||
| 82 | static struct rhashtable_params test_rht_params = { | 97 | static struct rhashtable_params test_rht_params = { |
| 83 | .head_offset = offsetof(struct test_obj, node), | 98 | .head_offset = offsetof(struct test_obj, node), |
| 84 | .key_offset = offsetof(struct test_obj, value), | 99 | .key_offset = offsetof(struct test_obj, value), |
| @@ -87,6 +102,17 @@ static struct rhashtable_params test_rht_params = { | |||
| 87 | .nulls_base = (3U << RHT_BASE_SHIFT), | 102 | .nulls_base = (3U << RHT_BASE_SHIFT), |
| 88 | }; | 103 | }; |
| 89 | 104 | ||
| 105 | static struct rhashtable_params test_rht_params_dup = { | ||
| 106 | .head_offset = offsetof(struct test_obj_rhl, list_node), | ||
| 107 | .key_offset = offsetof(struct test_obj_rhl, value), | ||
| 108 | .key_len = sizeof(struct test_obj_val), | ||
| 109 | .hashfn = jhash, | ||
| 110 | .obj_hashfn = my_hashfn, | ||
| 111 | .obj_cmpfn = my_cmpfn, | ||
| 112 | .nelem_hint = 128, | ||
| 113 | .automatic_shrinking = false, | ||
| 114 | }; | ||
| 115 | |||
| 90 | static struct semaphore prestart_sem; | 116 | static struct semaphore prestart_sem; |
| 91 | static struct semaphore startup_sem = __SEMAPHORE_INITIALIZER(startup_sem, 0); | 117 | static struct semaphore startup_sem = __SEMAPHORE_INITIALIZER(startup_sem, 0); |
| 92 | 118 | ||
| @@ -465,6 +491,112 @@ static int __init test_rhashtable_max(struct test_obj *array, | |||
| 465 | return err; | 491 | return err; |
| 466 | } | 492 | } |
| 467 | 493 | ||
| 494 | static unsigned int __init print_ht(struct rhltable *rhlt) | ||
| 495 | { | ||
| 496 | struct rhashtable *ht; | ||
| 497 | const struct bucket_table *tbl; | ||
| 498 | char buff[512] = ""; | ||
| 499 | unsigned int i, cnt = 0; | ||
| 500 | |||
| 501 | ht = &rhlt->ht; | ||
| 502 | tbl = rht_dereference(ht->tbl, ht); | ||
| 503 | for (i = 0; i < tbl->size; i++) { | ||
| 504 | struct rhash_head *pos, *next; | ||
| 505 | struct test_obj_rhl *p; | ||
| 506 | |||
| 507 | pos = rht_dereference(tbl->buckets[i], ht); | ||
| 508 | next = !rht_is_a_nulls(pos) ? rht_dereference(pos->next, ht) : NULL; | ||
| 509 | |||
| 510 | if (!rht_is_a_nulls(pos)) { | ||
| 511 | sprintf(buff, "%s\nbucket[%d] -> ", buff, i); | ||
| 512 | } | ||
| 513 | |||
| 514 | while (!rht_is_a_nulls(pos)) { | ||
| 515 | struct rhlist_head *list = container_of(pos, struct rhlist_head, rhead); | ||
| 516 | sprintf(buff, "%s[[", buff); | ||
| 517 | do { | ||
| 518 | pos = &list->rhead; | ||
| 519 | list = rht_dereference(list->next, ht); | ||
| 520 | p = rht_obj(ht, pos); | ||
| 521 | |||
| 522 | sprintf(buff, "%s val %d (tid=%d)%s", buff, p->value.id, p->value.tid, | ||
| 523 | list? ", " : " "); | ||
| 524 | cnt++; | ||
| 525 | } while (list); | ||
| 526 | |||
| 527 | pos = next, | ||
| 528 | next = !rht_is_a_nulls(pos) ? | ||
| 529 | rht_dereference(pos->next, ht) : NULL; | ||
| 530 | |||
| 531 | sprintf(buff, "%s]]%s", buff, !rht_is_a_nulls(pos) ? " -> " : ""); | ||
| 532 | } | ||
| 533 | } | ||
| 534 | printk(KERN_ERR "\n---- ht: ----%s\n-------------\n", buff); | ||
| 535 | |||
| 536 | return cnt; | ||
| 537 | } | ||
| 538 | |||
| 539 | static int __init test_insert_dup(struct test_obj_rhl *rhl_test_objects, | ||
| 540 | int cnt, bool slow) | ||
| 541 | { | ||
| 542 | struct rhltable rhlt; | ||
| 543 | unsigned int i, ret; | ||
| 544 | const char *key; | ||
| 545 | int err = 0; | ||
| 546 | |||
| 547 | err = rhltable_init(&rhlt, &test_rht_params_dup); | ||
| 548 | if (WARN_ON(err)) | ||
| 549 | return err; | ||
| 550 | |||
| 551 | for (i = 0; i < cnt; i++) { | ||
| 552 | rhl_test_objects[i].value.tid = i; | ||
| 553 | key = rht_obj(&rhlt.ht, &rhl_test_objects[i].list_node.rhead); | ||
| 554 | key += test_rht_params_dup.key_offset; | ||
| 555 | |||
| 556 | if (slow) { | ||
| 557 | err = PTR_ERR(rhashtable_insert_slow(&rhlt.ht, key, | ||
| 558 | &rhl_test_objects[i].list_node.rhead)); | ||
| 559 | if (err == -EAGAIN) | ||
| 560 | err = 0; | ||
| 561 | } else | ||
| 562 | err = rhltable_insert(&rhlt, | ||
| 563 | &rhl_test_objects[i].list_node, | ||
| 564 | test_rht_params_dup); | ||
| 565 | if (WARN(err, "error %d on element %d/%d (%s)\n", err, i, cnt, slow? "slow" : "fast")) | ||
| 566 | goto skip_print; | ||
| 567 | } | ||
| 568 | |||
| 569 | ret = print_ht(&rhlt); | ||
| 570 | WARN(ret != cnt, "missing rhltable elements (%d != %d, %s)\n", ret, cnt, slow? "slow" : "fast"); | ||
| 571 | |||
| 572 | skip_print: | ||
| 573 | rhltable_destroy(&rhlt); | ||
| 574 | |||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int __init test_insert_duplicates_run(void) | ||
| 579 | { | ||
| 580 | struct test_obj_rhl rhl_test_objects[3] = {}; | ||
| 581 | |||
| 582 | pr_info("test inserting duplicates\n"); | ||
| 583 | |||
| 584 | /* two different values that map to same bucket */ | ||
| 585 | rhl_test_objects[0].value.id = 1; | ||
| 586 | rhl_test_objects[1].value.id = 21; | ||
| 587 | |||
| 588 | /* and another duplicate with same as [0] value | ||
| 589 | * which will be second on the bucket list */ | ||
| 590 | rhl_test_objects[2].value.id = rhl_test_objects[0].value.id; | ||
| 591 | |||
| 592 | test_insert_dup(rhl_test_objects, 2, false); | ||
| 593 | test_insert_dup(rhl_test_objects, 3, false); | ||
| 594 | test_insert_dup(rhl_test_objects, 2, true); | ||
| 595 | test_insert_dup(rhl_test_objects, 3, true); | ||
| 596 | |||
| 597 | return 0; | ||
| 598 | } | ||
| 599 | |||
| 468 | static int thread_lookup_test(struct thread_data *tdata) | 600 | static int thread_lookup_test(struct thread_data *tdata) |
| 469 | { | 601 | { |
| 470 | unsigned int entries = tdata->entries; | 602 | unsigned int entries = tdata->entries; |
| @@ -613,6 +745,8 @@ static int __init test_rht_init(void) | |||
| 613 | do_div(total_time, runs); | 745 | do_div(total_time, runs); |
| 614 | pr_info("Average test time: %llu\n", total_time); | 746 | pr_info("Average test time: %llu\n", total_time); |
| 615 | 747 | ||
| 748 | test_insert_duplicates_run(); | ||
| 749 | |||
| 616 | if (!tcount) | 750 | if (!tcount) |
| 617 | return 0; | 751 | return 0; |
| 618 | 752 | ||
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 87ab9b8f56b5..5a68730eebd6 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
| @@ -555,7 +555,8 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, | |||
| 555 | 555 | ||
| 556 | VM_BUG_ON_PAGE(!PageCompound(page), page); | 556 | VM_BUG_ON_PAGE(!PageCompound(page), page); |
| 557 | 557 | ||
| 558 | if (mem_cgroup_try_charge(page, vma->vm_mm, gfp, &memcg, true)) { | 558 | if (mem_cgroup_try_charge(page, vma->vm_mm, gfp | __GFP_NORETRY, &memcg, |
| 559 | true)) { | ||
| 559 | put_page(page); | 560 | put_page(page); |
| 560 | count_vm_event(THP_FAULT_FALLBACK); | 561 | count_vm_event(THP_FAULT_FALLBACK); |
| 561 | return VM_FAULT_FALLBACK; | 562 | return VM_FAULT_FALLBACK; |
| @@ -1316,7 +1317,7 @@ alloc: | |||
| 1316 | } | 1317 | } |
| 1317 | 1318 | ||
| 1318 | if (unlikely(mem_cgroup_try_charge(new_page, vma->vm_mm, | 1319 | if (unlikely(mem_cgroup_try_charge(new_page, vma->vm_mm, |
| 1319 | huge_gfp, &memcg, true))) { | 1320 | huge_gfp | __GFP_NORETRY, &memcg, true))) { |
| 1320 | put_page(new_page); | 1321 | put_page(new_page); |
| 1321 | split_huge_pmd(vma, vmf->pmd, vmf->address); | 1322 | split_huge_pmd(vma, vmf->pmd, vmf->address); |
| 1322 | if (page) | 1323 | if (page) |
| @@ -2783,11 +2784,13 @@ static unsigned long deferred_split_scan(struct shrinker *shrink, | |||
| 2783 | 2784 | ||
| 2784 | list_for_each_safe(pos, next, &list) { | 2785 | list_for_each_safe(pos, next, &list) { |
| 2785 | page = list_entry((void *)pos, struct page, mapping); | 2786 | page = list_entry((void *)pos, struct page, mapping); |
| 2786 | lock_page(page); | 2787 | if (!trylock_page(page)) |
| 2788 | goto next; | ||
| 2787 | /* split_huge_page() removes page from list on success */ | 2789 | /* split_huge_page() removes page from list on success */ |
| 2788 | if (!split_huge_page(page)) | 2790 | if (!split_huge_page(page)) |
| 2789 | split++; | 2791 | split++; |
| 2790 | unlock_page(page); | 2792 | unlock_page(page); |
| 2793 | next: | ||
| 2791 | put_page(page); | 2794 | put_page(page); |
| 2792 | } | 2795 | } |
| 2793 | 2796 | ||
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a963f2034dfc..976bbc5646fe 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/bootmem.h> | 18 | #include <linux/bootmem.h> |
| 19 | #include <linux/sysfs.h> | 19 | #include <linux/sysfs.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/mmdebug.h> | ||
| 21 | #include <linux/sched/signal.h> | 22 | #include <linux/sched/signal.h> |
| 22 | #include <linux/rmap.h> | 23 | #include <linux/rmap.h> |
| 23 | #include <linux/string_helpers.h> | 24 | #include <linux/string_helpers.h> |
| @@ -4374,6 +4375,12 @@ int hugetlb_reserve_pages(struct inode *inode, | |||
| 4374 | struct resv_map *resv_map; | 4375 | struct resv_map *resv_map; |
| 4375 | long gbl_reserve; | 4376 | long gbl_reserve; |
| 4376 | 4377 | ||
| 4378 | /* This should never happen */ | ||
| 4379 | if (from > to) { | ||
| 4380 | VM_WARN(1, "%s called with a negative range\n", __func__); | ||
| 4381 | return -EINVAL; | ||
| 4382 | } | ||
| 4383 | |||
| 4377 | /* | 4384 | /* |
| 4378 | * Only apply hugepage reservation if asked. At fault time, an | 4385 | * Only apply hugepage reservation if asked. At fault time, an |
| 4379 | * attempt will be made for VM_NORESERVE to allocate a page | 4386 | * attempt will be made for VM_NORESERVE to allocate a page |
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index b7e2268dfc9a..e42568284e06 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c | |||
| @@ -530,7 +530,12 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma, | |||
| 530 | goto out; | 530 | goto out; |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | VM_BUG_ON_PAGE(PageCompound(page), page); | 533 | /* TODO: teach khugepaged to collapse THP mapped with pte */ |
| 534 | if (PageCompound(page)) { | ||
| 535 | result = SCAN_PAGE_COMPOUND; | ||
| 536 | goto out; | ||
| 537 | } | ||
| 538 | |||
| 534 | VM_BUG_ON_PAGE(!PageAnon(page), page); | 539 | VM_BUG_ON_PAGE(!PageAnon(page), page); |
| 535 | 540 | ||
| 536 | /* | 541 | /* |
| @@ -960,7 +965,9 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
| 960 | goto out_nolock; | 965 | goto out_nolock; |
| 961 | } | 966 | } |
| 962 | 967 | ||
| 963 | if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg, true))) { | 968 | /* Do not oom kill for khugepaged charges */ |
| 969 | if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp | __GFP_NORETRY, | ||
| 970 | &memcg, true))) { | ||
| 964 | result = SCAN_CGROUP_CHARGE_FAIL; | 971 | result = SCAN_CGROUP_CHARGE_FAIL; |
| 965 | goto out_nolock; | 972 | goto out_nolock; |
| 966 | } | 973 | } |
| @@ -1319,7 +1326,9 @@ static void collapse_shmem(struct mm_struct *mm, | |||
| 1319 | goto out; | 1326 | goto out; |
| 1320 | } | 1327 | } |
| 1321 | 1328 | ||
| 1322 | if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg, true))) { | 1329 | /* Do not oom kill for khugepaged charges */ |
| 1330 | if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp | __GFP_NORETRY, | ||
| 1331 | &memcg, true))) { | ||
| 1323 | result = SCAN_CGROUP_CHARGE_FAIL; | 1332 | result = SCAN_CGROUP_CHARGE_FAIL; |
| 1324 | goto out; | 1333 | goto out; |
| 1325 | } | 1334 | } |
diff --git a/mm/memblock.c b/mm/memblock.c index b6ba6b7adadc..48376bd33274 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
| @@ -1101,34 +1101,6 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid, | |||
| 1101 | *out_nid = r->nid; | 1101 | *out_nid = r->nid; |
| 1102 | } | 1102 | } |
| 1103 | 1103 | ||
| 1104 | unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn, | ||
| 1105 | unsigned long max_pfn) | ||
| 1106 | { | ||
| 1107 | struct memblock_type *type = &memblock.memory; | ||
| 1108 | unsigned int right = type->cnt; | ||
| 1109 | unsigned int mid, left = 0; | ||
| 1110 | phys_addr_t addr = PFN_PHYS(++pfn); | ||
| 1111 | |||
| 1112 | do { | ||
| 1113 | mid = (right + left) / 2; | ||
| 1114 | |||
| 1115 | if (addr < type->regions[mid].base) | ||
| 1116 | right = mid; | ||
| 1117 | else if (addr >= (type->regions[mid].base + | ||
| 1118 | type->regions[mid].size)) | ||
| 1119 | left = mid + 1; | ||
| 1120 | else { | ||
| 1121 | /* addr is within the region, so pfn is valid */ | ||
| 1122 | return pfn; | ||
| 1123 | } | ||
| 1124 | } while (left < right); | ||
| 1125 | |||
| 1126 | if (right == type->cnt) | ||
| 1127 | return -1UL; | ||
| 1128 | else | ||
| 1129 | return PHYS_PFN(type->regions[right].base); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | /** | 1104 | /** |
| 1133 | * memblock_set_node - set node ID on memblock regions | 1105 | * memblock_set_node - set node ID on memblock regions |
| 1134 | * @base: base of area to set node ID for | 1106 | * @base: base of area to set node ID for |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d879f1d8a44a..32cba0332787 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
| @@ -2124,6 +2124,9 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) | |||
| 2124 | case MPOL_INTERLEAVE: | 2124 | case MPOL_INTERLEAVE: |
| 2125 | return !!nodes_equal(a->v.nodes, b->v.nodes); | 2125 | return !!nodes_equal(a->v.nodes, b->v.nodes); |
| 2126 | case MPOL_PREFERRED: | 2126 | case MPOL_PREFERRED: |
| 2127 | /* a's ->flags is the same as b's */ | ||
| 2128 | if (a->flags & MPOL_F_LOCAL) | ||
| 2129 | return true; | ||
| 2127 | return a->v.preferred_node == b->v.preferred_node; | 2130 | return a->v.preferred_node == b->v.preferred_node; |
| 2128 | default: | 2131 | default: |
| 2129 | BUG(); | 2132 | BUG(); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 635d7dd29d7f..1741dd23e7c1 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -3596,7 +3596,7 @@ static bool __need_fs_reclaim(gfp_t gfp_mask) | |||
| 3596 | return false; | 3596 | return false; |
| 3597 | 3597 | ||
| 3598 | /* this guy won't enter reclaim */ | 3598 | /* this guy won't enter reclaim */ |
| 3599 | if ((current->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) | 3599 | if (current->flags & PF_MEMALLOC) |
| 3600 | return false; | 3600 | return false; |
| 3601 | 3601 | ||
| 3602 | /* We're only interested __GFP_FS allocations for now */ | 3602 | /* We're only interested __GFP_FS allocations for now */ |
| @@ -5356,17 +5356,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, | |||
| 5356 | if (context != MEMMAP_EARLY) | 5356 | if (context != MEMMAP_EARLY) |
| 5357 | goto not_early; | 5357 | goto not_early; |
| 5358 | 5358 | ||
| 5359 | if (!early_pfn_valid(pfn)) { | 5359 | if (!early_pfn_valid(pfn)) |
| 5360 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | ||
| 5361 | /* | ||
| 5362 | * Skip to the pfn preceding the next valid one (or | ||
| 5363 | * end_pfn), such that we hit a valid pfn (or end_pfn) | ||
| 5364 | * on our next iteration of the loop. | ||
| 5365 | */ | ||
| 5366 | pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1; | ||
| 5367 | #endif | ||
| 5368 | continue; | 5360 | continue; |
| 5369 | } | ||
| 5370 | if (!early_pfn_in_nid(pfn, nid)) | 5361 | if (!early_pfn_in_nid(pfn, nid)) |
| 5371 | continue; | 5362 | continue; |
| 5372 | if (!update_defer_init(pgdat, pfn, end_pfn, &nr_initialised)) | 5363 | if (!update_defer_init(pgdat, pfn, end_pfn, &nr_initialised)) |
diff --git a/mm/percpu-km.c b/mm/percpu-km.c index d2a76642c4ae..38de70ab1a0d 100644 --- a/mm/percpu-km.c +++ b/mm/percpu-km.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | #include <linux/log2.h> | 34 | #include <linux/log2.h> |
| 35 | 35 | ||
| 36 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, | 36 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, |
| 37 | int page_start, int page_end) | 37 | int page_start, int page_end, gfp_t gfp) |
| 38 | { | 38 | { |
| 39 | return 0; | 39 | return 0; |
| 40 | } | 40 | } |
| @@ -45,18 +45,18 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, | |||
| 45 | /* nada */ | 45 | /* nada */ |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static struct pcpu_chunk *pcpu_create_chunk(void) | 48 | static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp) |
| 49 | { | 49 | { |
| 50 | const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; | 50 | const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT; |
| 51 | struct pcpu_chunk *chunk; | 51 | struct pcpu_chunk *chunk; |
| 52 | struct page *pages; | 52 | struct page *pages; |
| 53 | int i; | 53 | int i; |
| 54 | 54 | ||
| 55 | chunk = pcpu_alloc_chunk(); | 55 | chunk = pcpu_alloc_chunk(gfp); |
| 56 | if (!chunk) | 56 | if (!chunk) |
| 57 | return NULL; | 57 | return NULL; |
| 58 | 58 | ||
| 59 | pages = alloc_pages(GFP_KERNEL, order_base_2(nr_pages)); | 59 | pages = alloc_pages(gfp, order_base_2(nr_pages)); |
| 60 | if (!pages) { | 60 | if (!pages) { |
| 61 | pcpu_free_chunk(chunk); | 61 | pcpu_free_chunk(chunk); |
| 62 | return NULL; | 62 | return NULL; |
diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index 9158e5a81391..d8078de912de 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c | |||
| @@ -37,7 +37,7 @@ static struct page **pcpu_get_pages(void) | |||
| 37 | lockdep_assert_held(&pcpu_alloc_mutex); | 37 | lockdep_assert_held(&pcpu_alloc_mutex); |
| 38 | 38 | ||
| 39 | if (!pages) | 39 | if (!pages) |
| 40 | pages = pcpu_mem_zalloc(pages_size); | 40 | pages = pcpu_mem_zalloc(pages_size, GFP_KERNEL); |
| 41 | return pages; | 41 | return pages; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| @@ -73,18 +73,21 @@ static void pcpu_free_pages(struct pcpu_chunk *chunk, | |||
| 73 | * @pages: array to put the allocated pages into, indexed by pcpu_page_idx() | 73 | * @pages: array to put the allocated pages into, indexed by pcpu_page_idx() |
| 74 | * @page_start: page index of the first page to be allocated | 74 | * @page_start: page index of the first page to be allocated |
| 75 | * @page_end: page index of the last page to be allocated + 1 | 75 | * @page_end: page index of the last page to be allocated + 1 |
| 76 | * @gfp: allocation flags passed to the underlying allocator | ||
| 76 | * | 77 | * |
| 77 | * Allocate pages [@page_start,@page_end) into @pages for all units. | 78 | * Allocate pages [@page_start,@page_end) into @pages for all units. |
| 78 | * The allocation is for @chunk. Percpu core doesn't care about the | 79 | * The allocation is for @chunk. Percpu core doesn't care about the |
| 79 | * content of @pages and will pass it verbatim to pcpu_map_pages(). | 80 | * content of @pages and will pass it verbatim to pcpu_map_pages(). |
| 80 | */ | 81 | */ |
| 81 | static int pcpu_alloc_pages(struct pcpu_chunk *chunk, | 82 | static int pcpu_alloc_pages(struct pcpu_chunk *chunk, |
| 82 | struct page **pages, int page_start, int page_end) | 83 | struct page **pages, int page_start, int page_end, |
| 84 | gfp_t gfp) | ||
| 83 | { | 85 | { |
| 84 | const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM; | ||
| 85 | unsigned int cpu, tcpu; | 86 | unsigned int cpu, tcpu; |
| 86 | int i; | 87 | int i; |
| 87 | 88 | ||
| 89 | gfp |= __GFP_HIGHMEM; | ||
| 90 | |||
| 88 | for_each_possible_cpu(cpu) { | 91 | for_each_possible_cpu(cpu) { |
| 89 | for (i = page_start; i < page_end; i++) { | 92 | for (i = page_start; i < page_end; i++) { |
| 90 | struct page **pagep = &pages[pcpu_page_idx(cpu, i)]; | 93 | struct page **pagep = &pages[pcpu_page_idx(cpu, i)]; |
| @@ -262,6 +265,7 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk, | |||
| 262 | * @chunk: chunk of interest | 265 | * @chunk: chunk of interest |
| 263 | * @page_start: the start page | 266 | * @page_start: the start page |
| 264 | * @page_end: the end page | 267 | * @page_end: the end page |
| 268 | * @gfp: allocation flags passed to the underlying memory allocator | ||
| 265 | * | 269 | * |
| 266 | * For each cpu, populate and map pages [@page_start,@page_end) into | 270 | * For each cpu, populate and map pages [@page_start,@page_end) into |
| 267 | * @chunk. | 271 | * @chunk. |
| @@ -270,7 +274,7 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk, | |||
| 270 | * pcpu_alloc_mutex, does GFP_KERNEL allocation. | 274 | * pcpu_alloc_mutex, does GFP_KERNEL allocation. |
| 271 | */ | 275 | */ |
| 272 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, | 276 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, |
| 273 | int page_start, int page_end) | 277 | int page_start, int page_end, gfp_t gfp) |
| 274 | { | 278 | { |
| 275 | struct page **pages; | 279 | struct page **pages; |
| 276 | 280 | ||
| @@ -278,7 +282,7 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, | |||
| 278 | if (!pages) | 282 | if (!pages) |
| 279 | return -ENOMEM; | 283 | return -ENOMEM; |
| 280 | 284 | ||
| 281 | if (pcpu_alloc_pages(chunk, pages, page_start, page_end)) | 285 | if (pcpu_alloc_pages(chunk, pages, page_start, page_end, gfp)) |
| 282 | return -ENOMEM; | 286 | return -ENOMEM; |
| 283 | 287 | ||
| 284 | if (pcpu_map_pages(chunk, pages, page_start, page_end)) { | 288 | if (pcpu_map_pages(chunk, pages, page_start, page_end)) { |
| @@ -325,12 +329,12 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, | |||
| 325 | pcpu_free_pages(chunk, pages, page_start, page_end); | 329 | pcpu_free_pages(chunk, pages, page_start, page_end); |
| 326 | } | 330 | } |
| 327 | 331 | ||
| 328 | static struct pcpu_chunk *pcpu_create_chunk(void) | 332 | static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp) |
| 329 | { | 333 | { |
| 330 | struct pcpu_chunk *chunk; | 334 | struct pcpu_chunk *chunk; |
| 331 | struct vm_struct **vms; | 335 | struct vm_struct **vms; |
| 332 | 336 | ||
| 333 | chunk = pcpu_alloc_chunk(); | 337 | chunk = pcpu_alloc_chunk(gfp); |
| 334 | if (!chunk) | 338 | if (!chunk) |
| 335 | return NULL; | 339 | return NULL; |
| 336 | 340 | ||
diff --git a/mm/percpu.c b/mm/percpu.c index 50e7fdf84055..9297098519a6 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
| @@ -80,6 +80,7 @@ | |||
| 80 | #include <linux/vmalloc.h> | 80 | #include <linux/vmalloc.h> |
| 81 | #include <linux/workqueue.h> | 81 | #include <linux/workqueue.h> |
| 82 | #include <linux/kmemleak.h> | 82 | #include <linux/kmemleak.h> |
| 83 | #include <linux/sched.h> | ||
| 83 | 84 | ||
| 84 | #include <asm/cacheflush.h> | 85 | #include <asm/cacheflush.h> |
| 85 | #include <asm/sections.h> | 86 | #include <asm/sections.h> |
| @@ -447,26 +448,25 @@ static void pcpu_next_fit_region(struct pcpu_chunk *chunk, int alloc_bits, | |||
| 447 | /** | 448 | /** |
| 448 | * pcpu_mem_zalloc - allocate memory | 449 | * pcpu_mem_zalloc - allocate memory |
| 449 | * @size: bytes to allocate | 450 | * @size: bytes to allocate |
| 451 | * @gfp: allocation flags | ||
| 450 | * | 452 | * |
| 451 | * Allocate @size bytes. If @size is smaller than PAGE_SIZE, | 453 | * Allocate @size bytes. If @size is smaller than PAGE_SIZE, |
| 452 | * kzalloc() is used; otherwise, vzalloc() is used. The returned | 454 | * kzalloc() is used; otherwise, the equivalent of vzalloc() is used. |
| 453 | * memory is always zeroed. | 455 | * This is to facilitate passing through whitelisted flags. The |
| 454 | * | 456 | * returned memory is always zeroed. |
| 455 | * CONTEXT: | ||
| 456 | * Does GFP_KERNEL allocation. | ||
| 457 | * | 457 | * |
| 458 | * RETURNS: | 458 | * RETURNS: |
| 459 | * Pointer to the allocated area on success, NULL on failure. | 459 | * Pointer to the allocated area on success, NULL on failure. |
| 460 | */ | 460 | */ |
| 461 | static void *pcpu_mem_zalloc(size_t size) | 461 | static void *pcpu_mem_zalloc(size_t size, gfp_t gfp) |
| 462 | { | 462 | { |
| 463 | if (WARN_ON_ONCE(!slab_is_available())) | 463 | if (WARN_ON_ONCE(!slab_is_available())) |
| 464 | return NULL; | 464 | return NULL; |
| 465 | 465 | ||
| 466 | if (size <= PAGE_SIZE) | 466 | if (size <= PAGE_SIZE) |
| 467 | return kzalloc(size, GFP_KERNEL); | 467 | return kzalloc(size, gfp); |
| 468 | else | 468 | else |
| 469 | return vzalloc(size); | 469 | return __vmalloc(size, gfp | __GFP_ZERO, PAGE_KERNEL); |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | /** | 472 | /** |
| @@ -1154,12 +1154,12 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr, | |||
| 1154 | return chunk; | 1154 | return chunk; |
| 1155 | } | 1155 | } |
| 1156 | 1156 | ||
| 1157 | static struct pcpu_chunk *pcpu_alloc_chunk(void) | 1157 | static struct pcpu_chunk *pcpu_alloc_chunk(gfp_t gfp) |
| 1158 | { | 1158 | { |
| 1159 | struct pcpu_chunk *chunk; | 1159 | struct pcpu_chunk *chunk; |
| 1160 | int region_bits; | 1160 | int region_bits; |
| 1161 | 1161 | ||
| 1162 | chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size); | 1162 | chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size, gfp); |
| 1163 | if (!chunk) | 1163 | if (!chunk) |
| 1164 | return NULL; | 1164 | return NULL; |
| 1165 | 1165 | ||
| @@ -1168,17 +1168,17 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void) | |||
| 1168 | region_bits = pcpu_chunk_map_bits(chunk); | 1168 | region_bits = pcpu_chunk_map_bits(chunk); |
| 1169 | 1169 | ||
| 1170 | chunk->alloc_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits) * | 1170 | chunk->alloc_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits) * |
| 1171 | sizeof(chunk->alloc_map[0])); | 1171 | sizeof(chunk->alloc_map[0]), gfp); |
| 1172 | if (!chunk->alloc_map) | 1172 | if (!chunk->alloc_map) |
| 1173 | goto alloc_map_fail; | 1173 | goto alloc_map_fail; |
| 1174 | 1174 | ||
| 1175 | chunk->bound_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits + 1) * | 1175 | chunk->bound_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits + 1) * |
| 1176 | sizeof(chunk->bound_map[0])); | 1176 | sizeof(chunk->bound_map[0]), gfp); |
| 1177 | if (!chunk->bound_map) | 1177 | if (!chunk->bound_map) |
| 1178 | goto bound_map_fail; | 1178 | goto bound_map_fail; |
| 1179 | 1179 | ||
| 1180 | chunk->md_blocks = pcpu_mem_zalloc(pcpu_chunk_nr_blocks(chunk) * | 1180 | chunk->md_blocks = pcpu_mem_zalloc(pcpu_chunk_nr_blocks(chunk) * |
| 1181 | sizeof(chunk->md_blocks[0])); | 1181 | sizeof(chunk->md_blocks[0]), gfp); |
| 1182 | if (!chunk->md_blocks) | 1182 | if (!chunk->md_blocks) |
| 1183 | goto md_blocks_fail; | 1183 | goto md_blocks_fail; |
| 1184 | 1184 | ||
| @@ -1277,9 +1277,11 @@ static void pcpu_chunk_depopulated(struct pcpu_chunk *chunk, | |||
| 1277 | * pcpu_addr_to_page - translate address to physical address | 1277 | * pcpu_addr_to_page - translate address to physical address |
| 1278 | * pcpu_verify_alloc_info - check alloc_info is acceptable during init | 1278 | * pcpu_verify_alloc_info - check alloc_info is acceptable during init |
| 1279 | */ | 1279 | */ |
| 1280 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size); | 1280 | static int pcpu_populate_chunk(struct pcpu_chunk *chunk, |
| 1281 | static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size); | 1281 | int page_start, int page_end, gfp_t gfp); |
| 1282 | static struct pcpu_chunk *pcpu_create_chunk(void); | 1282 | static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, |
| 1283 | int page_start, int page_end); | ||
| 1284 | static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp); | ||
| 1283 | static void pcpu_destroy_chunk(struct pcpu_chunk *chunk); | 1285 | static void pcpu_destroy_chunk(struct pcpu_chunk *chunk); |
| 1284 | static struct page *pcpu_addr_to_page(void *addr); | 1286 | static struct page *pcpu_addr_to_page(void *addr); |
| 1285 | static int __init pcpu_verify_alloc_info(const struct pcpu_alloc_info *ai); | 1287 | static int __init pcpu_verify_alloc_info(const struct pcpu_alloc_info *ai); |
| @@ -1339,6 +1341,8 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr) | |||
| 1339 | static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, | 1341 | static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, |
| 1340 | gfp_t gfp) | 1342 | gfp_t gfp) |
| 1341 | { | 1343 | { |
| 1344 | /* whitelisted flags that can be passed to the backing allocators */ | ||
| 1345 | gfp_t pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); | ||
| 1342 | bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; | 1346 | bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; |
| 1343 | bool do_warn = !(gfp & __GFP_NOWARN); | 1347 | bool do_warn = !(gfp & __GFP_NOWARN); |
| 1344 | static int warn_limit = 10; | 1348 | static int warn_limit = 10; |
| @@ -1369,8 +1373,17 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, | |||
| 1369 | return NULL; | 1373 | return NULL; |
| 1370 | } | 1374 | } |
| 1371 | 1375 | ||
| 1372 | if (!is_atomic) | 1376 | if (!is_atomic) { |
| 1373 | mutex_lock(&pcpu_alloc_mutex); | 1377 | /* |
| 1378 | * pcpu_balance_workfn() allocates memory under this mutex, | ||
| 1379 | * and it may wait for memory reclaim. Allow current task | ||
| 1380 | * to become OOM victim, in case of memory pressure. | ||
| 1381 | */ | ||
| 1382 | if (gfp & __GFP_NOFAIL) | ||
| 1383 | mutex_lock(&pcpu_alloc_mutex); | ||
| 1384 | else if (mutex_lock_killable(&pcpu_alloc_mutex)) | ||
| 1385 | return NULL; | ||
| 1386 | } | ||
| 1374 | 1387 | ||
| 1375 | spin_lock_irqsave(&pcpu_lock, flags); | 1388 | spin_lock_irqsave(&pcpu_lock, flags); |
| 1376 | 1389 | ||
| @@ -1421,7 +1434,7 @@ restart: | |||
| 1421 | } | 1434 | } |
| 1422 | 1435 | ||
| 1423 | if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) { | 1436 | if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) { |
| 1424 | chunk = pcpu_create_chunk(); | 1437 | chunk = pcpu_create_chunk(pcpu_gfp); |
| 1425 | if (!chunk) { | 1438 | if (!chunk) { |
| 1426 | err = "failed to allocate new chunk"; | 1439 | err = "failed to allocate new chunk"; |
| 1427 | goto fail; | 1440 | goto fail; |
| @@ -1450,7 +1463,7 @@ area_found: | |||
| 1450 | page_start, page_end) { | 1463 | page_start, page_end) { |
| 1451 | WARN_ON(chunk->immutable); | 1464 | WARN_ON(chunk->immutable); |
| 1452 | 1465 | ||
| 1453 | ret = pcpu_populate_chunk(chunk, rs, re); | 1466 | ret = pcpu_populate_chunk(chunk, rs, re, pcpu_gfp); |
| 1454 | 1467 | ||
| 1455 | spin_lock_irqsave(&pcpu_lock, flags); | 1468 | spin_lock_irqsave(&pcpu_lock, flags); |
| 1456 | if (ret) { | 1469 | if (ret) { |
| @@ -1561,10 +1574,17 @@ void __percpu *__alloc_reserved_percpu(size_t size, size_t align) | |||
| 1561 | * pcpu_balance_workfn - manage the amount of free chunks and populated pages | 1574 | * pcpu_balance_workfn - manage the amount of free chunks and populated pages |
| 1562 | * @work: unused | 1575 | * @work: unused |
| 1563 | * | 1576 | * |
| 1564 | * Reclaim all fully free chunks except for the first one. | 1577 | * Reclaim all fully free chunks except for the first one. This is also |
| 1578 | * responsible for maintaining the pool of empty populated pages. However, | ||
| 1579 | * it is possible that this is called when physical memory is scarce causing | ||
| 1580 | * OOM killer to be triggered. We should avoid doing so until an actual | ||
| 1581 | * allocation causes the failure as it is possible that requests can be | ||
| 1582 | * serviced from already backed regions. | ||
| 1565 | */ | 1583 | */ |
| 1566 | static void pcpu_balance_workfn(struct work_struct *work) | 1584 | static void pcpu_balance_workfn(struct work_struct *work) |
| 1567 | { | 1585 | { |
| 1586 | /* gfp flags passed to underlying allocators */ | ||
| 1587 | const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN; | ||
| 1568 | LIST_HEAD(to_free); | 1588 | LIST_HEAD(to_free); |
| 1569 | struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1]; | 1589 | struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1]; |
| 1570 | struct pcpu_chunk *chunk, *next; | 1590 | struct pcpu_chunk *chunk, *next; |
| @@ -1600,6 +1620,7 @@ static void pcpu_balance_workfn(struct work_struct *work) | |||
| 1600 | spin_unlock_irq(&pcpu_lock); | 1620 | spin_unlock_irq(&pcpu_lock); |
| 1601 | } | 1621 | } |
| 1602 | pcpu_destroy_chunk(chunk); | 1622 | pcpu_destroy_chunk(chunk); |
| 1623 | cond_resched(); | ||
| 1603 | } | 1624 | } |
| 1604 | 1625 | ||
| 1605 | /* | 1626 | /* |
| @@ -1645,7 +1666,7 @@ retry_pop: | |||
| 1645 | chunk->nr_pages) { | 1666 | chunk->nr_pages) { |
| 1646 | int nr = min(re - rs, nr_to_pop); | 1667 | int nr = min(re - rs, nr_to_pop); |
| 1647 | 1668 | ||
| 1648 | ret = pcpu_populate_chunk(chunk, rs, rs + nr); | 1669 | ret = pcpu_populate_chunk(chunk, rs, rs + nr, gfp); |
| 1649 | if (!ret) { | 1670 | if (!ret) { |
| 1650 | nr_to_pop -= nr; | 1671 | nr_to_pop -= nr; |
| 1651 | spin_lock_irq(&pcpu_lock); | 1672 | spin_lock_irq(&pcpu_lock); |
| @@ -1662,7 +1683,7 @@ retry_pop: | |||
| 1662 | 1683 | ||
| 1663 | if (nr_to_pop) { | 1684 | if (nr_to_pop) { |
| 1664 | /* ran out of chunks to populate, create a new one and retry */ | 1685 | /* ran out of chunks to populate, create a new one and retry */ |
| 1665 | chunk = pcpu_create_chunk(); | 1686 | chunk = pcpu_create_chunk(gfp); |
| 1666 | if (chunk) { | 1687 | if (chunk) { |
| 1667 | spin_lock_irq(&pcpu_lock); | 1688 | spin_lock_irq(&pcpu_lock); |
| 1668 | pcpu_chunk_relocate(chunk, -1); | 1689 | pcpu_chunk_relocate(chunk, -1); |
diff --git a/mm/shmem.c b/mm/shmem.c index 1907688b75ee..b85919243399 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -493,36 +493,45 @@ next: | |||
| 493 | info = list_entry(pos, struct shmem_inode_info, shrinklist); | 493 | info = list_entry(pos, struct shmem_inode_info, shrinklist); |
| 494 | inode = &info->vfs_inode; | 494 | inode = &info->vfs_inode; |
| 495 | 495 | ||
| 496 | if (nr_to_split && split >= nr_to_split) { | 496 | if (nr_to_split && split >= nr_to_split) |
| 497 | iput(inode); | 497 | goto leave; |
| 498 | continue; | ||
| 499 | } | ||
| 500 | 498 | ||
| 501 | page = find_lock_page(inode->i_mapping, | 499 | page = find_get_page(inode->i_mapping, |
| 502 | (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT); | 500 | (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT); |
| 503 | if (!page) | 501 | if (!page) |
| 504 | goto drop; | 502 | goto drop; |
| 505 | 503 | ||
| 504 | /* No huge page at the end of the file: nothing to split */ | ||
| 506 | if (!PageTransHuge(page)) { | 505 | if (!PageTransHuge(page)) { |
| 507 | unlock_page(page); | ||
| 508 | put_page(page); | 506 | put_page(page); |
| 509 | goto drop; | 507 | goto drop; |
| 510 | } | 508 | } |
| 511 | 509 | ||
| 510 | /* | ||
| 511 | * Leave the inode on the list if we failed to lock | ||
| 512 | * the page at this time. | ||
| 513 | * | ||
| 514 | * Waiting for the lock may lead to deadlock in the | ||
| 515 | * reclaim path. | ||
| 516 | */ | ||
| 517 | if (!trylock_page(page)) { | ||
| 518 | put_page(page); | ||
| 519 | goto leave; | ||
| 520 | } | ||
| 521 | |||
| 512 | ret = split_huge_page(page); | 522 | ret = split_huge_page(page); |
| 513 | unlock_page(page); | 523 | unlock_page(page); |
| 514 | put_page(page); | 524 | put_page(page); |
| 515 | 525 | ||
| 516 | if (ret) { | 526 | /* If split failed leave the inode on the list */ |
| 517 | /* split failed: leave it on the list */ | 527 | if (ret) |
| 518 | iput(inode); | 528 | goto leave; |
| 519 | continue; | ||
| 520 | } | ||
| 521 | 529 | ||
| 522 | split++; | 530 | split++; |
| 523 | drop: | 531 | drop: |
| 524 | list_del_init(&info->shrinklist); | 532 | list_del_init(&info->shrinklist); |
| 525 | removed++; | 533 | removed++; |
| 534 | leave: | ||
| 526 | iput(inode); | 535 | iput(inode); |
| 527 | } | 536 | } |
| 528 | 537 | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index bee53495a829..cd5dc3faaa57 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -1780,6 +1780,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, | |||
| 1780 | set_bit(PGDAT_WRITEBACK, &pgdat->flags); | 1780 | set_bit(PGDAT_WRITEBACK, &pgdat->flags); |
| 1781 | 1781 | ||
| 1782 | /* | 1782 | /* |
| 1783 | * If dirty pages are scanned that are not queued for IO, it | ||
| 1784 | * implies that flushers are not doing their job. This can | ||
| 1785 | * happen when memory pressure pushes dirty pages to the end of | ||
| 1786 | * the LRU before the dirty limits are breached and the dirty | ||
| 1787 | * data has expired. It can also happen when the proportion of | ||
| 1788 | * dirty pages grows not through writes but through memory | ||
| 1789 | * pressure reclaiming all the clean cache. And in some cases, | ||
| 1790 | * the flushers simply cannot keep up with the allocation | ||
| 1791 | * rate. Nudge the flusher threads in case they are asleep. | ||
| 1792 | */ | ||
| 1793 | if (stat.nr_unqueued_dirty == nr_taken) | ||
| 1794 | wakeup_flusher_threads(WB_REASON_VMSCAN); | ||
| 1795 | |||
| 1796 | /* | ||
| 1783 | * Legacy memcg will stall in page writeback so avoid forcibly | 1797 | * Legacy memcg will stall in page writeback so avoid forcibly |
| 1784 | * stalling here. | 1798 | * stalling here. |
| 1785 | */ | 1799 | */ |
| @@ -1791,22 +1805,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, | |||
| 1791 | if (stat.nr_dirty && stat.nr_dirty == stat.nr_congested) | 1805 | if (stat.nr_dirty && stat.nr_dirty == stat.nr_congested) |
| 1792 | set_bit(PGDAT_CONGESTED, &pgdat->flags); | 1806 | set_bit(PGDAT_CONGESTED, &pgdat->flags); |
| 1793 | 1807 | ||
| 1794 | /* | 1808 | /* Allow kswapd to start writing pages during reclaim. */ |
| 1795 | * If dirty pages are scanned that are not queued for IO, it | 1809 | if (stat.nr_unqueued_dirty == nr_taken) |
| 1796 | * implies that flushers are not doing their job. This can | ||
| 1797 | * happen when memory pressure pushes dirty pages to the end of | ||
| 1798 | * the LRU before the dirty limits are breached and the dirty | ||
| 1799 | * data has expired. It can also happen when the proportion of | ||
| 1800 | * dirty pages grows not through writes but through memory | ||
| 1801 | * pressure reclaiming all the clean cache. And in some cases, | ||
| 1802 | * the flushers simply cannot keep up with the allocation | ||
| 1803 | * rate. Nudge the flusher threads in case they are asleep, but | ||
| 1804 | * also allow kswapd to start writing pages during reclaim. | ||
| 1805 | */ | ||
| 1806 | if (stat.nr_unqueued_dirty == nr_taken) { | ||
| 1807 | wakeup_flusher_threads(WB_REASON_VMSCAN); | ||
| 1808 | set_bit(PGDAT_DIRTY, &pgdat->flags); | 1810 | set_bit(PGDAT_DIRTY, &pgdat->flags); |
| 1809 | } | ||
| 1810 | 1811 | ||
| 1811 | /* | 1812 | /* |
| 1812 | * If kswapd scans pages marked marked for immediate | 1813 | * If kswapd scans pages marked marked for immediate |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 64aa9f755e1d..45c9bf5ff3a0 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -48,8 +48,8 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 48 | * original position later | 48 | * original position later |
| 49 | */ | 49 | */ |
| 50 | skb_push(skb, offset); | 50 | skb_push(skb, offset); |
| 51 | skb = *skbp = vlan_insert_tag(skb, skb->vlan_proto, | 51 | skb = *skbp = vlan_insert_inner_tag(skb, skb->vlan_proto, |
| 52 | skb->vlan_tci); | 52 | skb->vlan_tci, skb->mac_len); |
| 53 | if (!skb) | 53 | if (!skb) |
| 54 | return false; | 54 | return false; |
| 55 | skb_pull(skb, offset + VLAN_HLEN); | 55 | skb_pull(skb, offset + VLAN_HLEN); |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 9703c791ffc5..87cd962d28d5 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
| @@ -393,7 +393,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | |||
| 393 | batadv_arp_hw_src(skb, hdr_size), &ip_src, | 393 | batadv_arp_hw_src(skb, hdr_size), &ip_src, |
| 394 | batadv_arp_hw_dst(skb, hdr_size), &ip_dst); | 394 | batadv_arp_hw_dst(skb, hdr_size), &ip_dst); |
| 395 | 395 | ||
| 396 | if (hdr_size == 0) | 396 | if (hdr_size < sizeof(struct batadv_unicast_packet)) |
| 397 | return; | 397 | return; |
| 398 | 398 | ||
| 399 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | 399 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; |
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index e91f29c7c638..5daa3d50da17 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
| 25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
| 26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
| 27 | #include <linux/eventpoll.h> | ||
| 27 | #include <linux/export.h> | 28 | #include <linux/export.h> |
| 28 | #include <linux/fcntl.h> | 29 | #include <linux/fcntl.h> |
| 29 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c index dc9fa37ddd14..cdbe0e5e208b 100644 --- a/net/batman-adv/log.c +++ b/net/batman-adv/log.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
| 23 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
| 24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
| 25 | #include <linux/eventpoll.h> | ||
| 25 | #include <linux/export.h> | 26 | #include <linux/export.h> |
| 26 | #include <linux/fcntl.h> | 27 | #include <linux/fcntl.h> |
| 27 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index cbdeb47ec3f6..d70640135e3a 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c | |||
| @@ -543,8 +543,8 @@ update: | |||
| 543 | bat_priv->mcast.enabled = true; | 543 | bat_priv->mcast.enabled = true; |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | return !(mcast_data.flags & | 546 | return !(mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV4 && |
| 547 | (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6)); | 547 | mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV6); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | /** | 550 | /** |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b6891e8b741c..e61dc1293bb5 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
| @@ -759,6 +759,7 @@ free_skb: | |||
| 759 | /** | 759 | /** |
| 760 | * batadv_reroute_unicast_packet() - update the unicast header for re-routing | 760 | * batadv_reroute_unicast_packet() - update the unicast header for re-routing |
| 761 | * @bat_priv: the bat priv with all the soft interface information | 761 | * @bat_priv: the bat priv with all the soft interface information |
| 762 | * @skb: unicast packet to process | ||
| 762 | * @unicast_packet: the unicast header to be updated | 763 | * @unicast_packet: the unicast header to be updated |
| 763 | * @dst_addr: the payload destination | 764 | * @dst_addr: the payload destination |
| 764 | * @vid: VLAN identifier | 765 | * @vid: VLAN identifier |
| @@ -770,7 +771,7 @@ free_skb: | |||
| 770 | * Return: true if the packet header has been updated, false otherwise | 771 | * Return: true if the packet header has been updated, false otherwise |
| 771 | */ | 772 | */ |
| 772 | static bool | 773 | static bool |
| 773 | batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, | 774 | batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, |
| 774 | struct batadv_unicast_packet *unicast_packet, | 775 | struct batadv_unicast_packet *unicast_packet, |
| 775 | u8 *dst_addr, unsigned short vid) | 776 | u8 *dst_addr, unsigned short vid) |
| 776 | { | 777 | { |
| @@ -799,8 +800,10 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, | |||
| 799 | } | 800 | } |
| 800 | 801 | ||
| 801 | /* update the packet header */ | 802 | /* update the packet header */ |
| 803 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | ||
| 802 | ether_addr_copy(unicast_packet->dest, orig_addr); | 804 | ether_addr_copy(unicast_packet->dest, orig_addr); |
| 803 | unicast_packet->ttvn = orig_ttvn; | 805 | unicast_packet->ttvn = orig_ttvn; |
| 806 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | ||
| 804 | 807 | ||
| 805 | ret = true; | 808 | ret = true; |
| 806 | out: | 809 | out: |
| @@ -841,7 +844,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
| 841 | * the packet to | 844 | * the packet to |
| 842 | */ | 845 | */ |
| 843 | if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) { | 846 | if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) { |
| 844 | if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, | 847 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, |
| 845 | ethhdr->h_dest, vid)) | 848 | ethhdr->h_dest, vid)) |
| 846 | batadv_dbg_ratelimited(BATADV_DBG_TT, | 849 | batadv_dbg_ratelimited(BATADV_DBG_TT, |
| 847 | bat_priv, | 850 | bat_priv, |
| @@ -887,7 +890,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
| 887 | * destination can possibly be updated and forwarded towards the new | 890 | * destination can possibly be updated and forwarded towards the new |
| 888 | * target host | 891 | * target host |
| 889 | */ | 892 | */ |
| 890 | if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, | 893 | if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet, |
| 891 | ethhdr->h_dest, vid)) { | 894 | ethhdr->h_dest, vid)) { |
| 892 | batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, | 895 | batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, |
| 893 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", | 896 | "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", |
| @@ -910,12 +913,14 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
| 910 | if (!primary_if) | 913 | if (!primary_if) |
| 911 | return false; | 914 | return false; |
| 912 | 915 | ||
| 916 | /* update the packet header */ | ||
| 917 | skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | ||
| 913 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); | 918 | ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); |
| 919 | unicast_packet->ttvn = curr_ttvn; | ||
| 920 | skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); | ||
| 914 | 921 | ||
| 915 | batadv_hardif_put(primary_if); | 922 | batadv_hardif_put(primary_if); |
| 916 | 923 | ||
| 917 | unicast_packet->ttvn = curr_ttvn; | ||
| 918 | |||
| 919 | return true; | 924 | return true; |
| 920 | } | 925 | } |
| 921 | 926 | ||
| @@ -968,14 +973,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
| 968 | struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; | 973 | struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; |
| 969 | int check, hdr_size = sizeof(*unicast_packet); | 974 | int check, hdr_size = sizeof(*unicast_packet); |
| 970 | enum batadv_subtype subtype; | 975 | enum batadv_subtype subtype; |
| 971 | struct ethhdr *ethhdr; | ||
| 972 | int ret = NET_RX_DROP; | 976 | int ret = NET_RX_DROP; |
| 973 | bool is4addr, is_gw; | 977 | bool is4addr, is_gw; |
| 974 | 978 | ||
| 975 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 979 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
| 976 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | ||
| 977 | ethhdr = eth_hdr(skb); | ||
| 978 | |||
| 979 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; | 980 | is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; |
| 980 | /* the caller function should have already pulled 2 bytes */ | 981 | /* the caller function should have already pulled 2 bytes */ |
| 981 | if (is4addr) | 982 | if (is4addr) |
| @@ -995,12 +996,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
| 995 | if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) | 996 | if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) |
| 996 | goto free_skb; | 997 | goto free_skb; |
| 997 | 998 | ||
| 999 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
| 1000 | |||
| 998 | /* packet for me */ | 1001 | /* packet for me */ |
| 999 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { | 1002 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
| 1000 | /* If this is a unicast packet from another backgone gw, | 1003 | /* If this is a unicast packet from another backgone gw, |
| 1001 | * drop it. | 1004 | * drop it. |
| 1002 | */ | 1005 | */ |
| 1003 | orig_addr_gw = ethhdr->h_source; | 1006 | orig_addr_gw = eth_hdr(skb)->h_source; |
| 1004 | orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); | 1007 | orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); |
| 1005 | if (orig_node_gw) { | 1008 | if (orig_node_gw) { |
| 1006 | is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, | 1009 | is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, |
| @@ -1015,6 +1018,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
| 1015 | } | 1018 | } |
| 1016 | 1019 | ||
| 1017 | if (is4addr) { | 1020 | if (is4addr) { |
| 1021 | unicast_4addr_packet = | ||
| 1022 | (struct batadv_unicast_4addr_packet *)skb->data; | ||
| 1018 | subtype = unicast_4addr_packet->subtype; | 1023 | subtype = unicast_4addr_packet->subtype; |
| 1019 | batadv_dat_inc_counter(bat_priv, subtype); | 1024 | batadv_dat_inc_counter(bat_priv, subtype); |
| 1020 | 1025 | ||
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 01117ae84f1d..a2ddae2f37d7 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -2296,8 +2296,14 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
| 2296 | else | 2296 | else |
| 2297 | sec_level = authreq_to_seclevel(auth); | 2297 | sec_level = authreq_to_seclevel(auth); |
| 2298 | 2298 | ||
| 2299 | if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) | 2299 | if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { |
| 2300 | /* If link is already encrypted with sufficient security we | ||
| 2301 | * still need refresh encryption as per Core Spec 5.0 Vol 3, | ||
| 2302 | * Part H 2.4.6 | ||
| 2303 | */ | ||
| 2304 | smp_ltk_encrypt(conn, hcon->sec_level); | ||
| 2300 | return 0; | 2305 | return 0; |
| 2306 | } | ||
| 2301 | 2307 | ||
| 2302 | if (sec_level > hcon->pending_sec_level) | 2308 | if (sec_level > hcon->pending_sec_level) |
| 2303 | hcon->pending_sec_level = sec_level; | 2309 | hcon->pending_sec_level = sec_level; |
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c index c5afb4232ecb..620e54f08296 100644 --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c | |||
| @@ -177,6 +177,28 @@ static bool poolsize_invalid(const struct ebt_mac_wormhash *w) | |||
| 177 | return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); | 177 | return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static bool wormhash_offset_invalid(int off, unsigned int len) | ||
| 181 | { | ||
| 182 | if (off == 0) /* not present */ | ||
| 183 | return false; | ||
| 184 | |||
| 185 | if (off < (int)sizeof(struct ebt_among_info) || | ||
| 186 | off % __alignof__(struct ebt_mac_wormhash)) | ||
| 187 | return true; | ||
| 188 | |||
| 189 | off += sizeof(struct ebt_mac_wormhash); | ||
| 190 | |||
| 191 | return off > len; | ||
| 192 | } | ||
| 193 | |||
| 194 | static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b) | ||
| 195 | { | ||
| 196 | if (a == 0) | ||
| 197 | a = sizeof(struct ebt_among_info); | ||
| 198 | |||
| 199 | return ebt_mac_wormhash_size(wh) + a == b; | ||
| 200 | } | ||
| 201 | |||
| 180 | static int ebt_among_mt_check(const struct xt_mtchk_param *par) | 202 | static int ebt_among_mt_check(const struct xt_mtchk_param *par) |
| 181 | { | 203 | { |
| 182 | const struct ebt_among_info *info = par->matchinfo; | 204 | const struct ebt_among_info *info = par->matchinfo; |
| @@ -189,6 +211,10 @@ static int ebt_among_mt_check(const struct xt_mtchk_param *par) | |||
| 189 | if (expected_length > em->match_size) | 211 | if (expected_length > em->match_size) |
| 190 | return -EINVAL; | 212 | return -EINVAL; |
| 191 | 213 | ||
| 214 | if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) || | ||
| 215 | wormhash_offset_invalid(info->wh_src_ofs, em->match_size)) | ||
| 216 | return -EINVAL; | ||
| 217 | |||
| 192 | wh_dst = ebt_among_wh_dst(info); | 218 | wh_dst = ebt_among_wh_dst(info); |
| 193 | if (poolsize_invalid(wh_dst)) | 219 | if (poolsize_invalid(wh_dst)) |
| 194 | return -EINVAL; | 220 | return -EINVAL; |
| @@ -201,6 +227,14 @@ static int ebt_among_mt_check(const struct xt_mtchk_param *par) | |||
| 201 | if (poolsize_invalid(wh_src)) | 227 | if (poolsize_invalid(wh_src)) |
| 202 | return -EINVAL; | 228 | return -EINVAL; |
| 203 | 229 | ||
| 230 | if (info->wh_src_ofs < info->wh_dst_ofs) { | ||
| 231 | if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs)) | ||
| 232 | return -EINVAL; | ||
| 233 | } else { | ||
| 234 | if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs)) | ||
| 235 | return -EINVAL; | ||
| 236 | } | ||
| 237 | |||
| 204 | expected_length += ebt_mac_wormhash_size(wh_src); | 238 | expected_length += ebt_mac_wormhash_size(wh_src); |
| 205 | 239 | ||
| 206 | if (em->match_size != EBT_ALIGN(expected_length)) { | 240 | if (em->match_size != EBT_ALIGN(expected_length)) { |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 254ef9f49567..a94d23b0a9af 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
| @@ -2119,8 +2119,12 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, | |||
| 2119 | * offsets are relative to beginning of struct ebt_entry (i.e., 0). | 2119 | * offsets are relative to beginning of struct ebt_entry (i.e., 0). |
| 2120 | */ | 2120 | */ |
| 2121 | for (i = 0; i < 4 ; ++i) { | 2121 | for (i = 0; i < 4 ; ++i) { |
| 2122 | if (offsets[i] >= *total) | 2122 | if (offsets[i] > *total) |
| 2123 | return -EINVAL; | 2123 | return -EINVAL; |
| 2124 | |||
| 2125 | if (i < 3 && offsets[i] == *total) | ||
| 2126 | return -EINVAL; | ||
| 2127 | |||
| 2124 | if (i == 0) | 2128 | if (i == 0) |
| 2125 | continue; | 2129 | continue; |
| 2126 | if (offsets[i-1] > offsets[i]) | 2130 | if (offsets[i-1] > offsets[i]) |
diff --git a/net/core/dev.c b/net/core/dev.c index 2cedf520cb28..12be20535714 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -3278,15 +3278,23 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
| 3278 | #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) | 3278 | #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO) |
| 3279 | static void skb_update_prio(struct sk_buff *skb) | 3279 | static void skb_update_prio(struct sk_buff *skb) |
| 3280 | { | 3280 | { |
| 3281 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); | 3281 | const struct netprio_map *map; |
| 3282 | const struct sock *sk; | ||
| 3283 | unsigned int prioidx; | ||
| 3282 | 3284 | ||
| 3283 | if (!skb->priority && skb->sk && map) { | 3285 | if (skb->priority) |
| 3284 | unsigned int prioidx = | 3286 | return; |
| 3285 | sock_cgroup_prioidx(&skb->sk->sk_cgrp_data); | 3287 | map = rcu_dereference_bh(skb->dev->priomap); |
| 3288 | if (!map) | ||
| 3289 | return; | ||
| 3290 | sk = skb_to_full_sk(skb); | ||
| 3291 | if (!sk) | ||
| 3292 | return; | ||
| 3286 | 3293 | ||
| 3287 | if (prioidx < map->priomap_len) | 3294 | prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data); |
| 3288 | skb->priority = map->priomap[prioidx]; | 3295 | |
| 3289 | } | 3296 | if (prioidx < map->priomap_len) |
| 3297 | skb->priority = map->priomap[prioidx]; | ||
| 3290 | } | 3298 | } |
| 3291 | #else | 3299 | #else |
| 3292 | #define skb_update_prio(skb) | 3300 | #define skb_update_prio(skb) |
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 0ab1af04296c..a04e1e88bf3a 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c | |||
| @@ -402,8 +402,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 402 | if (colon) | 402 | if (colon) |
| 403 | *colon = 0; | 403 | *colon = 0; |
| 404 | 404 | ||
| 405 | dev_load(net, ifr->ifr_name); | ||
| 406 | |||
| 407 | /* | 405 | /* |
| 408 | * See which interface the caller is talking about. | 406 | * See which interface the caller is talking about. |
| 409 | */ | 407 | */ |
| @@ -423,6 +421,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 423 | case SIOCGIFMAP: | 421 | case SIOCGIFMAP: |
| 424 | case SIOCGIFINDEX: | 422 | case SIOCGIFINDEX: |
| 425 | case SIOCGIFTXQLEN: | 423 | case SIOCGIFTXQLEN: |
| 424 | dev_load(net, ifr->ifr_name); | ||
| 426 | rcu_read_lock(); | 425 | rcu_read_lock(); |
| 427 | ret = dev_ifsioc_locked(net, ifr, cmd); | 426 | ret = dev_ifsioc_locked(net, ifr, cmd); |
| 428 | rcu_read_unlock(); | 427 | rcu_read_unlock(); |
| @@ -431,6 +430,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 431 | return ret; | 430 | return ret; |
| 432 | 431 | ||
| 433 | case SIOCETHTOOL: | 432 | case SIOCETHTOOL: |
| 433 | dev_load(net, ifr->ifr_name); | ||
| 434 | rtnl_lock(); | 434 | rtnl_lock(); |
| 435 | ret = dev_ethtool(net, ifr); | 435 | ret = dev_ethtool(net, ifr); |
| 436 | rtnl_unlock(); | 436 | rtnl_unlock(); |
| @@ -447,6 +447,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 447 | case SIOCGMIIPHY: | 447 | case SIOCGMIIPHY: |
| 448 | case SIOCGMIIREG: | 448 | case SIOCGMIIREG: |
| 449 | case SIOCSIFNAME: | 449 | case SIOCSIFNAME: |
| 450 | dev_load(net, ifr->ifr_name); | ||
| 450 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 451 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
| 451 | return -EPERM; | 452 | return -EPERM; |
| 452 | rtnl_lock(); | 453 | rtnl_lock(); |
| @@ -494,6 +495,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 494 | /* fall through */ | 495 | /* fall through */ |
| 495 | case SIOCBONDSLAVEINFOQUERY: | 496 | case SIOCBONDSLAVEINFOQUERY: |
| 496 | case SIOCBONDINFOQUERY: | 497 | case SIOCBONDINFOQUERY: |
| 498 | dev_load(net, ifr->ifr_name); | ||
| 497 | rtnl_lock(); | 499 | rtnl_lock(); |
| 498 | ret = dev_ifsioc(net, ifr, cmd); | 500 | ret = dev_ifsioc(net, ifr, cmd); |
| 499 | rtnl_unlock(); | 501 | rtnl_unlock(); |
| @@ -518,6 +520,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c | |||
| 518 | cmd == SIOCGHWTSTAMP || | 520 | cmd == SIOCGHWTSTAMP || |
| 519 | (cmd >= SIOCDEVPRIVATE && | 521 | (cmd >= SIOCDEVPRIVATE && |
| 520 | cmd <= SIOCDEVPRIVATE + 15)) { | 522 | cmd <= SIOCDEVPRIVATE + 15)) { |
| 523 | dev_load(net, ifr->ifr_name); | ||
| 521 | rtnl_lock(); | 524 | rtnl_lock(); |
| 522 | ret = dev_ifsioc(net, ifr, cmd); | 525 | ret = dev_ifsioc(net, ifr, cmd); |
| 523 | rtnl_unlock(); | 526 | rtnl_unlock(); |
diff --git a/net/core/devlink.c b/net/core/devlink.c index 2f2307d94787..effd4848c2b4 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c | |||
| @@ -1798,7 +1798,7 @@ send_done: | |||
| 1798 | if (!nlh) { | 1798 | if (!nlh) { |
| 1799 | err = devlink_dpipe_send_and_alloc_skb(&skb, info); | 1799 | err = devlink_dpipe_send_and_alloc_skb(&skb, info); |
| 1800 | if (err) | 1800 | if (err) |
| 1801 | goto err_skb_send_alloc; | 1801 | return err; |
| 1802 | goto send_done; | 1802 | goto send_done; |
| 1803 | } | 1803 | } |
| 1804 | 1804 | ||
| @@ -1807,7 +1807,6 @@ send_done: | |||
| 1807 | nla_put_failure: | 1807 | nla_put_failure: |
| 1808 | err = -EMSGSIZE; | 1808 | err = -EMSGSIZE; |
| 1809 | err_table_put: | 1809 | err_table_put: |
| 1810 | err_skb_send_alloc: | ||
| 1811 | genlmsg_cancel(skb, hdr); | 1810 | genlmsg_cancel(skb, hdr); |
| 1812 | nlmsg_free(skb); | 1811 | nlmsg_free(skb); |
| 1813 | return err; | 1812 | return err; |
| @@ -2073,7 +2072,7 @@ static int devlink_dpipe_entries_fill(struct genl_info *info, | |||
| 2073 | table->counters_enabled, | 2072 | table->counters_enabled, |
| 2074 | &dump_ctx); | 2073 | &dump_ctx); |
| 2075 | if (err) | 2074 | if (err) |
| 2076 | goto err_entries_dump; | 2075 | return err; |
| 2077 | 2076 | ||
| 2078 | send_done: | 2077 | send_done: |
| 2079 | nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, | 2078 | nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, |
| @@ -2081,16 +2080,10 @@ send_done: | |||
| 2081 | if (!nlh) { | 2080 | if (!nlh) { |
| 2082 | err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); | 2081 | err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); |
| 2083 | if (err) | 2082 | if (err) |
| 2084 | goto err_skb_send_alloc; | 2083 | return err; |
| 2085 | goto send_done; | 2084 | goto send_done; |
| 2086 | } | 2085 | } |
| 2087 | return genlmsg_reply(dump_ctx.skb, info); | 2086 | return genlmsg_reply(dump_ctx.skb, info); |
| 2088 | |||
| 2089 | err_entries_dump: | ||
| 2090 | err_skb_send_alloc: | ||
| 2091 | genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr); | ||
| 2092 | nlmsg_free(dump_ctx.skb); | ||
| 2093 | return err; | ||
| 2094 | } | 2087 | } |
| 2095 | 2088 | ||
| 2096 | static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, | 2089 | static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, |
| @@ -2229,7 +2222,7 @@ send_done: | |||
| 2229 | if (!nlh) { | 2222 | if (!nlh) { |
| 2230 | err = devlink_dpipe_send_and_alloc_skb(&skb, info); | 2223 | err = devlink_dpipe_send_and_alloc_skb(&skb, info); |
| 2231 | if (err) | 2224 | if (err) |
| 2232 | goto err_skb_send_alloc; | 2225 | return err; |
| 2233 | goto send_done; | 2226 | goto send_done; |
| 2234 | } | 2227 | } |
| 2235 | return genlmsg_reply(skb, info); | 2228 | return genlmsg_reply(skb, info); |
| @@ -2237,7 +2230,6 @@ send_done: | |||
| 2237 | nla_put_failure: | 2230 | nla_put_failure: |
| 2238 | err = -EMSGSIZE; | 2231 | err = -EMSGSIZE; |
| 2239 | err_table_put: | 2232 | err_table_put: |
| 2240 | err_skb_send_alloc: | ||
| 2241 | genlmsg_cancel(skb, hdr); | 2233 | genlmsg_cancel(skb, hdr); |
| 2242 | nlmsg_free(skb); | 2234 | nlmsg_free(skb); |
| 2243 | return err; | 2235 | return err; |
diff --git a/net/core/filter.c b/net/core/filter.c index 0c121adbdbaa..48aa7c7320db 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -2087,6 +2087,10 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) | |||
| 2087 | u32 off = skb_mac_header_len(skb); | 2087 | u32 off = skb_mac_header_len(skb); |
| 2088 | int ret; | 2088 | int ret; |
| 2089 | 2089 | ||
| 2090 | /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ | ||
| 2091 | if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) | ||
| 2092 | return -ENOTSUPP; | ||
| 2093 | |||
| 2090 | ret = skb_cow(skb, len_diff); | 2094 | ret = skb_cow(skb, len_diff); |
| 2091 | if (unlikely(ret < 0)) | 2095 | if (unlikely(ret < 0)) |
| 2092 | return ret; | 2096 | return ret; |
| @@ -2096,19 +2100,21 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) | |||
| 2096 | return ret; | 2100 | return ret; |
| 2097 | 2101 | ||
| 2098 | if (skb_is_gso(skb)) { | 2102 | if (skb_is_gso(skb)) { |
| 2103 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
| 2104 | |||
| 2099 | /* SKB_GSO_TCPV4 needs to be changed into | 2105 | /* SKB_GSO_TCPV4 needs to be changed into |
| 2100 | * SKB_GSO_TCPV6. | 2106 | * SKB_GSO_TCPV6. |
| 2101 | */ | 2107 | */ |
| 2102 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { | 2108 | if (shinfo->gso_type & SKB_GSO_TCPV4) { |
| 2103 | skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV4; | 2109 | shinfo->gso_type &= ~SKB_GSO_TCPV4; |
| 2104 | skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; | 2110 | shinfo->gso_type |= SKB_GSO_TCPV6; |
| 2105 | } | 2111 | } |
| 2106 | 2112 | ||
| 2107 | /* Due to IPv6 header, MSS needs to be downgraded. */ | 2113 | /* Due to IPv6 header, MSS needs to be downgraded. */ |
| 2108 | skb_shinfo(skb)->gso_size -= len_diff; | 2114 | skb_decrease_gso_size(shinfo, len_diff); |
| 2109 | /* Header must be checked, and gso_segs recomputed. */ | 2115 | /* Header must be checked, and gso_segs recomputed. */ |
| 2110 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 2116 | shinfo->gso_type |= SKB_GSO_DODGY; |
| 2111 | skb_shinfo(skb)->gso_segs = 0; | 2117 | shinfo->gso_segs = 0; |
| 2112 | } | 2118 | } |
| 2113 | 2119 | ||
| 2114 | skb->protocol = htons(ETH_P_IPV6); | 2120 | skb->protocol = htons(ETH_P_IPV6); |
| @@ -2123,6 +2129,10 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) | |||
| 2123 | u32 off = skb_mac_header_len(skb); | 2129 | u32 off = skb_mac_header_len(skb); |
| 2124 | int ret; | 2130 | int ret; |
| 2125 | 2131 | ||
| 2132 | /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ | ||
| 2133 | if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) | ||
| 2134 | return -ENOTSUPP; | ||
| 2135 | |||
| 2126 | ret = skb_unclone(skb, GFP_ATOMIC); | 2136 | ret = skb_unclone(skb, GFP_ATOMIC); |
| 2127 | if (unlikely(ret < 0)) | 2137 | if (unlikely(ret < 0)) |
| 2128 | return ret; | 2138 | return ret; |
| @@ -2132,19 +2142,21 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) | |||
| 2132 | return ret; | 2142 | return ret; |
| 2133 | 2143 | ||
| 2134 | if (skb_is_gso(skb)) { | 2144 | if (skb_is_gso(skb)) { |
| 2145 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
| 2146 | |||
| 2135 | /* SKB_GSO_TCPV6 needs to be changed into | 2147 | /* SKB_GSO_TCPV6 needs to be changed into |
| 2136 | * SKB_GSO_TCPV4. | 2148 | * SKB_GSO_TCPV4. |
| 2137 | */ | 2149 | */ |
| 2138 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { | 2150 | if (shinfo->gso_type & SKB_GSO_TCPV6) { |
| 2139 | skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV6; | 2151 | shinfo->gso_type &= ~SKB_GSO_TCPV6; |
| 2140 | skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; | 2152 | shinfo->gso_type |= SKB_GSO_TCPV4; |
| 2141 | } | 2153 | } |
| 2142 | 2154 | ||
| 2143 | /* Due to IPv4 header, MSS can be upgraded. */ | 2155 | /* Due to IPv4 header, MSS can be upgraded. */ |
| 2144 | skb_shinfo(skb)->gso_size += len_diff; | 2156 | skb_increase_gso_size(shinfo, len_diff); |
| 2145 | /* Header must be checked, and gso_segs recomputed. */ | 2157 | /* Header must be checked, and gso_segs recomputed. */ |
| 2146 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 2158 | shinfo->gso_type |= SKB_GSO_DODGY; |
| 2147 | skb_shinfo(skb)->gso_segs = 0; | 2159 | shinfo->gso_segs = 0; |
| 2148 | } | 2160 | } |
| 2149 | 2161 | ||
| 2150 | skb->protocol = htons(ETH_P_IP); | 2162 | skb->protocol = htons(ETH_P_IP); |
| @@ -2243,6 +2255,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) | |||
| 2243 | u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); | 2255 | u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); |
| 2244 | int ret; | 2256 | int ret; |
| 2245 | 2257 | ||
| 2258 | /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ | ||
| 2259 | if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) | ||
| 2260 | return -ENOTSUPP; | ||
| 2261 | |||
| 2246 | ret = skb_cow(skb, len_diff); | 2262 | ret = skb_cow(skb, len_diff); |
| 2247 | if (unlikely(ret < 0)) | 2263 | if (unlikely(ret < 0)) |
| 2248 | return ret; | 2264 | return ret; |
| @@ -2252,11 +2268,13 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) | |||
| 2252 | return ret; | 2268 | return ret; |
| 2253 | 2269 | ||
| 2254 | if (skb_is_gso(skb)) { | 2270 | if (skb_is_gso(skb)) { |
| 2271 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
| 2272 | |||
| 2255 | /* Due to header grow, MSS needs to be downgraded. */ | 2273 | /* Due to header grow, MSS needs to be downgraded. */ |
| 2256 | skb_shinfo(skb)->gso_size -= len_diff; | 2274 | skb_decrease_gso_size(shinfo, len_diff); |
| 2257 | /* Header must be checked, and gso_segs recomputed. */ | 2275 | /* Header must be checked, and gso_segs recomputed. */ |
| 2258 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 2276 | shinfo->gso_type |= SKB_GSO_DODGY; |
| 2259 | skb_shinfo(skb)->gso_segs = 0; | 2277 | shinfo->gso_segs = 0; |
| 2260 | } | 2278 | } |
| 2261 | 2279 | ||
| 2262 | return 0; | 2280 | return 0; |
| @@ -2267,6 +2285,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff) | |||
| 2267 | u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); | 2285 | u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); |
| 2268 | int ret; | 2286 | int ret; |
| 2269 | 2287 | ||
| 2288 | /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ | ||
| 2289 | if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) | ||
| 2290 | return -ENOTSUPP; | ||
| 2291 | |||
| 2270 | ret = skb_unclone(skb, GFP_ATOMIC); | 2292 | ret = skb_unclone(skb, GFP_ATOMIC); |
| 2271 | if (unlikely(ret < 0)) | 2293 | if (unlikely(ret < 0)) |
| 2272 | return ret; | 2294 | return ret; |
| @@ -2276,11 +2298,13 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff) | |||
| 2276 | return ret; | 2298 | return ret; |
| 2277 | 2299 | ||
| 2278 | if (skb_is_gso(skb)) { | 2300 | if (skb_is_gso(skb)) { |
| 2301 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
| 2302 | |||
| 2279 | /* Due to header shrink, MSS can be upgraded. */ | 2303 | /* Due to header shrink, MSS can be upgraded. */ |
| 2280 | skb_shinfo(skb)->gso_size += len_diff; | 2304 | skb_increase_gso_size(shinfo, len_diff); |
| 2281 | /* Header must be checked, and gso_segs recomputed. */ | 2305 | /* Header must be checked, and gso_segs recomputed. */ |
| 2282 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 2306 | shinfo->gso_type |= SKB_GSO_DODGY; |
| 2283 | skb_shinfo(skb)->gso_segs = 0; | 2307 | shinfo->gso_segs = 0; |
| 2284 | } | 2308 | } |
| 2285 | 2309 | ||
| 2286 | return 0; | 2310 | return 0; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0bb0d8877954..1e7acdc30732 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -4179,7 +4179,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) | |||
| 4179 | 4179 | ||
| 4180 | skb_queue_tail(&sk->sk_error_queue, skb); | 4180 | skb_queue_tail(&sk->sk_error_queue, skb); |
| 4181 | if (!sock_flag(sk, SOCK_DEAD)) | 4181 | if (!sock_flag(sk, SOCK_DEAD)) |
| 4182 | sk->sk_data_ready(sk); | 4182 | sk->sk_error_report(sk); |
| 4183 | return 0; | 4183 | return 0; |
| 4184 | } | 4184 | } |
| 4185 | EXPORT_SYMBOL(sock_queue_err_skb); | 4185 | EXPORT_SYMBOL(sock_queue_err_skb); |
| @@ -4904,7 +4904,7 @@ static unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) | |||
| 4904 | thlen += inner_tcp_hdrlen(skb); | 4904 | thlen += inner_tcp_hdrlen(skb); |
| 4905 | } else if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) { | 4905 | } else if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) { |
| 4906 | thlen = tcp_hdrlen(skb); | 4906 | thlen = tcp_hdrlen(skb); |
| 4907 | } else if (unlikely(shinfo->gso_type & SKB_GSO_SCTP)) { | 4907 | } else if (unlikely(skb_is_gso_sctp(skb))) { |
| 4908 | thlen = sizeof(struct sctphdr); | 4908 | thlen = sizeof(struct sctphdr); |
| 4909 | } | 4909 | } |
| 4910 | /* UFO sets gso_size to the size of the fragmentation | 4910 | /* UFO sets gso_size to the size of the fragmentation |
| @@ -5020,13 +5020,16 @@ EXPORT_SYMBOL_GPL(skb_gso_validate_mac_len); | |||
| 5020 | 5020 | ||
| 5021 | static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) | 5021 | static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) |
| 5022 | { | 5022 | { |
| 5023 | int mac_len; | ||
| 5024 | |||
| 5023 | if (skb_cow(skb, skb_headroom(skb)) < 0) { | 5025 | if (skb_cow(skb, skb_headroom(skb)) < 0) { |
| 5024 | kfree_skb(skb); | 5026 | kfree_skb(skb); |
| 5025 | return NULL; | 5027 | return NULL; |
| 5026 | } | 5028 | } |
| 5027 | 5029 | ||
| 5028 | memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN, | 5030 | mac_len = skb->data - skb_mac_header(skb); |
| 5029 | 2 * ETH_ALEN); | 5031 | memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb), |
| 5032 | mac_len - VLAN_HLEN - ETH_TLEN); | ||
| 5030 | skb->mac_header += VLAN_HLEN; | 5033 | skb->mac_header += VLAN_HLEN; |
| 5031 | return skb; | 5034 | return skb; |
| 5032 | } | 5035 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index c501499a04fe..85b0b64e7f9d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -3261,6 +3261,27 @@ void proto_unregister(struct proto *prot) | |||
| 3261 | } | 3261 | } |
| 3262 | EXPORT_SYMBOL(proto_unregister); | 3262 | EXPORT_SYMBOL(proto_unregister); |
| 3263 | 3263 | ||
| 3264 | int sock_load_diag_module(int family, int protocol) | ||
| 3265 | { | ||
| 3266 | if (!protocol) { | ||
| 3267 | if (!sock_is_registered(family)) | ||
| 3268 | return -ENOENT; | ||
| 3269 | |||
| 3270 | return request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | ||
| 3271 | NETLINK_SOCK_DIAG, family); | ||
| 3272 | } | ||
| 3273 | |||
| 3274 | #ifdef CONFIG_INET | ||
| 3275 | if (family == AF_INET && | ||
| 3276 | !rcu_access_pointer(inet_protos[protocol])) | ||
| 3277 | return -ENOENT; | ||
| 3278 | #endif | ||
| 3279 | |||
| 3280 | return request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK, | ||
| 3281 | NETLINK_SOCK_DIAG, family, protocol); | ||
| 3282 | } | ||
| 3283 | EXPORT_SYMBOL(sock_load_diag_module); | ||
| 3284 | |||
| 3264 | #ifdef CONFIG_PROC_FS | 3285 | #ifdef CONFIG_PROC_FS |
| 3265 | static void *proto_seq_start(struct seq_file *seq, loff_t *pos) | 3286 | static void *proto_seq_start(struct seq_file *seq, loff_t *pos) |
| 3266 | __acquires(proto_list_mutex) | 3287 | __acquires(proto_list_mutex) |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 146b50e30659..c37b5be7c5e4 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
| @@ -220,8 +220,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 220 | return -EINVAL; | 220 | return -EINVAL; |
| 221 | 221 | ||
| 222 | if (sock_diag_handlers[req->sdiag_family] == NULL) | 222 | if (sock_diag_handlers[req->sdiag_family] == NULL) |
| 223 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 223 | sock_load_diag_module(req->sdiag_family, 0); |
| 224 | NETLINK_SOCK_DIAG, req->sdiag_family); | ||
| 225 | 224 | ||
| 226 | mutex_lock(&sock_diag_table_mutex); | 225 | mutex_lock(&sock_diag_table_mutex); |
| 227 | hndl = sock_diag_handlers[req->sdiag_family]; | 226 | hndl = sock_diag_handlers[req->sdiag_family]; |
| @@ -247,8 +246,7 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 247 | case TCPDIAG_GETSOCK: | 246 | case TCPDIAG_GETSOCK: |
| 248 | case DCCPDIAG_GETSOCK: | 247 | case DCCPDIAG_GETSOCK: |
| 249 | if (inet_rcv_compat == NULL) | 248 | if (inet_rcv_compat == NULL) |
| 250 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 249 | sock_load_diag_module(AF_INET, 0); |
| 251 | NETLINK_SOCK_DIAG, AF_INET); | ||
| 252 | 250 | ||
| 253 | mutex_lock(&sock_diag_table_mutex); | 251 | mutex_lock(&sock_diag_table_mutex); |
| 254 | if (inet_rcv_compat != NULL) | 252 | if (inet_rcv_compat != NULL) |
| @@ -281,14 +279,12 @@ static int sock_diag_bind(struct net *net, int group) | |||
| 281 | case SKNLGRP_INET_TCP_DESTROY: | 279 | case SKNLGRP_INET_TCP_DESTROY: |
| 282 | case SKNLGRP_INET_UDP_DESTROY: | 280 | case SKNLGRP_INET_UDP_DESTROY: |
| 283 | if (!sock_diag_handlers[AF_INET]) | 281 | if (!sock_diag_handlers[AF_INET]) |
| 284 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 282 | sock_load_diag_module(AF_INET, 0); |
| 285 | NETLINK_SOCK_DIAG, AF_INET); | ||
| 286 | break; | 283 | break; |
| 287 | case SKNLGRP_INET6_TCP_DESTROY: | 284 | case SKNLGRP_INET6_TCP_DESTROY: |
| 288 | case SKNLGRP_INET6_UDP_DESTROY: | 285 | case SKNLGRP_INET6_UDP_DESTROY: |
| 289 | if (!sock_diag_handlers[AF_INET6]) | 286 | if (!sock_diag_handlers[AF_INET6]) |
| 290 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 287 | sock_load_diag_module(AF_INET6, 0); |
| 291 | NETLINK_SOCK_DIAG, AF_INET6); | ||
| 292 | break; | 288 | break; |
| 293 | } | 289 | } |
| 294 | return 0; | 290 | return 0; |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 15bdc002d90c..84cd4e3fd01b 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
| @@ -794,6 +794,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
| 794 | if (skb == NULL) | 794 | if (skb == NULL) |
| 795 | goto out_release; | 795 | goto out_release; |
| 796 | 796 | ||
| 797 | if (sk->sk_state == DCCP_CLOSED) { | ||
| 798 | rc = -ENOTCONN; | ||
| 799 | goto out_discard; | ||
| 800 | } | ||
| 801 | |||
| 797 | skb_reserve(skb, sk->sk_prot->max_header); | 802 | skb_reserve(skb, sk->sk_prot->max_header); |
| 798 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); | 803 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
| 799 | if (rc != 0) | 804 | if (rc != 0) |
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c index cb54b81d0bd9..42a7b85b84e1 100644 --- a/net/dsa/legacy.c +++ b/net/dsa/legacy.c | |||
| @@ -194,7 +194,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, | |||
| 194 | ds->ports[i].dn = cd->port_dn[i]; | 194 | ds->ports[i].dn = cd->port_dn[i]; |
| 195 | ds->ports[i].cpu_dp = dst->cpu_dp; | 195 | ds->ports[i].cpu_dp = dst->cpu_dp; |
| 196 | 196 | ||
| 197 | if (dsa_is_user_port(ds, i)) | 197 | if (!dsa_is_user_port(ds, i)) |
| 198 | continue; | 198 | continue; |
| 199 | 199 | ||
| 200 | ret = dsa_slave_create(&ds->ports[i]); | 200 | ret = dsa_slave_create(&ds->ports[i]); |
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c index 974765b7d92a..e9f0489e4229 100644 --- a/net/ieee802154/6lowpan/core.c +++ b/net/ieee802154/6lowpan/core.c | |||
| @@ -206,9 +206,13 @@ static inline void lowpan_netlink_fini(void) | |||
| 206 | static int lowpan_device_event(struct notifier_block *unused, | 206 | static int lowpan_device_event(struct notifier_block *unused, |
| 207 | unsigned long event, void *ptr) | 207 | unsigned long event, void *ptr) |
| 208 | { | 208 | { |
| 209 | struct net_device *wdev = netdev_notifier_info_to_dev(ptr); | 209 | struct net_device *ndev = netdev_notifier_info_to_dev(ptr); |
| 210 | struct wpan_dev *wpan_dev; | ||
| 210 | 211 | ||
| 211 | if (wdev->type != ARPHRD_IEEE802154) | 212 | if (ndev->type != ARPHRD_IEEE802154) |
| 213 | return NOTIFY_DONE; | ||
| 214 | wpan_dev = ndev->ieee802154_ptr; | ||
| 215 | if (!wpan_dev) | ||
| 212 | return NOTIFY_DONE; | 216 | return NOTIFY_DONE; |
| 213 | 217 | ||
| 214 | switch (event) { | 218 | switch (event) { |
| @@ -217,8 +221,8 @@ static int lowpan_device_event(struct notifier_block *unused, | |||
| 217 | * also delete possible lowpan interfaces which belongs | 221 | * also delete possible lowpan interfaces which belongs |
| 218 | * to the wpan interface. | 222 | * to the wpan interface. |
| 219 | */ | 223 | */ |
| 220 | if (wdev->ieee802154_ptr->lowpan_dev) | 224 | if (wpan_dev->lowpan_dev) |
| 221 | lowpan_dellink(wdev->ieee802154_ptr->lowpan_dev, NULL); | 225 | lowpan_dellink(wpan_dev->lowpan_dev, NULL); |
| 222 | break; | 226 | break; |
| 223 | default: | 227 | default: |
| 224 | return NOTIFY_DONE; | 228 | return NOTIFY_DONE; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index a383f299ce24..4e5bc4b2f14e 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -53,8 +53,7 @@ static DEFINE_MUTEX(inet_diag_table_mutex); | |||
| 53 | static const struct inet_diag_handler *inet_diag_lock_handler(int proto) | 53 | static const struct inet_diag_handler *inet_diag_lock_handler(int proto) |
| 54 | { | 54 | { |
| 55 | if (!inet_diag_table[proto]) | 55 | if (!inet_diag_table[proto]) |
| 56 | request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK, | 56 | sock_load_diag_module(AF_INET, proto); |
| 57 | NETLINK_SOCK_DIAG, AF_INET, proto); | ||
| 58 | 57 | ||
| 59 | mutex_lock(&inet_diag_table_mutex); | 58 | mutex_lock(&inet_diag_table_mutex); |
| 60 | if (!inet_diag_table[proto]) | 59 | if (!inet_diag_table[proto]) |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 26a3d0315728..e8ec28999f5c 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
| @@ -119,6 +119,9 @@ out: | |||
| 119 | 119 | ||
| 120 | static bool inet_fragq_should_evict(const struct inet_frag_queue *q) | 120 | static bool inet_fragq_should_evict(const struct inet_frag_queue *q) |
| 121 | { | 121 | { |
| 122 | if (!hlist_unhashed(&q->list_evictor)) | ||
| 123 | return false; | ||
| 124 | |||
| 122 | return q->net->low_thresh == 0 || | 125 | return q->net->low_thresh == 0 || |
| 123 | frag_mem_limit(q->net) >= q->net->low_thresh; | 126 | frag_mem_limit(q->net) >= q->net->low_thresh; |
| 124 | } | 127 | } |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 9c41a0cef1a5..74c962b9b09c 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -258,7 +258,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc, | |||
| 258 | src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); | 258 | src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); |
| 259 | if (!ipv6_addr_v4mapped(&src_info->ipi6_addr)) | 259 | if (!ipv6_addr_v4mapped(&src_info->ipi6_addr)) |
| 260 | return -EINVAL; | 260 | return -EINVAL; |
| 261 | ipc->oif = src_info->ipi6_ifindex; | 261 | if (src_info->ipi6_ifindex) |
| 262 | ipc->oif = src_info->ipi6_ifindex; | ||
| 262 | ipc->addr = src_info->ipi6_addr.s6_addr32[3]; | 263 | ipc->addr = src_info->ipi6_addr.s6_addr32[3]; |
| 263 | continue; | 264 | continue; |
| 264 | } | 265 | } |
| @@ -288,7 +289,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc, | |||
| 288 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo))) | 289 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo))) |
| 289 | return -EINVAL; | 290 | return -EINVAL; |
| 290 | info = (struct in_pktinfo *)CMSG_DATA(cmsg); | 291 | info = (struct in_pktinfo *)CMSG_DATA(cmsg); |
| 291 | ipc->oif = info->ipi_ifindex; | 292 | if (info->ipi_ifindex) |
| 293 | ipc->oif = info->ipi_ifindex; | ||
| 292 | ipc->addr = info->ipi_spec_dst.s_addr; | 294 | ipc->addr = info->ipi_spec_dst.s_addr; |
| 293 | break; | 295 | break; |
| 294 | } | 296 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 860b3fd2f54b..299e247b2032 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -634,6 +634,7 @@ static inline u32 fnhe_hashfun(__be32 daddr) | |||
| 634 | static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe) | 634 | static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe) |
| 635 | { | 635 | { |
| 636 | rt->rt_pmtu = fnhe->fnhe_pmtu; | 636 | rt->rt_pmtu = fnhe->fnhe_pmtu; |
| 637 | rt->rt_mtu_locked = fnhe->fnhe_mtu_locked; | ||
| 637 | rt->dst.expires = fnhe->fnhe_expires; | 638 | rt->dst.expires = fnhe->fnhe_expires; |
| 638 | 639 | ||
| 639 | if (fnhe->fnhe_gw) { | 640 | if (fnhe->fnhe_gw) { |
| @@ -644,7 +645,7 @@ static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnh | |||
| 644 | } | 645 | } |
| 645 | 646 | ||
| 646 | static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, | 647 | static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, |
| 647 | u32 pmtu, unsigned long expires) | 648 | u32 pmtu, bool lock, unsigned long expires) |
| 648 | { | 649 | { |
| 649 | struct fnhe_hash_bucket *hash; | 650 | struct fnhe_hash_bucket *hash; |
| 650 | struct fib_nh_exception *fnhe; | 651 | struct fib_nh_exception *fnhe; |
| @@ -681,8 +682,10 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, | |||
| 681 | fnhe->fnhe_genid = genid; | 682 | fnhe->fnhe_genid = genid; |
| 682 | if (gw) | 683 | if (gw) |
| 683 | fnhe->fnhe_gw = gw; | 684 | fnhe->fnhe_gw = gw; |
| 684 | if (pmtu) | 685 | if (pmtu) { |
| 685 | fnhe->fnhe_pmtu = pmtu; | 686 | fnhe->fnhe_pmtu = pmtu; |
| 687 | fnhe->fnhe_mtu_locked = lock; | ||
| 688 | } | ||
| 686 | fnhe->fnhe_expires = max(1UL, expires); | 689 | fnhe->fnhe_expires = max(1UL, expires); |
| 687 | /* Update all cached dsts too */ | 690 | /* Update all cached dsts too */ |
| 688 | rt = rcu_dereference(fnhe->fnhe_rth_input); | 691 | rt = rcu_dereference(fnhe->fnhe_rth_input); |
| @@ -706,6 +709,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, | |||
| 706 | fnhe->fnhe_daddr = daddr; | 709 | fnhe->fnhe_daddr = daddr; |
| 707 | fnhe->fnhe_gw = gw; | 710 | fnhe->fnhe_gw = gw; |
| 708 | fnhe->fnhe_pmtu = pmtu; | 711 | fnhe->fnhe_pmtu = pmtu; |
| 712 | fnhe->fnhe_mtu_locked = lock; | ||
| 709 | fnhe->fnhe_expires = expires; | 713 | fnhe->fnhe_expires = expires; |
| 710 | 714 | ||
| 711 | /* Exception created; mark the cached routes for the nexthop | 715 | /* Exception created; mark the cached routes for the nexthop |
| @@ -787,7 +791,8 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow | |||
| 787 | struct fib_nh *nh = &FIB_RES_NH(res); | 791 | struct fib_nh *nh = &FIB_RES_NH(res); |
| 788 | 792 | ||
| 789 | update_or_create_fnhe(nh, fl4->daddr, new_gw, | 793 | update_or_create_fnhe(nh, fl4->daddr, new_gw, |
| 790 | 0, jiffies + ip_rt_gc_timeout); | 794 | 0, false, |
| 795 | jiffies + ip_rt_gc_timeout); | ||
| 791 | } | 796 | } |
| 792 | if (kill_route) | 797 | if (kill_route) |
| 793 | rt->dst.obsolete = DST_OBSOLETE_KILL; | 798 | rt->dst.obsolete = DST_OBSOLETE_KILL; |
| @@ -1009,15 +1014,18 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | |||
| 1009 | { | 1014 | { |
| 1010 | struct dst_entry *dst = &rt->dst; | 1015 | struct dst_entry *dst = &rt->dst; |
| 1011 | struct fib_result res; | 1016 | struct fib_result res; |
| 1017 | bool lock = false; | ||
| 1012 | 1018 | ||
| 1013 | if (dst_metric_locked(dst, RTAX_MTU)) | 1019 | if (ip_mtu_locked(dst)) |
| 1014 | return; | 1020 | return; |
| 1015 | 1021 | ||
| 1016 | if (ipv4_mtu(dst) < mtu) | 1022 | if (ipv4_mtu(dst) < mtu) |
| 1017 | return; | 1023 | return; |
| 1018 | 1024 | ||
| 1019 | if (mtu < ip_rt_min_pmtu) | 1025 | if (mtu < ip_rt_min_pmtu) { |
| 1026 | lock = true; | ||
| 1020 | mtu = ip_rt_min_pmtu; | 1027 | mtu = ip_rt_min_pmtu; |
| 1028 | } | ||
| 1021 | 1029 | ||
| 1022 | if (rt->rt_pmtu == mtu && | 1030 | if (rt->rt_pmtu == mtu && |
| 1023 | time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2)) | 1031 | time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2)) |
| @@ -1027,7 +1035,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | |||
| 1027 | if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) { | 1035 | if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) { |
| 1028 | struct fib_nh *nh = &FIB_RES_NH(res); | 1036 | struct fib_nh *nh = &FIB_RES_NH(res); |
| 1029 | 1037 | ||
| 1030 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, | 1038 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, lock, |
| 1031 | jiffies + ip_rt_mtu_expires); | 1039 | jiffies + ip_rt_mtu_expires); |
| 1032 | } | 1040 | } |
| 1033 | rcu_read_unlock(); | 1041 | rcu_read_unlock(); |
| @@ -1280,7 +1288,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) | |||
| 1280 | 1288 | ||
| 1281 | mtu = READ_ONCE(dst->dev->mtu); | 1289 | mtu = READ_ONCE(dst->dev->mtu); |
| 1282 | 1290 | ||
| 1283 | if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { | 1291 | if (unlikely(ip_mtu_locked(dst))) { |
| 1284 | if (rt->rt_uses_gateway && mtu > 576) | 1292 | if (rt->rt_uses_gateway && mtu > 576) |
| 1285 | mtu = 576; | 1293 | mtu = 576; |
| 1286 | } | 1294 | } |
| @@ -1393,7 +1401,7 @@ struct uncached_list { | |||
| 1393 | 1401 | ||
| 1394 | static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list); | 1402 | static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list); |
| 1395 | 1403 | ||
| 1396 | static void rt_add_uncached_list(struct rtable *rt) | 1404 | void rt_add_uncached_list(struct rtable *rt) |
| 1397 | { | 1405 | { |
| 1398 | struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list); | 1406 | struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list); |
| 1399 | 1407 | ||
| @@ -1404,14 +1412,8 @@ static void rt_add_uncached_list(struct rtable *rt) | |||
| 1404 | spin_unlock_bh(&ul->lock); | 1412 | spin_unlock_bh(&ul->lock); |
| 1405 | } | 1413 | } |
| 1406 | 1414 | ||
| 1407 | static void ipv4_dst_destroy(struct dst_entry *dst) | 1415 | void rt_del_uncached_list(struct rtable *rt) |
| 1408 | { | 1416 | { |
| 1409 | struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); | ||
| 1410 | struct rtable *rt = (struct rtable *) dst; | ||
| 1411 | |||
| 1412 | if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) | ||
| 1413 | kfree(p); | ||
| 1414 | |||
| 1415 | if (!list_empty(&rt->rt_uncached)) { | 1417 | if (!list_empty(&rt->rt_uncached)) { |
| 1416 | struct uncached_list *ul = rt->rt_uncached_list; | 1418 | struct uncached_list *ul = rt->rt_uncached_list; |
| 1417 | 1419 | ||
| @@ -1421,6 +1423,17 @@ static void ipv4_dst_destroy(struct dst_entry *dst) | |||
| 1421 | } | 1423 | } |
| 1422 | } | 1424 | } |
| 1423 | 1425 | ||
| 1426 | static void ipv4_dst_destroy(struct dst_entry *dst) | ||
| 1427 | { | ||
| 1428 | struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst); | ||
| 1429 | struct rtable *rt = (struct rtable *)dst; | ||
| 1430 | |||
| 1431 | if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt)) | ||
| 1432 | kfree(p); | ||
| 1433 | |||
| 1434 | rt_del_uncached_list(rt); | ||
| 1435 | } | ||
| 1436 | |||
| 1424 | void rt_flush_dev(struct net_device *dev) | 1437 | void rt_flush_dev(struct net_device *dev) |
| 1425 | { | 1438 | { |
| 1426 | struct net *net = dev_net(dev); | 1439 | struct net *net = dev_net(dev); |
| @@ -1516,6 +1529,7 @@ struct rtable *rt_dst_alloc(struct net_device *dev, | |||
| 1516 | rt->rt_is_input = 0; | 1529 | rt->rt_is_input = 0; |
| 1517 | rt->rt_iif = 0; | 1530 | rt->rt_iif = 0; |
| 1518 | rt->rt_pmtu = 0; | 1531 | rt->rt_pmtu = 0; |
| 1532 | rt->rt_mtu_locked = 0; | ||
| 1519 | rt->rt_gateway = 0; | 1533 | rt->rt_gateway = 0; |
| 1520 | rt->rt_uses_gateway = 0; | 1534 | rt->rt_uses_gateway = 0; |
| 1521 | rt->rt_table_id = 0; | 1535 | rt->rt_table_id = 0; |
| @@ -2541,6 +2555,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
| 2541 | rt->rt_is_input = ort->rt_is_input; | 2555 | rt->rt_is_input = ort->rt_is_input; |
| 2542 | rt->rt_iif = ort->rt_iif; | 2556 | rt->rt_iif = ort->rt_iif; |
| 2543 | rt->rt_pmtu = ort->rt_pmtu; | 2557 | rt->rt_pmtu = ort->rt_pmtu; |
| 2558 | rt->rt_mtu_locked = ort->rt_mtu_locked; | ||
| 2544 | 2559 | ||
| 2545 | rt->rt_genid = rt_genid_ipv4(net); | 2560 | rt->rt_genid = rt_genid_ipv4(net); |
| 2546 | rt->rt_flags = ort->rt_flags; | 2561 | rt->rt_flags = ort->rt_flags; |
| @@ -2643,6 +2658,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id, | |||
| 2643 | memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics)); | 2658 | memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics)); |
| 2644 | if (rt->rt_pmtu && expires) | 2659 | if (rt->rt_pmtu && expires) |
| 2645 | metrics[RTAX_MTU - 1] = rt->rt_pmtu; | 2660 | metrics[RTAX_MTU - 1] = rt->rt_pmtu; |
| 2661 | if (rt->rt_mtu_locked && expires) | ||
| 2662 | metrics[RTAX_LOCK - 1] |= BIT(RTAX_MTU); | ||
| 2646 | if (rtnetlink_put_metrics(skb, metrics) < 0) | 2663 | if (rtnetlink_put_metrics(skb, metrics) < 0) |
| 2647 | goto nla_put_failure; | 2664 | goto nla_put_failure; |
| 2648 | 2665 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 48636aee23c3..8b8059b7af4d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -3566,6 +3566,7 @@ int tcp_abort(struct sock *sk, int err) | |||
| 3566 | 3566 | ||
| 3567 | bh_unlock_sock(sk); | 3567 | bh_unlock_sock(sk); |
| 3568 | local_bh_enable(); | 3568 | local_bh_enable(); |
| 3569 | tcp_write_queue_purge(sk); | ||
| 3569 | release_sock(sk); | 3570 | release_sock(sk); |
| 3570 | return 0; | 3571 | return 0; |
| 3571 | } | 3572 | } |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 71fc60f1b326..f7d944855f8e 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
| @@ -34,6 +34,7 @@ static void tcp_write_err(struct sock *sk) | |||
| 34 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; | 34 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; |
| 35 | sk->sk_error_report(sk); | 35 | sk->sk_error_report(sk); |
| 36 | 36 | ||
| 37 | tcp_write_queue_purge(sk); | ||
| 37 | tcp_done(sk); | 38 | tcp_done(sk); |
| 38 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT); | 39 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT); |
| 39 | } | 40 | } |
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 63faeee989a9..2a9764bd1719 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
| @@ -92,7 +92,8 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 92 | 92 | ||
| 93 | skb_reset_network_header(skb); | 93 | skb_reset_network_header(skb); |
| 94 | skb_mac_header_rebuild(skb); | 94 | skb_mac_header_rebuild(skb); |
| 95 | eth_hdr(skb)->h_proto = skb->protocol; | 95 | if (skb->mac_len) |
| 96 | eth_hdr(skb)->h_proto = skb->protocol; | ||
| 96 | 97 | ||
| 97 | err = 0; | 98 | err = 0; |
| 98 | 99 | ||
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 05017e2c849c..fbebda67ac1b 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -100,8 +100,10 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
| 100 | xdst->u.rt.rt_gateway = rt->rt_gateway; | 100 | xdst->u.rt.rt_gateway = rt->rt_gateway; |
| 101 | xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; | 101 | xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; |
| 102 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; | 102 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; |
| 103 | xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked; | ||
| 103 | xdst->u.rt.rt_table_id = rt->rt_table_id; | 104 | xdst->u.rt.rt_table_id = rt->rt_table_id; |
| 104 | INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); | 105 | INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); |
| 106 | rt_add_uncached_list(&xdst->u.rt); | ||
| 105 | 107 | ||
| 106 | return 0; | 108 | return 0; |
| 107 | } | 109 | } |
| @@ -241,7 +243,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) | |||
| 241 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 243 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
| 242 | 244 | ||
| 243 | dst_destroy_metrics_generic(dst); | 245 | dst_destroy_metrics_generic(dst); |
| 244 | 246 | if (xdst->u.rt.rt_uncached_list) | |
| 247 | rt_del_uncached_list(&xdst->u.rt); | ||
| 245 | xfrm_dst_destroy(xdst); | 248 | xfrm_dst_destroy(xdst); |
| 246 | } | 249 | } |
| 247 | 250 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index fbf08ce3f5ab..a9f7eca0b6a3 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -146,10 +146,12 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 146 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 146 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
| 147 | struct inet_sock *inet = inet_sk(sk); | 147 | struct inet_sock *inet = inet_sk(sk); |
| 148 | struct ipv6_pinfo *np = inet6_sk(sk); | 148 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 149 | struct in6_addr *daddr; | 149 | struct in6_addr *daddr, old_daddr; |
| 150 | __be32 fl6_flowlabel = 0; | ||
| 151 | __be32 old_fl6_flowlabel; | ||
| 152 | __be16 old_dport; | ||
| 150 | int addr_type; | 153 | int addr_type; |
| 151 | int err; | 154 | int err; |
| 152 | __be32 fl6_flowlabel = 0; | ||
| 153 | 155 | ||
| 154 | if (usin->sin6_family == AF_INET) { | 156 | if (usin->sin6_family == AF_INET) { |
| 155 | if (__ipv6_only_sock(sk)) | 157 | if (__ipv6_only_sock(sk)) |
| @@ -238,9 +240,13 @@ ipv4_connected: | |||
| 238 | } | 240 | } |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 243 | /* save the current peer information before updating it */ | ||
| 244 | old_daddr = sk->sk_v6_daddr; | ||
| 245 | old_fl6_flowlabel = np->flow_label; | ||
| 246 | old_dport = inet->inet_dport; | ||
| 247 | |||
| 241 | sk->sk_v6_daddr = *daddr; | 248 | sk->sk_v6_daddr = *daddr; |
| 242 | np->flow_label = fl6_flowlabel; | 249 | np->flow_label = fl6_flowlabel; |
| 243 | |||
| 244 | inet->inet_dport = usin->sin6_port; | 250 | inet->inet_dport = usin->sin6_port; |
| 245 | 251 | ||
| 246 | /* | 252 | /* |
| @@ -250,11 +256,12 @@ ipv4_connected: | |||
| 250 | 256 | ||
| 251 | err = ip6_datagram_dst_update(sk, true); | 257 | err = ip6_datagram_dst_update(sk, true); |
| 252 | if (err) { | 258 | if (err) { |
| 253 | /* Reset daddr and dport so that udp_v6_early_demux() | 259 | /* Restore the socket peer info, to keep it consistent with |
| 254 | * fails to find this socket | 260 | * the old socket state |
| 255 | */ | 261 | */ |
| 256 | memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr)); | 262 | sk->sk_v6_daddr = old_daddr; |
| 257 | inet->inet_dport = 0; | 263 | np->flow_label = old_fl6_flowlabel; |
| 264 | inet->inet_dport = old_dport; | ||
| 258 | goto out; | 265 | goto out; |
| 259 | } | 266 | } |
| 260 | 267 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 3c353125546d..1bbd0930063e 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -126,7 +126,8 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev, | |||
| 126 | struct ip6_tnl *t, *cand = NULL; | 126 | struct ip6_tnl *t, *cand = NULL; |
| 127 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); | 127 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); |
| 128 | int dev_type = (gre_proto == htons(ETH_P_TEB) || | 128 | int dev_type = (gre_proto == htons(ETH_P_TEB) || |
| 129 | gre_proto == htons(ETH_P_ERSPAN)) ? | 129 | gre_proto == htons(ETH_P_ERSPAN) || |
| 130 | gre_proto == htons(ETH_P_ERSPAN2)) ? | ||
| 130 | ARPHRD_ETHER : ARPHRD_IP6GRE; | 131 | ARPHRD_ETHER : ARPHRD_IP6GRE; |
| 131 | int score, cand_score = 4; | 132 | int score, cand_score = 4; |
| 132 | 133 | ||
| @@ -902,6 +903,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, | |||
| 902 | truncate = true; | 903 | truncate = true; |
| 903 | } | 904 | } |
| 904 | 905 | ||
| 906 | if (skb_cow_head(skb, dev->needed_headroom)) | ||
| 907 | goto tx_err; | ||
| 908 | |||
| 905 | t->parms.o_flags &= ~TUNNEL_KEY; | 909 | t->parms.o_flags &= ~TUNNEL_KEY; |
| 906 | IPCB(skb)->flags = 0; | 910 | IPCB(skb)->flags = 0; |
| 907 | 911 | ||
| @@ -944,6 +948,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, | |||
| 944 | md->u.md2.dir, | 948 | md->u.md2.dir, |
| 945 | get_hwid(&md->u.md2), | 949 | get_hwid(&md->u.md2), |
| 946 | truncate, false); | 950 | truncate, false); |
| 951 | } else { | ||
| 952 | goto tx_err; | ||
| 947 | } | 953 | } |
| 948 | } else { | 954 | } else { |
| 949 | switch (skb->protocol) { | 955 | switch (skb->protocol) { |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f61a5b613b52..ba5e04c6ae17 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1554,7 +1554,8 @@ static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb, | |||
| 1554 | *(opt++) = (rd_len >> 3); | 1554 | *(opt++) = (rd_len >> 3); |
| 1555 | opt += 6; | 1555 | opt += 6; |
| 1556 | 1556 | ||
| 1557 | memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); | 1557 | skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt, |
| 1558 | rd_len - 8); | ||
| 1558 | } | 1559 | } |
| 1559 | 1560 | ||
| 1560 | void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | 1561 | void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9dcfadddd800..b0d5c64e1978 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -128,7 +128,7 @@ struct uncached_list { | |||
| 128 | 128 | ||
| 129 | static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list); | 129 | static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list); |
| 130 | 130 | ||
| 131 | static void rt6_uncached_list_add(struct rt6_info *rt) | 131 | void rt6_uncached_list_add(struct rt6_info *rt) |
| 132 | { | 132 | { |
| 133 | struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list); | 133 | struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list); |
| 134 | 134 | ||
| @@ -139,7 +139,7 @@ static void rt6_uncached_list_add(struct rt6_info *rt) | |||
| 139 | spin_unlock_bh(&ul->lock); | 139 | spin_unlock_bh(&ul->lock); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static void rt6_uncached_list_del(struct rt6_info *rt) | 142 | void rt6_uncached_list_del(struct rt6_info *rt) |
| 143 | { | 143 | { |
| 144 | if (!list_empty(&rt->rt6i_uncached)) { | 144 | if (!list_empty(&rt->rt6i_uncached)) { |
| 145 | struct uncached_list *ul = rt->rt6i_uncached_list; | 145 | struct uncached_list *ul = rt->rt6i_uncached_list; |
| @@ -1509,7 +1509,30 @@ static void rt6_exceptions_remove_prefsrc(struct rt6_info *rt) | |||
| 1509 | } | 1509 | } |
| 1510 | } | 1510 | } |
| 1511 | 1511 | ||
| 1512 | static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu) | 1512 | static bool rt6_mtu_change_route_allowed(struct inet6_dev *idev, |
| 1513 | struct rt6_info *rt, int mtu) | ||
| 1514 | { | ||
| 1515 | /* If the new MTU is lower than the route PMTU, this new MTU will be the | ||
| 1516 | * lowest MTU in the path: always allow updating the route PMTU to | ||
| 1517 | * reflect PMTU decreases. | ||
| 1518 | * | ||
| 1519 | * If the new MTU is higher, and the route PMTU is equal to the local | ||
| 1520 | * MTU, this means the old MTU is the lowest in the path, so allow | ||
| 1521 | * updating it: if other nodes now have lower MTUs, PMTU discovery will | ||
| 1522 | * handle this. | ||
| 1523 | */ | ||
| 1524 | |||
| 1525 | if (dst_mtu(&rt->dst) >= mtu) | ||
| 1526 | return true; | ||
| 1527 | |||
| 1528 | if (dst_mtu(&rt->dst) == idev->cnf.mtu6) | ||
| 1529 | return true; | ||
| 1530 | |||
| 1531 | return false; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | static void rt6_exceptions_update_pmtu(struct inet6_dev *idev, | ||
| 1535 | struct rt6_info *rt, int mtu) | ||
| 1513 | { | 1536 | { |
| 1514 | struct rt6_exception_bucket *bucket; | 1537 | struct rt6_exception_bucket *bucket; |
| 1515 | struct rt6_exception *rt6_ex; | 1538 | struct rt6_exception *rt6_ex; |
| @@ -1518,20 +1541,22 @@ static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu) | |||
| 1518 | bucket = rcu_dereference_protected(rt->rt6i_exception_bucket, | 1541 | bucket = rcu_dereference_protected(rt->rt6i_exception_bucket, |
| 1519 | lockdep_is_held(&rt6_exception_lock)); | 1542 | lockdep_is_held(&rt6_exception_lock)); |
| 1520 | 1543 | ||
| 1521 | if (bucket) { | 1544 | if (!bucket) |
| 1522 | for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) { | 1545 | return; |
| 1523 | hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) { | 1546 | |
| 1524 | struct rt6_info *entry = rt6_ex->rt6i; | 1547 | for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) { |
| 1525 | /* For RTF_CACHE with rt6i_pmtu == 0 | 1548 | hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) { |
| 1526 | * (i.e. a redirected route), | 1549 | struct rt6_info *entry = rt6_ex->rt6i; |
| 1527 | * the metrics of its rt->dst.from has already | 1550 | |
| 1528 | * been updated. | 1551 | /* For RTF_CACHE with rt6i_pmtu == 0 (i.e. a redirected |
| 1529 | */ | 1552 | * route), the metrics of its rt->dst.from have already |
| 1530 | if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu) | 1553 | * been updated. |
| 1531 | entry->rt6i_pmtu = mtu; | 1554 | */ |
| 1532 | } | 1555 | if (entry->rt6i_pmtu && |
| 1533 | bucket++; | 1556 | rt6_mtu_change_route_allowed(idev, entry, mtu)) |
| 1557 | entry->rt6i_pmtu = mtu; | ||
| 1534 | } | 1558 | } |
| 1559 | bucket++; | ||
| 1535 | } | 1560 | } |
| 1536 | } | 1561 | } |
| 1537 | 1562 | ||
| @@ -3809,25 +3834,13 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) | |||
| 3809 | Since RFC 1981 doesn't include administrative MTU increase | 3834 | Since RFC 1981 doesn't include administrative MTU increase |
| 3810 | update PMTU increase is a MUST. (i.e. jumbo frame) | 3835 | update PMTU increase is a MUST. (i.e. jumbo frame) |
| 3811 | */ | 3836 | */ |
| 3812 | /* | ||
| 3813 | If new MTU is less than route PMTU, this new MTU will be the | ||
| 3814 | lowest MTU in the path, update the route PMTU to reflect PMTU | ||
| 3815 | decreases; if new MTU is greater than route PMTU, and the | ||
| 3816 | old MTU is the lowest MTU in the path, update the route PMTU | ||
| 3817 | to reflect the increase. In this case if the other nodes' MTU | ||
| 3818 | also have the lowest MTU, TOO BIG MESSAGE will be lead to | ||
| 3819 | PMTU discovery. | ||
| 3820 | */ | ||
| 3821 | if (rt->dst.dev == arg->dev && | 3837 | if (rt->dst.dev == arg->dev && |
| 3822 | dst_metric_raw(&rt->dst, RTAX_MTU) && | ||
| 3823 | !dst_metric_locked(&rt->dst, RTAX_MTU)) { | 3838 | !dst_metric_locked(&rt->dst, RTAX_MTU)) { |
| 3824 | spin_lock_bh(&rt6_exception_lock); | 3839 | spin_lock_bh(&rt6_exception_lock); |
| 3825 | if (dst_mtu(&rt->dst) >= arg->mtu || | 3840 | if (dst_metric_raw(&rt->dst, RTAX_MTU) && |
| 3826 | (dst_mtu(&rt->dst) < arg->mtu && | 3841 | rt6_mtu_change_route_allowed(idev, rt, arg->mtu)) |
| 3827 | dst_mtu(&rt->dst) == idev->cnf.mtu6)) { | ||
| 3828 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); | 3842 | dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); |
| 3829 | } | 3843 | rt6_exceptions_update_pmtu(idev, rt, arg->mtu); |
| 3830 | rt6_exceptions_update_pmtu(rt, arg->mtu); | ||
| 3831 | spin_unlock_bh(&rt6_exception_lock); | 3844 | spin_unlock_bh(&rt6_exception_lock); |
| 3832 | } | 3845 | } |
| 3833 | return 0; | 3846 | return 0; |
| @@ -4099,6 +4112,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg, | |||
| 4099 | r_cfg.fc_encap_type = nla_get_u16(nla); | 4112 | r_cfg.fc_encap_type = nla_get_u16(nla); |
| 4100 | } | 4113 | } |
| 4101 | 4114 | ||
| 4115 | r_cfg.fc_flags |= (rtnh->rtnh_flags & RTNH_F_ONLINK); | ||
| 4102 | rt = ip6_route_info_create(&r_cfg, extack); | 4116 | rt = ip6_route_info_create(&r_cfg, extack); |
| 4103 | if (IS_ERR(rt)) { | 4117 | if (IS_ERR(rt)) { |
| 4104 | err = PTR_ERR(rt); | 4118 | err = PTR_ERR(rt); |
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index bd6cc688bd19..7a78dcfda68a 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c | |||
| @@ -93,7 +93,8 @@ static void set_tun_src(struct net *net, struct net_device *dev, | |||
| 93 | /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ | 93 | /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ |
| 94 | int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) | 94 | int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) |
| 95 | { | 95 | { |
| 96 | struct net *net = dev_net(skb_dst(skb)->dev); | 96 | struct dst_entry *dst = skb_dst(skb); |
| 97 | struct net *net = dev_net(dst->dev); | ||
| 97 | struct ipv6hdr *hdr, *inner_hdr; | 98 | struct ipv6hdr *hdr, *inner_hdr; |
| 98 | struct ipv6_sr_hdr *isrh; | 99 | struct ipv6_sr_hdr *isrh; |
| 99 | int hdrlen, tot_len, err; | 100 | int hdrlen, tot_len, err; |
| @@ -134,7 +135,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) | |||
| 134 | isrh->nexthdr = proto; | 135 | isrh->nexthdr = proto; |
| 135 | 136 | ||
| 136 | hdr->daddr = isrh->segments[isrh->first_segment]; | 137 | hdr->daddr = isrh->segments[isrh->first_segment]; |
| 137 | set_tun_src(net, skb->dev, &hdr->daddr, &hdr->saddr); | 138 | set_tun_src(net, ip6_dst_idev(dst)->dev, &hdr->daddr, &hdr->saddr); |
| 138 | 139 | ||
| 139 | #ifdef CONFIG_IPV6_SEG6_HMAC | 140 | #ifdef CONFIG_IPV6_SEG6_HMAC |
| 140 | if (sr_has_hmac(isrh)) { | 141 | if (sr_has_hmac(isrh)) { |
| @@ -418,7 +419,7 @@ static int seg6_build_state(struct nlattr *nla, | |||
| 418 | 419 | ||
| 419 | slwt = seg6_lwt_lwtunnel(newts); | 420 | slwt = seg6_lwt_lwtunnel(newts); |
| 420 | 421 | ||
| 421 | err = dst_cache_init(&slwt->cache, GFP_KERNEL); | 422 | err = dst_cache_init(&slwt->cache, GFP_ATOMIC); |
| 422 | if (err) { | 423 | if (err) { |
| 423 | kfree(newts); | 424 | kfree(newts); |
| 424 | return err; | 425 | return err; |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index bb935a3b7fea..de1b0b8c53b0 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
| @@ -92,7 +92,8 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 92 | 92 | ||
| 93 | skb_reset_network_header(skb); | 93 | skb_reset_network_header(skb); |
| 94 | skb_mac_header_rebuild(skb); | 94 | skb_mac_header_rebuild(skb); |
| 95 | eth_hdr(skb)->h_proto = skb->protocol; | 95 | if (skb->mac_len) |
| 96 | eth_hdr(skb)->h_proto = skb->protocol; | ||
| 96 | 97 | ||
| 97 | err = 0; | 98 | err = 0; |
| 98 | 99 | ||
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 09fb44ee3b45..416fe67271a9 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -113,6 +113,9 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
| 113 | xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway; | 113 | xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway; |
| 114 | xdst->u.rt6.rt6i_dst = rt->rt6i_dst; | 114 | xdst->u.rt6.rt6i_dst = rt->rt6i_dst; |
| 115 | xdst->u.rt6.rt6i_src = rt->rt6i_src; | 115 | xdst->u.rt6.rt6i_src = rt->rt6i_src; |
| 116 | INIT_LIST_HEAD(&xdst->u.rt6.rt6i_uncached); | ||
| 117 | rt6_uncached_list_add(&xdst->u.rt6); | ||
| 118 | atomic_inc(&dev_net(dev)->ipv6.rt6_stats->fib_rt_uncache); | ||
| 116 | 119 | ||
| 117 | return 0; | 120 | return 0; |
| 118 | } | 121 | } |
| @@ -244,6 +247,8 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) | |||
| 244 | if (likely(xdst->u.rt6.rt6i_idev)) | 247 | if (likely(xdst->u.rt6.rt6i_idev)) |
| 245 | in6_dev_put(xdst->u.rt6.rt6i_idev); | 248 | in6_dev_put(xdst->u.rt6.rt6i_idev); |
| 246 | dst_destroy_metrics_generic(dst); | 249 | dst_destroy_metrics_generic(dst); |
| 250 | if (xdst->u.rt6.rt6i_uncached_list) | ||
| 251 | rt6_uncached_list_del(&xdst->u.rt6); | ||
| 247 | xfrm_dst_destroy(xdst); | 252 | xfrm_dst_destroy(xdst); |
| 248 | } | 253 | } |
| 249 | 254 | ||
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 1e8cc7bcbca3..9e2643ab4ccb 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
| @@ -2433,9 +2433,11 @@ static int afiucv_iucv_init(void) | |||
| 2433 | af_iucv_dev->driver = &af_iucv_driver; | 2433 | af_iucv_dev->driver = &af_iucv_driver; |
| 2434 | err = device_register(af_iucv_dev); | 2434 | err = device_register(af_iucv_dev); |
| 2435 | if (err) | 2435 | if (err) |
| 2436 | goto out_driver; | 2436 | goto out_iucv_dev; |
| 2437 | return 0; | 2437 | return 0; |
| 2438 | 2438 | ||
| 2439 | out_iucv_dev: | ||
| 2440 | put_device(af_iucv_dev); | ||
| 2439 | out_driver: | 2441 | out_driver: |
| 2440 | driver_unregister(&af_iucv_driver); | 2442 | driver_unregister(&af_iucv_driver); |
| 2441 | out_iucv: | 2443 | out_iucv: |
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index f297d53a11aa..34355fd19f27 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
| @@ -1381,24 +1381,32 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
| 1381 | .parse_msg = kcm_parse_func_strparser, | 1381 | .parse_msg = kcm_parse_func_strparser, |
| 1382 | .read_sock_done = kcm_read_sock_done, | 1382 | .read_sock_done = kcm_read_sock_done, |
| 1383 | }; | 1383 | }; |
| 1384 | int err; | 1384 | int err = 0; |
| 1385 | 1385 | ||
| 1386 | csk = csock->sk; | 1386 | csk = csock->sk; |
| 1387 | if (!csk) | 1387 | if (!csk) |
| 1388 | return -EINVAL; | 1388 | return -EINVAL; |
| 1389 | 1389 | ||
| 1390 | lock_sock(csk); | ||
| 1391 | |||
| 1390 | /* Only allow TCP sockets to be attached for now */ | 1392 | /* Only allow TCP sockets to be attached for now */ |
| 1391 | if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) || | 1393 | if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) || |
| 1392 | csk->sk_protocol != IPPROTO_TCP) | 1394 | csk->sk_protocol != IPPROTO_TCP) { |
| 1393 | return -EOPNOTSUPP; | 1395 | err = -EOPNOTSUPP; |
| 1396 | goto out; | ||
| 1397 | } | ||
| 1394 | 1398 | ||
| 1395 | /* Don't allow listeners or closed sockets */ | 1399 | /* Don't allow listeners or closed sockets */ |
| 1396 | if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) | 1400 | if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) { |
| 1397 | return -EOPNOTSUPP; | 1401 | err = -EOPNOTSUPP; |
| 1402 | goto out; | ||
| 1403 | } | ||
| 1398 | 1404 | ||
| 1399 | psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); | 1405 | psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); |
| 1400 | if (!psock) | 1406 | if (!psock) { |
| 1401 | return -ENOMEM; | 1407 | err = -ENOMEM; |
| 1408 | goto out; | ||
| 1409 | } | ||
| 1402 | 1410 | ||
| 1403 | psock->mux = mux; | 1411 | psock->mux = mux; |
| 1404 | psock->sk = csk; | 1412 | psock->sk = csk; |
| @@ -1407,7 +1415,7 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
| 1407 | err = strp_init(&psock->strp, csk, &cb); | 1415 | err = strp_init(&psock->strp, csk, &cb); |
| 1408 | if (err) { | 1416 | if (err) { |
| 1409 | kmem_cache_free(kcm_psockp, psock); | 1417 | kmem_cache_free(kcm_psockp, psock); |
| 1410 | return err; | 1418 | goto out; |
| 1411 | } | 1419 | } |
| 1412 | 1420 | ||
| 1413 | write_lock_bh(&csk->sk_callback_lock); | 1421 | write_lock_bh(&csk->sk_callback_lock); |
| @@ -1419,7 +1427,8 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
| 1419 | write_unlock_bh(&csk->sk_callback_lock); | 1427 | write_unlock_bh(&csk->sk_callback_lock); |
| 1420 | strp_done(&psock->strp); | 1428 | strp_done(&psock->strp); |
| 1421 | kmem_cache_free(kcm_psockp, psock); | 1429 | kmem_cache_free(kcm_psockp, psock); |
| 1422 | return -EALREADY; | 1430 | err = -EALREADY; |
| 1431 | goto out; | ||
| 1423 | } | 1432 | } |
| 1424 | 1433 | ||
| 1425 | psock->save_data_ready = csk->sk_data_ready; | 1434 | psock->save_data_ready = csk->sk_data_ready; |
| @@ -1455,7 +1464,10 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
| 1455 | /* Schedule RX work in case there are already bytes queued */ | 1464 | /* Schedule RX work in case there are already bytes queued */ |
| 1456 | strp_check_rcv(&psock->strp); | 1465 | strp_check_rcv(&psock->strp); |
| 1457 | 1466 | ||
| 1458 | return 0; | 1467 | out: |
| 1468 | release_sock(csk); | ||
| 1469 | |||
| 1470 | return err; | ||
| 1459 | } | 1471 | } |
| 1460 | 1472 | ||
| 1461 | static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info) | 1473 | static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info) |
| @@ -1507,6 +1519,7 @@ static void kcm_unattach(struct kcm_psock *psock) | |||
| 1507 | 1519 | ||
| 1508 | if (WARN_ON(psock->rx_kcm)) { | 1520 | if (WARN_ON(psock->rx_kcm)) { |
| 1509 | write_unlock_bh(&csk->sk_callback_lock); | 1521 | write_unlock_bh(&csk->sk_callback_lock); |
| 1522 | release_sock(csk); | ||
| 1510 | return; | 1523 | return; |
| 1511 | } | 1524 | } |
| 1512 | 1525 | ||
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 83421c6f0bef..14b67dfacc4b 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
| @@ -111,6 +111,13 @@ struct l2tp_net { | |||
| 111 | spinlock_t l2tp_session_hlist_lock; | 111 | spinlock_t l2tp_session_hlist_lock; |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 115 | static bool l2tp_sk_is_v6(struct sock *sk) | ||
| 116 | { | ||
| 117 | return sk->sk_family == PF_INET6 && | ||
| 118 | !ipv6_addr_v4mapped(&sk->sk_v6_daddr); | ||
| 119 | } | ||
| 120 | #endif | ||
| 114 | 121 | ||
| 115 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) | 122 | static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) |
| 116 | { | 123 | { |
| @@ -1049,7 +1056,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, | |||
| 1049 | /* Queue the packet to IP for output */ | 1056 | /* Queue the packet to IP for output */ |
| 1050 | skb->ignore_df = 1; | 1057 | skb->ignore_df = 1; |
| 1051 | #if IS_ENABLED(CONFIG_IPV6) | 1058 | #if IS_ENABLED(CONFIG_IPV6) |
| 1052 | if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) | 1059 | if (l2tp_sk_is_v6(tunnel->sock)) |
| 1053 | error = inet6_csk_xmit(tunnel->sock, skb, NULL); | 1060 | error = inet6_csk_xmit(tunnel->sock, skb, NULL); |
| 1054 | else | 1061 | else |
| 1055 | #endif | 1062 | #endif |
| @@ -1112,6 +1119,15 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
| 1112 | goto out_unlock; | 1119 | goto out_unlock; |
| 1113 | } | 1120 | } |
| 1114 | 1121 | ||
| 1122 | /* The user-space may change the connection status for the user-space | ||
| 1123 | * provided socket at run time: we must check it under the socket lock | ||
| 1124 | */ | ||
| 1125 | if (tunnel->fd >= 0 && sk->sk_state != TCP_ESTABLISHED) { | ||
| 1126 | kfree_skb(skb); | ||
| 1127 | ret = NET_XMIT_DROP; | ||
| 1128 | goto out_unlock; | ||
| 1129 | } | ||
| 1130 | |||
| 1115 | /* Get routing info from the tunnel socket */ | 1131 | /* Get routing info from the tunnel socket */ |
| 1116 | skb_dst_drop(skb); | 1132 | skb_dst_drop(skb); |
| 1117 | skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0))); | 1133 | skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0))); |
| @@ -1131,7 +1147,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
| 1131 | 1147 | ||
| 1132 | /* Calculate UDP checksum if configured to do so */ | 1148 | /* Calculate UDP checksum if configured to do so */ |
| 1133 | #if IS_ENABLED(CONFIG_IPV6) | 1149 | #if IS_ENABLED(CONFIG_IPV6) |
| 1134 | if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) | 1150 | if (l2tp_sk_is_v6(sk)) |
| 1135 | udp6_set_csum(udp_get_no_check6_tx(sk), | 1151 | udp6_set_csum(udp_get_no_check6_tx(sk), |
| 1136 | skb, &inet6_sk(sk)->saddr, | 1152 | skb, &inet6_sk(sk)->saddr, |
| 1137 | &sk->sk_v6_daddr, udp_len); | 1153 | &sk->sk_v6_daddr, udp_len); |
| @@ -1457,9 +1473,14 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
| 1457 | encap = cfg->encap; | 1473 | encap = cfg->encap; |
| 1458 | 1474 | ||
| 1459 | /* Quick sanity checks */ | 1475 | /* Quick sanity checks */ |
| 1476 | err = -EPROTONOSUPPORT; | ||
| 1477 | if (sk->sk_type != SOCK_DGRAM) { | ||
| 1478 | pr_debug("tunl %hu: fd %d wrong socket type\n", | ||
| 1479 | tunnel_id, fd); | ||
| 1480 | goto err; | ||
| 1481 | } | ||
| 1460 | switch (encap) { | 1482 | switch (encap) { |
| 1461 | case L2TP_ENCAPTYPE_UDP: | 1483 | case L2TP_ENCAPTYPE_UDP: |
| 1462 | err = -EPROTONOSUPPORT; | ||
| 1463 | if (sk->sk_protocol != IPPROTO_UDP) { | 1484 | if (sk->sk_protocol != IPPROTO_UDP) { |
| 1464 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", | 1485 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", |
| 1465 | tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); | 1486 | tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); |
| @@ -1467,7 +1488,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
| 1467 | } | 1488 | } |
| 1468 | break; | 1489 | break; |
| 1469 | case L2TP_ENCAPTYPE_IP: | 1490 | case L2TP_ENCAPTYPE_IP: |
| 1470 | err = -EPROTONOSUPPORT; | ||
| 1471 | if (sk->sk_protocol != IPPROTO_L2TP) { | 1491 | if (sk->sk_protocol != IPPROTO_L2TP) { |
| 1472 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", | 1492 | pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n", |
| 1473 | tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP); | 1493 | tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP); |
| @@ -1507,24 +1527,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
| 1507 | if (cfg != NULL) | 1527 | if (cfg != NULL) |
| 1508 | tunnel->debug = cfg->debug; | 1528 | tunnel->debug = cfg->debug; |
| 1509 | 1529 | ||
| 1510 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 1511 | if (sk->sk_family == PF_INET6) { | ||
| 1512 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
| 1513 | |||
| 1514 | if (ipv6_addr_v4mapped(&np->saddr) && | ||
| 1515 | ipv6_addr_v4mapped(&sk->sk_v6_daddr)) { | ||
| 1516 | struct inet_sock *inet = inet_sk(sk); | ||
| 1517 | |||
| 1518 | tunnel->v4mapped = true; | ||
| 1519 | inet->inet_saddr = np->saddr.s6_addr32[3]; | ||
| 1520 | inet->inet_rcv_saddr = sk->sk_v6_rcv_saddr.s6_addr32[3]; | ||
| 1521 | inet->inet_daddr = sk->sk_v6_daddr.s6_addr32[3]; | ||
| 1522 | } else { | ||
| 1523 | tunnel->v4mapped = false; | ||
| 1524 | } | ||
| 1525 | } | ||
| 1526 | #endif | ||
| 1527 | |||
| 1528 | /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ | 1530 | /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ |
| 1529 | tunnel->encap = encap; | 1531 | tunnel->encap = encap; |
| 1530 | if (encap == L2TP_ENCAPTYPE_UDP) { | 1532 | if (encap == L2TP_ENCAPTYPE_UDP) { |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index a1aa9550f04e..2718d0b284d0 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
| @@ -188,9 +188,6 @@ struct l2tp_tunnel { | |||
| 188 | struct sock *sock; /* Parent socket */ | 188 | struct sock *sock; /* Parent socket */ |
| 189 | int fd; /* Parent fd, if tunnel socket | 189 | int fd; /* Parent fd, if tunnel socket |
| 190 | * was created by userspace */ | 190 | * was created by userspace */ |
| 191 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 192 | bool v4mapped; | ||
| 193 | #endif | ||
| 194 | 191 | ||
| 195 | struct work_struct del_work; | 192 | struct work_struct del_work; |
| 196 | 193 | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 1f466d12a6bc..94c7ee9df33b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
| @@ -212,6 +212,7 @@ static const char *hw_flag_names[] = { | |||
| 212 | FLAG(REPORTS_LOW_ACK), | 212 | FLAG(REPORTS_LOW_ACK), |
| 213 | FLAG(SUPPORTS_TX_FRAG), | 213 | FLAG(SUPPORTS_TX_FRAG), |
| 214 | FLAG(SUPPORTS_TDLS_BUFFER_STA), | 214 | FLAG(SUPPORTS_TDLS_BUFFER_STA), |
| 215 | FLAG(DOESNT_SUPPORT_QOS_NDP), | ||
| 215 | #undef FLAG | 216 | #undef FLAG |
| 216 | }; | 217 | }; |
| 217 | 218 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 39b660b9a908..5f303abac5ad 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -896,7 +896,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
| 896 | struct ieee80211_hdr_3addr *nullfunc; | 896 | struct ieee80211_hdr_3addr *nullfunc; |
| 897 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 897 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 898 | 898 | ||
| 899 | skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, true); | 899 | skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, |
| 900 | !ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP)); | ||
| 900 | if (!skb) | 901 | if (!skb) |
| 901 | return; | 902 | return; |
| 902 | 903 | ||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 558593e6a0a3..c4acc7340eb1 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -5423,6 +5423,7 @@ err: | |||
| 5423 | static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) | 5423 | static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) |
| 5424 | { | 5424 | { |
| 5425 | cancel_delayed_work_sync(&flowtable->data.gc_work); | 5425 | cancel_delayed_work_sync(&flowtable->data.gc_work); |
| 5426 | kfree(flowtable->ops); | ||
| 5426 | kfree(flowtable->name); | 5427 | kfree(flowtable->name); |
| 5427 | flowtable->data.type->free(&flowtable->data); | 5428 | flowtable->data.type->free(&flowtable->data); |
| 5428 | rhashtable_destroy(&flowtable->data.rhashtable); | 5429 | rhashtable_destroy(&flowtable->data.rhashtable); |
diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c index 3f1624ee056f..d40591fe1b2f 100644 --- a/net/netfilter/nft_set_hash.c +++ b/net/netfilter/nft_set_hash.c | |||
| @@ -674,7 +674,7 @@ static const struct nft_set_ops * | |||
| 674 | nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc, | 674 | nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc, |
| 675 | u32 flags) | 675 | u32 flags) |
| 676 | { | 676 | { |
| 677 | if (desc->size) { | 677 | if (desc->size && !(flags & NFT_SET_TIMEOUT)) { |
| 678 | switch (desc->klen) { | 678 | switch (desc->klen) { |
| 679 | case 4: | 679 | case 4: |
| 680 | return &nft_hash_fast_ops; | 680 | return &nft_hash_fast_ops; |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index fa1655aff8d3..4aa01c90e9d1 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
| @@ -423,6 +423,36 @@ textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto) | |||
| 423 | return buf; | 423 | return buf; |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | /** | ||
| 427 | * xt_check_proc_name - check that name is suitable for /proc file creation | ||
| 428 | * | ||
| 429 | * @name: file name candidate | ||
| 430 | * @size: length of buffer | ||
| 431 | * | ||
| 432 | * some x_tables modules wish to create a file in /proc. | ||
| 433 | * This function makes sure that the name is suitable for this | ||
| 434 | * purpose, it checks that name is NUL terminated and isn't a 'special' | ||
| 435 | * name, like "..". | ||
| 436 | * | ||
| 437 | * returns negative number on error or 0 if name is useable. | ||
| 438 | */ | ||
| 439 | int xt_check_proc_name(const char *name, unsigned int size) | ||
| 440 | { | ||
| 441 | if (name[0] == '\0') | ||
| 442 | return -EINVAL; | ||
| 443 | |||
| 444 | if (strnlen(name, size) == size) | ||
| 445 | return -ENAMETOOLONG; | ||
| 446 | |||
| 447 | if (strcmp(name, ".") == 0 || | ||
| 448 | strcmp(name, "..") == 0 || | ||
| 449 | strchr(name, '/')) | ||
| 450 | return -EINVAL; | ||
| 451 | |||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | EXPORT_SYMBOL(xt_check_proc_name); | ||
| 455 | |||
| 426 | int xt_check_match(struct xt_mtchk_param *par, | 456 | int xt_check_match(struct xt_mtchk_param *par, |
| 427 | unsigned int size, u_int8_t proto, bool inv_proto) | 457 | unsigned int size, u_int8_t proto, bool inv_proto) |
| 428 | { | 458 | { |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 66f5aca62a08..3360f13dc208 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
| @@ -917,8 +917,9 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par) | |||
| 917 | struct hashlimit_cfg3 cfg = {}; | 917 | struct hashlimit_cfg3 cfg = {}; |
| 918 | int ret; | 918 | int ret; |
| 919 | 919 | ||
| 920 | if (info->name[sizeof(info->name) - 1] != '\0') | 920 | ret = xt_check_proc_name(info->name, sizeof(info->name)); |
| 921 | return -EINVAL; | 921 | if (ret) |
| 922 | return ret; | ||
| 922 | 923 | ||
| 923 | ret = cfg_copy(&cfg, (void *)&info->cfg, 1); | 924 | ret = cfg_copy(&cfg, (void *)&info->cfg, 1); |
| 924 | 925 | ||
| @@ -935,8 +936,9 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) | |||
| 935 | struct hashlimit_cfg3 cfg = {}; | 936 | struct hashlimit_cfg3 cfg = {}; |
| 936 | int ret; | 937 | int ret; |
| 937 | 938 | ||
| 938 | if (info->name[sizeof(info->name) - 1] != '\0') | 939 | ret = xt_check_proc_name(info->name, sizeof(info->name)); |
| 939 | return -EINVAL; | 940 | if (ret) |
| 941 | return ret; | ||
| 940 | 942 | ||
| 941 | ret = cfg_copy(&cfg, (void *)&info->cfg, 2); | 943 | ret = cfg_copy(&cfg, (void *)&info->cfg, 2); |
| 942 | 944 | ||
| @@ -950,9 +952,11 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par) | |||
| 950 | static int hashlimit_mt_check(const struct xt_mtchk_param *par) | 952 | static int hashlimit_mt_check(const struct xt_mtchk_param *par) |
| 951 | { | 953 | { |
| 952 | struct xt_hashlimit_mtinfo3 *info = par->matchinfo; | 954 | struct xt_hashlimit_mtinfo3 *info = par->matchinfo; |
| 955 | int ret; | ||
| 953 | 956 | ||
| 954 | if (info->name[sizeof(info->name) - 1] != '\0') | 957 | ret = xt_check_proc_name(info->name, sizeof(info->name)); |
| 955 | return -EINVAL; | 958 | if (ret) |
| 959 | return ret; | ||
| 956 | 960 | ||
| 957 | return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg, | 961 | return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg, |
| 958 | info->name, 3); | 962 | info->name, 3); |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 6d232d18faff..81ee1d6543b2 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
| @@ -361,9 +361,9 @@ static int recent_mt_check(const struct xt_mtchk_param *par, | |||
| 361 | info->hit_count, XT_RECENT_MAX_NSTAMPS - 1); | 361 | info->hit_count, XT_RECENT_MAX_NSTAMPS - 1); |
| 362 | return -EINVAL; | 362 | return -EINVAL; |
| 363 | } | 363 | } |
| 364 | if (info->name[0] == '\0' || | 364 | ret = xt_check_proc_name(info->name, sizeof(info->name)); |
| 365 | strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN) | 365 | if (ret) |
| 366 | return -EINVAL; | 366 | return ret; |
| 367 | 367 | ||
| 368 | if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot) | 368 | if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot) |
| 369 | nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1; | 369 | nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 6f02499ef007..b9ce82c9440f 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -1106,7 +1106,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | |||
| 1106 | if (!err) | 1106 | if (!err) |
| 1107 | delivered = true; | 1107 | delivered = true; |
| 1108 | else if (err != -ESRCH) | 1108 | else if (err != -ESRCH) |
| 1109 | goto error; | 1109 | return err; |
| 1110 | return delivered ? 0 : -ESRCH; | 1110 | return delivered ? 0 : -ESRCH; |
| 1111 | error: | 1111 | error: |
| 1112 | kfree_skb(skb); | 1112 | kfree_skb(skb); |
diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c index 04b94281a30b..b891a91577f8 100644 --- a/net/openvswitch/meter.c +++ b/net/openvswitch/meter.c | |||
| @@ -242,14 +242,20 @@ static struct dp_meter *dp_meter_create(struct nlattr **a) | |||
| 242 | 242 | ||
| 243 | band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]); | 243 | band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]); |
| 244 | band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]); | 244 | band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]); |
| 245 | if (band->rate == 0) { | ||
| 246 | err = -EINVAL; | ||
| 247 | goto exit_free_meter; | ||
| 248 | } | ||
| 249 | |||
| 245 | band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]); | 250 | band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]); |
| 246 | /* Figure out max delta_t that is enough to fill any bucket. | 251 | /* Figure out max delta_t that is enough to fill any bucket. |
| 247 | * Keep max_delta_t size to the bucket units: | 252 | * Keep max_delta_t size to the bucket units: |
| 248 | * pkts => 1/1000 packets, kilobits => bits. | 253 | * pkts => 1/1000 packets, kilobits => bits. |
| 254 | * | ||
| 255 | * Start with a full bucket. | ||
| 249 | */ | 256 | */ |
| 250 | band_max_delta_t = (band->burst_size + band->rate) * 1000; | 257 | band->bucket = (band->burst_size + band->rate) * 1000; |
| 251 | /* Start with a full bucket. */ | 258 | band_max_delta_t = band->bucket / band->rate; |
| 252 | band->bucket = band_max_delta_t; | ||
| 253 | if (band_max_delta_t > meter->max_delta_t) | 259 | if (band_max_delta_t > meter->max_delta_t) |
| 254 | meter->max_delta_t = band_max_delta_t; | 260 | meter->max_delta_t = band_max_delta_t; |
| 255 | band++; | 261 | band++; |
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index b3f2c15affa7..9d2cabf1dc7e 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c | |||
| @@ -352,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, | |||
| 352 | return res; | 352 | return res; |
| 353 | out: | 353 | out: |
| 354 | if (res == ACT_P_CREATED) | 354 | if (res == ACT_P_CREATED) |
| 355 | tcf_idr_cleanup(*act, est); | 355 | tcf_idr_release(*act, bind); |
| 356 | 356 | ||
| 357 | return ret; | 357 | return ret; |
| 358 | } | 358 | } |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index b7ba9b06b147..2a5c8fd860cf 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
| @@ -350,7 +350,7 @@ static int tcf_csum_sctp(struct sk_buff *skb, unsigned int ihl, | |||
| 350 | { | 350 | { |
| 351 | struct sctphdr *sctph; | 351 | struct sctphdr *sctph; |
| 352 | 352 | ||
| 353 | if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) | 353 | if (skb_is_gso(skb) && skb_is_gso_sctp(skb)) |
| 354 | return 1; | 354 | return 1; |
| 355 | 355 | ||
| 356 | sctph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*sctph)); | 356 | sctph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*sctph)); |
| @@ -626,7 +626,8 @@ static void tcf_csum_cleanup(struct tc_action *a) | |||
| 626 | struct tcf_csum_params *params; | 626 | struct tcf_csum_params *params; |
| 627 | 627 | ||
| 628 | params = rcu_dereference_protected(p->params, 1); | 628 | params = rcu_dereference_protected(p->params, 1); |
| 629 | kfree_rcu(params, rcu); | 629 | if (params) |
| 630 | kfree_rcu(params, rcu); | ||
| 630 | } | 631 | } |
| 631 | 632 | ||
| 632 | static int tcf_csum_walker(struct net *net, struct sk_buff *skb, | 633 | static int tcf_csum_walker(struct net *net, struct sk_buff *skb, |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 06e380ae0928..7e06b9b62613 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -80,9 +80,12 @@ static void ipt_destroy_target(struct xt_entry_target *t) | |||
| 80 | static void tcf_ipt_release(struct tc_action *a) | 80 | static void tcf_ipt_release(struct tc_action *a) |
| 81 | { | 81 | { |
| 82 | struct tcf_ipt *ipt = to_ipt(a); | 82 | struct tcf_ipt *ipt = to_ipt(a); |
| 83 | ipt_destroy_target(ipt->tcfi_t); | 83 | |
| 84 | if (ipt->tcfi_t) { | ||
| 85 | ipt_destroy_target(ipt->tcfi_t); | ||
| 86 | kfree(ipt->tcfi_t); | ||
| 87 | } | ||
| 84 | kfree(ipt->tcfi_tname); | 88 | kfree(ipt->tcfi_tname); |
| 85 | kfree(ipt->tcfi_t); | ||
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { | 91 | static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { |
| @@ -187,7 +190,7 @@ err2: | |||
| 187 | kfree(tname); | 190 | kfree(tname); |
| 188 | err1: | 191 | err1: |
| 189 | if (ret == ACT_P_CREATED) | 192 | if (ret == ACT_P_CREATED) |
| 190 | tcf_idr_cleanup(*a, est); | 193 | tcf_idr_release(*a, bind); |
| 191 | return err; | 194 | return err; |
| 192 | } | 195 | } |
| 193 | 196 | ||
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 349beaffb29e..fef08835f26d 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -176,7 +176,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
| 176 | p = to_pedit(*a); | 176 | p = to_pedit(*a); |
| 177 | keys = kmalloc(ksize, GFP_KERNEL); | 177 | keys = kmalloc(ksize, GFP_KERNEL); |
| 178 | if (keys == NULL) { | 178 | if (keys == NULL) { |
| 179 | tcf_idr_cleanup(*a, est); | 179 | tcf_idr_release(*a, bind); |
| 180 | kfree(keys_ex); | 180 | kfree(keys_ex); |
| 181 | return -ENOMEM; | 181 | return -ENOMEM; |
| 182 | } | 182 | } |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 95d3c9097b25..faebf82b99f1 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
| @@ -194,7 +194,7 @@ failure: | |||
| 194 | qdisc_put_rtab(P_tab); | 194 | qdisc_put_rtab(P_tab); |
| 195 | qdisc_put_rtab(R_tab); | 195 | qdisc_put_rtab(R_tab); |
| 196 | if (ret == ACT_P_CREATED) | 196 | if (ret == ACT_P_CREATED) |
| 197 | tcf_idr_cleanup(*a, est); | 197 | tcf_idr_release(*a, bind); |
| 198 | return err; | 198 | return err; |
| 199 | } | 199 | } |
| 200 | 200 | ||
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 1ba0df238756..74c5d7e6a0fa 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c | |||
| @@ -103,7 +103,8 @@ static void tcf_sample_cleanup(struct tc_action *a) | |||
| 103 | 103 | ||
| 104 | psample_group = rtnl_dereference(s->psample_group); | 104 | psample_group = rtnl_dereference(s->psample_group); |
| 105 | RCU_INIT_POINTER(s->psample_group, NULL); | 105 | RCU_INIT_POINTER(s->psample_group, NULL); |
| 106 | psample_group_put(psample_group); | 106 | if (psample_group) |
| 107 | psample_group_put(psample_group); | ||
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static bool tcf_sample_dev_ok_push(struct net_device *dev) | 110 | static bool tcf_sample_dev_ok_push(struct net_device *dev) |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 425eac11f6da..b1f38063ada0 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -121,7 +121,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 121 | d = to_defact(*a); | 121 | d = to_defact(*a); |
| 122 | ret = alloc_defdata(d, defdata); | 122 | ret = alloc_defdata(d, defdata); |
| 123 | if (ret < 0) { | 123 | if (ret < 0) { |
| 124 | tcf_idr_cleanup(*a, est); | 124 | tcf_idr_release(*a, bind); |
| 125 | return ret; | 125 | return ret; |
| 126 | } | 126 | } |
| 127 | d->tcf_action = parm->action; | 127 | d->tcf_action = parm->action; |
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index fa975262dbac..7b0700f52b50 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
| @@ -152,7 +152,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, | |||
| 152 | ASSERT_RTNL(); | 152 | ASSERT_RTNL(); |
| 153 | p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL); | 153 | p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL); |
| 154 | if (unlikely(!p)) { | 154 | if (unlikely(!p)) { |
| 155 | if (ovr) | 155 | if (ret == ACT_P_CREATED) |
| 156 | tcf_idr_release(*a, bind); | 156 | tcf_idr_release(*a, bind); |
| 157 | return -ENOMEM; | 157 | return -ENOMEM; |
| 158 | } | 158 | } |
| @@ -190,7 +190,8 @@ static void tcf_skbmod_cleanup(struct tc_action *a) | |||
| 190 | struct tcf_skbmod_params *p; | 190 | struct tcf_skbmod_params *p; |
| 191 | 191 | ||
| 192 | p = rcu_dereference_protected(d->skbmod_p, 1); | 192 | p = rcu_dereference_protected(d->skbmod_p, 1); |
| 193 | kfree_rcu(p, rcu); | 193 | if (p) |
| 194 | kfree_rcu(p, rcu); | ||
| 194 | } | 195 | } |
| 195 | 196 | ||
| 196 | static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, | 197 | static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, |
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 0e23aac09ad6..1281ca463727 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
| @@ -153,6 +153,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, | |||
| 153 | metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX; | 153 | metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX; |
| 154 | break; | 154 | break; |
| 155 | default: | 155 | default: |
| 156 | ret = -EINVAL; | ||
| 156 | goto err_out; | 157 | goto err_out; |
| 157 | } | 158 | } |
| 158 | 159 | ||
| @@ -207,11 +208,12 @@ static void tunnel_key_release(struct tc_action *a) | |||
| 207 | struct tcf_tunnel_key_params *params; | 208 | struct tcf_tunnel_key_params *params; |
| 208 | 209 | ||
| 209 | params = rcu_dereference_protected(t->params, 1); | 210 | params = rcu_dereference_protected(t->params, 1); |
| 211 | if (params) { | ||
| 212 | if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) | ||
| 213 | dst_release(¶ms->tcft_enc_metadata->dst); | ||
| 210 | 214 | ||
| 211 | if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) | 215 | kfree_rcu(params, rcu); |
| 212 | dst_release(¶ms->tcft_enc_metadata->dst); | 216 | } |
| 213 | |||
| 214 | kfree_rcu(params, rcu); | ||
| 215 | } | 217 | } |
| 216 | 218 | ||
| 217 | static int tunnel_key_dump_addresses(struct sk_buff *skb, | 219 | static int tunnel_key_dump_addresses(struct sk_buff *skb, |
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index e1a1b3f3983a..c49cb61adedf 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c | |||
| @@ -195,7 +195,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, | |||
| 195 | ASSERT_RTNL(); | 195 | ASSERT_RTNL(); |
| 196 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 196 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
| 197 | if (!p) { | 197 | if (!p) { |
| 198 | if (ovr) | 198 | if (ret == ACT_P_CREATED) |
| 199 | tcf_idr_release(*a, bind); | 199 | tcf_idr_release(*a, bind); |
| 200 | return -ENOMEM; | 200 | return -ENOMEM; |
| 201 | } | 201 | } |
| @@ -225,7 +225,8 @@ static void tcf_vlan_cleanup(struct tc_action *a) | |||
| 225 | struct tcf_vlan_params *p; | 225 | struct tcf_vlan_params *p; |
| 226 | 226 | ||
| 227 | p = rcu_dereference_protected(v->vlan_p, 1); | 227 | p = rcu_dereference_protected(v->vlan_p, 1); |
| 228 | kfree_rcu(p, rcu); | 228 | if (p) |
| 229 | kfree_rcu(p, rcu); | ||
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, | 232 | static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 190570f21b20..7e3fbe9cc936 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
| @@ -106,6 +106,14 @@ static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q, | |||
| 106 | 106 | ||
| 107 | __skb_queue_tail(&q->skb_bad_txq, skb); | 107 | __skb_queue_tail(&q->skb_bad_txq, skb); |
| 108 | 108 | ||
| 109 | if (qdisc_is_percpu_stats(q)) { | ||
| 110 | qdisc_qstats_cpu_backlog_inc(q, skb); | ||
| 111 | qdisc_qstats_cpu_qlen_inc(q); | ||
| 112 | } else { | ||
| 113 | qdisc_qstats_backlog_inc(q, skb); | ||
| 114 | q->q.qlen++; | ||
| 115 | } | ||
| 116 | |||
| 109 | if (lock) | 117 | if (lock) |
| 110 | spin_unlock(lock); | 118 | spin_unlock(lock); |
| 111 | } | 119 | } |
| @@ -196,14 +204,6 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q, | |||
| 196 | break; | 204 | break; |
| 197 | if (unlikely(skb_get_queue_mapping(nskb) != mapping)) { | 205 | if (unlikely(skb_get_queue_mapping(nskb) != mapping)) { |
| 198 | qdisc_enqueue_skb_bad_txq(q, nskb); | 206 | qdisc_enqueue_skb_bad_txq(q, nskb); |
| 199 | |||
| 200 | if (qdisc_is_percpu_stats(q)) { | ||
| 201 | qdisc_qstats_cpu_backlog_inc(q, nskb); | ||
| 202 | qdisc_qstats_cpu_qlen_inc(q); | ||
| 203 | } else { | ||
| 204 | qdisc_qstats_backlog_inc(q, nskb); | ||
| 205 | q->q.qlen++; | ||
| 206 | } | ||
| 207 | break; | 207 | break; |
| 208 | } | 208 | } |
| 209 | skb->next = nskb; | 209 | skb->next = nskb; |
| @@ -628,6 +628,7 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc, | |||
| 628 | int band = prio2band[skb->priority & TC_PRIO_MAX]; | 628 | int band = prio2band[skb->priority & TC_PRIO_MAX]; |
| 629 | struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | 629 | struct pfifo_fast_priv *priv = qdisc_priv(qdisc); |
| 630 | struct skb_array *q = band2list(priv, band); | 630 | struct skb_array *q = band2list(priv, band); |
| 631 | unsigned int pkt_len = qdisc_pkt_len(skb); | ||
| 631 | int err; | 632 | int err; |
| 632 | 633 | ||
| 633 | err = skb_array_produce(q, skb); | 634 | err = skb_array_produce(q, skb); |
| @@ -636,7 +637,10 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc, | |||
| 636 | return qdisc_drop_cpu(skb, qdisc, to_free); | 637 | return qdisc_drop_cpu(skb, qdisc, to_free); |
| 637 | 638 | ||
| 638 | qdisc_qstats_cpu_qlen_inc(qdisc); | 639 | qdisc_qstats_cpu_qlen_inc(qdisc); |
| 639 | qdisc_qstats_cpu_backlog_inc(qdisc, skb); | 640 | /* Note: skb can not be used after skb_array_produce(), |
| 641 | * so we better not use qdisc_qstats_cpu_backlog_inc() | ||
| 642 | */ | ||
| 643 | this_cpu_add(qdisc->cpu_qstats->backlog, pkt_len); | ||
| 640 | return NET_XMIT_SUCCESS; | 644 | return NET_XMIT_SUCCESS; |
| 641 | } | 645 | } |
| 642 | 646 | ||
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 7c179addebcd..7d6801fc5340 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -509,7 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | if (unlikely(sch->q.qlen >= sch->limit)) | 511 | if (unlikely(sch->q.qlen >= sch->limit)) |
| 512 | return qdisc_drop(skb, sch, to_free); | 512 | return qdisc_drop_all(skb, sch, to_free); |
| 513 | 513 | ||
| 514 | qdisc_qstats_backlog_inc(sch, skb); | 514 | qdisc_qstats_backlog_inc(sch, skb); |
| 515 | 515 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 0247cc432e02..b381d78548ac 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -106,6 +106,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 106 | int family; | 106 | int family; |
| 107 | struct sctp_af *af; | 107 | struct sctp_af *af; |
| 108 | struct net *net = dev_net(skb->dev); | 108 | struct net *net = dev_net(skb->dev); |
| 109 | bool is_gso = skb_is_gso(skb) && skb_is_gso_sctp(skb); | ||
| 109 | 110 | ||
| 110 | if (skb->pkt_type != PACKET_HOST) | 111 | if (skb->pkt_type != PACKET_HOST) |
| 111 | goto discard_it; | 112 | goto discard_it; |
| @@ -123,8 +124,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 123 | * it's better to just linearize it otherwise crc computing | 124 | * it's better to just linearize it otherwise crc computing |
| 124 | * takes longer. | 125 | * takes longer. |
| 125 | */ | 126 | */ |
| 126 | if ((!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) && | 127 | if ((!is_gso && skb_linearize(skb)) || |
| 127 | skb_linearize(skb)) || | ||
| 128 | !pskb_may_pull(skb, sizeof(struct sctphdr))) | 128 | !pskb_may_pull(skb, sizeof(struct sctphdr))) |
| 129 | goto discard_it; | 129 | goto discard_it; |
| 130 | 130 | ||
| @@ -135,7 +135,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 135 | if (skb_csum_unnecessary(skb)) | 135 | if (skb_csum_unnecessary(skb)) |
| 136 | __skb_decr_checksum_unnecessary(skb); | 136 | __skb_decr_checksum_unnecessary(skb); |
| 137 | else if (!sctp_checksum_disable && | 137 | else if (!sctp_checksum_disable && |
| 138 | !(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) && | 138 | !is_gso && |
| 139 | sctp_rcv_checksum(net, skb) < 0) | 139 | sctp_rcv_checksum(net, skb) < 0) |
| 140 | goto discard_it; | 140 | goto discard_it; |
| 141 | skb->csum_valid = 1; | 141 | skb->csum_valid = 1; |
| @@ -1218,7 +1218,7 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net, | |||
| 1218 | * issue as packets hitting this are mostly INIT or INIT-ACK and | 1218 | * issue as packets hitting this are mostly INIT or INIT-ACK and |
| 1219 | * those cannot be on GSO-style anyway. | 1219 | * those cannot be on GSO-style anyway. |
| 1220 | */ | 1220 | */ |
| 1221 | if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) | 1221 | if (skb_is_gso(skb) && skb_is_gso_sctp(skb)) |
| 1222 | return NULL; | 1222 | return NULL; |
| 1223 | 1223 | ||
| 1224 | ch = (struct sctp_chunkhdr *)skb->data; | 1224 | ch = (struct sctp_chunkhdr *)skb->data; |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 48392552ee7c..23ebc5318edc 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
| @@ -170,7 +170,7 @@ next_chunk: | |||
| 170 | 170 | ||
| 171 | chunk = list_entry(entry, struct sctp_chunk, list); | 171 | chunk = list_entry(entry, struct sctp_chunk, list); |
| 172 | 172 | ||
| 173 | if ((skb_shinfo(chunk->skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) { | 173 | if (skb_is_gso(chunk->skb) && skb_is_gso_sctp(chunk->skb)) { |
| 174 | /* GSO-marked skbs but without frags, handle | 174 | /* GSO-marked skbs but without frags, handle |
| 175 | * them normally | 175 | * them normally |
| 176 | */ | 176 | */ |
diff --git a/net/sctp/offload.c b/net/sctp/offload.c index 35bc7106d182..123e9f2dc226 100644 --- a/net/sctp/offload.c +++ b/net/sctp/offload.c | |||
| @@ -45,7 +45,7 @@ static struct sk_buff *sctp_gso_segment(struct sk_buff *skb, | |||
| 45 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 45 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
| 46 | struct sctphdr *sh; | 46 | struct sctphdr *sh; |
| 47 | 47 | ||
| 48 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP)) | 48 | if (!skb_is_gso_sctp(skb)) |
| 49 | goto out; | 49 | goto out; |
| 50 | 50 | ||
| 51 | sh = sctp_hdr(skb); | 51 | sh = sctp_hdr(skb); |
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 8cc97834d4f6..1e0d780855c3 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
| @@ -978,10 +978,6 @@ out: | |||
| 978 | lsmc->clcsock = NULL; | 978 | lsmc->clcsock = NULL; |
| 979 | } | 979 | } |
| 980 | release_sock(lsk); | 980 | release_sock(lsk); |
| 981 | /* no more listening, wake up smc_close_wait_listen_clcsock and | ||
| 982 | * accept | ||
| 983 | */ | ||
| 984 | lsk->sk_state_change(lsk); | ||
| 985 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ | 981 | sock_put(&lsmc->sk); /* sock_hold in smc_listen */ |
| 986 | } | 982 | } |
| 987 | 983 | ||
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index e339c0186dcf..fa41d9881741 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c | |||
| @@ -30,27 +30,6 @@ static void smc_close_cleanup_listen(struct sock *parent) | |||
| 30 | smc_close_non_accepted(sk); | 30 | smc_close_non_accepted(sk); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | static void smc_close_wait_listen_clcsock(struct smc_sock *smc) | ||
| 34 | { | ||
| 35 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
| 36 | struct sock *sk = &smc->sk; | ||
| 37 | signed long timeout; | ||
| 38 | |||
| 39 | timeout = SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME; | ||
| 40 | add_wait_queue(sk_sleep(sk), &wait); | ||
| 41 | do { | ||
| 42 | release_sock(sk); | ||
| 43 | if (smc->clcsock) | ||
| 44 | timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE, | ||
| 45 | timeout); | ||
| 46 | sched_annotate_sleep(); | ||
| 47 | lock_sock(sk); | ||
| 48 | if (!smc->clcsock) | ||
| 49 | break; | ||
| 50 | } while (timeout); | ||
| 51 | remove_wait_queue(sk_sleep(sk), &wait); | ||
| 52 | } | ||
| 53 | |||
| 54 | /* wait for sndbuf data being transmitted */ | 33 | /* wait for sndbuf data being transmitted */ |
| 55 | static void smc_close_stream_wait(struct smc_sock *smc, long timeout) | 34 | static void smc_close_stream_wait(struct smc_sock *smc, long timeout) |
| 56 | { | 35 | { |
| @@ -204,9 +183,11 @@ again: | |||
| 204 | rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); | 183 | rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); |
| 205 | /* wake up kernel_accept of smc_tcp_listen_worker */ | 184 | /* wake up kernel_accept of smc_tcp_listen_worker */ |
| 206 | smc->clcsock->sk->sk_data_ready(smc->clcsock->sk); | 185 | smc->clcsock->sk->sk_data_ready(smc->clcsock->sk); |
| 207 | smc_close_wait_listen_clcsock(smc); | ||
| 208 | } | 186 | } |
| 209 | smc_close_cleanup_listen(sk); | 187 | smc_close_cleanup_listen(sk); |
| 188 | release_sock(sk); | ||
| 189 | flush_work(&smc->tcp_listen_work); | ||
| 190 | lock_sock(sk); | ||
| 210 | break; | 191 | break; |
| 211 | case SMC_ACTIVE: | 192 | case SMC_ACTIVE: |
| 212 | smc_close_stream_wait(smc, timeout); | 193 | smc_close_stream_wait(smc, timeout); |
diff --git a/net/socket.c b/net/socket.c index a93c99b518ca..08847c3b8c39 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -2587,6 +2587,11 @@ void sock_unregister(int family) | |||
| 2587 | } | 2587 | } |
| 2588 | EXPORT_SYMBOL(sock_unregister); | 2588 | EXPORT_SYMBOL(sock_unregister); |
| 2589 | 2589 | ||
| 2590 | bool sock_is_registered(int family) | ||
| 2591 | { | ||
| 2592 | return family < NPROTO && rcu_access_pointer(net_families[family]); | ||
| 2593 | } | ||
| 2594 | |||
| 2590 | static int __init sock_init(void) | 2595 | static int __init sock_init(void) |
| 2591 | { | 2596 | { |
| 2592 | int err; | 2597 | int err; |
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index ccfdc7115a83..a00ec715aa46 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c | |||
| @@ -283,7 +283,7 @@ static struct crypto_comp * __percpu *ipcomp_alloc_tfms(const char *alg_name) | |||
| 283 | struct crypto_comp *tfm; | 283 | struct crypto_comp *tfm; |
| 284 | 284 | ||
| 285 | /* This can be any valid CPU ID so we don't need locking. */ | 285 | /* This can be any valid CPU ID so we don't need locking. */ |
| 286 | tfm = __this_cpu_read(*pos->tfms); | 286 | tfm = this_cpu_read(*pos->tfms); |
| 287 | 287 | ||
| 288 | if (!strcmp(crypto_comp_name(tfm), alg_name)) { | 288 | if (!strcmp(crypto_comp_name(tfm), alg_name)) { |
| 289 | pos->users++; | 289 | pos->users++; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 7a23078132cf..625b3fca5704 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1458,10 +1458,13 @@ xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, const struct flowi *fl, | |||
| 1458 | static int xfrm_get_tos(const struct flowi *fl, int family) | 1458 | static int xfrm_get_tos(const struct flowi *fl, int family) |
| 1459 | { | 1459 | { |
| 1460 | const struct xfrm_policy_afinfo *afinfo; | 1460 | const struct xfrm_policy_afinfo *afinfo; |
| 1461 | int tos = 0; | 1461 | int tos; |
| 1462 | 1462 | ||
| 1463 | afinfo = xfrm_policy_get_afinfo(family); | 1463 | afinfo = xfrm_policy_get_afinfo(family); |
| 1464 | tos = afinfo ? afinfo->get_tos(fl) : 0; | 1464 | if (!afinfo) |
| 1465 | return 0; | ||
| 1466 | |||
| 1467 | tos = afinfo->get_tos(fl); | ||
| 1465 | 1468 | ||
| 1466 | rcu_read_unlock(); | 1469 | rcu_read_unlock(); |
| 1467 | 1470 | ||
| @@ -1891,7 +1894,7 @@ static void xfrm_policy_queue_process(struct timer_list *t) | |||
| 1891 | spin_unlock(&pq->hold_queue.lock); | 1894 | spin_unlock(&pq->hold_queue.lock); |
| 1892 | 1895 | ||
| 1893 | dst_hold(xfrm_dst_path(dst)); | 1896 | dst_hold(xfrm_dst_path(dst)); |
| 1894 | dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0); | 1897 | dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, XFRM_LOOKUP_QUEUE); |
| 1895 | if (IS_ERR(dst)) | 1898 | if (IS_ERR(dst)) |
| 1896 | goto purge_queue; | 1899 | goto purge_queue; |
| 1897 | 1900 | ||
| @@ -2729,14 +2732,14 @@ static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst, | |||
| 2729 | while (dst->xfrm) { | 2732 | while (dst->xfrm) { |
| 2730 | const struct xfrm_state *xfrm = dst->xfrm; | 2733 | const struct xfrm_state *xfrm = dst->xfrm; |
| 2731 | 2734 | ||
| 2735 | dst = xfrm_dst_child(dst); | ||
| 2736 | |||
| 2732 | if (xfrm->props.mode == XFRM_MODE_TRANSPORT) | 2737 | if (xfrm->props.mode == XFRM_MODE_TRANSPORT) |
| 2733 | continue; | 2738 | continue; |
| 2734 | if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR) | 2739 | if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR) |
| 2735 | daddr = xfrm->coaddr; | 2740 | daddr = xfrm->coaddr; |
| 2736 | else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) | 2741 | else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR)) |
| 2737 | daddr = &xfrm->id.daddr; | 2742 | daddr = &xfrm->id.daddr; |
| 2738 | |||
| 2739 | dst = xfrm_dst_child(dst); | ||
| 2740 | } | 2743 | } |
| 2741 | return daddr; | 2744 | return daddr; |
| 2742 | } | 2745 | } |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 1d38c6acf8af..9e3a5e85f828 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
| @@ -660,7 +660,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff | |||
| 660 | } else { | 660 | } else { |
| 661 | XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; | 661 | XFRM_SKB_CB(skb)->seq.output.low = oseq + 1; |
| 662 | XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; | 662 | XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; |
| 663 | xo->seq.low = oseq = oseq + 1; | 663 | xo->seq.low = oseq + 1; |
| 664 | xo->seq.hi = oseq_hi; | 664 | xo->seq.hi = oseq_hi; |
| 665 | oseq += skb_shinfo(skb)->gso_segs; | 665 | oseq += skb_shinfo(skb)->gso_segs; |
| 666 | } | 666 | } |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 54e21f19d722..f9d2f2233f09 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -2056,6 +2056,11 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen | |||
| 2056 | struct xfrm_mgr *km; | 2056 | struct xfrm_mgr *km; |
| 2057 | struct xfrm_policy *pol = NULL; | 2057 | struct xfrm_policy *pol = NULL; |
| 2058 | 2058 | ||
| 2059 | #ifdef CONFIG_COMPAT | ||
| 2060 | if (in_compat_syscall()) | ||
| 2061 | return -EOPNOTSUPP; | ||
| 2062 | #endif | ||
| 2063 | |||
| 2059 | if (!optval && !optlen) { | 2064 | if (!optval && !optlen) { |
| 2060 | xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); | 2065 | xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); |
| 2061 | xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL); | 2066 | xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 7f52b8eb177d..080035f056d9 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -121,22 +121,17 @@ static inline int verify_replay(struct xfrm_usersa_info *p, | |||
| 121 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; | 121 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; |
| 122 | struct xfrm_replay_state_esn *rs; | 122 | struct xfrm_replay_state_esn *rs; |
| 123 | 123 | ||
| 124 | if (p->flags & XFRM_STATE_ESN) { | 124 | if (!rt) |
| 125 | if (!rt) | 125 | return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0; |
| 126 | return -EINVAL; | ||
| 127 | 126 | ||
| 128 | rs = nla_data(rt); | 127 | rs = nla_data(rt); |
| 129 | 128 | ||
| 130 | if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) | 129 | if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) |
| 131 | return -EINVAL; | 130 | return -EINVAL; |
| 132 | |||
| 133 | if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) && | ||
| 134 | nla_len(rt) != sizeof(*rs)) | ||
| 135 | return -EINVAL; | ||
| 136 | } | ||
| 137 | 131 | ||
| 138 | if (!rt) | 132 | if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) && |
| 139 | return 0; | 133 | nla_len(rt) != sizeof(*rs)) |
| 134 | return -EINVAL; | ||
| 140 | 135 | ||
| 141 | /* As only ESP and AH support ESN feature. */ | 136 | /* As only ESP and AH support ESN feature. */ |
| 142 | if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH)) | 137 | if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH)) |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 0333143a1fa7..1063a4377502 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
| @@ -192,6 +192,11 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm) | |||
| 192 | dpcm->timer.expires = 0; | 192 | dpcm->timer.expires = 0; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static inline void loopback_timer_stop_sync(struct loopback_pcm *dpcm) | ||
| 196 | { | ||
| 197 | del_timer_sync(&dpcm->timer); | ||
| 198 | } | ||
| 199 | |||
| 195 | #define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK) | 200 | #define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK) |
| 196 | #define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE) | 201 | #define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE) |
| 197 | #define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE) | 202 | #define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE) |
| @@ -326,6 +331,8 @@ static int loopback_prepare(struct snd_pcm_substream *substream) | |||
| 326 | struct loopback_cable *cable = dpcm->cable; | 331 | struct loopback_cable *cable = dpcm->cable; |
| 327 | int bps, salign; | 332 | int bps, salign; |
| 328 | 333 | ||
| 334 | loopback_timer_stop_sync(dpcm); | ||
| 335 | |||
| 329 | salign = (snd_pcm_format_width(runtime->format) * | 336 | salign = (snd_pcm_format_width(runtime->format) * |
| 330 | runtime->channels) / 8; | 337 | runtime->channels) / 8; |
| 331 | bps = salign * runtime->rate; | 338 | bps = salign * runtime->rate; |
| @@ -659,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream) | |||
| 659 | return; | 666 | return; |
| 660 | if (cable->streams[!substream->stream]) { | 667 | if (cable->streams[!substream->stream]) { |
| 661 | /* other stream is still alive */ | 668 | /* other stream is still alive */ |
| 669 | spin_lock_irq(&cable->lock); | ||
| 662 | cable->streams[substream->stream] = NULL; | 670 | cable->streams[substream->stream] = NULL; |
| 671 | spin_unlock_irq(&cable->lock); | ||
| 663 | } else { | 672 | } else { |
| 664 | /* free the cable */ | 673 | /* free the cable */ |
| 665 | loopback->cables[substream->number][dev] = NULL; | 674 | loopback->cables[substream->number][dev] = NULL; |
| @@ -698,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream) | |||
| 698 | loopback->cables[substream->number][dev] = cable; | 707 | loopback->cables[substream->number][dev] = cable; |
| 699 | } | 708 | } |
| 700 | dpcm->cable = cable; | 709 | dpcm->cable = cable; |
| 701 | cable->streams[substream->stream] = dpcm; | ||
| 702 | 710 | ||
| 703 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 711 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
| 704 | 712 | ||
| @@ -730,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream) | |||
| 730 | runtime->hw = loopback_pcm_hardware; | 738 | runtime->hw = loopback_pcm_hardware; |
| 731 | else | 739 | else |
| 732 | runtime->hw = cable->hw; | 740 | runtime->hw = cable->hw; |
| 741 | |||
| 742 | spin_lock_irq(&cable->lock); | ||
| 743 | cable->streams[substream->stream] = dpcm; | ||
| 744 | spin_unlock_irq(&cable->lock); | ||
| 745 | |||
| 733 | unlock: | 746 | unlock: |
| 734 | if (err < 0) { | 747 | if (err < 0) { |
| 735 | free_cable(substream); | 748 | free_cable(substream); |
| @@ -744,7 +757,7 @@ static int loopback_close(struct snd_pcm_substream *substream) | |||
| 744 | struct loopback *loopback = substream->private_data; | 757 | struct loopback *loopback = substream->private_data; |
| 745 | struct loopback_pcm *dpcm = substream->runtime->private_data; | 758 | struct loopback_pcm *dpcm = substream->runtime->private_data; |
| 746 | 759 | ||
| 747 | loopback_timer_stop(dpcm); | 760 | loopback_timer_stop_sync(dpcm); |
| 748 | mutex_lock(&loopback->cable_lock); | 761 | mutex_lock(&loopback->cable_lock); |
| 749 | free_cable(substream); | 762 | free_cable(substream); |
| 750 | mutex_unlock(&loopback->cable_lock); | 763 | mutex_unlock(&loopback->cable_lock); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d5017adf9feb..c507c69029e3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -375,6 +375,7 @@ enum { | |||
| 375 | ((pci)->device == 0x160c)) | 375 | ((pci)->device == 0x160c)) |
| 376 | 376 | ||
| 377 | #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) | 377 | #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) |
| 378 | #define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348) | ||
| 378 | 379 | ||
| 379 | static char *driver_short_names[] = { | 380 | static char *driver_short_names[] = { |
| 380 | [AZX_DRIVER_ICH] = "HDA Intel", | 381 | [AZX_DRIVER_ICH] = "HDA Intel", |
| @@ -1744,6 +1745,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1744 | else | 1745 | else |
| 1745 | chip->bdl_pos_adj = bdl_pos_adj[dev]; | 1746 | chip->bdl_pos_adj = bdl_pos_adj[dev]; |
| 1746 | 1747 | ||
| 1748 | /* Workaround for a communication error on CFL (bko#199007) */ | ||
| 1749 | if (IS_CFL(pci)) | ||
| 1750 | chip->polling_mode = 1; | ||
| 1751 | |||
| 1747 | err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); | 1752 | err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); |
| 1748 | if (err < 0) { | 1753 | if (err < 0) { |
| 1749 | kfree(hda); | 1754 | kfree(hda); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9af301c6bba2..aef1f52db7d9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -3130,6 +3130,8 @@ static void alc256_init(struct hda_codec *codec) | |||
| 3130 | 3130 | ||
| 3131 | alc_update_coef_idx(codec, 0x46, 3 << 12, 0); | 3131 | alc_update_coef_idx(codec, 0x46, 3 << 12, 0); |
| 3132 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ | 3132 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ |
| 3133 | alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */ | ||
| 3134 | alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15); | ||
| 3133 | } | 3135 | } |
| 3134 | 3136 | ||
| 3135 | static void alc256_shutup(struct hda_codec *codec) | 3137 | static void alc256_shutup(struct hda_codec *codec) |
| @@ -3596,8 +3598,12 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | |||
| 3596 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); | 3598 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); |
| 3597 | pinval &= ~AC_PINCTL_VREFEN; | 3599 | pinval &= ~AC_PINCTL_VREFEN; |
| 3598 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; | 3600 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; |
| 3599 | if (spec->mute_led_nid) | 3601 | if (spec->mute_led_nid) { |
| 3602 | /* temporarily power up/down for setting VREF */ | ||
| 3603 | snd_hda_power_up_pm(codec); | ||
| 3600 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); | 3604 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); |
| 3605 | snd_hda_power_down_pm(codec); | ||
| 3606 | } | ||
| 3601 | } | 3607 | } |
| 3602 | 3608 | ||
| 3603 | /* Make sure the led works even in runtime suspend */ | 3609 | /* Make sure the led works even in runtime suspend */ |
| @@ -5497,6 +5503,7 @@ enum { | |||
| 5497 | ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, | 5503 | ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, |
| 5498 | ALC298_FIXUP_TPT470_DOCK, | 5504 | ALC298_FIXUP_TPT470_DOCK, |
| 5499 | ALC255_FIXUP_DUMMY_LINEOUT_VERB, | 5505 | ALC255_FIXUP_DUMMY_LINEOUT_VERB, |
| 5506 | ALC255_FIXUP_DELL_HEADSET_MIC, | ||
| 5500 | }; | 5507 | }; |
| 5501 | 5508 | ||
| 5502 | static const struct hda_fixup alc269_fixups[] = { | 5509 | static const struct hda_fixup alc269_fixups[] = { |
| @@ -6357,6 +6364,13 @@ static const struct hda_fixup alc269_fixups[] = { | |||
| 6357 | .chained = true, | 6364 | .chained = true, |
| 6358 | .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE | 6365 | .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE |
| 6359 | }, | 6366 | }, |
| 6367 | [ALC255_FIXUP_DELL_HEADSET_MIC] = { | ||
| 6368 | .type = HDA_FIXUP_PINS, | ||
| 6369 | .v.pins = (const struct hda_pintbl[]) { | ||
| 6370 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
| 6371 | { } | ||
| 6372 | }, | ||
| 6373 | }, | ||
| 6360 | }; | 6374 | }; |
| 6361 | 6375 | ||
| 6362 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 6376 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -6411,6 +6425,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 6411 | SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), | 6425 | SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), |
| 6412 | SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), | 6426 | SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), |
| 6413 | SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), | 6427 | SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), |
| 6428 | SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), | ||
| 6429 | SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), | ||
| 6414 | SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), | 6430 | SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), |
| 6415 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 6431 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 6416 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | 6432 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), |
| @@ -7154,6 +7170,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
| 7154 | break; | 7170 | break; |
| 7155 | case 0x10ec0257: | 7171 | case 0x10ec0257: |
| 7156 | spec->codec_variant = ALC269_TYPE_ALC257; | 7172 | spec->codec_variant = ALC269_TYPE_ALC257; |
| 7173 | spec->shutup = alc256_shutup; | ||
| 7174 | spec->init_hook = alc256_init; | ||
| 7157 | spec->gen.mixer_nid = 0; | 7175 | spec->gen.mixer_nid = 0; |
| 7158 | break; | 7176 | break; |
| 7159 | case 0x10ec0215: | 7177 | case 0x10ec0215: |
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 0b482c0070e0..465995281dcd 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c | |||
| @@ -55,6 +55,10 @@ | |||
| 55 | 55 | ||
| 56 | #include "main.h" | 56 | #include "main.h" |
| 57 | 57 | ||
| 58 | #ifndef BPF_FS_MAGIC | ||
| 59 | #define BPF_FS_MAGIC 0xcafe4a11 | ||
| 60 | #endif | ||
| 61 | |||
| 58 | void p_err(const char *fmt, ...) | 62 | void p_err(const char *fmt, ...) |
| 59 | { | 63 | { |
| 60 | va_list ap; | 64 | va_list ap; |
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc new file mode 100644 index 000000000000..5ba73035e1d9 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # description: Kprobe event string type argument | ||
| 4 | |||
| 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
| 6 | |||
| 7 | echo 0 > events/enable | ||
| 8 | echo > kprobe_events | ||
| 9 | |||
| 10 | case `uname -m` in | ||
| 11 | x86_64) | ||
| 12 | ARG2=%si | ||
| 13 | OFFS=8 | ||
| 14 | ;; | ||
| 15 | i[3456]86) | ||
| 16 | ARG2=%cx | ||
| 17 | OFFS=4 | ||
| 18 | ;; | ||
| 19 | aarch64) | ||
| 20 | ARG2=%x1 | ||
| 21 | OFFS=8 | ||
| 22 | ;; | ||
| 23 | arm*) | ||
| 24 | ARG2=%r1 | ||
| 25 | OFFS=4 | ||
| 26 | ;; | ||
| 27 | *) | ||
| 28 | echo "Please implement other architecture here" | ||
| 29 | exit_untested | ||
| 30 | esac | ||
| 31 | |||
| 32 | : "Test get argument (1)" | ||
| 33 | echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events | ||
| 34 | echo 1 > events/kprobes/testprobe/enable | ||
| 35 | ! echo test >> kprobe_events | ||
| 36 | tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\"" | ||
| 37 | |||
| 38 | echo 0 > events/kprobes/testprobe/enable | ||
| 39 | : "Test get argument (2)" | ||
| 40 | echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events | ||
| 41 | echo 1 > events/kprobes/testprobe/enable | ||
| 42 | ! echo test1 test2 >> kprobe_events | ||
| 43 | tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\"" | ||
| 44 | |||
| 45 | echo 0 > events/enable | ||
| 46 | echo > kprobe_events | ||
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc new file mode 100644 index 000000000000..231bcd2c4eb5 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # description: Kprobe event argument syntax | ||
| 4 | |||
| 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
| 6 | |||
| 7 | grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue | ||
| 8 | |||
| 9 | echo 0 > events/enable | ||
| 10 | echo > kprobe_events | ||
| 11 | |||
| 12 | PROBEFUNC="vfs_read" | ||
| 13 | GOODREG= | ||
| 14 | BADREG= | ||
| 15 | GOODSYM="_sdata" | ||
| 16 | if ! grep -qw ${GOODSYM} /proc/kallsyms ; then | ||
| 17 | GOODSYM=$PROBEFUNC | ||
| 18 | fi | ||
| 19 | BADSYM="deaqswdefr" | ||
| 20 | SYMADDR=0x`grep -w ${GOODSYM} /proc/kallsyms | cut -f 1 -d " "` | ||
| 21 | GOODTYPE="x16" | ||
| 22 | BADTYPE="y16" | ||
| 23 | |||
| 24 | case `uname -m` in | ||
| 25 | x86_64|i[3456]86) | ||
| 26 | GOODREG=%ax | ||
| 27 | BADREG=%ex | ||
| 28 | ;; | ||
| 29 | aarch64) | ||
| 30 | GOODREG=%x0 | ||
| 31 | BADREG=%ax | ||
| 32 | ;; | ||
| 33 | arm*) | ||
| 34 | GOODREG=%r0 | ||
| 35 | BADREG=%ax | ||
| 36 | ;; | ||
| 37 | esac | ||
| 38 | |||
| 39 | test_goodarg() # Good-args | ||
| 40 | { | ||
| 41 | while [ "$1" ]; do | ||
| 42 | echo "p ${PROBEFUNC} $1" > kprobe_events | ||
| 43 | shift 1 | ||
| 44 | done; | ||
| 45 | } | ||
| 46 | |||
| 47 | test_badarg() # Bad-args | ||
| 48 | { | ||
| 49 | while [ "$1" ]; do | ||
| 50 | ! echo "p ${PROBEFUNC} $1" > kprobe_events | ||
| 51 | shift 1 | ||
| 52 | done; | ||
| 53 | } | ||
| 54 | |||
| 55 | echo > kprobe_events | ||
| 56 | |||
| 57 | : "Register access" | ||
| 58 | test_goodarg ${GOODREG} | ||
| 59 | test_badarg ${BADREG} | ||
| 60 | |||
| 61 | : "Symbol access" | ||
| 62 | test_goodarg "@${GOODSYM}" "@${SYMADDR}" "@${GOODSYM}+10" "@${GOODSYM}-10" | ||
| 63 | test_badarg "@" "@${BADSYM}" "@${GOODSYM}*10" "@${GOODSYM}/10" \ | ||
| 64 | "@${GOODSYM}%10" "@${GOODSYM}&10" "@${GOODSYM}|10" | ||
| 65 | |||
| 66 | : "Stack access" | ||
| 67 | test_goodarg "\$stack" "\$stack0" "\$stack1" | ||
| 68 | test_badarg "\$stackp" "\$stack0+10" "\$stack1-10" | ||
| 69 | |||
| 70 | : "Retval access" | ||
| 71 | echo "r ${PROBEFUNC} \$retval" > kprobe_events | ||
| 72 | ! echo "p ${PROBEFUNC} \$retval" > kprobe_events | ||
| 73 | |||
| 74 | : "Comm access" | ||
| 75 | test_goodarg "\$comm" | ||
| 76 | |||
| 77 | : "Indirect memory access" | ||
| 78 | test_goodarg "+0(${GOODREG})" "-0(${GOODREG})" "+10(\$stack)" \ | ||
| 79 | "+0(\$stack1)" "+10(@${GOODSYM}-10)" "+0(+10(+20(\$stack)))" | ||
| 80 | test_badarg "+(${GOODREG})" "(${GOODREG}+10)" "-(${GOODREG})" "(${GOODREG})" \ | ||
| 81 | "+10(\$comm)" "+0(${GOODREG})+10" | ||
| 82 | |||
| 83 | : "Name assignment" | ||
| 84 | test_goodarg "varname=${GOODREG}" | ||
| 85 | test_badarg "varname=varname2=${GOODREG}" | ||
| 86 | |||
| 87 | : "Type syntax" | ||
| 88 | test_goodarg "${GOODREG}:${GOODTYPE}" | ||
| 89 | test_badarg "${GOODREG}::${GOODTYPE}" "${GOODREG}:${BADTYPE}" \ | ||
| 90 | "${GOODTYPE}:${GOODREG}" | ||
| 91 | |||
| 92 | : "Combination check" | ||
| 93 | |||
| 94 | test_goodarg "\$comm:string" "+0(\$stack):string" | ||
| 95 | test_badarg "\$comm:x64" "\$stack:string" "${GOODREG}:string" | ||
| 96 | |||
| 97 | echo > kprobe_events | ||
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc b/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc new file mode 100644 index 000000000000..4fda01a08da4 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # description: Kprobe events - probe points | ||
| 4 | |||
| 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
| 6 | |||
| 7 | TARGET_FUNC=create_trace_kprobe | ||
| 8 | |||
| 9 | dec_addr() { # hexaddr | ||
| 10 | printf "%d" "0x"`echo $1 | tail -c 8` | ||
| 11 | } | ||
| 12 | |||
| 13 | set_offs() { # prev target next | ||
| 14 | A1=`dec_addr $1` | ||
| 15 | A2=`dec_addr $2` | ||
| 16 | A3=`dec_addr $3` | ||
| 17 | TARGET="0x$2" # an address | ||
| 18 | PREV=`expr $A1 - $A2` # offset to previous symbol | ||
| 19 | NEXT=+`expr $A3 - $A2` # offset to next symbol | ||
| 20 | OVERFLOW=+`printf "0x%x" ${PREV}` # overflow offset to previous symbol | ||
| 21 | } | ||
| 22 | |||
| 23 | # We have to decode symbol addresses to get correct offsets. | ||
| 24 | # If the offset is not an instruction boundary, it cause -EILSEQ. | ||
| 25 | set_offs `grep -A1 -B1 ${TARGET_FUNC} /proc/kallsyms | cut -f 1 -d " " | xargs` | ||
| 26 | |||
| 27 | UINT_TEST=no | ||
| 28 | # printf "%x" -1 returns (unsigned long)-1. | ||
| 29 | if [ `printf "%x" -1 | wc -c` != 9 ]; then | ||
| 30 | UINT_TEST=yes | ||
| 31 | fi | ||
| 32 | |||
| 33 | echo 0 > events/enable | ||
| 34 | echo > kprobe_events | ||
| 35 | echo "p:testprobe ${TARGET_FUNC}" > kprobe_events | ||
| 36 | echo "p:testprobe ${TARGET}" > kprobe_events | ||
| 37 | echo "p:testprobe ${TARGET_FUNC}${NEXT}" > kprobe_events | ||
| 38 | ! echo "p:testprobe ${TARGET_FUNC}${PREV}" > kprobe_events | ||
| 39 | if [ "${UINT_TEST}" = yes ]; then | ||
| 40 | ! echo "p:testprobe ${TARGET_FUNC}${OVERFLOW}" > kprobe_events | ||
| 41 | fi | ||
| 42 | echo > kprobe_events | ||
| 43 | clear_trace | ||
