diff --git a/Documentation/ABI/stable/sysfs-driver-dma-idxd b/Documentation/ABI/stable/sysfs-driver-dma-idxd index 825e619250bf..f2ec42949a54 100644 --- a/Documentation/ABI/stable/sysfs-driver-dma-idxd +++ b/Documentation/ABI/stable/sysfs-driver-dma-idxd @@ -270,6 +270,12 @@ Description: Shows the operation capability bits displayed in bitmap format correlates to the operations allowed. It's visible only on platforms that support the capability. +What: /sys/bus/dsa/devices/wq./driver_name +Date: Sept 8, 2023 +KernelVersion: 6.7.0 +Contact: dmaengine@vger.kernel.org +Description: Name of driver to be bounded to the wq. + What: /sys/bus/dsa/devices/engine./group_id Date: Oct 25, 2019 KernelVersion: 5.6.0 diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 3371c39f651d..a2bf4fd82a5b 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -35,4 +35,6 @@ Description: req_number the number of pre-allocated requests for both capture and playback function_name name of the interface + c_terminal_type code of the capture terminal type + p_terminal_type code of the playback terminal type ===================== ======================================= diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index a44bfe020061..2b7108e21977 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -313,6 +313,15 @@ Description: Inter-Chip SSIC devices support asymmetric lanes up to 4 lanes per direction. Devices before USB 3.2 are single lane (tx_lanes = 1) +What: /sys/bus/usb/devices/.../typec +Date: November 2023 +Contact: Heikki Krogerus +Description: + Symlink to the USB Type-C partner device. USB Type-C partner + represents the component that communicates over the + Configuration Channel (CC signal on USB Type-C connectors and + cables) with the local port. + What: /sys/bus/usb/devices/usbX/bAlternateSetting Description: The current interface alternate setting number, in decimal. diff --git a/Documentation/ABI/testing/sysfs-class-usb_power_delivery b/Documentation/ABI/testing/sysfs-class-usb_power_delivery index 1bf9d1d7902c..61d233c320ea 100644 --- a/Documentation/ABI/testing/sysfs-class-usb_power_delivery +++ b/Documentation/ABI/testing/sysfs-class-usb_power_delivery @@ -124,6 +124,13 @@ Contact: Heikki Krogerus Description: The voltage the supply supports in millivolts. +What: /sys/class/usb_power_delivery/.../source-capabilities/:fixed_supply/peak_current +Date: October 2023 +Contact: Heikki Krogerus +Description: + This file shows the value of the Fixed Power Source Peak Current + Capability field. + What: /sys/class/usb_power_delivery/.../source-capabilities/:fixed_supply/maximum_current Date: May 2022 Contact: Heikki Krogerus diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 820e412d38a8..895c47f05f6f 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -87,19 +87,22 @@ What: /sys/class/tty/ttyS/close_delay Date: October 2012 Contact: Alan Cox Description: - Show the closing delay time for this port in ms. + Show the closing delay time for this port in centiseconds. - These sysfs values expose the TIOCGSERIAL interface via - sysfs rather than via ioctls. + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. What: /sys/class/tty/ttyS/closing_wait Date: October 2012 Contact: Alan Cox Description: - Show the close wait time for this port in ms. + Show the close wait time for this port in centiseconds. - These sysfs values expose the TIOCGSERIAL interface via - sysfs rather than via ioctls. + Waiting forever is represented as 0. If waiting on close is + disabled then the value is 65535. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. What: /sys/class/tty/ttyS/custom_divisor Date: October 2012 diff --git a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml index f61145c91b6d..88d0de3d1b46 100644 --- a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml +++ b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml @@ -69,6 +69,8 @@ properties: dma-channel-mask: maxItems: 1 + dma-coherent: true + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml index f99fbbcd68fb..d58dd744d5d2 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml @@ -20,6 +20,7 @@ properties: - qcom,qcm2290-qmp-usb3-phy - qcom,sa8775p-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy + - qcom,sdx75-qmp-usb3-uni-phy - qcom,sm6115-qmp-usb3-phy reg: @@ -75,6 +76,7 @@ allOf: contains: enum: - qcom,ipq9574-qmp-usb3-phy + - qcom,sdx75-qmp-usb3-uni-phy then: properties: clock-names: diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml index c53bab107b6d..c95828607ab6 100644 --- a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-phy.yaml @@ -14,7 +14,12 @@ description: properties: compatible: - const: qcom,sm8550-snps-eusb2-phy + oneOf: + - items: + - enum: + - qcom,sdx75-snps-eusb2-phy + - const: qcom,sm8550-snps-eusb2-phy + - const: qcom,sm8550-snps-eusb2-phy reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml b/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml new file mode 100644 index 000000000000..77fbb2c72171 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/esp,esp32-acm.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/esp,esp32-acm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESP32S3 ACM gadget controller + +maintainers: + - Max Filippov + +description: + Fixed function USB CDC-ACM gadget controller of the Espressif ESP32S3 SoC. + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + const: esp,esp32s3-acm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + serial@60038000 { + compatible = "esp,esp32s3-acm"; + reg = <0x60038000 0x1000>; + interrupts = <96 3 0>; + }; diff --git a/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml b/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml new file mode 100644 index 000000000000..2a80ca997a0c --- /dev/null +++ b/Documentation/devicetree/bindings/serial/esp,esp32-uart.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/esp,esp32-uart.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESP32xx UART controllers + +maintainers: + - Max Filippov + +description: + ESP32 UART controller is a part of the ESP32 SoC. + ESP32S3 UART controller is a part of the ESP32S3 SoC. + Both SoCs are produced by Espressif Systems Co. Ltd. + +allOf: + - $ref: serial.yaml# + +properties: + compatible: + enum: + - esp,esp32-uart + - esp,esp32s3-uart + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + serial@60000000 { + compatible = "esp,esp32s3-uart"; + reg = <0x60000000 0x80>; + interrupts = <27 1 0>; + clocks = <&serial_clk>; + }; diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml index 40414247d61a..83035553044a 100644 --- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml @@ -70,6 +70,8 @@ properties: interrupts: maxItems: 1 + wakeup-source: true + fsl,dte-mode: $ref: /schemas/types.yaml#/definitions/flag description: | diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml index 6a400a5e6fc7..da032effffe6 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.yaml @@ -14,10 +14,13 @@ allOf: properties: compatible: - enum: - - fsl,imx23-auart - - fsl,imx28-auart - - alphascale,asm9260-auart + oneOf: + - const: fsl,imx23-auart + - const: alphascale,asm9260-auart + - items: + - enum: + - fsl,imx28-auart + - const: fsl,imx23-auart reg: maxItems: 1 @@ -82,7 +85,7 @@ examples: }; auart0: serial@8006a000 { - compatible = "fsl,imx28-auart"; + compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.txt b/Documentation/devicetree/bindings/serial/maxim,max310x.txt deleted file mode 100644 index 79e10a05a96a..000000000000 --- a/Documentation/devicetree/bindings/serial/maxim,max310x.txt +++ /dev/null @@ -1,48 +0,0 @@ -* Maxim MAX310X advanced Universal Asynchronous Receiver-Transmitter (UART) - -Required properties: -- compatible: Should be one of the following: - - "maxim,max3107" for Maxim MAX3107, - - "maxim,max3108" for Maxim MAX3108, - - "maxim,max3109" for Maxim MAX3109, - - "maxim,max14830" for Maxim MAX14830. -- reg: SPI chip select number. -- interrupts: Specifies the interrupt source of the parent interrupt - controller. The format of the interrupt specifier depends on the - parent interrupt controller. -- clocks: phandle to the IC source clock. -- clock-names: Should be "xtal" if clock is an external crystal or - "osc" if an external clock source is used. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. - -Example: - -/ { - clocks { - spi_uart_clk: osc_max14830 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <3686400>; - }; - - }; -}; - -&spi0 { - max14830: max14830@0 { - compatible = "maxim,max14830"; - reg = <0>; - clocks = <&spi_uart_clk>; - clock-names = "osc"; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - gpio-controller; - #gpio-cells = <2>; - }; -}; diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.yaml b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml new file mode 100644 index 000000000000..889eeaca64a0 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/maxim,max310x.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/maxim,max310x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Maxim MAX310X Advanced Universal Asynchronous Receiver-Transmitter (UART) + +maintainers: + - Hugo Villeneuve + +properties: + compatible: + enum: + - maxim,max3107 + - maxim,max3108 + - maxim,max3109 + - maxim,max14830 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + enum: + - xtal # External crystal + - osc # External clock source + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 16 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/serial/rs485.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + serial@2c { + compatible = "maxim,max3107"; + reg = <0x2c>; + clocks = <&xtal4m>; + clock-names = "xtal"; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + gpio-controller; + #gpio-cells = <2>; + }; + }; diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml index 04d55fecf47c..a5d67563cd53 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.yaml @@ -91,11 +91,6 @@ properties: - description: range upper bound - description: adjustment (in permyriad, i.e. 0.01%) -allOf: - - $ref: serial.yaml - -unevaluatedProperties: false - required: - compatible - reg @@ -106,6 +101,11 @@ required: - dmas - dma-names +allOf: + - $ref: serial.yaml + +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt deleted file mode 100644 index 1a7e4bff0456..000000000000 --- a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt +++ /dev/null @@ -1,118 +0,0 @@ -* NXP SC16IS7xx advanced Universal Asynchronous Receiver-Transmitter (UART) -* i2c as bus - -Required properties: -- compatible: Should be one of the following: - - "nxp,sc16is740" for NXP SC16IS740, - - "nxp,sc16is741" for NXP SC16IS741, - - "nxp,sc16is750" for NXP SC16IS750, - - "nxp,sc16is752" for NXP SC16IS752, - - "nxp,sc16is760" for NXP SC16IS760, - - "nxp,sc16is762" for NXP SC16IS762. -- reg: I2C address of the SC16IS7xx device. -- interrupts: Should contain the UART interrupt -- clocks: Reference to the IC source clock. - OR (when there is no clock provider visible to the platform) -- clock-frequency: The source clock frequency for the IC. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. -- irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -- nxp,modem-control-line-ports: An array that lists the indices of the port that - should have shared GPIO lines configured as - modem control lines. - -Example: - sc16is750: sc16is750@51 { - compatible = "nxp,sc16is750"; - reg = <0x51>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - gpio-controller; - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@53 { - compatible = "nxp,sc16is752"; - reg = <0x53>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ - gpio-controller; /* Port 0 as GPIOs */ - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@54 { - compatible = "nxp,sc16is752"; - reg = <0x54>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ - }; - -* spi as bus - -Required properties: -- compatible: Should be one of the following: - - "nxp,sc16is740" for NXP SC16IS740, - - "nxp,sc16is741" for NXP SC16IS741, - - "nxp,sc16is750" for NXP SC16IS750, - - "nxp,sc16is752" for NXP SC16IS752, - - "nxp,sc16is760" for NXP SC16IS760, - - "nxp,sc16is762" for NXP SC16IS762. -- reg: SPI chip select number. -- interrupts: Specifies the interrupt source of the parent interrupt - controller. The format of the interrupt specifier depends on the - parent interrupt controller. -- clocks: phandle to the IC source clock. - -Optional properties: -- gpio-controller: Marks the device node as a GPIO controller. -- #gpio-cells: Should be two. The first cell is the GPIO number and - the second cell is used to specify the GPIO polarity: - 0 = active high, - 1 = active low. -- irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -- nxp,modem-control-line-ports: An array that lists the indices of the port that - should have shared GPIO lines configured as - modem control lines. - -Example: - sc16is750: sc16is750@0 { - compatible = "nxp,sc16is750"; - reg = <0>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - gpio-controller; - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@1 { - compatible = "nxp,sc16is752"; - reg = <1>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ - gpio-controller; /* Port 0 as GPIOs */ - #gpio-cells = <2>; - }; - - sc16is752: sc16is752@2 { - compatible = "nxp,sc16is752"; - reg = <2>; - clocks = <&clk20m>; - interrupt-parent = <&gpio3>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ - }; diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml new file mode 100644 index 000000000000..5dec15b7e7c3 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/nxp,sc16is7xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP SC16IS7xx Advanced Universal Asynchronous Receiver-Transmitter (UART) + +maintainers: + - Hugo Villeneuve + +properties: + compatible: + enum: + - nxp,sc16is740 + - nxp,sc16is741 + - nxp,sc16is750 + - nxp,sc16is752 + - nxp,sc16is760 + - nxp,sc16is762 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + description: + When there is no clock provider visible to the platform, this + is the source crystal or external clock frequency for the IC in Hz. + minimum: 1 + maximum: 80000000 + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 8 + + irda-mode-ports: + description: | + An array that lists the indices of the port that should operate in IrDA + mode: + 0: port A + 1: port B + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 2 + items: + minimum: 0 + maximum: 1 + + nxp,modem-control-line-ports: + description: | + An array that lists the indices of the port that should have shared GPIO + lines configured as modem control lines: + 0: port A + 1: port B + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 2 + items: + minimum: 0 + maximum: 1 + +required: + - compatible + - reg + - interrupts + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/serial/rs485.yaml# + +oneOf: + - required: + - clocks + - required: + - clock-frequency + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + serial@51 { + compatible = "nxp,sc16is750"; + reg = <0x51>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + }; + + serial@53 { + compatible = "nxp,sc16is752"; + reg = <0x53>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ + gpio-controller; /* Port 0 as GPIOs */ + #gpio-cells = <2>; + }; + + serial@54 { + compatible = "nxp,sc16is752"; + reg = <0x54>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ + }; + }; diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml index a052aaef21f4..ea6abfe2d95e 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uart.yaml @@ -40,11 +40,11 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: /schemas/serial/serial.yaml# +unevaluatedProperties: false + examples: - | serial@a9c00000 { diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml index 484b9a51f6a9..ee52bf8e8917 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml @@ -78,8 +78,6 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: /schemas/serial/serial.yaml# @@ -97,6 +95,8 @@ allOf: reg: maxItems: 1 +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml index 3fc2601f1338..89f1eb0f2c5a 100644 --- a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml @@ -38,6 +38,13 @@ properties: - const: sclk - const: pclk +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + allOf: - $ref: serial.yaml# @@ -53,13 +60,6 @@ allOf: clock-names: minItems: 2 -required: - - compatible - - reg - - interrupts - - clocks - - clock-names - unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml index 1c7f1276aed6..2046e2dc0a3d 100644 --- a/Documentation/devicetree/bindings/serial/renesas,hscif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,hscif.yaml @@ -111,8 +111,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -125,6 +123,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 99030fc18c45..4610a5bd580c 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -79,6 +79,7 @@ properties: - enum: - renesas,scif-r9a07g043 # RZ/G2UL and RZ/Five - renesas,scif-r9a07g054 # RZ/V2L + - renesas,scif-r9a08g045 # RZ/G3S - const: renesas,scif-r9a07g044 # RZ/G2{L,LC} fallback reg: diff --git a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml index 499507678cdf..c98657cf4666 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifa.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifa.yaml @@ -77,8 +77,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -89,6 +87,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml index 810d8a991fdd..fb695b3111ac 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scifb.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scifb.yaml @@ -77,8 +77,6 @@ required: - clock-names - power-domains -unevaluatedProperties: false - if: properties: compatible: @@ -89,6 +87,8 @@ then: required: - resets +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml index 303a443d9e29..9418fd66a8e9 100644 --- a/Documentation/devicetree/bindings/serial/rs485.yaml +++ b/Documentation/devicetree/bindings/serial/rs485.yaml @@ -29,6 +29,10 @@ properties: default: 0 maximum: 100 + rs485-rts-active-high: + description: drive RTS high when sending (this is the default). + $ref: /schemas/types.yaml#/definitions/flag + rs485-rts-active-low: description: drive RTS low when sending (default is high). $ref: /schemas/types.yaml#/definitions/flag diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 8bd88d5cbb11..ac60ab1e35e3 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -24,9 +24,6 @@ properties: - enum: - apple,s5l-uart - axis,artpec8-uart - - samsung,s3c2410-uart - - samsung,s3c2412-uart - - samsung,s3c2440-uart - samsung,s3c6400-uart - samsung,s5pv210-uart - samsung,exynos4210-uart @@ -86,8 +83,6 @@ required: - interrupts - reg -unevaluatedProperties: false - allOf: - $ref: serial.yaml# @@ -96,7 +91,6 @@ allOf: compatible: contains: enum: - - samsung,s3c2410-uart - samsung,s5pv210-uart then: properties: @@ -128,6 +122,8 @@ allOf: - const: uart - const: clk_uart_baud0 +unevaluatedProperties: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml index ea277560a596..65804ca274ae 100644 --- a/Documentation/devicetree/bindings/serial/serial.yaml +++ b/Documentation/devicetree/bindings/serial/serial.yaml @@ -87,16 +87,8 @@ properties: description: TX FIFO threshold configuration (in bytes). -if: - required: - - uart-has-rtscts -then: - properties: - cts-gpios: false - rts-gpios: false - patternProperties: - "^bluetooth|gnss|gps|mcu$": + "^(bluetooth|bluetooth-gnss|gnss|gps|mcu)$": if: type: object then: @@ -136,6 +128,14 @@ patternProperties: required: - compatible +if: + required: + - uart-has-rtscts +then: + properties: + cts-gpios: false + rts-gpios: false + additionalProperties: true examples: diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml index bceb479f74c5..422921cf1f82 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml @@ -35,6 +35,12 @@ properties: '#size-cells': const: 0 + orientation-gpios: + description: Array of input gpios for the Type-C connector orientation indication. + The GPIO indication is used to detect the orientation of the Type-C connector. + The array should contain a gpio entry for each PMIC Glink connector, in reg order. + It is defined that GPIO active level means "CC2" or Reversed/Flipped orientation. + patternProperties: '^connector@\d$': $ref: /schemas/connector/usb-connector.yaml# @@ -44,6 +50,19 @@ patternProperties: required: - compatible +allOf: + - if: + not: + properties: + compatible: + contains: + enum: + - qcom,sm8450-pmic-glink + - qcom,sm8550-pmic-glink + then: + properties: + orientation-gpios: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml index 1394557517b1..b7e664f7395b 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml @@ -15,7 +15,9 @@ properties: oneOf: - enum: - chipidea,usb2 + - fsl,imx27-usb - lsi,zevio-usb + - nuvoton,npcm750-udc - nvidia,tegra20-ehci - nvidia,tegra20-udc - nvidia,tegra30-ehci @@ -66,6 +68,10 @@ properties: - items: - const: xlnx,zynq-usb-2.20a - const: chipidea,usb2 + - items: + - enum: + - nuvoton,npcm845-udc + - const: nuvoton,npcm750-udc reg: minItems: 1 @@ -388,6 +394,7 @@ allOf: enum: - chipidea,usb2 - lsi,zevio-usb + - nuvoton,npcm750-udc - nvidia,tegra20-udc - nvidia,tegra30-udc - nvidia,tegra114-udc diff --git a/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml b/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml index f6e7a5c1ff0b..f9410eb76a62 100644 --- a/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml +++ b/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml @@ -11,8 +11,12 @@ maintainers: properties: compatible: - enum: - - fcs,fsa4480 + oneOf: + - const: fcs,fsa4480 + - items: + - enum: + - ocs,ocp96011 + - const: fcs,fsa4480 reg: maxItems: 1 @@ -32,10 +36,43 @@ properties: type: boolean port: - $ref: /schemas/graph.yaml#/properties/port + $ref: /schemas/graph.yaml#/$defs/port-base description: A port node to link the FSA4480 to a TypeC controller for the purpose of handling altmode muxing and orientation switching. + unevaluatedProperties: false + + properties: + endpoint: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false + + properties: + data-lanes: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Specifies how the AUX+/- lines are connected to SBU1/2. + oneOf: + - items: + - const: 0 + - const: 1 + description: | + Default AUX/SBU layout (FSA4480) + - AUX+ connected to SBU2 + - AUX- connected to SBU1 + Default AUX/SBU layout (OCP96011) + - AUX+ connected to SBU1 + - AUX- connected to SBU2 + - items: + - const: 1 + - const: 0 + description: | + Swapped AUX/SBU layout (FSA4480) + - AUX+ connected to SBU1 + - AUX- connected to SBU2 + Swapped AUX/SBU layout (OCP96011) + - AUX+ connected to SBU2 + - AUX- connected to SBU1 required: - compatible diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml index d0927f6768a4..ee08b9c3721f 100644 --- a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/usb/genesys,gl850g.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Genesys Logic GL850G USB 2.0 hub controller +title: Genesys Logic USB hub controller maintainers: - Icenowy Zheng @@ -18,6 +18,7 @@ properties: - usb5e3,608 - usb5e3,610 - usb5e3,620 + - usb5e3,626 reg: true diff --git a/Documentation/devicetree/bindings/usb/gpio-sbu-mux.yaml b/Documentation/devicetree/bindings/usb/gpio-sbu-mux.yaml index f196beb826d8..d3b2b666ec2a 100644 --- a/Documentation/devicetree/bindings/usb/gpio-sbu-mux.yaml +++ b/Documentation/devicetree/bindings/usb/gpio-sbu-mux.yaml @@ -19,6 +19,7 @@ properties: compatible: items: - enum: + - nxp,cbdtu02043 - onnn,fsusb43l10x - pericom,pi3usb102 - const: gpio-sbu-mux @@ -50,7 +51,6 @@ required: - compatible - enable-gpios - select-gpios - - mode-switch - orientation-switch - port diff --git a/Documentation/devicetree/bindings/usb/nxp,ptn36502.yaml b/Documentation/devicetree/bindings/usb/nxp,ptn36502.yaml new file mode 100644 index 000000000000..eee548ac1abe --- /dev/null +++ b/Documentation/devicetree/bindings/usb/nxp,ptn36502.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/nxp,ptn36502.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort v1.2 combo redriver + +maintainers: + - Luca Weiss + +properties: + compatible: + enum: + - nxp,ptn36502 + + reg: + maxItems: 1 + + vdd18-supply: + description: Power supply for VDD18 pin + + retimer-switch: + description: Flag the port as possible handle of SuperSpeed signals retiming + type: boolean + + orientation-switch: + description: Flag the port as possible handler of orientation switching + type: boolean + + ports: + $ref: /schemas/graph.yaml#/properties/ports + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Super Speed (SS) Output endpoint to the Type-C connector + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Super Speed (SS) Input endpoint from the Super-Speed PHY + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Sideband Use (SBU) AUX lines endpoint to the Type-C connector for the purpose of + handling altmode muxing and orientation switching. + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + typec-mux@1a { + compatible = "nxp,ptn36502"; + reg = <0x1a>; + + vdd18-supply = <&usb_redrive_1v8>; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_con_ss: endpoint { + remote-endpoint = <&typec_con_ss>; + }; + }; + port@1 { + reg = <1>; + phy_con_ss: endpoint { + remote-endpoint = <&usb_phy_ss>; + }; + }; + port@2 { + reg = <2>; + usb_con_sbu: endpoint { + remote-endpoint = <&typec_dp_aux>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index 67591057f234..e889158ca205 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -14,6 +14,7 @@ properties: items: - enum: - qcom,ipq4019-dwc3 + - qcom,ipq5018-dwc3 - qcom,ipq5332-dwc3 - qcom,ipq6018-dwc3 - qcom,ipq8064-dwc3 @@ -34,6 +35,7 @@ properties: - qcom,sdm845-dwc3 - qcom,sdx55-dwc3 - qcom,sdx65-dwc3 + - qcom,sdx75-dwc3 - qcom,sm4250-dwc3 - qcom,sm6115-dwc3 - qcom,sm6125-dwc3 @@ -180,6 +182,8 @@ allOf: - qcom,sdm670-dwc3 - qcom,sdm845-dwc3 - qcom,sdx55-dwc3 + - qcom,sdx65-dwc3 + - qcom,sdx75-dwc3 - qcom,sm6350-dwc3 then: properties: @@ -238,6 +242,7 @@ allOf: compatible: contains: enum: + - qcom,ipq5018-dwc3 - qcom,ipq5332-dwc3 - qcom,msm8994-dwc3 - qcom,qcs404-dwc3 @@ -363,6 +368,7 @@ allOf: - qcom,sdm845-dwc3 - qcom,sdx55-dwc3 - qcom,sdx65-dwc3 + - qcom,sdx75-dwc3 - qcom,sm4250-dwc3 - qcom,sm6125-dwc3 - qcom,sm6350-dwc3 @@ -411,6 +417,7 @@ allOf: compatible: contains: enum: + - qcom,ipq5018-dwc3 - qcom,ipq5332-dwc3 - qcom,sdm660-dwc3 then: diff --git a/Documentation/devicetree/bindings/usb/realtek,rtd-dwc3.yaml b/Documentation/devicetree/bindings/usb/realtek,rtd-dwc3.yaml new file mode 100644 index 000000000000..345d0132d4a5 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/realtek,rtd-dwc3.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2023 Realtek Semiconductor Corporation +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/realtek,rtd-dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek DWC3 USB SoC Controller Glue + +maintainers: + - Stanley Chang + +description: + The Realtek DHC SoC embeds a DWC3 USB IP Core configured for USB 2.0 + and USB 3.0 in host or dual-role mode. + +properties: + compatible: + items: + - enum: + - realtek,rtd1295-dwc3 + - realtek,rtd1315e-dwc3 + - realtek,rtd1319-dwc3 + - realtek,rtd1319d-dwc3 + - realtek,rtd1395-dwc3 + - realtek,rtd1619-dwc3 + - realtek,rtd1619b-dwc3 + - const: realtek,rtd-dwc3 + + reg: + items: + - description: Address and length of register set for wrapper of dwc3 core. + - description: Address and length of register set for pm control. + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + + ranges: true + +patternProperties: + "^usb@[0-9a-f]+$": + $ref: snps,dwc3.yaml# + description: Required child node + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - ranges + +additionalProperties: false + +examples: + - | + usb@98013e00 { + compatible = "realtek,rtd1319d-dwc3", "realtek,rtd-dwc3"; + reg = <0x98013e00 0x140>, <0x98013f60 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + usb@98050000 { + compatible = "snps,dwc3"; + reg = <0x98050000 0x9000>; + interrupts = <0 94 4>; + phys = <&usb2phy &usb3phy>; + phy-names = "usb2-phy", "usb3-phy"; + dr_mode = "otg"; + usb-role-switch; + role-switch-default-mode = "host"; + snps,dis_u2_susphy_quirk; + snps,parkmode-disable-ss-quirk; + snps,parkmode-disable-hs-quirk; + maximum-speed = "high-speed"; + }; + }; diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml index c983dfe0f629..c4924113f9bd 100644 --- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml @@ -20,9 +20,6 @@ description: Type-C PHY Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt -allOf: - - $ref: snps,dwc3.yaml# - select: properties: compatible: @@ -30,6 +27,7 @@ select: enum: - rockchip,rk3328-dwc3 - rockchip,rk3568-dwc3 + - rockchip,rk3588-dwc3 required: - compatible @@ -39,6 +37,7 @@ properties: - enum: - rockchip,rk3328-dwc3 - rockchip,rk3568-dwc3 + - rockchip,rk3588-dwc3 - const: snps,dwc3 reg: @@ -58,7 +57,9 @@ properties: Master/Core clock, must to be >= 62.5 MHz for SS operation and >= 30MHz for HS operation - description: - Controller grf clock + Controller grf clock OR UTMI clock + - description: + PIPE clock clock-names: minItems: 3 @@ -66,7 +67,10 @@ properties: - const: ref_clk - const: suspend_clk - const: bus_clk - - const: grf_clk + - enum: + - grf_clk + - utmi + - const: pipe power-domains: maxItems: 1 @@ -86,6 +90,52 @@ required: - clocks - clock-names +allOf: + - $ref: snps,dwc3.yaml# + - if: + properties: + compatible: + contains: + const: rockchip,rk3328-dwc3 + then: + properties: + clocks: + minItems: 3 + maxItems: 4 + clock-names: + minItems: 3 + items: + - const: ref_clk + - const: suspend_clk + - const: bus_clk + - const: grf_clk + - if: + properties: + compatible: + contains: + const: rockchip,rk3568-dwc3 + then: + properties: + clocks: + maxItems: 3 + clock-names: + maxItems: 3 + - if: + properties: + compatible: + contains: + const: rockchip,rk3588-dwc3 + then: + properties: + clock-names: + minItems: 3 + items: + - const: ref_clk + - const: suspend_clk + - const: bus_clk + - const: utmi + - const: pipe + examples: - | #include diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index a696f23730d3..ee5af4b381b1 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -310,6 +310,62 @@ properties: maximum: 62 deprecated: true + snps,rx-thr-num-pkt: + description: + USB RX packet threshold count. In host mode, this field specifies + the space that must be available in the RX FIFO before the core can + start the corresponding USB RX transaction (burst). + In device mode, this field specifies the space that must be + available in the RX FIFO before the core can send ERDY for a + flow-controlled endpoint. It is only used for SuperSpeed. + The valid values for this field are from 1 to 15. (DWC3 SuperSpeed + USB 3.0 Controller Databook) + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 15 + + snps,rx-max-burst: + description: + Max USB RX burst size. In host mode, this field specifies the + Maximum Bulk IN burst the DWC_usb3 core can perform. When the system + bus is slower than the USB, RX FIFO can overrun during a long burst. + You can program a smaller value to this field to limit the RX burst + size that the core can perform. It only applies to SS Bulk, + Isochronous, and Interrupt IN endpoints in the host mode. + In device mode, this field specifies the NUMP value that is sent in + ERDY for an OUT endpoint. + The valid values for this field are from 1 to 16. (DWC3 SuperSpeed + USB 3.0 Controller Databook) + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,tx-thr-num-pkt: + description: + USB TX packet threshold count. This field specifies the number of + packets that must be in the TXFIFO before the core can start + transmission for the corresponding USB transaction (burst). + This count is valid in both host and device modes. It is only used + for SuperSpeed operation. + Valid values are from 1 to 15. (DWC3 SuperSpeed USB 3.0 Controller + Databook) + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 15 + + snps,tx-max-burst: + description: + Max USB TX burst size. When the system bus is slower than the USB, + TX FIFO can underrun during a long burst. Program a smaller value + to this field to limit the TX burst size that the core can execute. + In Host mode, it only applies to SS Bulk, Isochronous, and Interrupt + OUT endpoints. This value is not used in device mode. + Valid values are from 1 to 16. (DWC3 SuperSpeed USB 3.0 Controller + Databook) + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + snps,rx-thr-num-pkt-prd: description: Periodic ESS RX packet threshold count (host mode only). Set this and diff --git a/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml b/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml index 6ab674dea4c6..323d664ae06a 100644 --- a/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml +++ b/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml @@ -20,8 +20,23 @@ properties: enum: - ti,tps6598x - apple,cd321x + - ti,tps25750 + reg: - maxItems: 1 + minItems: 1 + items: + - description: main PD controller address + - description: | + I2C slave address field in PBMs input data + which is used as the device address when writing the + patch for TPS25750. + The patch address can be any value except 0x00, 0x20, + 0x21, 0x22, and 0x23 + + reg-names: + items: + - const: main + - const: patch-address wakeup-source: true @@ -35,10 +50,42 @@ properties: connector: $ref: /schemas/connector/usb-connector.yaml# + firmware-name: + description: | + Should contain the name of the default patch binary + file located on the firmware search path which is + used to switch the controller into APP mode. + This is used when tps25750 doesn't have an EEPROM + connected to it. + maxItems: 1 + required: - compatible - reg +allOf: + - if: + properties: + compatible: + contains: + const: ti,tps25750 + then: + properties: + reg: + maxItems: 2 + + connector: + required: + - data-role + + required: + - connector + - reg-names + else: + properties: + reg: + maxItems: 1 + additionalProperties: false examples: @@ -71,4 +118,36 @@ examples: }; }; }; + + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + typec@21 { + compatible = "ti,tps25750"; + reg = <0x21>, <0x0f>; + reg-names = "main", "patch-address"; + + interrupt-parent = <&msmgpio>; + interrupts = <100 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "irq"; + firmware-name = "tps25750.bin"; + + pinctrl-names = "default"; + pinctrl-0 = <&typec_pins>; + + typec_con0: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + port { + typec_ep0: endpoint { + remote-endpoint = <&otg_ep>; + }; + }; + }; + }; + }; ... diff --git a/Documentation/devicetree/bindings/usb/vialab,vl817.yaml b/Documentation/devicetree/bindings/usb/vialab,vl817.yaml index 76db9071b352..c815010ba9c2 100644 --- a/Documentation/devicetree/bindings/usb/vialab,vl817.yaml +++ b/Documentation/devicetree/bindings/usb/vialab,vl817.yaml @@ -37,7 +37,6 @@ properties: required: - compatible - reg - - reset-gpios - vdd-supply - peer-hub diff --git a/Documentation/driver-api/tty/index.rst b/Documentation/driver-api/tty/index.rst index 2d32606a4278..b490da11f257 100644 --- a/Documentation/driver-api/tty/index.rst +++ b/Documentation/driver-api/tty/index.rst @@ -36,6 +36,7 @@ In-detail description of the named TTY structures is in separate documents: tty_struct tty_ldisc tty_buffer + tty_ioctl tty_internals Writing TTY Driver diff --git a/Documentation/driver-api/tty/tty_ioctl.rst b/Documentation/driver-api/tty/tty_ioctl.rst new file mode 100644 index 000000000000..3ff1ac5e07f1 --- /dev/null +++ b/Documentation/driver-api/tty/tty_ioctl.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +TTY IOCTL Helpers +================= + +.. kernel-doc:: drivers/tty/tty_ioctl.c + +.. kernel-doc:: include/linux/tty.h + :identifiers: tty_get_baud_rate diff --git a/Documentation/driver-api/usb/dma.rst b/Documentation/driver-api/usb/dma.rst index d32c27e11b90..02f6825ff830 100644 --- a/Documentation/driver-api/usb/dma.rst +++ b/Documentation/driver-api/usb/dma.rst @@ -93,44 +93,18 @@ DMA address space of the device. However, most buffers passed to your driver can safely be used with such DMA mapping. (See the first section of Documentation/core-api/dma-api-howto.rst, titled "What memory is DMA-able?") -- When you're using scatterlists, you can map everything at once. On some - systems, this kicks in an IOMMU and turns the scatterlists into single - DMA transactions:: +- When you have the scatterlists which have been mapped for the USB controller, + you could use the new ``usb_sg_*()`` calls, which would turn scatterlist + into URBs:: - int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int nents); + int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, + unsigned pipe, unsigned period, struct scatterlist *sg, + int nents, size_t length, gfp_t mem_flags); - void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int n_hw_ents); + void usb_sg_wait(struct usb_sg_request *io); - void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int n_hw_ents); + void usb_sg_cancel(struct usb_sg_request *io); - It's probably easier to use the new ``usb_sg_*()`` calls, which do the DMA - mapping and apply other tweaks to make scatterlist i/o be fast. - -- Some drivers may prefer to work with the model that they're mapping large - buffers, synchronizing their safe re-use. (If there's no re-use, then let - usbcore do the map/unmap.) Large periodic transfers make good examples - here, since it's cheaper to just synchronize the buffer than to unmap it - each time an urb completes and then re-map it on during resubmission. - - These calls all work with initialized urbs: ``urb->dev``, ``urb->pipe``, - ``urb->transfer_buffer``, and ``urb->transfer_buffer_length`` must all be - valid when these calls are used (``urb->setup_packet`` must be valid too - if urb is a control request):: - - struct urb *usb_buffer_map (struct urb *urb); - - void usb_buffer_dmasync (struct urb *urb); - - void usb_buffer_unmap (struct urb *urb); - - The calls manage ``urb->transfer_dma`` for you, and set - ``URB_NO_TRANSFER_DMA_MAP`` so that usbcore won't map or unmap the buffer. - They cannot be used for setup_packet buffers in control requests. - -Note that several of those interfaces are currently commented out, since -they don't have current users. See the source code. Other than the dmasync -calls (where the underlying DMA primitives have changed), most of them can -easily be commented back in if you want to use them. + When the USB controller doesn't support DMA, the ``usb_sg_init()`` would try + to submit URBs in PIO way as long as the page in scatterlists is not in the + Highmem, which could be very rare in modern architectures. diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index 2f0285a5bc80..0dd30a84ce25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,7 +15,6 @@ Contents: ethernet/index fddi/index hamradio/index - qlogic/index wifi/index wwan/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst deleted file mode 100644 index ad05b04286e4..000000000000 --- a/Documentation/networking/device_drivers/qlogic/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) - -QLogic QLGE Device Drivers -=============================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - qlge - -.. only:: subproject and html - - Indices - ======= - - * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst deleted file mode 100644 index 0b888253d152..000000000000 --- a/Documentation/networking/device_drivers/qlogic/qlge.rst +++ /dev/null @@ -1,118 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -======================================= -QLogic QLGE 10Gb Ethernet device driver -======================================= - -This driver use drgn and devlink for debugging. - -Dump kernel data structures in drgn ------------------------------------ - -To dump kernel data structures, the following Python script can be used -in drgn: - -.. code-block:: python - - def align(x, a): - """the alignment a should be a power of 2 - """ - mask = a - 1 - return (x+ mask) & ~mask - - def struct_size(struct_type): - struct_str = "struct {}".format(struct_type) - return sizeof(Object(prog, struct_str, address=0x0)) - - def netdev_priv(netdevice): - NETDEV_ALIGN = 32 - return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) - - name = 'xxx' - qlge_device = None - netdevices = prog['init_net'].dev_base_head.address_of_() - for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): - if netdevice.name.string_().decode('ascii') == name: - print(netdevice.name) - - ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) - -The struct ql_adapter will be printed in drgn as follows, - - >>> ql_adapter - (struct ql_adapter){ - .ricb = (struct ricb){ - .base_cq = (u8)0, - .flags = (u8)120, - .mask = (__le16)26637, - .hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, - .ipv6_hash_key = (__le32 [10]){}, - .ipv4_hash_key = (__le32 [4]){}, - }, - .flags = (unsigned long)0, - .wol = (u32)0, - .nic_stats = (struct nic_stats){ - .tx_pkts = (u64)0, - .tx_bytes = (u64)0, - .tx_mcast_pkts = (u64)0, - .tx_bcast_pkts = (u64)0, - .tx_ucast_pkts = (u64)0, - .tx_ctl_pkts = (u64)0, - .tx_pause_pkts = (u64)0, - ... - }, - .active_vlans = (unsigned long [64]){ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, - 18446619461681283072, 0, 42949673024, 2147483647, - }, - .rx_ring = (struct rx_ring [17]){ - { - .cqicb = (struct cqicb){ - .msix_vect = (u8)0, - .reserved1 = (u8)0, - .reserved2 = (u8)0, - .flags = (u8)0, - .len = (__le16)0, - .rid = (__le16)0, - ... - }, - .cq_base = (void *)0x0, - .cq_base_dma = (dma_addr_t)0, - } - ... - } - } - -coredump via devlink --------------------- - - -And the coredump obtained via devlink in json format looks like, - -.. code:: shell - - $ devlink health dump show DEVICE reporter coredump -p -j - { - "Core Registers": { - "segment": 1, - "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] - }, - "Test Logic Regs": { - "segment": 2, - "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] - }, - "RMII Registers": { - "segment": 3, - "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] - }, - ... - "Sem Registers": { - "segment": 50, - "values": [ 0,0,0,0 ] - } - } - -When the module parameter qlge_force_coredump is set to be true, the MPI -RISC reset before coredumping. So coredumping will much longer since -devlink tool has to wait for 5 secs for the resetting to be -finished. diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 394cd226bfae..29072c166d23 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -755,6 +755,8 @@ The uac2 function provides these attributes in its function directory: req_number the number of pre-allocated request for both capture and playback function_name name of the interface + c_terminal_type code of the capture terminal type + p_terminal_type code of the playback terminal type ================ ==================================================== The attributes have sane default values. diff --git a/MAINTAINERS b/MAINTAINERS index 463eb1e86040..a4d2cc3f5945 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8338,6 +8338,14 @@ F: Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt F: drivers/spi/spi-fsl-dspi.c F: include/linux/spi/spi-fsl-dspi.h +FREESCALE eDMA DRIVER +M: Frank Li +L: imx@lists.linux.dev +L: dmaengine@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/dma/fsl,edma.yaml +F: drivers/dma/fsl-edma*.* + FREESCALE ENETC ETHERNET DRIVERS M: Claudiu Manoil M: Vladimir Oltean @@ -17680,15 +17688,6 @@ L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/qlogic/qlcnic/ -QLOGIC QLGE 10Gb ETHERNET DRIVER -M: Manish Chopra -M: GR-Linux-NIC-Dev@marvell.com -M: Coiby Xu -L: netdev@vger.kernel.org -S: Supported -F: Documentation/networking/device_drivers/qlogic/qlge.rst -F: drivers/staging/qlge/ - QM1D1B0004 MEDIA DRIVER M: Akihiro Tsukada L: linux-media@vger.kernel.org diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 5816a31c1b38..2c89c1c55712 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +#include #include /* Prototypes of functions used across modules here in this directory. */ @@ -113,6 +114,7 @@ extern int boot_cpuid; #ifdef CONFIG_VERBOSE_MCHECK extern unsigned long alpha_verbose_mcheck; #endif +extern struct screen_info vgacon_screen_info; /* srmcons.c */ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index c80258ec332f..0738f9396f95 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -131,13 +131,14 @@ static void determine_cpu_caches (unsigned int); static char __initdata command_line[COMMAND_LINE_SIZE]; +#ifdef CONFIG_VGA_CONSOLE /* * The format of "screen_info" is strange, and due to early * i386-setup code. This is just enough to make the console * code think we're on a VGA color display. */ -struct screen_info screen_info = { +struct screen_info vgacon_screen_info = { .orig_x = 0, .orig_y = 25, .orig_video_cols = 80, @@ -145,8 +146,7 @@ struct screen_info screen_info = { .orig_video_isVGA = 1, .orig_video_points = 16 }; - -EXPORT_SYMBOL(screen_info); +#endif /* * The direct map I/O window, if any. This should be the same @@ -652,7 +652,7 @@ setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; + vgacon_register_screen(&vgacon_screen_info); #endif #endif diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index 7c420d8dac53..086488ed83a7 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -57,11 +57,13 @@ sio_init_irq(void) static inline void __init alphabook1_init_arch(void) { +#ifdef CONFIG_VGA_CONSOLE /* The AlphaBook1 has LCD video fixed at 800x600, 37 rows and 100 cols. */ - screen_info.orig_y = 37; - screen_info.orig_video_cols = 100; - screen_info.orig_video_lines = 37; + vgacon_screen_info.orig_y = 37; + vgacon_screen_info.orig_video_cols = 100; + vgacon_screen_info.orig_video_lines = 37; +#endif lca_init_arch(); } diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 546af8b1e3f6..cc106f946c69 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -11,6 +11,7 @@ #ifndef __ASMARM_SETUP_H #define __ASMARM_SETUP_H +#include #include @@ -35,4 +36,8 @@ void early_mm_init(const struct machine_desc *); void adjust_lowmem_bounds(void); void setup_dma_zone(const struct machine_desc *desc); +#ifdef CONFIG_VGA_CONSOLE +extern struct screen_info vgacon_screen_info; +#endif + #endif diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h index 7c0bee57855a..6c430ec371df 100644 --- a/arch/arm/include/asm/vga.h +++ b/arch/arm/include/asm/vga.h @@ -5,6 +5,7 @@ #include extern unsigned long vga_base; +extern struct screen_info vgacon_screen_info; #define VGA_MAP_MEM(x,s) (vga_base + (x)) diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 33f6eb5213a5..4ec591bde3df 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c @@ -69,18 +69,18 @@ static int __init parse_tag_mem32(const struct tag *tag) __tagtable(ATAG_MEM, parse_tag_mem32); -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_VGA_CONSOLE) static int __init parse_tag_videotext(const struct tag *tag) { - screen_info.orig_x = tag->u.videotext.x; - screen_info.orig_y = tag->u.videotext.y; - screen_info.orig_video_page = tag->u.videotext.video_page; - screen_info.orig_video_mode = tag->u.videotext.video_mode; - screen_info.orig_video_cols = tag->u.videotext.video_cols; - screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; - screen_info.orig_video_lines = tag->u.videotext.video_lines; - screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; - screen_info.orig_video_points = tag->u.videotext.video_points; + vgacon_screen_info.orig_x = tag->u.videotext.x; + vgacon_screen_info.orig_y = tag->u.videotext.y; + vgacon_screen_info.orig_video_page = tag->u.videotext.video_page; + vgacon_screen_info.orig_video_mode = tag->u.videotext.video_mode; + vgacon_screen_info.orig_video_cols = tag->u.videotext.video_cols; + vgacon_screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; + vgacon_screen_info.orig_video_lines = tag->u.videotext.video_lines; + vgacon_screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; + vgacon_screen_info.orig_video_points = tag->u.videotext.video_points; return 0; } diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index e94655ef16bb..6f9ec7d28a71 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -123,12 +123,6 @@ void __init arm_efi_init(void) { efi_init(); - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { - /* dummycon on ARM needs non-zero values for columns/lines */ - screen_info.orig_video_cols = 80; - screen_info.orig_video_lines = 25; - } - /* ARM does not permit early mappings to persist across paging_init() */ efi_memmap_unmap(); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b01cac05bd4c..ff2299ce1ad7 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -928,9 +928,8 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) request_resource(&ioport_resource, &lp2); } -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) || \ - defined(CONFIG_EFI) -struct screen_info screen_info = { +#if defined(CONFIG_VGA_CONSOLE) +struct screen_info vgacon_screen_info = { .orig_video_lines = 30, .orig_video_cols = 80, .orig_video_mode = 0, @@ -1194,7 +1193,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; + vgacon_register_screen(&vgacon_screen_info); #endif #endif diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts index 5b3488736fbe..9a70875028b7 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts @@ -59,6 +59,7 @@ compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink"; #address-cells = <1>; #size-cells = <0>; + orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; connector@0 { compatible = "usb-c-connector"; diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts index 320662024e89..eef811def39b 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts @@ -77,6 +77,7 @@ compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink"; #address-cells = <1>; #size-cells = <0>; + orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; connector@0 { compatible = "usb-c-connector"; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi index 2993e1255042..7064c0e9179f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -443,6 +443,27 @@ status = "disabled"; }; + usb_host2_xhci: usb@fcd00000 { + compatible = "rockchip,rk3588-dwc3", "snps,dwc3"; + reg = <0x0 0xfcd00000 0x0 0x400000>; + interrupts = ; + clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>, + <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>, + <&cru CLK_PIPEPHY2_PIPE_U3_G>; + clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe"; + dr_mode = "host"; + phys = <&combphy2_psu PHY_TYPE_USB3>; + phy-names = "usb3-phy"; + phy_type = "utmi_wide"; + resets = <&cru SRST_A_USB3OTG2>; + snps,dis_enblslpm_quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,dis_rxdet_inp3_quirk; + status = "disabled"; + }; + pmu1grf: syscon@fd58a000 { compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd"; reg = <0x0 0xfd58a000 0x0 0x10000>; diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 3f8c9c143552..0228001347be 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -71,10 +71,6 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) return pgprot_val(PAGE_KERNEL_EXEC); } -/* we will fill this structure from the stub, so don't put it in .bss */ -struct screen_info screen_info __section(".data"); -EXPORT_SYMBOL(screen_info); - int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) { pteval_t prot_val = create_mapping_protection(md); diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 35f3c7959513..5e4dc72ab1bd 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -27,7 +27,9 @@ PROVIDE(__efistub__text = _text); PROVIDE(__efistub__end = _end); PROVIDE(__efistub___inittext_end = __inittext_end); PROVIDE(__efistub__edata = _edata); +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) PROVIDE(__efistub_screen_info = screen_info); +#endif PROVIDE(__efistub__ctype = _ctype); PROVIDE(__pi___memcpy = __pi_memcpy); diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 106fbf0b6f3b..51012e90780d 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -8,22 +8,10 @@ #include #include #include -#include #include #include #include -#ifdef CONFIG_DUMMY_CONSOLE -struct screen_info screen_info = { - .orig_video_lines = 30, - .orig_video_cols = 80, - .orig_video_mode = 0, - .orig_video_ega_bx = 0, - .orig_video_isVGA = 1, - .orig_video_points = 8 -}; -#endif - static void __init csky_memblock_init(void) { unsigned long lowmem_size = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index e73cb321630e..3fdf937eb572 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -17,5 +17,3 @@ obj-y += vm_vectors.o obj-$(CONFIG_HAS_DMA) += dma.o obj-$(CONFIG_STACKTRACE) += stacktrace.o - -obj-$(CONFIG_VGA_CONSOLE) += screen_info.o diff --git a/arch/hexagon/kernel/screen_info.c b/arch/hexagon/kernel/screen_info.c deleted file mode 100644 index 1e1ceb18bafe..000000000000 --- a/arch/hexagon/kernel/screen_info.c +++ /dev/null @@ -1,3 +0,0 @@ -#include - -struct screen_info screen_info; diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 9fc10cea21e1..acb5d3385675 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -68,6 +68,11 @@ void __init efi_runtime_init(void) unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; +#if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) +struct screen_info screen_info __section(".data"); +EXPORT_SYMBOL_GPL(screen_info); +#endif + static void __init init_screen_info(void) { struct screen_info *si; @@ -115,7 +120,8 @@ void __init efi_init(void) set_bit(EFI_CONFIG_TABLES, &efi.flags); - init_screen_info(); + if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) + init_screen_info(); if (boot_memmap == EFI_INVALID_TABLE_ADDR) return; diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h index e561989d02de..5087416b9678 100644 --- a/arch/loongarch/kernel/image-vars.h +++ b/arch/loongarch/kernel/image-vars.h @@ -12,7 +12,9 @@ __efistub_kernel_entry = kernel_entry; __efistub_kernel_asize = kernel_asize; __efistub_kernel_fsize = kernel_fsize; __efistub_kernel_offset = kernel_offset; +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) __efistub_screen_info = screen_info; +#endif #endif diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index b35186f7b254..d183a745fb85 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -57,8 +56,6 @@ #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 #define LOONGSON_EFI_ENABLE (1 << 3) -struct screen_info screen_info __section(".data"); - unsigned long fw_arg0, fw_arg1, fw_arg2; DEFINE_PER_CPU(unsigned long, kernelsp); struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly; diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index 04aab419a0fc..e318ea11c858 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -76,14 +75,6 @@ void __init plat_mem_setup(void) _machine_restart = jazz_machine_restart; -#ifdef CONFIG_VT - screen_info = (struct screen_info) { - .orig_video_cols = 160, - .orig_video_lines = 64, - .orig_video_points = 16, - }; -#endif - add_preferred_console("ttyS", 0, "9600"); } diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 08321c945ac4..2d2ca024bd47 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -54,10 +53,6 @@ struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_data); -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - /* * Setup information * @@ -793,12 +788,6 @@ void __init setup_arch(char **cmdline_p) if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) check_bugs64_early(); -#if defined(CONFIG_VT) -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; -#endif -#endif - arch_mem_init(cmdline_p); dmi_setup(); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 21cb3ac1237b..3a2836e9d856 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -161,7 +161,7 @@ static void __init pci_clock_check(void) #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) static void __init screen_info_setup(void) { - screen_info = (struct screen_info) { + static struct screen_info si = { .orig_x = 0, .orig_y = 25, .ext_mem_k = 0, @@ -175,6 +175,8 @@ static void __init screen_info_setup(void) .orig_video_isVGA = VIDEO_TYPE_VGAC, .orig_video_points = 16 }; + + vgacon_register_screen(&si); } #endif diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 76683993cdd3..38c90b5e8754 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -112,6 +113,19 @@ int update_persistent_clock64(struct timespec64 now) } } +#ifdef CONFIG_VGA_CONSOLE +static struct screen_info vgacon_screen_info = { + .orig_video_page = 52, + .orig_video_mode = 3, + .orig_video_cols = 80, + .flags = 12, + .orig_video_ega_bx = 3, + .orig_video_lines = 25, + .orig_video_isVGA = 0x22, + .orig_video_points = 16, +}; +#endif + void __init plat_mem_setup(void) { #ifdef CONFIG_SIBYTE_BCM1x80 @@ -129,17 +143,8 @@ void __init plat_mem_setup(void) if (m41t81_probe()) swarm_rtc_type = RTC_M41T81; -#ifdef CONFIG_VT - screen_info = (struct screen_info) { - .orig_video_page = 52, - .orig_video_mode = 3, - .orig_video_cols = 80, - .flags = 12, - .orig_video_ega_bx = 3, - .orig_video_lines = 25, - .orig_video_isVGA = 0x22, - .orig_video_points = 16, - }; +#ifdef CONFIG_VGA_CONSOLE + vgacon_register_screen(&vgacon_screen_info); /* XXXKW for CFE, get lines/cols from environment */ #endif } diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index efad85c8c823..42fdb939c88d 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -38,19 +38,21 @@ extern void sni_machine_power_off(void); static void __init sni_display_setup(void) { -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC) - struct screen_info *si = &screen_info; +#if defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC) + static struct screen_info si; DISPLAY_STATUS *di; di = ArcGetDisplayStatus(1); if (di) { - si->orig_x = di->CursorXPosition; - si->orig_y = di->CursorYPosition; - si->orig_video_cols = di->CursorMaxXPosition; - si->orig_video_lines = di->CursorMaxYPosition; - si->orig_video_isVGA = VIDEO_TYPE_VGAC; - si->orig_video_points = 16; + si.orig_x = di->CursorXPosition; + si.orig_y = di->CursorYPosition; + si.orig_video_cols = di->CursorMaxXPosition; + si.orig_video_lines = di->CursorMaxYPosition; + si.orig_video_isVGA = VIDEO_TYPE_VGAC; + si.orig_video_points = 16; + + vgacon_register_screen(&si); } #endif } diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c index 8582ed965844..da122a5fa43b 100644 --- a/arch/nios2/kernel/setup.c +++ b/arch/nios2/kernel/setup.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -36,10 +35,6 @@ static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - /* Copy a short hook instruction sequence to the exception address */ static inline void copy_exception_handler(unsigned int addr) { diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index f6ded7147b4d..19a804860ed5 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -248,7 +248,6 @@ CONFIG_UIO_AEC=m CONFIG_UIO_SERCOS3=m CONFIG_UIO_PCI_GENERIC=m CONFIG_STAGING=y -CONFIG_QLGE=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_SECURITY=y diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index ca92cf0ffde1..9b142b9d5187 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -98,21 +97,6 @@ int boot_cpu_hwid = -1; int dcache_bsize; int icache_bsize; -/* - * This still seems to be needed... -- paulus - */ -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 25, - .orig_video_cols = 80, - .orig_video_lines = 25, - .orig_video_isVGA = 1, - .orig_video_points = 16 -}; -#if defined(CONFIG_FB_VGA16_MODULE) -EXPORT_SYMBOL(screen_info); -#endif - /* Variables required to store legacy IO irq routing */ int of_i8042_kbd_irq; EXPORT_SYMBOL_GPL(of_i8042_kbd_irq); diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h index ea1a10355ce9..3df30dd1c458 100644 --- a/arch/riscv/kernel/image-vars.h +++ b/arch/riscv/kernel/image-vars.h @@ -28,7 +28,9 @@ __efistub__start_kernel = _start_kernel; __efistub__end = _end; __efistub__edata = _edata; __efistub___init_text_end = __init_text_end; +#if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) __efistub_screen_info = screen_info; +#endif #endif diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index aac853ae4eb7..0624f44d43ec 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -40,17 +39,6 @@ #include "head.h" -#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_EFI) -struct screen_info screen_info __section(".data") = { - .orig_video_lines = 30, - .orig_video_cols = 80, - .orig_video_mode = 0, - .orig_video_ega_bx = 0, - .orig_video_isVGA = 1, - .orig_video_points = 8 -}; -#endif - /* * The lucky hart to first increment this variable will boot the other cores. * This is used before the kernel initializes the BSS so it can't be in the diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index b3da2757faaf..3d80515298d2 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -7,7 +7,6 @@ * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2002 - 2010 Paul Mundt */ -#include #include #include #include @@ -69,10 +68,6 @@ EXPORT_SYMBOL(cpu_data); struct sh_machine_vector sh_mv = { .mv_name = "generic", }; EXPORT_SYMBOL(sh_mv); -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif - extern int root_mountflags; #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 34ef7febf0d5..e3b72a7b46d3 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -51,18 +50,6 @@ #include "kernel.h" -struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 128, /* orig-video-cols */ - 0,0,0, /* ega_ax, ega_bx, ega_cx */ - 54, /* orig-video-lines */ - 0, /* orig-video-isVGA */ - 16 /* orig-video-points */ -}; - /* Typing sync at the prom prompt calls the function pointed to by * romvec->pv_synchook which I set to the following function. * This should sync all filesystems and return, for now it just diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 6546ca9d4d3f..6a4797dec34b 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -68,18 +67,6 @@ DEFINE_SPINLOCK(ns87303_lock); EXPORT_SYMBOL(ns87303_lock); -struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig-video-page */ - 0, /* orig-video-mode */ - 128, /* orig-video-cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 54, /* orig-video-lines */ - 0, /* orig-video-isVGA */ - 16 /* orig-video-points */ -}; - static void prom_console_write(struct console *con, const char *s, unsigned int n) { diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 163c35db3d04..1526747bedf2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1167,7 +1167,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) - conswitchp = &vga_con; + vgacon_register_screen(&screen_info); #endif #endif x86_init.oem.banner(); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 52d6e4870a04..bdec4a773af0 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -49,17 +48,6 @@ #include #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 24, - .orig_video_cols = 80, - .orig_video_lines = 24, - .orig_video_isVGA = 1, - .orig_video_points = 16, -}; -#endif - #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start; extern unsigned long initrd_end; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 4ccae1a3b884..70ba506dabab 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -362,7 +362,7 @@ config INTEL_IOATDMA config K3_DMA tristate "Hisilicon K3 DMA support" - depends on ARCH_HI3xxx || ARCH_HISI || COMPILE_TEST + depends on ARCH_HISI || COMPILE_TEST select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index 4153c2edb049..a8e3615235b8 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -923,7 +923,7 @@ fail: * * Return: Always '0' */ -static int msgdma_remove(struct platform_device *pdev) +static void msgdma_remove(struct platform_device *pdev) { struct msgdma_device *mdev = platform_get_drvdata(pdev); @@ -933,8 +933,6 @@ static int msgdma_remove(struct platform_device *pdev) msgdma_dev_remove(mdev); dev_notice(&pdev->dev, "Altera mSGDMA driver removed\n"); - - return 0; } #ifdef CONFIG_OF @@ -952,7 +950,7 @@ static struct platform_driver msgdma_driver = { .of_match_table = of_match_ptr(msgdma_match), }, .probe = msgdma_probe, - .remove = msgdma_remove, + .remove_new = msgdma_remove, }; module_platform_driver(msgdma_driver); diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c index 3af795635c5c..5b63996640d9 100644 --- a/drivers/dma/apple-admac.c +++ b/drivers/dma/apple-admac.c @@ -128,7 +128,7 @@ struct admac_data { int irq; int irq_index; int nchannels; - struct admac_chan channels[]; + struct admac_chan channels[] __counted_by(nchannels); }; struct admac_tx { @@ -925,7 +925,7 @@ free_reset: return err; } -static int admac_remove(struct platform_device *pdev) +static void admac_remove(struct platform_device *pdev) { struct admac_data *ad = platform_get_drvdata(pdev); @@ -933,8 +933,6 @@ static int admac_remove(struct platform_device *pdev) dma_async_device_unregister(&ad->dma); free_irq(ad->irq, ad); reset_control_rearm(ad->rstc); - - return 0; } static const struct of_device_id admac_of_match[] = { @@ -949,7 +947,7 @@ static struct platform_driver apple_admac_driver = { .of_match_table = admac_of_match, }, .probe = admac_probe, - .remove = admac_remove, + .remove_new = admac_remove, }; module_platform_driver(apple_admac_driver); diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index b2876f67471f..fb89ecbf0cc5 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -239,7 +239,7 @@ struct at_desc { bool memset_buffer; dma_addr_t memset_paddr; int *memset_vaddr; - struct atdma_sg sg[]; + struct atdma_sg sg[] __counted_by(sglen); }; /*-- Channels --------------------------------------------------------*/ @@ -2100,7 +2100,7 @@ err_irq: return err; } -static int at_dma_remove(struct platform_device *pdev) +static void at_dma_remove(struct platform_device *pdev) { struct at_dma *atdma = platform_get_drvdata(pdev); struct dma_chan *chan, *_chan; @@ -2122,8 +2122,6 @@ static int at_dma_remove(struct platform_device *pdev) } clk_disable_unprepare(atdma->clk); - - return 0; } static void at_dma_shutdown(struct platform_device *pdev) @@ -2242,7 +2240,7 @@ static const struct dev_pm_ops __maybe_unused at_dma_dev_pm_ops = { }; static struct platform_driver at_dma_driver = { - .remove = at_dma_remove, + .remove_new = at_dma_remove, .shutdown = at_dma_shutdown, .id_table = atdma_devtypes, .driver = { diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index c3b37168b21f..299396121e6d 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -2431,7 +2431,7 @@ err_free_irq: return ret; } -static int at_xdmac_remove(struct platform_device *pdev) +static void at_xdmac_remove(struct platform_device *pdev) { struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); int i; @@ -2452,8 +2452,6 @@ static int at_xdmac_remove(struct platform_device *pdev) tasklet_kill(&atchan->tasklet); at_xdmac_free_chan_resources(&atchan->chan); } - - return 0; } static const struct dev_pm_ops __maybe_unused atmel_xdmac_dev_pm_ops = { @@ -2478,7 +2476,7 @@ MODULE_DEVICE_TABLE(of, atmel_xdmac_dt_ids); static struct platform_driver at_xdmac_driver = { .probe = at_xdmac_probe, - .remove = at_xdmac_remove, + .remove_new = at_xdmac_remove, .driver = { .name = "at_xdmac", .of_match_table = of_match_ptr(atmel_xdmac_dt_ids), diff --git a/drivers/dma/bcm-sba-raid.c b/drivers/dma/bcm-sba-raid.c index 94ea35330eb5..fbaacb4c19b2 100644 --- a/drivers/dma/bcm-sba-raid.c +++ b/drivers/dma/bcm-sba-raid.c @@ -1734,7 +1734,7 @@ fail_free_mchan: return ret; } -static int sba_remove(struct platform_device *pdev) +static void sba_remove(struct platform_device *pdev) { struct sba_device *sba = platform_get_drvdata(pdev); @@ -1745,8 +1745,6 @@ static int sba_remove(struct platform_device *pdev) sba_freeup_channel_resources(sba); mbox_free_channel(sba->mchan); - - return 0; } static const struct of_device_id sba_of_match[] = { @@ -1758,7 +1756,7 @@ MODULE_DEVICE_TABLE(of, sba_of_match); static struct platform_driver sba_driver = { .probe = sba_probe, - .remove = sba_remove, + .remove_new = sba_remove, .driver = { .name = "bcm-sba-raid", .of_match_table = sba_of_match, diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 0807fb9eb262..9d74fe97452e 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -1019,19 +1019,17 @@ err_no_dma: return rc; } -static int bcm2835_dma_remove(struct platform_device *pdev) +static void bcm2835_dma_remove(struct platform_device *pdev) { struct bcm2835_dmadev *od = platform_get_drvdata(pdev); dma_async_device_unregister(&od->ddev); bcm2835_dma_free(od); - - return 0; } static struct platform_driver bcm2835_dma_driver = { .probe = bcm2835_dma_probe, - .remove = bcm2835_dma_remove, + .remove_new = bcm2835_dma_remove, .driver = { .name = "bcm2835-dma", .of_match_table = of_match_ptr(bcm2835_dma_of_match), diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index 80096f94032d..0bbaa7620bdd 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -455,7 +455,7 @@ error_ofput: } -static int mpc52xx_bcom_remove(struct platform_device *op) +static void mpc52xx_bcom_remove(struct platform_device *op) { /* Clean up the engine */ bcom_engine_cleanup(); @@ -473,8 +473,6 @@ static int mpc52xx_bcom_remove(struct platform_device *op) /* Release memory */ kfree(bcom_eng); bcom_eng = NULL; - - return 0; } static const struct of_device_id mpc52xx_bcom_of_match[] = { @@ -488,7 +486,7 @@ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); static struct platform_driver mpc52xx_bcom_of_platform_driver = { .probe = mpc52xx_bcom_probe, - .remove = mpc52xx_bcom_remove, + .remove_new = mpc52xx_bcom_remove, .driver = { .name = DRIVER_NAME, .of_match_table = mpc52xx_bcom_of_match, diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index fc7cdad37161..2457a420c13d 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -117,7 +117,7 @@ struct axi_dmac_desc { unsigned int num_submitted; unsigned int num_completed; unsigned int num_sgs; - struct axi_dmac_sg sg[]; + struct axi_dmac_sg sg[] __counted_by(num_sgs); }; struct axi_dmac_chan { @@ -484,12 +484,11 @@ static struct axi_dmac_desc *axi_dmac_alloc_desc(unsigned int num_sgs) desc = kzalloc(struct_size(desc, sg, num_sgs), GFP_NOWAIT); if (!desc) return NULL; + desc->num_sgs = num_sgs; for (i = 0; i < num_sgs; i++) desc->sg[i].id = AXI_DMAC_SG_UNUSED; - desc->num_sgs = num_sgs; - return desc; } @@ -1029,7 +1028,7 @@ err_clk_disable: return ret; } -static int axi_dmac_remove(struct platform_device *pdev) +static void axi_dmac_remove(struct platform_device *pdev) { struct axi_dmac *dmac = platform_get_drvdata(pdev); @@ -1038,8 +1037,6 @@ static int axi_dmac_remove(struct platform_device *pdev) tasklet_kill(&dmac->chan.vchan.task); dma_async_device_unregister(&dmac->dma_dev); clk_disable_unprepare(dmac->clk); - - return 0; } static const struct of_device_id axi_dmac_of_match_table[] = { @@ -1054,7 +1051,7 @@ static struct platform_driver axi_dmac_driver = { .of_match_table = axi_dmac_of_match_table, }, .probe = axi_dmac_probe, - .remove = axi_dmac_remove, + .remove_new = axi_dmac_remove, }; module_platform_driver(axi_dmac_driver); diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c index adbd47bd6adf..c9cfa341db51 100644 --- a/drivers/dma/dma-jz4780.c +++ b/drivers/dma/dma-jz4780.c @@ -1008,7 +1008,7 @@ err_disable_clk: return ret; } -static int jz4780_dma_remove(struct platform_device *pdev) +static void jz4780_dma_remove(struct platform_device *pdev) { struct jz4780_dma_dev *jzdma = platform_get_drvdata(pdev); int i; @@ -1020,8 +1020,6 @@ static int jz4780_dma_remove(struct platform_device *pdev) for (i = 0; i < jzdma->soc_data->nb_channels; i++) tasklet_kill(&jzdma->chan[i].vchan.task); - - return 0; } static const struct jz4780_dma_soc_data jz4740_dma_soc_data = { @@ -1124,7 +1122,7 @@ MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match); static struct platform_driver jz4780_dma_driver = { .probe = jz4780_dma_probe, - .remove = jz4780_dma_remove, + .remove_new = jz4780_dma_remove, .driver = { .name = "jz4780-dma", .of_match_table = jz4780_dma_dt_match, diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index dd02f84e404d..a86a81ff0caa 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -62,6 +62,17 @@ static inline u32 axi_dma_ioread32(struct axi_dma_chip *chip, u32 reg) return ioread32(chip->regs + reg); } +static inline void +axi_dma_iowrite64(struct axi_dma_chip *chip, u32 reg, u64 val) +{ + iowrite64(val, chip->regs + reg); +} + +static inline u64 axi_dma_ioread64(struct axi_dma_chip *chip, u32 reg) +{ + return ioread64(chip->regs + reg); +} + static inline void axi_chan_iowrite32(struct axi_dma_chan *chan, u32 reg, u32 val) { @@ -182,38 +193,73 @@ static inline u32 axi_chan_irq_read(struct axi_dma_chan *chan) static inline void axi_chan_disable(struct axi_dma_chan *chan) { - u32 val; + u64 val; - val = axi_dma_ioread32(chan->chip, DMAC_CHEN); - val &= ~(BIT(chan->id) << DMAC_CHAN_EN_SHIFT); - if (chan->chip->dw->hdata->reg_map_8_channels) - val |= BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT; - else - val |= BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT; - axi_dma_iowrite32(chan->chip, DMAC_CHEN, val); + if (chan->chip->dw->hdata->nr_channels >= DMAC_CHAN_16) { + val = axi_dma_ioread64(chan->chip, DMAC_CHEN); + if (chan->id >= DMAC_CHAN_16) { + val &= ~((u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_EN_SHIFT + DMAC_CHAN_BLOCK_SHIFT)); + val |= (u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_EN2_WE_SHIFT + DMAC_CHAN_BLOCK_SHIFT); + } else { + val &= ~(BIT(chan->id) << DMAC_CHAN_EN_SHIFT); + val |= BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT; + } + axi_dma_iowrite64(chan->chip, DMAC_CHEN, val); + } else { + val = axi_dma_ioread32(chan->chip, DMAC_CHEN); + val &= ~(BIT(chan->id) << DMAC_CHAN_EN_SHIFT); + if (chan->chip->dw->hdata->reg_map_8_channels) + val |= BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT; + else + val |= BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT; + axi_dma_iowrite32(chan->chip, DMAC_CHEN, (u32)val); + } } static inline void axi_chan_enable(struct axi_dma_chan *chan) { - u32 val; + u64 val; - val = axi_dma_ioread32(chan->chip, DMAC_CHEN); - if (chan->chip->dw->hdata->reg_map_8_channels) - val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT | - BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT; - else - val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT | + if (chan->chip->dw->hdata->nr_channels >= DMAC_CHAN_16) { + val = axi_dma_ioread64(chan->chip, DMAC_CHEN); + if (chan->id >= DMAC_CHAN_16) { + val |= (u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_EN_SHIFT + DMAC_CHAN_BLOCK_SHIFT) | + (u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_EN2_WE_SHIFT + DMAC_CHAN_BLOCK_SHIFT); + } else { + val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT | BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT; - axi_dma_iowrite32(chan->chip, DMAC_CHEN, val); + } + axi_dma_iowrite64(chan->chip, DMAC_CHEN, val); + } else { + val = axi_dma_ioread32(chan->chip, DMAC_CHEN); + if (chan->chip->dw->hdata->reg_map_8_channels) { + val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT | + BIT(chan->id) << DMAC_CHAN_EN_WE_SHIFT; + } else { + val |= BIT(chan->id) << DMAC_CHAN_EN_SHIFT | + BIT(chan->id) << DMAC_CHAN_EN2_WE_SHIFT; + } + axi_dma_iowrite32(chan->chip, DMAC_CHEN, (u32)val); + } } static inline bool axi_chan_is_hw_enable(struct axi_dma_chan *chan) { - u32 val; + u64 val; - val = axi_dma_ioread32(chan->chip, DMAC_CHEN); + if (chan->chip->dw->hdata->nr_channels >= DMAC_CHAN_16) + val = axi_dma_ioread64(chan->chip, DMAC_CHEN); + else + val = axi_dma_ioread32(chan->chip, DMAC_CHEN); - return !!(val & (BIT(chan->id) << DMAC_CHAN_EN_SHIFT)); + if (chan->id >= DMAC_CHAN_16) + return !!(val & ((u64)(BIT(chan->id) >> DMAC_CHAN_16) << DMAC_CHAN_BLOCK_SHIFT)); + else + return !!(val & (BIT(chan->id) << DMAC_CHAN_EN_SHIFT)); } static void axi_dma_hw_init(struct axi_dma_chip *chip) @@ -1175,20 +1221,34 @@ static int dma_chan_pause(struct dma_chan *dchan) struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); unsigned long flags; unsigned int timeout = 20; /* timeout iterations */ - u32 val; + u64 val; spin_lock_irqsave(&chan->vc.lock, flags); - if (chan->chip->dw->hdata->reg_map_8_channels) { - val = axi_dma_ioread32(chan->chip, DMAC_CHEN); - val |= BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT | - BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT; - axi_dma_iowrite32(chan->chip, DMAC_CHEN, val); + if (chan->chip->dw->hdata->nr_channels >= DMAC_CHAN_16) { + val = axi_dma_ioread64(chan->chip, DMAC_CHSUSPREG); + if (chan->id >= DMAC_CHAN_16) { + val |= (u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_SUSP2_SHIFT + DMAC_CHAN_BLOCK_SHIFT) | + (u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_SUSP2_WE_SHIFT + DMAC_CHAN_BLOCK_SHIFT); + } else { + val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT | + BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT; + } + axi_dma_iowrite64(chan->chip, DMAC_CHSUSPREG, val); } else { - val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG); - val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT | + if (chan->chip->dw->hdata->reg_map_8_channels) { + val = axi_dma_ioread32(chan->chip, DMAC_CHEN); + val |= BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT | + BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT; + axi_dma_iowrite32(chan->chip, DMAC_CHEN, (u32)val); + } else { + val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG); + val |= BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT | BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT; - axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val); + axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, (u32)val); + } } do { @@ -1210,18 +1270,32 @@ static int dma_chan_pause(struct dma_chan *dchan) /* Called in chan locked context */ static inline void axi_chan_resume(struct axi_dma_chan *chan) { - u32 val; + u64 val; - if (chan->chip->dw->hdata->reg_map_8_channels) { - val = axi_dma_ioread32(chan->chip, DMAC_CHEN); - val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT); - val |= (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT); - axi_dma_iowrite32(chan->chip, DMAC_CHEN, val); + if (chan->chip->dw->hdata->nr_channels >= DMAC_CHAN_16) { + val = axi_dma_ioread64(chan->chip, DMAC_CHSUSPREG); + if (chan->id >= DMAC_CHAN_16) { + val &= ~((u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_SUSP2_SHIFT + DMAC_CHAN_BLOCK_SHIFT)); + val |= ((u64)(BIT(chan->id) >> DMAC_CHAN_16) + << (DMAC_CHAN_SUSP2_WE_SHIFT + DMAC_CHAN_BLOCK_SHIFT)); + } else { + val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT); + val |= (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT); + } + axi_dma_iowrite64(chan->chip, DMAC_CHSUSPREG, val); } else { - val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG); - val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT); - val |= (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT); - axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, val); + if (chan->chip->dw->hdata->reg_map_8_channels) { + val = axi_dma_ioread32(chan->chip, DMAC_CHEN); + val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP_SHIFT); + val |= (BIT(chan->id) << DMAC_CHAN_SUSP_WE_SHIFT); + axi_dma_iowrite32(chan->chip, DMAC_CHEN, (u32)val); + } else { + val = axi_dma_ioread32(chan->chip, DMAC_CHSUSPREG); + val &= ~(BIT(chan->id) << DMAC_CHAN_SUSP2_SHIFT); + val |= (BIT(chan->id) << DMAC_CHAN_SUSP2_WE_SHIFT); + axi_dma_iowrite32(chan->chip, DMAC_CHSUSPREG, (u32)val); + } } chan->is_paused = false; @@ -1535,7 +1609,7 @@ err_pm_disable: return ret; } -static int dw_remove(struct platform_device *pdev) +static void dw_remove(struct platform_device *pdev) { struct axi_dma_chip *chip = platform_get_drvdata(pdev); struct dw_axi_dma *dw = chip->dw; @@ -1564,8 +1638,6 @@ static int dw_remove(struct platform_device *pdev) list_del(&chan->vc.chan.device_node); tasklet_kill(&chan->vc.task); } - - return 0; } static const struct dev_pm_ops dw_axi_dma_pm_ops = { @@ -1588,7 +1660,7 @@ MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); static struct platform_driver dw_driver = { .probe = dw_probe, - .remove = dw_remove, + .remove_new = dw_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = dw_dma_of_id_table, diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index eb267cb24f67..454904d99654 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -18,7 +18,7 @@ #include "../virt-dma.h" -#define DMAC_MAX_CHANNELS 16 +#define DMAC_MAX_CHANNELS 32 #define DMAC_MAX_MASTERS 2 #define DMAC_MAX_BLK_SIZE 0x200000 @@ -222,6 +222,10 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan) /* DMAC_CHEN2 */ #define DMAC_CHAN_EN2_WE_SHIFT 16 +/* DMAC CHAN BLOCKS */ +#define DMAC_CHAN_BLOCK_SHIFT 32 +#define DMAC_CHAN_16 16 + /* DMAC_CHSUSP */ #define DMAC_CHAN_SUSP2_SHIFT 0 #define DMAC_CHAN_SUSP2_WE_SHIFT 16 diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index 47f2292dba98..7d9d4c951724 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -93,7 +93,7 @@ err_dw_dma_probe: return err; } -static int dw_remove(struct platform_device *pdev) +static void dw_remove(struct platform_device *pdev) { struct dw_dma_chip_pdata *data = platform_get_drvdata(pdev); struct dw_dma_chip *chip = data->chip; @@ -109,8 +109,6 @@ static int dw_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); clk_disable_unprepare(chip->clk); - - return 0; } static void dw_shutdown(struct platform_device *pdev) @@ -193,7 +191,7 @@ static const struct dev_pm_ops dw_dev_pm_ops = { static struct platform_driver dw_driver = { .probe = dw_probe, - .remove = dw_remove, + .remove_new = dw_remove, .shutdown = dw_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index 5c4a448a1254..d6c60635e90d 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -213,7 +213,7 @@ struct ep93xx_dma_engine { #define INTERRUPT_NEXT_BUFFER 2 size_t num_channels; - struct ep93xx_dma_chan channels[]; + struct ep93xx_dma_chan channels[] __counted_by(num_channels); }; static inline struct device *chan2dev(struct ep93xx_dma_chan *edmac) diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c index a42a37634881..7958ac33e36c 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -814,7 +814,6 @@ static const struct fsl_mc_device_id dpaa2_qdma_id_table[] = { static struct fsl_mc_driver dpaa2_qdma_driver = { .driver = { .name = "dpaa2-qdma", - .owner = THIS_MODULE, }, .probe = dpaa2_qdma_probe, .remove = dpaa2_qdma_remove, diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index 40d50cc3d75a..bb5221158a77 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -225,7 +225,7 @@ struct fsl_edma_engine { bool big_endian; struct edma_regs regs; u64 chan_masked; - struct fsl_edma_chan chans[]; + struct fsl_edma_chan chans[] __counted_by(n_chans); }; #define edma_read_tcdreg(chan, __name) \ diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index 8c4ed7012e23..4635e16d7705 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -13,13 +13,11 @@ #include #include #include -#include -#include -#include #include #include #include #include +#include #include "fsl-edma-common.h" @@ -232,10 +230,8 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi /* request channel irq */ fsl_chan->txirq = platform_get_irq(pdev, i); - if (fsl_chan->txirq < 0) { - dev_err(&pdev->dev, "Can't get chan %d's irq.\n", i); + if (fsl_chan->txirq < 0) return -EINVAL; - } ret = devm_request_irq(&pdev->dev, fsl_chan->txirq, fsl_edma3_tx_handler, IRQF_SHARED, @@ -418,8 +414,6 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng static int fsl_edma_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(fsl_edma_dt_ids, &pdev->dev); struct device_node *np = pdev->dev.of_node; struct fsl_edma_engine *fsl_edma; const struct fsl_edma_drvdata *drvdata = NULL; @@ -428,8 +422,7 @@ static int fsl_edma_probe(struct platform_device *pdev) int chans; int ret, i; - if (of_id) - drvdata = of_id->data; + drvdata = device_get_match_data(&pdev->dev); if (!drvdata) { dev_err(&pdev->dev, "unable to find driver data\n"); return -EINVAL; @@ -617,7 +610,7 @@ static int fsl_edma_probe(struct platform_device *pdev) return 0; } -static int fsl_edma_remove(struct platform_device *pdev) +static void fsl_edma_remove(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev); @@ -627,8 +620,6 @@ static int fsl_edma_remove(struct platform_device *pdev) of_dma_controller_free(np); dma_async_device_unregister(&fsl_edma->dma_dev); fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs); - - return 0; } static int fsl_edma_suspend_late(struct device *dev) @@ -692,7 +683,7 @@ static struct platform_driver fsl_edma_driver = { .pm = &fsl_edma_pm_ops, }, .probe = fsl_edma_probe, - .remove = fsl_edma_remove, + .remove_new = fsl_edma_remove, }; static int __init fsl_edma_init(void) diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c index a8cc8a4bc610..47cb28468049 100644 --- a/drivers/dma/fsl-qdma.c +++ b/drivers/dma/fsl-qdma.c @@ -1266,7 +1266,7 @@ static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev) } } -static int fsl_qdma_remove(struct platform_device *pdev) +static void fsl_qdma_remove(struct platform_device *pdev) { int i; struct fsl_qdma_queue *status; @@ -1283,7 +1283,6 @@ static int fsl_qdma_remove(struct platform_device *pdev) dma_free_coherent(&pdev->dev, sizeof(struct fsl_qdma_format) * status->n_cq, status->cq, status->bus_addr); } - return 0; } static const struct of_device_id fsl_qdma_dt_ids[] = { @@ -1298,7 +1297,7 @@ static struct platform_driver fsl_qdma_driver = { .of_match_table = fsl_qdma_dt_ids, }, .probe = fsl_qdma_probe, - .remove = fsl_qdma_remove, + .remove_new = fsl_qdma_remove, }; module_platform_driver(fsl_qdma_driver); diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c index 0b9ca93ce3dc..014ff523d5ec 100644 --- a/drivers/dma/fsl_raid.c +++ b/drivers/dma/fsl_raid.c @@ -857,7 +857,7 @@ static void fsl_re_remove_chan(struct fsl_re_chan *chan) chan->oub_phys_addr); } -static int fsl_re_remove(struct platform_device *ofdev) +static void fsl_re_remove(struct platform_device *ofdev) { struct fsl_re_drv_private *re_priv; struct device *dev; @@ -872,8 +872,6 @@ static int fsl_re_remove(struct platform_device *ofdev) /* Unregister the driver */ dma_async_device_unregister(&re_priv->dma_dev); - - return 0; } static const struct of_device_id fsl_re_ids[] = { @@ -888,7 +886,7 @@ static struct platform_driver fsl_re_driver = { .of_match_table = fsl_re_ids, }, .probe = fsl_re_probe, - .remove = fsl_re_remove, + .remove_new = fsl_re_remove, }; module_platform_driver(fsl_re_driver); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index ddcf736d283d..18a6c4bf6275 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1306,7 +1306,7 @@ out_return: return err; } -static int fsldma_of_remove(struct platform_device *op) +static void fsldma_of_remove(struct platform_device *op) { struct fsldma_device *fdev; unsigned int i; @@ -1324,8 +1324,6 @@ static int fsldma_of_remove(struct platform_device *op) iounmap(fdev->regs); kfree(fdev); - - return 0; } #ifdef CONFIG_PM @@ -1406,7 +1404,7 @@ static struct platform_driver fsldma_of_driver = { #endif }, .probe = fsldma_of_probe, - .remove = fsldma_of_remove, + .remove_new = fsldma_of_remove, }; /*----------------------------------------------------------------------------*/ diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index c1350a36fddd..4c47bff81064 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -163,7 +163,7 @@ struct hisi_dma_dev { u32 chan_depth; enum hisi_dma_reg_layout reg_layout; void __iomem *queue_base; /* queue region start of register */ - struct hisi_dma_chan chan[]; + struct hisi_dma_chan chan[] __counted_by(chan_num); }; #ifdef CONFIG_DEBUG_FS diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 0ac634a51c5e..78a938969d7d 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -660,13 +660,11 @@ static int idma64_platform_probe(struct platform_device *pdev) return 0; } -static int idma64_platform_remove(struct platform_device *pdev) +static void idma64_platform_remove(struct platform_device *pdev) { struct idma64_chip *chip = platform_get_drvdata(pdev); idma64_remove(chip); - - return 0; } static int __maybe_unused idma64_pm_suspend(struct device *dev) @@ -691,7 +689,7 @@ static const struct dev_pm_ops idma64_dev_pm_ops = { static struct platform_driver idma64_platform_driver = { .probe = idma64_platform_probe, - .remove = idma64_platform_remove, + .remove_new = idma64_platform_remove, .driver = { .name = LPSS_IDMA64_DRIVER_NAME, .pm = &idma64_dev_pm_ops, diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile index dc096839ac63..c5e679070e46 100644 --- a/drivers/dma/idxd/Makefile +++ b/drivers/dma/idxd/Makefile @@ -1,12 +1,12 @@ ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD +obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o +idxd_bus-y := bus.o + obj-$(CONFIG_INTEL_IDXD) += idxd.o idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o -obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o -idxd_bus-y := bus.o - obj-$(CONFIG_INTEL_IDXD_COMPAT) += idxd_compat.o idxd_compat-y := compat.o diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index d32deb9b4e3d..0423655f5a88 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -509,6 +509,7 @@ void idxd_wq_del_cdev(struct idxd_wq *wq) static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) { + struct device *dev = &idxd_dev->conf_dev; struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); struct idxd_device *idxd = wq->idxd; int rc; @@ -536,6 +537,12 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) mutex_lock(&wq->wq_lock); + if (!idxd_wq_driver_name_match(wq, dev)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME; + rc = -ENODEV; + goto wq_err; + } + wq->wq = create_workqueue(dev_name(wq_confdev(wq))); if (!wq->wq) { rc = -ENOMEM; diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index 07623fb0f52f..47a01893cfdb 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -306,6 +306,12 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev) return -ENXIO; mutex_lock(&wq->wq_lock); + if (!idxd_wq_driver_name_match(wq, dev)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME; + rc = -ENODEV; + goto err; + } + wq->type = IDXD_WQT_KERNEL; rc = drv_enable_wq(wq); diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index e269ca1f4862..1e89c80a07fc 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -159,6 +159,8 @@ struct idxd_cdev { int minor; }; +#define DRIVER_NAME_SIZE 128 + #define IDXD_ALLOCATED_BATCH_SIZE 128U #define WQ_NAME_SIZE 1024 #define WQ_TYPE_SIZE 10 @@ -227,6 +229,8 @@ struct idxd_wq { /* Lock to protect upasid_xa access. */ struct mutex uc_lock; struct xarray upasid_xa; + + char driver_name[DRIVER_NAME_SIZE + 1]; }; struct idxd_engine { @@ -646,6 +650,11 @@ static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wq wqcfg->max_batch_shift = max_batch_shift; } +static inline int idxd_wq_driver_name_match(struct idxd_wq *wq, struct device *dev) +{ + return (strncmp(wq->driver_name, dev->driver->name, strlen(dev->driver->name)) == 0); +} + int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *module, const char *mod_name); #define idxd_driver_register(driver) \ diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index b501320a9c7a..2183d7f9cdbd 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -434,8 +434,8 @@ irqreturn_t idxd_misc_thread(int vec, void *data) val |= IDXD_INTC_ERR; for (i = 0; i < 4; i++) - dev_warn(dev, "err[%d]: %#16.16llx\n", - i, idxd->sw_err.bits[i]); + dev_warn_ratelimited(dev, "err[%d]: %#16.16llx\n", + i, idxd->sw_err.bits[i]); err = true; } diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 7caba90d85b3..523ae0dff7d4 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -1259,6 +1259,39 @@ err: static struct device_attribute dev_attr_wq_op_config = __ATTR(op_config, 0644, wq_op_config_show, wq_op_config_store); +static ssize_t wq_driver_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct idxd_wq *wq = confdev_to_wq(dev); + + return sysfs_emit(buf, "%s\n", wq->driver_name); +} + +static ssize_t wq_driver_name_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct idxd_wq *wq = confdev_to_wq(dev); + char *input, *pos; + + if (wq->state != IDXD_WQ_DISABLED) + return -EPERM; + + if (strlen(buf) > DRIVER_NAME_SIZE || strlen(buf) == 0) + return -EINVAL; + + input = kstrndup(buf, count, GFP_KERNEL); + if (!input) + return -ENOMEM; + + pos = strim(input); + memset(wq->driver_name, 0, DRIVER_NAME_SIZE + 1); + sprintf(wq->driver_name, "%s", pos); + kfree(input); + return count; +} + +static struct device_attribute dev_attr_wq_driver_name = + __ATTR(driver_name, 0644, wq_driver_name_show, wq_driver_name_store); + static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_clients.attr, &dev_attr_wq_state.attr, @@ -1278,6 +1311,7 @@ static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_occupancy.attr, &dev_attr_wq_enqcmds_retries.attr, &dev_attr_wq_op_config.attr, + &dev_attr_wq_driver_name.attr, NULL, }; diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index 9be0d3226e19..0532dd2640dc 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c @@ -1017,7 +1017,7 @@ suspend: return ret; } -static int mdc_dma_remove(struct platform_device *pdev) +static void mdc_dma_remove(struct platform_device *pdev) { struct mdc_dma *mdma = platform_get_drvdata(pdev); struct mdc_chan *mchan, *next; @@ -1037,8 +1037,6 @@ static int mdc_dma_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) img_mdc_runtime_suspend(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1078,7 +1076,7 @@ static struct platform_driver mdc_dma_driver = { .of_match_table = of_match_ptr(mdc_dma_of_match), }, .probe = mdc_dma_probe, - .remove = mdc_dma_remove, + .remove_new = mdc_dma_remove, }; module_platform_driver(mdc_dma_driver); diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 114f254b9f50..ebf7c115d553 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -1216,7 +1216,7 @@ static void imxdma_free_irq(struct platform_device *pdev, struct imxdma_engine * } } -static int imxdma_remove(struct platform_device *pdev) +static void imxdma_remove(struct platform_device *pdev) { struct imxdma_engine *imxdma = platform_get_drvdata(pdev); @@ -1229,8 +1229,6 @@ static int imxdma_remove(struct platform_device *pdev) clk_disable_unprepare(imxdma->dma_ipg); clk_disable_unprepare(imxdma->dma_ahb); - - return 0; } static struct platform_driver imxdma_driver = { @@ -1238,7 +1236,7 @@ static struct platform_driver imxdma_driver = { .name = "imx-dma", .of_match_table = imx_dma_of_dev_id, }, - .remove = imxdma_remove, + .remove_new = imxdma_remove, }; static int __init imxdma_module_init(void) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 51012bd39900..f81ecf5863e8 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -2358,7 +2358,7 @@ err_clk: return ret; } -static int sdma_remove(struct platform_device *pdev) +static void sdma_remove(struct platform_device *pdev) { struct sdma_engine *sdma = platform_get_drvdata(pdev); int i; @@ -2377,7 +2377,6 @@ static int sdma_remove(struct platform_device *pdev) } platform_set_drvdata(pdev, NULL); - return 0; } static struct platform_driver sdma_driver = { @@ -2385,7 +2384,7 @@ static struct platform_driver sdma_driver = { .name = "imx-sdma", .of_match_table = sdma_dt_ids, }, - .remove = sdma_remove, + .remove_new = sdma_remove, .probe = sdma_probe, }; diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index ecdaada95120..5de8c21d41e7 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -839,7 +838,6 @@ static int k3_dma_probe(struct platform_device *op) { const struct k3dma_soc_data *soc_data; struct k3_dma_dev *d; - const struct of_device_id *of_id; int i, ret, irq = 0; d = devm_kzalloc(&op->dev, sizeof(*d), GFP_KERNEL); @@ -854,19 +852,16 @@ static int k3_dma_probe(struct platform_device *op) if (IS_ERR(d->base)) return PTR_ERR(d->base); - of_id = of_match_device(k3_pdma_dt_ids, &op->dev); - if (of_id) { - of_property_read_u32((&op->dev)->of_node, - "dma-channels", &d->dma_channels); - of_property_read_u32((&op->dev)->of_node, - "dma-requests", &d->dma_requests); - ret = of_property_read_u32((&op->dev)->of_node, - "dma-channel-mask", &d->dma_channel_mask); - if (ret) { - dev_warn(&op->dev, - "dma-channel-mask doesn't exist, considering all as available.\n"); - d->dma_channel_mask = (u32)~0UL; - } + of_property_read_u32((&op->dev)->of_node, + "dma-channels", &d->dma_channels); + of_property_read_u32((&op->dev)->of_node, + "dma-requests", &d->dma_requests); + ret = of_property_read_u32((&op->dev)->of_node, + "dma-channel-mask", &d->dma_channel_mask); + if (ret) { + dev_warn(&op->dev, + "dma-channel-mask doesn't exist, considering all as available.\n"); + d->dma_channel_mask = (u32)~0UL; } if (!(soc_data->flags & K3_FLAG_NOCLK)) { @@ -974,7 +969,7 @@ dma_async_register_fail: return ret; } -static int k3_dma_remove(struct platform_device *op) +static void k3_dma_remove(struct platform_device *op) { struct k3_dma_chan *c, *cn; struct k3_dma_dev *d = platform_get_drvdata(op); @@ -990,7 +985,6 @@ static int k3_dma_remove(struct platform_device *op) } tasklet_kill(&d->task); clk_disable_unprepare(d->clk); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -1034,7 +1028,7 @@ static struct platform_driver k3_pdma_driver = { .of_match_table = k3_pdma_dt_ids, }, .probe = k3_dma_probe, - .remove = k3_dma_remove, + .remove_new = k3_dma_remove, }; module_platform_driver(k3_pdma_driver); diff --git a/drivers/dma/mcf-edma-main.c b/drivers/dma/mcf-edma-main.c index b359421ee9ea..ab21455d9c3a 100644 --- a/drivers/dma/mcf-edma-main.c +++ b/drivers/dma/mcf-edma-main.c @@ -255,15 +255,13 @@ static int mcf_edma_probe(struct platform_device *pdev) return 0; } -static int mcf_edma_remove(struct platform_device *pdev) +static void mcf_edma_remove(struct platform_device *pdev) { struct fsl_edma_engine *mcf_edma = platform_get_drvdata(pdev); mcf_edma_irq_free(pdev, mcf_edma); fsl_edma_cleanup_vchan(&mcf_edma->dma_dev); dma_async_device_unregister(&mcf_edma->dma_dev); - - return 0; } static struct platform_driver mcf_edma_driver = { @@ -271,7 +269,7 @@ static struct platform_driver mcf_edma_driver = { .name = "mcf-edma", }, .probe = mcf_edma_probe, - .remove = mcf_edma_remove, + .remove_new = mcf_edma_remove, }; bool mcf_edma_filter_fn(struct dma_chan *chan, void *param) diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c index 324b7387b1b9..529100c5b9f5 100644 --- a/drivers/dma/mediatek/mtk-cqdma.c +++ b/drivers/dma/mediatek/mtk-cqdma.c @@ -885,7 +885,7 @@ err_unregister: return err; } -static int mtk_cqdma_remove(struct platform_device *pdev) +static void mtk_cqdma_remove(struct platform_device *pdev) { struct mtk_cqdma_device *cqdma = platform_get_drvdata(pdev); struct mtk_cqdma_vchan *vc; @@ -918,13 +918,11 @@ static int mtk_cqdma_remove(struct platform_device *pdev) dma_async_device_unregister(&cqdma->ddev); of_dma_controller_free(pdev->dev.of_node); - - return 0; } static struct platform_driver mtk_cqdma_driver = { .probe = mtk_cqdma_probe, - .remove = mtk_cqdma_remove, + .remove_new = mtk_cqdma_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = mtk_cqdma_match, diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c index 64120767d983..36ff11e909ea 100644 --- a/drivers/dma/mediatek/mtk-hsdma.c +++ b/drivers/dma/mediatek/mtk-hsdma.c @@ -1009,7 +1009,7 @@ err_unregister: return err; } -static int mtk_hsdma_remove(struct platform_device *pdev) +static void mtk_hsdma_remove(struct platform_device *pdev) { struct mtk_hsdma_device *hsdma = platform_get_drvdata(pdev); struct mtk_hsdma_vchan *vc; @@ -1034,13 +1034,11 @@ static int mtk_hsdma_remove(struct platform_device *pdev) dma_async_device_unregister(&hsdma->ddev); of_dma_controller_free(pdev->dev.of_node); - - return 0; } static struct platform_driver mtk_hsdma_driver = { .probe = mtk_hsdma_probe, - .remove = mtk_hsdma_remove, + .remove_new = mtk_hsdma_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = mtk_hsdma_match, diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c index 06d12ac39144..1bdc1500be40 100644 --- a/drivers/dma/mediatek/mtk-uart-apdma.c +++ b/drivers/dma/mediatek/mtk-uart-apdma.c @@ -572,7 +572,7 @@ err_no_dma: return rc; } -static int mtk_uart_apdma_remove(struct platform_device *pdev) +static void mtk_uart_apdma_remove(struct platform_device *pdev) { struct mtk_uart_apdmadev *mtkd = platform_get_drvdata(pdev); @@ -583,8 +583,6 @@ static int mtk_uart_apdma_remove(struct platform_device *pdev) dma_async_device_unregister(&mtkd->ddev); pm_runtime_disable(&pdev->dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -639,7 +637,7 @@ static const struct dev_pm_ops mtk_uart_apdma_pm_ops = { static struct platform_driver mtk_uart_apdma_driver = { .probe = mtk_uart_apdma_probe, - .remove = mtk_uart_apdma_remove, + .remove_new = mtk_uart_apdma_remove, .driver = { .name = KBUILD_MODNAME, .pm = &mtk_uart_apdma_pm_ops, diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index ebdfdcbb4f7a..136fcaeff8dd 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -932,7 +931,7 @@ static void dma_do_tasklet(struct tasklet_struct *t) } } -static int mmp_pdma_remove(struct platform_device *op) +static void mmp_pdma_remove(struct platform_device *op) { struct mmp_pdma_device *pdev = platform_get_drvdata(op); struct mmp_pdma_phy *phy; @@ -958,7 +957,6 @@ static int mmp_pdma_remove(struct platform_device *op) } dma_async_device_unregister(&pdev->device); - return 0; } static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq) @@ -1020,7 +1018,6 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, static int mmp_pdma_probe(struct platform_device *op) { struct mmp_pdma_device *pdev; - const struct of_device_id *of_id; struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev); int i, ret, irq = 0; int dma_channels = 0, irq_num = 0; @@ -1040,8 +1037,7 @@ static int mmp_pdma_probe(struct platform_device *op) if (IS_ERR(pdev->base)) return PTR_ERR(pdev->base); - of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev); - if (of_id) { + if (pdev->dev->of_node) { /* Parse new and deprecated dma-channels properties */ if (of_property_read_u32(pdev->dev->of_node, "dma-channels", &dma_channels)) @@ -1141,7 +1137,7 @@ static struct platform_driver mmp_pdma_driver = { }, .id_table = mmp_pdma_id_table, .probe = mmp_pdma_probe, - .remove = mmp_pdma_remove, + .remove_new = mmp_pdma_remove, }; module_platform_driver(mmp_pdma_driver); diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index d49fa6bc6775..b76fe99e1151 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -14,9 +14,9 @@ #include #include #include +#include #include #include -#include #include #include "dmaengine.h" @@ -552,12 +552,10 @@ static void mmp_tdma_issue_pending(struct dma_chan *chan) mmp_tdma_enable_chan(tdmac); } -static int mmp_tdma_remove(struct platform_device *pdev) +static void mmp_tdma_remove(struct platform_device *pdev) { if (pdev->dev.of_node) of_dma_controller_free(pdev->dev.of_node); - - return 0; } static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev, @@ -637,18 +635,13 @@ MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids); static int mmp_tdma_probe(struct platform_device *pdev) { enum mmp_tdma_type type; - const struct of_device_id *of_id; struct mmp_tdma_device *tdev; int i, ret; int irq = 0, irq_num = 0; int chan_num = TDMA_CHANNEL_NUM; struct gen_pool *pool = NULL; - of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev); - if (of_id) - type = (enum mmp_tdma_type) of_id->data; - else - type = platform_get_device_id(pdev)->driver_data; + type = (enum mmp_tdma_type)device_get_match_data(&pdev->dev); /* always have couple channels */ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL); @@ -726,34 +719,24 @@ static int mmp_tdma_probe(struct platform_device *pdev) return ret; } - if (pdev->dev.of_node) { - ret = of_dma_controller_register(pdev->dev.of_node, - mmp_tdma_xlate, tdev); - if (ret) { - dev_err(tdev->device.dev, - "failed to register controller\n"); - return ret; - } + ret = of_dma_controller_register(pdev->dev.of_node, + mmp_tdma_xlate, tdev); + if (ret) { + dev_err(tdev->device.dev, "failed to register controller\n"); + return ret; } dev_info(tdev->device.dev, "initialized\n"); return 0; } -static const struct platform_device_id mmp_tdma_id_table[] = { - { "mmp-adma", MMP_AUD_TDMA }, - { "pxa910-squ", PXA910_SQU }, - { }, -}; - static struct platform_driver mmp_tdma_driver = { .driver = { .name = "mmp-tdma", .of_match_table = mmp_tdma_dt_ids, }, - .id_table = mmp_tdma_id_table, .probe = mmp_tdma_probe, - .remove = mmp_tdma_remove, + .remove_new = mmp_tdma_remove, }; module_platform_driver(mmp_tdma_driver); diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index 7565ad98ba66..c48d68cbff92 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -124,7 +124,7 @@ struct moxart_desc { unsigned int dma_cycles; struct virt_dma_desc vd; uint8_t es; - struct moxart_sg sg[]; + struct moxart_sg sg[] __counted_by(sglen); }; struct moxart_chan { @@ -309,6 +309,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( d = kzalloc(struct_size(d, sg, sg_len), GFP_ATOMIC); if (!d) return NULL; + d->sglen = sg_len; d->dma_dir = dir; d->dev_addr = dev_addr; @@ -319,8 +320,6 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( d->sg[i].len = sg_dma_len(sgent); } - d->sglen = sg_len; - ch->error = 0; return vchan_tx_prep(&ch->vc, &d->vd, tx_flags); @@ -630,7 +629,7 @@ static int moxart_probe(struct platform_device *pdev) return 0; } -static int moxart_remove(struct platform_device *pdev) +static void moxart_remove(struct platform_device *pdev) { struct moxart_dmadev *m = platform_get_drvdata(pdev); @@ -640,8 +639,6 @@ static int moxart_remove(struct platform_device *pdev) if (pdev->dev.of_node) of_dma_controller_free(pdev->dev.of_node); - - return 0; } static const struct of_device_id moxart_dma_match[] = { @@ -652,7 +649,7 @@ MODULE_DEVICE_TABLE(of, moxart_dma_match); static struct platform_driver moxart_driver = { .probe = moxart_probe, - .remove = moxart_remove, + .remove_new = moxart_remove, .driver = { .name = "moxart-dma-engine", .of_match_table = moxart_dma_match, diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 1104017320b8..68c247a46321 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -1084,7 +1084,7 @@ err: return retval; } -static int mpc_dma_remove(struct platform_device *op) +static void mpc_dma_remove(struct platform_device *op) { struct device *dev = &op->dev; struct mpc_dma *mdma = dev_get_drvdata(dev); @@ -1099,8 +1099,6 @@ static int mpc_dma_remove(struct platform_device *op) free_irq(mdma->irq, mdma); irq_dispose_mapping(mdma->irq); tasklet_kill(&mdma->tasklet); - - return 0; } static const struct of_device_id mpc_dma_match[] = { @@ -1112,7 +1110,7 @@ MODULE_DEVICE_TABLE(of, mpc_dma_match); static struct platform_driver mpc_dma_driver = { .probe = mpc_dma_probe, - .remove = mpc_dma_remove, + .remove_new = mpc_dma_remove, .driver = { .name = DRV_NAME, .of_match_table = mpc_dma_match, diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 23b232b57518..bcd3b623ac6c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -10,8 +10,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -1328,13 +1328,8 @@ static int mv_xor_probe(struct platform_device *pdev) * setting up. In non-dt case it can only be the legacy one. */ xordev->xor_type = XOR_ORION; - if (pdev->dev.of_node) { - const struct of_device_id *of_id = - of_match_device(mv_xor_dt_ids, - &pdev->dev); - - xordev->xor_type = (uintptr_t)of_id->data; - } + if (pdev->dev.of_node) + xordev->xor_type = (uintptr_t)device_get_match_data(&pdev->dev); /* * (Re-)program MBUS remapping windows if we are asked to. diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c index 0e1e9ca1c005..1ebfbe88e733 100644 --- a/drivers/dma/mv_xor_v2.c +++ b/drivers/dma/mv_xor_v2.c @@ -855,7 +855,7 @@ free_msi_irqs: return ret; } -static int mv_xor_v2_remove(struct platform_device *pdev) +static void mv_xor_v2_remove(struct platform_device *pdev) { struct mv_xor_v2_device *xor_dev = platform_get_drvdata(pdev); @@ -870,8 +870,6 @@ static int mv_xor_v2_remove(struct platform_device *pdev) platform_msi_domain_free_irqs(&pdev->dev); tasklet_kill(&xor_dev->irq_tasklet); - - return 0; } #ifdef CONFIG_OF @@ -886,7 +884,7 @@ static struct platform_driver mv_xor_v2_driver = { .probe = mv_xor_v2_probe, .suspend = mv_xor_v2_suspend, .resume = mv_xor_v2_resume, - .remove = mv_xor_v2_remove, + .remove_new = mv_xor_v2_remove, .driver = { .name = "mv_xor_v2", .of_match_table = of_match_ptr(mv_xor_v2_dt_ids), diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 0b2f96fd8bf0..c08916339aa7 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1454,7 +1454,7 @@ e_clk_off: return ret; } -static int nbpf_remove(struct platform_device *pdev) +static void nbpf_remove(struct platform_device *pdev) { struct nbpf_device *nbpf = platform_get_drvdata(pdev); int i; @@ -1472,8 +1472,6 @@ static int nbpf_remove(struct platform_device *pdev) of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&nbpf->dma_dev); clk_disable_unprepare(nbpf->clk); - - return 0; } static const struct platform_device_id nbpf_ids[] = { @@ -1517,7 +1515,7 @@ static struct platform_driver nbpf_driver = { }, .id_table = nbpf_ids, .probe = nbpf_probe, - .remove = nbpf_remove, + .remove_new = nbpf_remove, }; module_platform_driver(nbpf_driver); diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c index 384476757c5e..4e76c4ec2d39 100644 --- a/drivers/dma/owl-dma.c +++ b/drivers/dma/owl-dma.c @@ -1231,7 +1231,7 @@ err_pool_free: return ret; } -static int owl_dma_remove(struct platform_device *pdev) +static void owl_dma_remove(struct platform_device *pdev) { struct owl_dma *od = platform_get_drvdata(pdev); @@ -1248,13 +1248,11 @@ static int owl_dma_remove(struct platform_device *pdev) clk_disable_unprepare(od->clk); dma_pool_destroy(od->lli_pool); - - return 0; } static struct platform_driver owl_dma_driver = { .probe = owl_dma_probe, - .remove = owl_dma_remove, + .remove_new = owl_dma_remove, .driver = { .name = "dma-owl", .of_match_table = of_match_ptr(owl_dma_match), diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index f9b82dff3387..bbb60a970dab 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4230,7 +4230,7 @@ out: /** * ppc440spe_adma_remove - remove the asynch device */ -static int ppc440spe_adma_remove(struct platform_device *ofdev) +static void ppc440spe_adma_remove(struct platform_device *ofdev) { struct ppc440spe_adma_device *adev = platform_get_drvdata(ofdev); struct device_node *np = ofdev->dev.of_node; @@ -4278,7 +4278,6 @@ static int ppc440spe_adma_remove(struct platform_device *ofdev) of_address_to_resource(np, 0, &res); release_mem_region(res.start, resource_size(&res)); kfree(adev); - return 0; } /* @@ -4550,7 +4549,7 @@ MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); static struct platform_driver ppc440spe_adma_driver = { .probe = ppc440spe_adma_probe, - .remove = ppc440spe_adma_remove, + .remove_new = ppc440spe_adma_remove, .driver = { .name = "PPC440SP(E)-ADMA", .of_match_table = ppc440spe_adma_of_match, diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index 1b046d9a3a26..31f8da810c05 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -15,9 +15,8 @@ #include #include #include -#include -#include #include +#include #include #include @@ -91,7 +90,8 @@ struct pxad_desc_sw { bool cyclic; struct dma_pool *desc_pool; /* Channel's used allocator */ - struct pxad_desc_hw *hw_desc[]; /* DMA coherent descriptors */ + struct pxad_desc_hw *hw_desc[] __counted_by(nb_desc); + /* DMA coherent descriptors */ }; struct pxad_phy { @@ -722,7 +722,6 @@ static void pxad_free_desc(struct virt_dma_desc *vd) dma_addr_t dma; struct pxad_desc_sw *sw_desc = to_pxad_sw_desc(vd); - BUG_ON(sw_desc->nb_desc == 0); for (i = sw_desc->nb_desc - 1; i >= 0; i--) { if (i > 0) dma = sw_desc->hw_desc[i - 1]->ddadr; @@ -740,6 +739,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) { struct pxad_desc_sw *sw_desc; dma_addr_t dma; + void *desc; int i; sw_desc = kzalloc(struct_size(sw_desc, hw_desc, nb_hw_desc), @@ -749,20 +749,21 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) sw_desc->desc_pool = chan->desc_pool; for (i = 0; i < nb_hw_desc; i++) { - sw_desc->hw_desc[i] = dma_pool_alloc(sw_desc->desc_pool, - GFP_NOWAIT, &dma); - if (!sw_desc->hw_desc[i]) { + desc = dma_pool_alloc(sw_desc->desc_pool, GFP_NOWAIT, &dma); + if (!desc) { dev_err(&chan->vc.chan.dev->device, "%s(): Couldn't allocate the %dth hw_desc from dma_pool %p\n", __func__, i, sw_desc->desc_pool); goto err; } + sw_desc->nb_desc++; + sw_desc->hw_desc[i] = desc; + if (i == 0) sw_desc->first = dma; else sw_desc->hw_desc[i - 1]->ddadr = dma; - sw_desc->nb_desc++; } return sw_desc; @@ -1221,13 +1222,12 @@ static void pxad_free_channels(struct dma_device *dmadev) } } -static int pxad_remove(struct platform_device *op) +static void pxad_remove(struct platform_device *op) { struct pxad_device *pdev = platform_get_drvdata(op); pxad_cleanup_debugfs(pdev); pxad_free_channels(&pdev->slave); - return 0; } static int pxad_init_phys(struct platform_device *op, @@ -1343,7 +1343,6 @@ static int pxad_init_dmadev(struct platform_device *op, static int pxad_probe(struct platform_device *op) { struct pxad_device *pdev; - const struct of_device_id *of_id; const struct dma_slave_map *slave_map = NULL; struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev); int ret, dma_channels = 0, nb_requestors = 0, slave_map_cnt = 0; @@ -1361,8 +1360,7 @@ static int pxad_probe(struct platform_device *op) if (IS_ERR(pdev->base)) return PTR_ERR(pdev->base); - of_id = of_match_device(pxad_dt_ids, &op->dev); - if (of_id) { + if (op->dev.of_node) { /* Parse new and deprecated dma-channels properties */ if (of_property_read_u32(op->dev.of_node, "dma-channels", &dma_channels)) @@ -1444,7 +1442,7 @@ static struct platform_driver pxad_driver = { }, .id_table = pxad_id_table, .probe = pxad_probe, - .remove = pxad_remove, + .remove_new = pxad_remove, }; static bool pxad_filter_fn(struct dma_chan *chan, void *param) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 4c3eb972039d..5e7d332731e0 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -74,7 +74,7 @@ struct bam_async_desc { struct list_head desc_node; enum dma_transfer_direction dir; size_t length; - struct bam_desc_hw desc[]; + struct bam_desc_hw desc[] __counted_by(num_desc); }; enum bam_reg { @@ -1386,7 +1386,7 @@ err_disable_clk: return ret; } -static int bam_dma_remove(struct platform_device *pdev) +static void bam_dma_remove(struct platform_device *pdev) { struct bam_device *bdev = platform_get_drvdata(pdev); u32 i; @@ -1416,8 +1416,6 @@ static int bam_dma_remove(struct platform_device *pdev) tasklet_kill(&bdev->task); clk_disable_unprepare(bdev->bamclk); - - return 0; } static int __maybe_unused bam_dma_runtime_suspend(struct device *dev) @@ -1475,7 +1473,7 @@ static const struct dev_pm_ops bam_dma_pm_ops = { static struct platform_driver bam_dma_driver = { .probe = bam_dma_probe, - .remove = bam_dma_remove, + .remove_new = bam_dma_remove, .driver = { .name = "bam-dma-engine", .pm = &bam_dma_pm_ops, diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index 834ae519c15d..d63b93dc7047 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -745,7 +745,7 @@ static bool hidma_test_capability(struct device *dev, enum hidma_cap test_cap) { enum hidma_cap cap; - cap = (enum hidma_cap) device_get_match_data(dev); + cap = (uintptr_t) device_get_match_data(dev); return cap ? ((cap & test_cap) > 0) : 0; } @@ -915,7 +915,7 @@ static void hidma_shutdown(struct platform_device *pdev) } -static int hidma_remove(struct platform_device *pdev) +static void hidma_remove(struct platform_device *pdev) { struct hidma_dev *dmadev = platform_get_drvdata(pdev); @@ -935,8 +935,6 @@ static int hidma_remove(struct platform_device *pdev) dev_info(&pdev->dev, "HI-DMA engine removed\n"); pm_runtime_put_sync_suspend(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } #if IS_ENABLED(CONFIG_ACPI) @@ -960,7 +958,7 @@ MODULE_DEVICE_TABLE(of, hidma_match); static struct platform_driver hidma_driver = { .probe = hidma_probe, - .remove = hidma_remove, + .remove_new = hidma_remove, .shutdown = hidma_shutdown, .driver = { .name = "hidma", diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c index d56caf1681ff..53f4273b657c 100644 --- a/drivers/dma/qcom/qcom_adm.c +++ b/drivers/dma/qcom/qcom_adm.c @@ -904,7 +904,7 @@ err_disable_core_clk: return ret; } -static int adm_dma_remove(struct platform_device *pdev) +static void adm_dma_remove(struct platform_device *pdev) { struct adm_device *adev = platform_get_drvdata(pdev); struct adm_chan *achan; @@ -927,8 +927,6 @@ static int adm_dma_remove(struct platform_device *pdev) clk_disable_unprepare(adev->core_clk); clk_disable_unprepare(adev->iface_clk); - - return 0; } static const struct of_device_id adm_of_match[] = { @@ -939,7 +937,7 @@ MODULE_DEVICE_TABLE(of, adm_of_match); static struct platform_driver adm_dma_driver = { .probe = adm_dma_probe, - .remove = adm_dma_remove, + .remove_new = adm_dma_remove, .driver = { .name = "adm-dma-engine", .of_match_table = adm_of_match, diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index a29c13cae716..01e656c69e6c 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -78,7 +78,7 @@ struct sa11x0_dma_desc { bool cyclic; unsigned sglen; - struct sa11x0_dma_sg sg[]; + struct sa11x0_dma_sg sg[] __counted_by(sglen); }; struct sa11x0_dma_phy; @@ -558,6 +558,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; } + txd->sglen = j; j = 0; for_each_sg(sg, sgent, sglen, i) { @@ -593,7 +594,6 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( txd->ddar = c->ddar; txd->size = size; - txd->sglen = j; dev_dbg(chan->device->dev, "vchan %p: txd %p: size %zu nr %u\n", &c->vc, &txd->vd, txd->size, txd->sglen); @@ -628,6 +628,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; } + txd->sglen = sglen; for (i = k = 0; i < size / period; i++) { size_t tlen, len = period; @@ -653,7 +654,6 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( txd->ddar = c->ddar; txd->size = size; - txd->sglen = sglen; txd->cyclic = 1; txd->period = sgperiod; @@ -984,7 +984,7 @@ static int sa11x0_dma_probe(struct platform_device *pdev) return ret; } -static int sa11x0_dma_remove(struct platform_device *pdev) +static void sa11x0_dma_remove(struct platform_device *pdev) { struct sa11x0_dma_dev *d = platform_get_drvdata(pdev); unsigned pch; @@ -997,8 +997,6 @@ static int sa11x0_dma_remove(struct platform_device *pdev) tasklet_kill(&d->task); iounmap(d->base); kfree(d); - - return 0; } static __maybe_unused int sa11x0_dma_suspend(struct device *dev) @@ -1081,7 +1079,7 @@ static struct platform_driver sa11x0_dma_driver = { .pm = &sa11x0_dma_pm_ops, }, .probe = sa11x0_dma_probe, - .remove = sa11x0_dma_remove, + .remove_new = sa11x0_dma_remove, }; static int __init sa11x0_dma_init(void) diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c index d1c6956af452..3125a2f162b4 100644 --- a/drivers/dma/sf-pdma/sf-pdma.c +++ b/drivers/dma/sf-pdma/sf-pdma.c @@ -566,7 +566,7 @@ static int sf_pdma_probe(struct platform_device *pdev) return 0; } -static int sf_pdma_remove(struct platform_device *pdev) +static void sf_pdma_remove(struct platform_device *pdev) { struct sf_pdma *pdma = platform_get_drvdata(pdev); struct sf_pdma_chan *ch; @@ -584,8 +584,6 @@ static int sf_pdma_remove(struct platform_device *pdev) } dma_async_device_unregister(&pdma->dma_dev); - - return 0; } static const struct of_device_id sf_pdma_dt_ids[] = { @@ -597,7 +595,7 @@ MODULE_DEVICE_TABLE(of, sf_pdma_dt_ids); static struct platform_driver sf_pdma_driver = { .probe = sf_pdma_probe, - .remove = sf_pdma_remove, + .remove_new = sf_pdma_remove, .driver = { .name = "sf-pdma", .of_match_table = sf_pdma_dt_ids, diff --git a/drivers/dma/sf-pdma/sf-pdma.h b/drivers/dma/sf-pdma/sf-pdma.h index 5c398a83b491..d05772b5d8d3 100644 --- a/drivers/dma/sf-pdma/sf-pdma.h +++ b/drivers/dma/sf-pdma/sf-pdma.h @@ -113,7 +113,7 @@ struct sf_pdma { void __iomem *membase; void __iomem *mappedbase; u32 n_chans; - struct sf_pdma_chan chans[]; + struct sf_pdma_chan chans[] __counted_by(n_chans); }; #endif /* _SF_PDMA_H */ diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 641d689d17ff..40482cb73d79 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1990,7 +1990,7 @@ err_pm_disable: return ret; } -static int rcar_dmac_remove(struct platform_device *pdev) +static void rcar_dmac_remove(struct platform_device *pdev) { struct rcar_dmac *dmac = platform_get_drvdata(pdev); @@ -1998,8 +1998,6 @@ static int rcar_dmac_remove(struct platform_device *pdev) dma_async_device_unregister(&dmac->engine); pm_runtime_disable(&pdev->dev); - - return 0; } static void rcar_dmac_shutdown(struct platform_device *pdev) @@ -2041,7 +2039,7 @@ static struct platform_driver rcar_dmac_driver = { .of_match_table = rcar_dmac_of_ids, }, .probe = rcar_dmac_probe, - .remove = rcar_dmac_remove, + .remove_new = rcar_dmac_remove, .shutdown = rcar_dmac_shutdown, }; diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index f777addda8ba..fea5bda34bc2 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -969,7 +969,7 @@ err_pm_disable: return ret; } -static int rz_dmac_remove(struct platform_device *pdev) +static void rz_dmac_remove(struct platform_device *pdev) { struct rz_dmac *dmac = platform_get_drvdata(pdev); unsigned int i; @@ -987,8 +987,6 @@ static int rz_dmac_remove(struct platform_device *pdev) reset_control_assert(dmac->rstc); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct of_device_id of_rz_dmac_match[] = { @@ -1003,7 +1001,7 @@ static struct platform_driver rz_dmac_driver = { .of_match_table = of_rz_dmac_match, }, .probe = rz_dmac_probe, - .remove = rz_dmac_remove, + .remove_new = rz_dmac_remove, }; module_platform_driver(rz_dmac_driver); diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index 00067b29e232..7cc9eb2217e8 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -882,7 +882,7 @@ eshdma: return err; } -static int sh_dmae_remove(struct platform_device *pdev) +static void sh_dmae_remove(struct platform_device *pdev) { struct sh_dmae_device *shdev = platform_get_drvdata(pdev); struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev; @@ -899,8 +899,6 @@ static int sh_dmae_remove(struct platform_device *pdev) shdma_cleanup(&shdev->shdma_dev); synchronize_rcu(); - - return 0; } static struct platform_driver sh_dmae_driver = { @@ -908,7 +906,7 @@ static struct platform_driver sh_dmae_driver = { .pm = &sh_dmae_pm, .name = SH_DMAE_DRV_NAME, }, - .remove = sh_dmae_remove, + .remove_new = sh_dmae_remove, }; static int __init sh_dmae_init(void) diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index b14cf350b669..a9b4302f6050 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -57,7 +57,7 @@ struct usb_dmac_desc { u32 residue; struct list_head node; dma_cookie_t done_cookie; - struct usb_dmac_sg sg[]; + struct usb_dmac_sg sg[] __counted_by(sg_allocated_len); }; #define to_usb_dmac_desc(vd) container_of(vd, struct usb_dmac_desc, vd) @@ -866,7 +866,7 @@ static void usb_dmac_chan_remove(struct usb_dmac *dmac, devm_free_irq(dmac->dev, uchan->irq, uchan); } -static int usb_dmac_remove(struct platform_device *pdev) +static void usb_dmac_remove(struct platform_device *pdev) { struct usb_dmac *dmac = platform_get_drvdata(pdev); int i; @@ -877,8 +877,6 @@ static int usb_dmac_remove(struct platform_device *pdev) dma_async_device_unregister(&dmac->engine); pm_runtime_disable(&pdev->dev); - - return 0; } static void usb_dmac_shutdown(struct platform_device *pdev) @@ -901,7 +899,7 @@ static struct platform_driver usb_dmac_driver = { .of_match_table = usb_dmac_of_ids, }, .probe = usb_dmac_probe, - .remove = usb_dmac_remove, + .remove_new = usb_dmac_remove, .shutdown = usb_dmac_shutdown, }; diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 168aa0bd73a0..3f54ff37c5e0 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -212,7 +212,7 @@ struct sprd_dma_dev { struct clk *ashb_clk; int irq; u32 total_chns; - struct sprd_dma_chn channels[]; + struct sprd_dma_chn channels[] __counted_by(total_chns); }; static void sprd_dma_free_desc(struct virt_dma_desc *vd); @@ -572,8 +572,7 @@ static void sprd_dma_stop(struct sprd_dma_chn *schan) schan->cur_desc = NULL; } -static bool sprd_dma_check_trans_done(struct sprd_dma_desc *sdesc, - enum sprd_dma_int_type int_type, +static bool sprd_dma_check_trans_done(enum sprd_dma_int_type int_type, enum sprd_dma_req_mode req_mode) { if (int_type == SPRD_DMA_NO_INT) @@ -619,8 +618,7 @@ static irqreturn_t dma_irq_handle(int irq, void *dev_id) vchan_cyclic_callback(&sdesc->vd); } else { /* Check if the dma request descriptor is done. */ - trans_done = sprd_dma_check_trans_done(sdesc, int_type, - req_type); + trans_done = sprd_dma_check_trans_done(int_type, req_type); if (trans_done == true) { vchan_cookie_complete(&sdesc->vd); schan->cur_desc = NULL; @@ -1117,6 +1115,15 @@ static int sprd_dma_probe(struct platform_device *pdev) u32 chn_count; int ret, i; + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); + if (ret) { + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "unable to set coherent mask to 32\n"); + return ret; + } + } + /* Parse new and deprecated dma-channels properties */ ret = device_property_read_u32(&pdev->dev, "dma-channels", &chn_count); if (ret) @@ -1232,7 +1239,7 @@ err_rpm: return ret; } -static int sprd_dma_remove(struct platform_device *pdev) +static void sprd_dma_remove(struct platform_device *pdev) { struct sprd_dma_dev *sdev = platform_get_drvdata(pdev); struct sprd_dma_chn *c, *cn; @@ -1255,7 +1262,6 @@ static int sprd_dma_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); - return 0; } static const struct of_device_id sprd_dma_match[] = { @@ -1292,7 +1298,7 @@ static const struct dev_pm_ops sprd_dma_pm_ops = { static struct platform_driver sprd_dma_driver = { .probe = sprd_dma_probe, - .remove = sprd_dma_remove, + .remove_new = sprd_dma_remove, .driver = { .name = "sprd-dma", .of_match_table = sprd_dma_match, diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c index d95c421877fb..8880b5e336f8 100644 --- a/drivers/dma/st_fdma.c +++ b/drivers/dma/st_fdma.c @@ -10,9 +10,10 @@ #include #include -#include +#include #include #include +#include #include #include #include @@ -739,18 +740,11 @@ static void st_fdma_free(struct st_fdma_dev *fdev) static int st_fdma_probe(struct platform_device *pdev) { struct st_fdma_dev *fdev; - const struct of_device_id *match; struct device_node *np = pdev->dev.of_node; const struct st_fdma_driverdata *drvdata; int ret, i; - match = of_match_device((st_fdma_match), &pdev->dev); - if (!match || !match->data) { - dev_err(&pdev->dev, "No device match found\n"); - return -ENODEV; - } - - drvdata = match->data; + drvdata = device_get_match_data(&pdev->dev); fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL); if (!fdev) @@ -849,15 +843,13 @@ err: return ret; } -static int st_fdma_remove(struct platform_device *pdev) +static void st_fdma_remove(struct platform_device *pdev) { struct st_fdma_dev *fdev = platform_get_drvdata(pdev); devm_free_irq(&pdev->dev, fdev->irq, fdev); st_slim_rproc_put(fdev->slim_rproc); of_dma_controller_free(pdev->dev.of_node); - - return 0; } static struct platform_driver st_fdma_platform_driver = { @@ -866,7 +858,7 @@ static struct platform_driver st_fdma_platform_driver = { .of_match_table = st_fdma_match, }, .probe = st_fdma_probe, - .remove = st_fdma_remove, + .remove_new = st_fdma_remove, }; module_platform_driver(st_fdma_platform_driver); diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h index fa15b97a3bab..f296412e96b6 100644 --- a/drivers/dma/st_fdma.h +++ b/drivers/dma/st_fdma.h @@ -97,7 +97,7 @@ struct st_fdma_desc { struct st_fdma_chan *fchan; bool iscyclic; unsigned int n_nodes; - struct st_fdma_sw_node node[]; + struct st_fdma_sw_node node[] __counted_by(n_nodes); }; enum st_fdma_type { diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index 0b30151fb45c..72d83cd9ed6b 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -191,7 +190,7 @@ struct stm32_dma_desc { struct virt_dma_desc vdesc; bool cyclic; u32 num_sgs; - struct stm32_dma_sg_req sg_req[]; + struct stm32_dma_sg_req sg_req[] __counted_by(num_sgs); }; /** @@ -1105,6 +1104,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( desc = kzalloc(struct_size(desc, sg_req, sg_len), GFP_NOWAIT); if (!desc) return NULL; + desc->num_sgs = sg_len; /* Set peripheral flow controller */ if (chan->dma_sconfig.device_fc) @@ -1143,8 +1143,6 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( desc->sg_req[i].chan_reg.dma_sm1ar += sg_dma_len(sg); desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; } - - desc->num_sgs = sg_len; desc->cyclic = false; return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); @@ -1218,6 +1216,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( desc = kzalloc(struct_size(desc, sg_req, num_periods), GFP_NOWAIT); if (!desc) return NULL; + desc->num_sgs = num_periods; for (i = 0; i < num_periods; i++) { desc->sg_req[i].len = period_len; @@ -1234,8 +1233,6 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( if (!chan->trig_mdma) buf_addr += period_len; } - - desc->num_sgs = num_periods; desc->cyclic = true; return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); @@ -1256,6 +1253,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( desc = kzalloc(struct_size(desc, sg_req, num_sgs), GFP_NOWAIT); if (!desc) return NULL; + desc->num_sgs = num_sgs; threshold = chan->threshold; @@ -1285,8 +1283,6 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( desc->sg_req[i].chan_reg.dma_sndtr = xfer_count; desc->sg_req[i].len = xfer_count; } - - desc->num_sgs = num_sgs; desc->cyclic = false; return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); @@ -1567,17 +1563,10 @@ static int stm32_dma_probe(struct platform_device *pdev) struct stm32_dma_chan *chan; struct stm32_dma_device *dmadev; struct dma_device *dd; - const struct of_device_id *match; struct resource *res; struct reset_control *rst; int i, ret; - match = of_match_device(stm32_dma_of_match, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } - dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL); if (!dmadev) return -ENOMEM; diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index bae08b3f55c7..6505081ced44 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -224,7 +224,7 @@ struct stm32_mdma_desc { u32 ccr; bool cyclic; u32 count; - struct stm32_mdma_desc_node node[]; + struct stm32_mdma_desc_node node[] __counted_by(count); }; struct stm32_mdma_dma_config { @@ -256,7 +256,7 @@ struct stm32_mdma_device { u32 nr_ahb_addr_masks; u32 chan_reserved; struct stm32_mdma_chan chan[STM32_MDMA_MAX_CHANNELS]; - u32 ahb_addr_masks[]; + u32 ahb_addr_masks[] __counted_by(nr_ahb_addr_masks); }; static struct stm32_mdma_device *stm32_mdma_get_dev( @@ -321,6 +321,7 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( desc = kzalloc(struct_size(desc, node, count), GFP_NOWAIT); if (!desc) return NULL; + desc->count = count; for (i = 0; i < count; i++) { desc->node[i].hwdesc = @@ -330,8 +331,6 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( goto err; } - desc->count = count; - return desc; err: @@ -489,7 +488,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, src_maxburst = chan->dma_config.src_maxburst; dst_maxburst = chan->dma_config.dst_maxburst; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); @@ -965,7 +964,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src, if (!desc) return NULL; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); @@ -1627,13 +1626,13 @@ static int stm32_mdma_probe(struct platform_device *pdev) GFP_KERNEL); if (!dmadev) return -ENOMEM; + dmadev->nr_ahb_addr_masks = count; dmadev->nr_channels = nr_channels; dmadev->nr_requests = nr_requests; device_property_read_u32_array(&pdev->dev, "st,ahb-addr-masks", dmadev->ahb_addr_masks, count); - dmadev->nr_ahb_addr_masks = count; dmadev->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dmadev->base)) diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c index e86c8829513a..2e7f9b07fdd2 100644 --- a/drivers/dma/sun4i-dma.c +++ b/drivers/dma/sun4i-dma.c @@ -1271,7 +1271,7 @@ err_clk_disable: return ret; } -static int sun4i_dma_remove(struct platform_device *pdev) +static void sun4i_dma_remove(struct platform_device *pdev) { struct sun4i_dma_dev *priv = platform_get_drvdata(pdev); @@ -1282,8 +1282,6 @@ static int sun4i_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&priv->slave); clk_disable_unprepare(priv->clk); - - return 0; } static const struct of_device_id sun4i_dma_match[] = { @@ -1294,7 +1292,7 @@ MODULE_DEVICE_TABLE(of, sun4i_dma_match); static struct platform_driver sun4i_dma_driver = { .probe = sun4i_dma_probe, - .remove = sun4i_dma_remove, + .remove_new = sun4i_dma_remove, .driver = { .name = "sun4i-dma", .of_match_table = sun4i_dma_match, diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 2469efddf540..583bf49031cf 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -1470,7 +1470,7 @@ err_chan_free: return ret; } -static int sun6i_dma_remove(struct platform_device *pdev) +static void sun6i_dma_remove(struct platform_device *pdev) { struct sun6i_dma_dev *sdc = platform_get_drvdata(pdev); @@ -1484,13 +1484,11 @@ static int sun6i_dma_remove(struct platform_device *pdev) reset_control_assert(sdc->rstc); sun6i_dma_free(sdc); - - return 0; } static struct platform_driver sun6i_dma_driver = { .probe = sun6i_dma_probe, - .remove = sun6i_dma_remove, + .remove_new = sun6i_dma_remove, .driver = { .name = "sun6i-dma", .of_match_table = sun6i_dma_match, diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c index 33b101001100..fa4d4142a68a 100644 --- a/drivers/dma/tegra186-gpc-dma.c +++ b/drivers/dma/tegra186-gpc-dma.c @@ -221,7 +221,7 @@ struct tegra_dma_desc { unsigned int sg_count; struct virt_dma_desc vd; struct tegra_dma_channel *tdc; - struct tegra_dma_sg_req sg_req[]; + struct tegra_dma_sg_req sg_req[] __counted_by(sg_count); }; /* @@ -1473,14 +1473,12 @@ static int tegra_dma_probe(struct platform_device *pdev) return 0; } -static int tegra_dma_remove(struct platform_device *pdev) +static void tegra_dma_remove(struct platform_device *pdev) { struct tegra_dma *tdma = platform_get_drvdata(pdev); of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&tdma->dma_dev); - - return 0; } static int __maybe_unused tegra_dma_pm_suspend(struct device *dev) @@ -1533,7 +1531,7 @@ static struct platform_driver tegra_dma_driver = { .of_match_table = tegra_dma_of_match, }, .probe = tegra_dma_probe, - .remove = tegra_dma_remove, + .remove_new = tegra_dma_remove, }; module_platform_driver(tegra_dma_driver); diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 063022f9df76..ac69778827f2 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1581,7 +1581,7 @@ err_clk_unprepare: return ret; } -static int tegra_dma_remove(struct platform_device *pdev) +static void tegra_dma_remove(struct platform_device *pdev) { struct tegra_dma *tdma = platform_get_drvdata(pdev); @@ -1589,8 +1589,6 @@ static int tegra_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&tdma->dma_dev); pm_runtime_disable(&pdev->dev); clk_unprepare(tdma->dma_clk); - - return 0; } static int __maybe_unused tegra_dma_runtime_suspend(struct device *dev) @@ -1677,7 +1675,7 @@ static struct platform_driver tegra_dmac_driver = { .of_match_table = tegra_dma_of_match, }, .probe = tegra_dma_probe, - .remove = tegra_dma_remove, + .remove_new = tegra_dma_remove, }; module_platform_driver(tegra_dmac_driver); diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index e557bada1510..7a0586633bf3 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -162,7 +162,7 @@ struct tegra_adma { const struct tegra_adma_chip_data *cdata; /* Last member of the structure */ - struct tegra_adma_chan channels[]; + struct tegra_adma_chan channels[] __counted_by(nr_channels); }; static inline void tdma_write(struct tegra_adma *tdma, u32 reg, u32 val) @@ -949,7 +949,7 @@ irq_dispose: return ret; } -static int tegra_adma_remove(struct platform_device *pdev) +static void tegra_adma_remove(struct platform_device *pdev) { struct tegra_adma *tdma = platform_get_drvdata(pdev); int i; @@ -961,8 +961,6 @@ static int tegra_adma_remove(struct platform_device *pdev) irq_dispose_mapping(tdma->channels[i].irq); pm_runtime_disable(&pdev->dev); - - return 0; } static const struct dev_pm_ops tegra_adma_dev_pm_ops = { @@ -979,7 +977,7 @@ static struct platform_driver tegra_admac_driver = { .of_match_table = tegra_adma_of_match, }, .probe = tegra_adma_probe, - .remove = tegra_adma_remove, + .remove_new = tegra_adma_remove, }; module_platform_driver(tegra_admac_driver); diff --git a/drivers/dma/ti/cppi41.c b/drivers/dma/ti/cppi41.c index c3555cfb0681..7e0b06b5dff0 100644 --- a/drivers/dma/ti/cppi41.c +++ b/drivers/dma/ti/cppi41.c @@ -1156,7 +1156,7 @@ err_get_sync: return ret; } -static int cppi41_dma_remove(struct platform_device *pdev) +static void cppi41_dma_remove(struct platform_device *pdev) { struct cppi41_dd *cdd = platform_get_drvdata(pdev); int error; @@ -1173,7 +1173,6 @@ static int cppi41_dma_remove(struct platform_device *pdev) pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - return 0; } static int __maybe_unused cppi41_suspend(struct device *dev) @@ -1244,7 +1243,7 @@ static const struct dev_pm_ops cppi41_pm_ops = { static struct platform_driver cpp41_dma_driver = { .probe = cppi41_dma_probe, - .remove = cppi41_dma_remove, + .remove_new = cppi41_dma_remove, .driver = { .name = "cppi41-dma-engine", .pm = &cppi41_pm_ops, diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c index aa8e2e8ac260..f1f920861fa9 100644 --- a/drivers/dma/ti/edma.c +++ b/drivers/dma/ti/edma.c @@ -202,7 +202,7 @@ struct edma_desc { u32 residue; u32 residue_stat; - struct edma_pset pset[]; + struct edma_pset pset[] __counted_by(pset_nr); }; struct edma_cc; @@ -2401,7 +2401,7 @@ static int edma_probe(struct platform_device *pdev) if (irq < 0 && node) irq = irq_of_parse_and_map(node, 0); - if (irq >= 0) { + if (irq > 0) { irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", dev_name(dev)); ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, @@ -2417,7 +2417,7 @@ static int edma_probe(struct platform_device *pdev) if (irq < 0 && node) irq = irq_of_parse_and_map(node, 2); - if (irq >= 0) { + if (irq > 0) { irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", dev_name(dev)); ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, @@ -2550,7 +2550,7 @@ static void edma_cleanupp_vchan(struct dma_device *dmadev) } } -static int edma_remove(struct platform_device *pdev) +static void edma_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct edma_cc *ecc = dev_get_drvdata(dev); @@ -2568,8 +2568,6 @@ static int edma_remove(struct platform_device *pdev) edma_free_slot(ecc, ecc->dummy_slot); pm_runtime_put_sync(dev); pm_runtime_disable(dev); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -2628,7 +2626,7 @@ static const struct dev_pm_ops edma_pm_ops = { static struct platform_driver edma_driver = { .probe = edma_probe, - .remove = edma_remove, + .remove_new = edma_remove, .driver = { .name = "edma", .pm = &edma_pm_ops, diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c index cf96cf915c0c..b9e0e22383b7 100644 --- a/drivers/dma/ti/omap-dma.c +++ b/drivers/dma/ti/omap-dma.c @@ -124,7 +124,7 @@ struct omap_desc { uint32_t csdp; /* CSDP value */ unsigned sglen; - struct omap_sg sg[]; + struct omap_sg sg[] __counted_by(sglen); }; enum { @@ -1005,6 +1005,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( d = kzalloc(struct_size(d, sg, sglen), GFP_ATOMIC); if (!d) return NULL; + d->sglen = sglen; d->dir = dir; d->dev_addr = dev_addr; @@ -1120,8 +1121,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( } } - d->sglen = sglen; - /* Release the dma_pool entries if one allocation failed */ if (ll_failed) { for (i = 0; i < d->sglen; i++) { @@ -1844,7 +1843,7 @@ static int omap_dma_probe(struct platform_device *pdev) return rc; } -static int omap_dma_remove(struct platform_device *pdev) +static void omap_dma_remove(struct platform_device *pdev) { struct omap_dmadev *od = platform_get_drvdata(pdev); int irq; @@ -1869,8 +1868,6 @@ static int omap_dma_remove(struct platform_device *pdev) dma_pool_destroy(od->desc_pool); omap_dma_free(od); - - return 0; } static const struct omap_dma_config omap2420_data = { @@ -1918,7 +1915,7 @@ MODULE_DEVICE_TABLE(of, omap_dma_match); static struct platform_driver omap_dma_driver = { .probe = omap_dma_probe, - .remove = omap_dma_remove, + .remove_new = omap_dma_remove, .driver = { .name = "omap-dma-engine", .of_match_table = omap_dma_match, diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 3f524be69efb..7410025605e0 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -740,7 +740,7 @@ err_release_region: } -static int td_remove(struct platform_device *pdev) +static void td_remove(struct platform_device *pdev) { struct timb_dma *td = platform_get_drvdata(pdev); struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -754,7 +754,6 @@ static int td_remove(struct platform_device *pdev) release_mem_region(iomem->start, resource_size(iomem)); dev_dbg(&pdev->dev, "Removed...\n"); - return 0; } static struct platform_driver td_driver = { @@ -762,7 +761,7 @@ static struct platform_driver td_driver = { .name = DRIVER_NAME, }, .probe = td_probe, - .remove = td_remove, + .remove_new = td_remove, }; module_platform_driver(td_driver); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 5b6b375a257e..44ba377b4b5a 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -1151,7 +1151,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) return 0; } -static int txx9dmac_chan_remove(struct platform_device *pdev) +static void txx9dmac_chan_remove(struct platform_device *pdev) { struct txx9dmac_chan *dc = platform_get_drvdata(pdev); @@ -1162,7 +1162,6 @@ static int txx9dmac_chan_remove(struct platform_device *pdev) tasklet_kill(&dc->tasklet); } dc->ddev->chan[pdev->id % TXX9_DMA_MAX_NR_CHANNELS] = NULL; - return 0; } static int __init txx9dmac_probe(struct platform_device *pdev) @@ -1215,7 +1214,7 @@ static int __init txx9dmac_probe(struct platform_device *pdev) return 0; } -static int txx9dmac_remove(struct platform_device *pdev) +static void txx9dmac_remove(struct platform_device *pdev) { struct txx9dmac_dev *ddev = platform_get_drvdata(pdev); @@ -1224,7 +1223,6 @@ static int txx9dmac_remove(struct platform_device *pdev) devm_free_irq(&pdev->dev, ddev->irq, ddev); tasklet_kill(&ddev->tasklet); } - return 0; } static void txx9dmac_shutdown(struct platform_device *pdev) @@ -1262,14 +1260,14 @@ static const struct dev_pm_ops txx9dmac_dev_pm_ops = { }; static struct platform_driver txx9dmac_chan_driver = { - .remove = txx9dmac_chan_remove, + .remove_new = txx9dmac_chan_remove, .driver = { .name = "txx9dmac-chan", }, }; static struct platform_driver txx9dmac_driver = { - .remove = txx9dmac_remove, + .remove_new = txx9dmac_remove, .shutdown = txx9dmac_shutdown, .driver = { .name = "txx9dmac", diff --git a/drivers/dma/uniphier-xdmac.c b/drivers/dma/uniphier-xdmac.c index 290836b7e1be..3a8ee2b173b5 100644 --- a/drivers/dma/uniphier-xdmac.c +++ b/drivers/dma/uniphier-xdmac.c @@ -80,7 +80,7 @@ struct uniphier_xdmac_desc { unsigned int nr_node; unsigned int cur_node; enum dma_transfer_direction dir; - struct uniphier_xdmac_desc_node nodes[]; + struct uniphier_xdmac_desc_node nodes[] __counted_by(nr_node); }; struct uniphier_xdmac_chan { @@ -97,7 +97,7 @@ struct uniphier_xdmac_device { struct dma_device ddev; void __iomem *reg_base; int nr_chans; - struct uniphier_xdmac_chan channels[]; + struct uniphier_xdmac_chan channels[] __counted_by(nr_chans); }; static struct uniphier_xdmac_chan * @@ -295,6 +295,7 @@ uniphier_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, xd = kzalloc(struct_size(xd, nodes, nr), GFP_NOWAIT); if (!xd) return NULL; + xd->nr_node = nr; for (i = 0; i < nr; i++) { burst_size = min_t(size_t, len, XDMAC_MAX_WORD_SIZE); @@ -309,7 +310,6 @@ uniphier_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, } xd->dir = DMA_MEM_TO_MEM; - xd->nr_node = nr; xd->cur_node = 0; return vchan_tx_prep(vc, &xd->vd, flags); @@ -351,6 +351,7 @@ uniphier_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, xd = kzalloc(struct_size(xd, nodes, sg_len), GFP_NOWAIT); if (!xd) return NULL; + xd->nr_node = sg_len; for_each_sg(sgl, sg, sg_len, i) { xd->nodes[i].src = (direction == DMA_DEV_TO_MEM) @@ -385,7 +386,6 @@ uniphier_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } xd->dir = direction; - xd->nr_node = sg_len; xd->cur_node = 0; return vchan_tx_prep(vc, &xd->vd, flags); diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c index bb4ff8c86733..fd4397adeb79 100644 --- a/drivers/dma/xgene-dma.c +++ b/drivers/dma/xgene-dma.c @@ -1776,7 +1776,7 @@ err_clk_enable: return ret; } -static int xgene_dma_remove(struct platform_device *pdev) +static void xgene_dma_remove(struct platform_device *pdev) { struct xgene_dma *pdma = platform_get_drvdata(pdev); struct xgene_dma_chan *chan; @@ -1797,8 +1797,6 @@ static int xgene_dma_remove(struct platform_device *pdev) if (!IS_ERR(pdma->clk)) clk_disable_unprepare(pdma->clk); - - return 0; } #ifdef CONFIG_ACPI @@ -1817,7 +1815,7 @@ MODULE_DEVICE_TABLE(of, xgene_dma_of_match_ptr); static struct platform_driver xgene_dma_driver = { .probe = xgene_dma_probe, - .remove = xgene_dma_remove, + .remove_new = xgene_dma_remove, .driver = { .name = "X-Gene-DMA", .of_match_table = xgene_dma_of_match_ptr, diff --git a/drivers/dma/xilinx/xdma-regs.h b/drivers/dma/xilinx/xdma-regs.h index dd98b4526b90..e641a5083e14 100644 --- a/drivers/dma/xilinx/xdma-regs.h +++ b/drivers/dma/xilinx/xdma-regs.h @@ -44,6 +44,8 @@ FIELD_PREP(XDMA_DESC_FLAGS_BITS, (flag))) #define XDMA_DESC_CONTROL_LAST \ XDMA_DESC_CONTROL(1, XDMA_DESC_STOPPED | XDMA_DESC_COMPLETED) +#define XDMA_DESC_CONTROL_CYCLIC \ + XDMA_DESC_CONTROL(1, XDMA_DESC_COMPLETED) /* * Descriptor for a single contiguous memory block transfer. diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index e0bfd129d563..84a88029226f 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -83,6 +83,9 @@ struct xdma_chan { * @dblk_num: Number of hardware descriptor blocks * @desc_num: Number of hardware descriptors * @completed_desc_num: Completed hardware descriptors + * @cyclic: Cyclic transfer vs. scatter-gather + * @periods: Number of periods in the cyclic transfer + * @period_size: Size of a period in bytes in cyclic transfers */ struct xdma_desc { struct virt_dma_desc vdesc; @@ -93,6 +96,9 @@ struct xdma_desc { u32 dblk_num; u32 desc_num; u32 completed_desc_num; + bool cyclic; + u32 periods; + u32 period_size; }; #define XDMA_DEV_STATUS_REG_DMA BIT(0) @@ -137,10 +143,10 @@ static inline void *xdma_blk_last_desc(struct xdma_desc_block *block) } /** - * xdma_link_desc_blocks - Link descriptor blocks for DMA transfer + * xdma_link_sg_desc_blocks - Link SG descriptor blocks for DMA transfer * @sw_desc: Tx descriptor pointer */ -static void xdma_link_desc_blocks(struct xdma_desc *sw_desc) +static void xdma_link_sg_desc_blocks(struct xdma_desc *sw_desc) { struct xdma_desc_block *block; u32 last_blk_desc, desc_control; @@ -174,6 +180,25 @@ static void xdma_link_desc_blocks(struct xdma_desc *sw_desc) desc->control = cpu_to_le32(XDMA_DESC_CONTROL_LAST); } +/** + * xdma_link_cyclic_desc_blocks - Link cyclic descriptor blocks for DMA transfer + * @sw_desc: Tx descriptor pointer + */ +static void xdma_link_cyclic_desc_blocks(struct xdma_desc *sw_desc) +{ + struct xdma_desc_block *block; + struct xdma_hw_desc *desc; + int i; + + block = sw_desc->desc_blocks; + for (i = 0; i < sw_desc->desc_num - 1; i++) { + desc = block->virt_addr + i * XDMA_DESC_SIZE; + desc->next_desc = cpu_to_le64(block->dma_addr + ((i + 1) * XDMA_DESC_SIZE)); + } + desc = block->virt_addr + i * XDMA_DESC_SIZE; + desc->next_desc = cpu_to_le64(block->dma_addr); +} + static inline struct xdma_chan *to_xdma_chan(struct dma_chan *chan) { return container_of(chan, struct xdma_chan, vchan.chan); @@ -231,14 +256,16 @@ static void xdma_free_desc(struct virt_dma_desc *vdesc) * xdma_alloc_desc - Allocate descriptor * @chan: DMA channel pointer * @desc_num: Number of hardware descriptors + * @cyclic: Whether this is a cyclic transfer */ static struct xdma_desc * -xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num) +xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, bool cyclic) { struct xdma_desc *sw_desc; struct xdma_hw_desc *desc; dma_addr_t dma_addr; u32 dblk_num; + u32 control; void *addr; int i, j; @@ -248,12 +275,18 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num) sw_desc->chan = chan; sw_desc->desc_num = desc_num; + sw_desc->cyclic = cyclic; dblk_num = DIV_ROUND_UP(desc_num, XDMA_DESC_ADJACENT); sw_desc->desc_blocks = kcalloc(dblk_num, sizeof(*sw_desc->desc_blocks), GFP_NOWAIT); if (!sw_desc->desc_blocks) goto failed; + if (cyclic) + control = XDMA_DESC_CONTROL_CYCLIC; + else + control = XDMA_DESC_CONTROL(1, 0); + sw_desc->dblk_num = dblk_num; for (i = 0; i < sw_desc->dblk_num; i++) { addr = dma_pool_alloc(chan->desc_pool, GFP_NOWAIT, &dma_addr); @@ -263,10 +296,13 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num) sw_desc->desc_blocks[i].virt_addr = addr; sw_desc->desc_blocks[i].dma_addr = dma_addr; for (j = 0, desc = addr; j < XDMA_DESC_ADJACENT; j++) - desc[j].control = cpu_to_le32(XDMA_DESC_CONTROL(1, 0)); + desc[j].control = cpu_to_le32(control); } - xdma_link_desc_blocks(sw_desc); + if (cyclic) + xdma_link_cyclic_desc_blocks(sw_desc); + else + xdma_link_sg_desc_blocks(sw_desc); return sw_desc; @@ -466,7 +502,7 @@ xdma_prep_device_sg(struct dma_chan *chan, struct scatterlist *sgl, for_each_sg(sgl, sg, sg_len, i) desc_num += DIV_ROUND_UP(sg_dma_len(sg), XDMA_DESC_BLEN_MAX); - sw_desc = xdma_alloc_desc(xdma_chan, desc_num); + sw_desc = xdma_alloc_desc(xdma_chan, desc_num, false); if (!sw_desc) return NULL; sw_desc->dir = dir; @@ -521,6 +557,81 @@ failed: return NULL; } +/** + * xdma_prep_dma_cyclic - prepare for cyclic DMA transactions + * @chan: DMA channel pointer + * @address: Device DMA address to access + * @size: Total length to transfer + * @period_size: Period size to use for each transfer + * @dir: Transfer direction + * @flags: Transfer ack flags + */ +static struct dma_async_tx_descriptor * +xdma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t address, + size_t size, size_t period_size, + enum dma_transfer_direction dir, + unsigned long flags) +{ + struct xdma_chan *xdma_chan = to_xdma_chan(chan); + struct xdma_device *xdev = xdma_chan->xdev_hdl; + unsigned int periods = size / period_size; + struct dma_async_tx_descriptor *tx_desc; + struct xdma_desc_block *dblk; + struct xdma_hw_desc *desc; + struct xdma_desc *sw_desc; + unsigned int i; + + /* + * Simplify the whole logic by preventing an abnormally high number of + * periods and periods size. + */ + if (period_size > XDMA_DESC_BLEN_MAX) { + xdma_err(xdev, "period size limited to %lu bytes\n", XDMA_DESC_BLEN_MAX); + return NULL; + } + + if (periods > XDMA_DESC_ADJACENT) { + xdma_err(xdev, "number of periods limited to %u\n", XDMA_DESC_ADJACENT); + return NULL; + } + + sw_desc = xdma_alloc_desc(xdma_chan, periods, true); + if (!sw_desc) + return NULL; + + sw_desc->periods = periods; + sw_desc->period_size = period_size; + sw_desc->dir = dir; + + dblk = sw_desc->desc_blocks; + desc = dblk->virt_addr; + + /* fill hardware descriptor */ + for (i = 0; i < periods; i++) { + desc->bytes = cpu_to_le32(period_size); + if (dir == DMA_MEM_TO_DEV) { + desc->src_addr = cpu_to_le64(address + i * period_size); + desc->dst_addr = cpu_to_le64(xdma_chan->cfg.dst_addr); + } else { + desc->src_addr = cpu_to_le64(xdma_chan->cfg.src_addr); + desc->dst_addr = cpu_to_le64(address + i * period_size); + } + + desc++; + } + + tx_desc = vchan_tx_prep(&xdma_chan->vchan, &sw_desc->vdesc, flags); + if (!tx_desc) + goto failed; + + return tx_desc; + +failed: + xdma_free_desc(&sw_desc->vdesc); + + return NULL; +} + /** * xdma_device_config - Configure the DMA channel * @chan: DMA channel @@ -577,6 +688,41 @@ static int xdma_alloc_chan_resources(struct dma_chan *chan) return 0; } +static enum dma_status xdma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *state) +{ + struct xdma_chan *xdma_chan = to_xdma_chan(chan); + struct xdma_desc *desc = NULL; + struct virt_dma_desc *vd; + enum dma_status ret; + unsigned long flags; + unsigned int period_idx; + u32 residue = 0; + + ret = dma_cookie_status(chan, cookie, state); + if (ret == DMA_COMPLETE) + return ret; + + spin_lock_irqsave(&xdma_chan->vchan.lock, flags); + + vd = vchan_find_desc(&xdma_chan->vchan, cookie); + if (vd) + desc = to_xdma_desc(vd); + if (!desc || !desc->cyclic) { + spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags); + return ret; + } + + period_idx = desc->completed_desc_num % desc->periods; + residue = (desc->periods - period_idx) * desc->period_size; + + spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags); + + dma_set_residue(state, residue); + + return ret; +} + /** * xdma_channel_isr - XDMA channel interrupt handler * @irq: IRQ number @@ -590,6 +736,7 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) struct virt_dma_desc *vd; struct xdma_desc *desc; int ret; + u32 st; spin_lock(&xchan->vchan.lock); @@ -608,6 +755,19 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) goto out; desc->completed_desc_num += complete_desc_num; + + if (desc->cyclic) { + ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS, + &st); + if (ret) + goto out; + + regmap_write(xdev->rmap, xchan->base + XDMA_CHAN_STATUS, st); + + vchan_cyclic_callback(vd); + goto out; + } + /* * if all data blocks are transferred, remove and complete the request */ @@ -621,7 +781,7 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) complete_desc_num != XDMA_DESC_BLOCK_NUM * XDMA_DESC_ADJACENT) goto out; - /* transfer the rest of data */ + /* transfer the rest of data (SG only) */ xdma_xfer_start(xchan); out: @@ -841,7 +1001,7 @@ EXPORT_SYMBOL(xdma_get_user_irq); * xdma_remove - Driver remove function * @pdev: Pointer to the platform_device structure */ -static int xdma_remove(struct platform_device *pdev) +static void xdma_remove(struct platform_device *pdev) { struct xdma_device *xdev = platform_get_drvdata(pdev); @@ -850,8 +1010,6 @@ static int xdma_remove(struct platform_device *pdev) if (xdev->status & XDMA_DEV_STATUS_REG_DMA) dma_async_device_unregister(&xdev->dma_dev); - - return 0; } /** @@ -885,7 +1043,7 @@ static int xdma_probe(struct platform_device *pdev) goto failed; } xdev->irq_start = res->start; - xdev->irq_num = res->end - res->start + 1; + xdev->irq_num = resource_size(res); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -921,17 +1079,20 @@ static int xdma_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, xdev->dma_dev.cap_mask); dma_cap_set(DMA_PRIVATE, xdev->dma_dev.cap_mask); + dma_cap_set(DMA_CYCLIC, xdev->dma_dev.cap_mask); xdev->dma_dev.dev = &pdev->dev; + xdev->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; xdev->dma_dev.device_free_chan_resources = xdma_free_chan_resources; xdev->dma_dev.device_alloc_chan_resources = xdma_alloc_chan_resources; - xdev->dma_dev.device_tx_status = dma_cookie_status; + xdev->dma_dev.device_tx_status = xdma_tx_status; xdev->dma_dev.device_prep_slave_sg = xdma_prep_device_sg; xdev->dma_dev.device_config = xdma_device_config; xdev->dma_dev.device_issue_pending = xdma_issue_pending; xdev->dma_dev.filter.map = pdata->device_map; xdev->dma_dev.filter.mapcnt = pdata->device_map_cnt; xdev->dma_dev.filter.fn = xdma_filter_fn; + xdev->dma_dev.device_prep_dma_cyclic = xdma_prep_dma_cyclic; ret = dma_async_device_register(&xdev->dma_dev); if (ret) { @@ -966,7 +1127,7 @@ static struct platform_driver xdma_driver = { }, .id_table = xdma_id_table, .probe = xdma_probe, - .remove = xdma_remove, + .remove_new = xdma_remove, }; module_platform_driver(xdma_driver); diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 0a3b2e22f23d..e40696f6f864 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -3242,10 +3242,8 @@ disable_clks: /** * xilinx_dma_remove - Driver remove function * @pdev: Pointer to the platform_device structure - * - * Return: Always '0' */ -static int xilinx_dma_remove(struct platform_device *pdev) +static void xilinx_dma_remove(struct platform_device *pdev) { struct xilinx_dma_device *xdev = platform_get_drvdata(pdev); int i; @@ -3259,8 +3257,6 @@ static int xilinx_dma_remove(struct platform_device *pdev) xilinx_dma_chan_remove(xdev->chan[i]); xdma_disable_allclks(xdev); - - return 0; } static struct platform_driver xilinx_vdma_driver = { @@ -3269,7 +3265,7 @@ static struct platform_driver xilinx_vdma_driver = { .of_match_table = xilinx_dma_of_ids, }, .probe = xilinx_dma_probe, - .remove = xilinx_dma_remove, + .remove_new = xilinx_dma_remove, }; module_platform_driver(xilinx_vdma_driver); diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c index 84dc5240a807..69587d85a7cd 100644 --- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -1736,7 +1736,7 @@ error: return ret; } -static int xilinx_dpdma_remove(struct platform_device *pdev) +static void xilinx_dpdma_remove(struct platform_device *pdev) { struct xilinx_dpdma_device *xdev = platform_get_drvdata(pdev); unsigned int i; @@ -1751,8 +1751,6 @@ static int xilinx_dpdma_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(xdev->chan); i++) xilinx_dpdma_chan_remove(xdev->chan[i]); - - return 0; } static const struct of_device_id xilinx_dpdma_of_match[] = { @@ -1763,7 +1761,7 @@ MODULE_DEVICE_TABLE(of, xilinx_dpdma_of_match); static struct platform_driver xilinx_dpdma_driver = { .probe = xilinx_dpdma_probe, - .remove = xilinx_dpdma_remove, + .remove_new = xilinx_dpdma_remove, .driver = { .name = "xilinx-zynqmp-dpdma", .of_match_table = xilinx_dpdma_of_match, diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index bd8c3cc2eaab..f31631bef961 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -1147,7 +1147,7 @@ err_disable_pm: * * Return: Always '0' */ -static int zynqmp_dma_remove(struct platform_device *pdev) +static void zynqmp_dma_remove(struct platform_device *pdev) { struct zynqmp_dma_device *zdev = platform_get_drvdata(pdev); @@ -1158,8 +1158,6 @@ static int zynqmp_dma_remove(struct platform_device *pdev) pm_runtime_disable(zdev->dev); if (!pm_runtime_enabled(zdev->dev)) zynqmp_dma_runtime_suspend(zdev->dev); - - return 0; } static const struct of_device_id zynqmp_dma_of_match[] = { @@ -1175,7 +1173,7 @@ static struct platform_driver zynqmp_dma_driver = { .pm = &zynqmp_dma_dev_pm_ops, }, .probe = zynqmp_dma_probe, - .remove = zynqmp_dma_remove, + .remove_new = zynqmp_dma_remove, }; module_platform_driver(zynqmp_dma_driver); diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index ef0820f1a924..d4987d013080 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -55,6 +55,15 @@ static phys_addr_t __init efi_to_phys(unsigned long addr) extern __weak const efi_config_table_type_t efi_arch_tables[]; +/* + * x86 defines its own screen_info and uses it even without EFI, + * everything else can get it from here. + */ +#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) +struct screen_info screen_info __section(".data"); +EXPORT_SYMBOL_GPL(screen_info); +#endif + static void __init init_screen_info(void) { struct screen_info *si; @@ -240,5 +249,8 @@ void __init efi_init(void) memblock_reserve(data.phys_map & PAGE_MASK, PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); - init_screen_info(); + if (IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_SYSFB) || + IS_ENABLED(CONFIG_EFI_EARLYCON)) + init_screen_info(); } diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c index 2f1902e5d407..a6c049835190 100644 --- a/drivers/firmware/efi/libstub/efi-stub-entry.c +++ b/drivers/firmware/efi/libstub/efi-stub-entry.c @@ -13,7 +13,13 @@ struct screen_info *alloc_screen_info(void) { if (IS_ENABLED(CONFIG_ARM)) return __alloc_screen_info(); - return (void *)&screen_info + screen_info_offset; + + if (IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_EFI_EARLYCON) || + IS_ENABLED(CONFIG_SYSFB)) + return (void *)&screen_info + screen_info_offset; + + return NULL; } /* diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 913948876c93..b3a133ed31ee 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1312,9 +1312,9 @@ config GPIO_KEMPLD config GPIO_LJCA tristate "INTEL La Jolla Cove Adapter GPIO support" - depends on MFD_LJCA + depends on USB_LJCA select GPIOLIB_IRQCHIP - default MFD_LJCA + default USB_LJCA help Select this option to enable GPIO driver for the INTEL La Jolla Cove Adapter (LJCA) board. diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c index aca69329455f..dfec9fbfc7a9 100644 --- a/drivers/gpio/gpio-ljca.c +++ b/drivers/gpio/gpio-ljca.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -13,19 +14,18 @@ #include #include #include -#include #include -#include #include #include +#include /* GPIO commands */ -#define LJCA_GPIO_CONFIG 1 -#define LJCA_GPIO_READ 2 -#define LJCA_GPIO_WRITE 3 -#define LJCA_GPIO_INT_EVENT 4 -#define LJCA_GPIO_INT_MASK 5 -#define LJCA_GPIO_INT_UNMASK 6 +#define LJCA_GPIO_CONFIG 1 +#define LJCA_GPIO_READ 2 +#define LJCA_GPIO_WRITE 3 +#define LJCA_GPIO_INT_EVENT 4 +#define LJCA_GPIO_INT_MASK 5 +#define LJCA_GPIO_INT_UNMASK 6 #define LJCA_GPIO_CONF_DISABLE BIT(0) #define LJCA_GPIO_CONF_INPUT BIT(1) @@ -36,45 +36,49 @@ #define LJCA_GPIO_CONF_INTERRUPT BIT(6) #define LJCA_GPIO_INT_TYPE BIT(7) -#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1) -#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0) +#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1) +#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0) /* Intentional overlap with PULLUP / PULLDOWN */ -#define LJCA_GPIO_CONF_SET BIT(3) -#define LJCA_GPIO_CONF_CLR BIT(4) +#define LJCA_GPIO_CONF_SET BIT(3) +#define LJCA_GPIO_CONF_CLR BIT(4) -struct gpio_op { +#define LJCA_GPIO_BUF_SIZE 60u + +struct ljca_gpio_op { u8 index; u8 value; } __packed; -struct gpio_packet { +struct ljca_gpio_packet { u8 num; - struct gpio_op item[]; + struct ljca_gpio_op item[] __counted_by(num); } __packed; -#define LJCA_GPIO_BUF_SIZE 60 struct ljca_gpio_dev { - struct platform_device *pdev; + struct ljca_client *ljca; struct gpio_chip gc; struct ljca_gpio_info *gpio_info; DECLARE_BITMAP(unmasked_irqs, LJCA_MAX_GPIO_NUM); DECLARE_BITMAP(enabled_irqs, LJCA_MAX_GPIO_NUM); DECLARE_BITMAP(reenable_irqs, LJCA_MAX_GPIO_NUM); + DECLARE_BITMAP(output_enabled, LJCA_MAX_GPIO_NUM); u8 *connect_mode; - /* mutex to protect irq bus */ + /* protect irq bus */ struct mutex irq_lock; struct work_struct work; - /* lock to protect package transfer to Hardware */ + /* protect package transfer to hardware */ struct mutex trans_lock; u8 obuf[LJCA_GPIO_BUF_SIZE]; u8 ibuf[LJCA_GPIO_BUF_SIZE]; }; -static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config) +static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, + u8 config) { - struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; + struct ljca_gpio_packet *packet = + (struct ljca_gpio_packet *)ljca_gpio->obuf; int ret; mutex_lock(&ljca_gpio->trans_lock); @@ -82,43 +86,43 @@ static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config) packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id]; packet->num = 1; - ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_CONFIG, packet, - struct_size(packet, item, packet->num), NULL, NULL); + ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet, + struct_size(packet, item, packet->num), NULL, 0); mutex_unlock(&ljca_gpio->trans_lock); - return ret; + + return ret < 0 ? ret : 0; } static int ljca_gpio_read(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id) { - struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; - struct gpio_packet *ack_packet = (struct gpio_packet *)ljca_gpio->ibuf; - unsigned int ibuf_len = LJCA_GPIO_BUF_SIZE; + struct ljca_gpio_packet *ack_packet = + (struct ljca_gpio_packet *)ljca_gpio->ibuf; + struct ljca_gpio_packet *packet = + (struct ljca_gpio_packet *)ljca_gpio->obuf; int ret; mutex_lock(&ljca_gpio->trans_lock); packet->num = 1; packet->item[0].index = gpio_id; - ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_READ, packet, - struct_size(packet, item, packet->num), ljca_gpio->ibuf, &ibuf_len); - if (ret) - goto out_unlock; + ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_READ, (u8 *)packet, + struct_size(packet, item, packet->num), + ljca_gpio->ibuf, LJCA_GPIO_BUF_SIZE); - if (!ibuf_len || ack_packet->num != packet->num) { - dev_err(&ljca_gpio->pdev->dev, "failed gpio_id:%u %u", gpio_id, ack_packet->num); - ret = -EIO; + if (ret <= 0 || ack_packet->num != packet->num) { + dev_err(&ljca_gpio->ljca->auxdev.dev, + "read package error, gpio_id: %u num: %u ret: %d\n", + gpio_id, ack_packet->num, ret); + ret = ret < 0 ? ret : -EIO; } - -out_unlock: mutex_unlock(&ljca_gpio->trans_lock); - if (ret) - return ret; - return ack_packet->item[0].value > 0; + + return ret < 0 ? ret : ack_packet->item[0].value > 0; } -static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, - int value) +static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, int value) { - struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; + struct ljca_gpio_packet *packet = + (struct ljca_gpio_packet *)ljca_gpio->obuf; int ret; mutex_lock(&ljca_gpio->trans_lock); @@ -126,10 +130,11 @@ static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, packet->item[0].index = gpio_id; packet->item[0].value = value & 1; - ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_WRITE, packet, - struct_size(packet, item, packet->num), NULL, NULL); + ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_WRITE, (u8 *)packet, + struct_size(packet, item, packet->num), NULL, 0); mutex_unlock(&ljca_gpio->trans_lock); - return ret; + + return ret < 0 ? ret : 0; } static int ljca_gpio_get_value(struct gpio_chip *chip, unsigned int offset) @@ -147,16 +152,24 @@ static void ljca_gpio_set_value(struct gpio_chip *chip, unsigned int offset, ret = ljca_gpio_write(ljca_gpio, offset, val); if (ret) - dev_err(chip->parent, "offset:%u val:%d set value failed %d\n", offset, val, ret); + dev_err(chip->parent, + "set value failed offset: %u val: %d ret: %d\n", + offset, val, ret); } -static int ljca_gpio_direction_input(struct gpio_chip *chip, - unsigned int offset) +static int ljca_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); u8 config = LJCA_GPIO_CONF_INPUT | LJCA_GPIO_CONF_CLR; + int ret; - return gpio_config(ljca_gpio, offset, config); + ret = ljca_gpio_config(ljca_gpio, offset, config); + if (ret) + return ret; + + clear_bit(offset, ljca_gpio->output_enabled); + + return 0; } static int ljca_gpio_direction_output(struct gpio_chip *chip, @@ -166,14 +179,26 @@ static int ljca_gpio_direction_output(struct gpio_chip *chip, u8 config = LJCA_GPIO_CONF_OUTPUT | LJCA_GPIO_CONF_CLR; int ret; - ret = gpio_config(ljca_gpio, offset, config); + ret = ljca_gpio_config(ljca_gpio, offset, config); if (ret) return ret; ljca_gpio_set_value(chip, offset, val); + set_bit(offset, ljca_gpio->output_enabled); + return 0; } +static int ljca_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); + + if (test_bit(offset, ljca_gpio->output_enabled)) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) { @@ -197,7 +222,8 @@ static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset, return 0; } -static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, +static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, unsigned int ngpios) { struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip); @@ -208,15 +234,18 @@ static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *vali return 0; } -static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask, +static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, unsigned int ngpios) { ljca_gpio_init_valid_mask(chip, valid_mask, ngpios); } -static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool enable) +static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, + bool enable) { - struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf; + struct ljca_gpio_packet *packet = + (struct ljca_gpio_packet *)ljca_gpio->obuf; int ret; mutex_lock(&ljca_gpio->trans_lock); @@ -224,18 +253,20 @@ static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool en packet->item[0].index = gpio_id; packet->item[0].value = 0; - ret = ljca_transfer(ljca_gpio->gpio_info->ljca, - enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, packet, - struct_size(packet, item, packet->num), NULL, NULL); + ret = ljca_transfer(ljca_gpio->ljca, + enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, + (u8 *)packet, struct_size(packet, item, packet->num), + NULL, 0); mutex_unlock(&ljca_gpio->trans_lock); - return ret; + + return ret < 0 ? ret : 0; } static void ljca_gpio_async(struct work_struct *work) { - struct ljca_gpio_dev *ljca_gpio = container_of(work, struct ljca_gpio_dev, work); - int gpio_id; - int unmasked; + struct ljca_gpio_dev *ljca_gpio = + container_of(work, struct ljca_gpio_dev, work); + int gpio_id, unmasked; for_each_set_bit(gpio_id, ljca_gpio->reenable_irqs, ljca_gpio->gc.ngpio) { clear_bit(gpio_id, ljca_gpio->reenable_irqs); @@ -245,20 +276,22 @@ static void ljca_gpio_async(struct work_struct *work) } } -static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, int len) +static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, + int len) { - const struct gpio_packet *packet = evt_data; + const struct ljca_gpio_packet *packet = evt_data; struct ljca_gpio_dev *ljca_gpio = context; - int i; - int irq; + int i, irq; if (cmd != LJCA_GPIO_INT_EVENT) return; for (i = 0; i < packet->num; i++) { - irq = irq_find_mapping(ljca_gpio->gc.irq.domain, packet->item[i].index); + irq = irq_find_mapping(ljca_gpio->gc.irq.domain, + packet->item[i].index); if (!irq) { - dev_err(ljca_gpio->gc.parent, "gpio_id %u does not mapped to IRQ yet\n", + dev_err(ljca_gpio->gc.parent, + "gpio_id %u does not mapped to IRQ yet\n", packet->item[i].index); return; } @@ -299,18 +332,22 @@ static int ljca_irq_set_type(struct irq_data *irqd, unsigned int type) ljca_gpio->connect_mode[gpio_id] = LJCA_GPIO_CONF_INTERRUPT; switch (type) { case IRQ_TYPE_LEVEL_HIGH: - ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP); + ljca_gpio->connect_mode[gpio_id] |= + (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP); break; case IRQ_TYPE_LEVEL_LOW: - ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN); + ljca_gpio->connect_mode[gpio_id] |= + (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN); break; case IRQ_TYPE_EDGE_BOTH: break; case IRQ_TYPE_EDGE_RISING: - ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP); + ljca_gpio->connect_mode[gpio_id] |= + (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP); break; case IRQ_TYPE_EDGE_FALLING: - ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN); + ljca_gpio->connect_mode[gpio_id] |= + (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN); break; default: return -EINVAL; @@ -332,15 +369,14 @@ static void ljca_irq_bus_unlock(struct irq_data *irqd) struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc); int gpio_id = irqd_to_hwirq(irqd); - int enabled; - int unmasked; + int enabled, unmasked; enabled = test_bit(gpio_id, ljca_gpio->enabled_irqs); unmasked = test_bit(gpio_id, ljca_gpio->unmasked_irqs); if (enabled != unmasked) { if (unmasked) { - gpio_config(ljca_gpio, gpio_id, 0); + ljca_gpio_config(ljca_gpio, gpio_id, 0); ljca_enable_irq(ljca_gpio, gpio_id, true); set_bit(gpio_id, ljca_gpio->enabled_irqs); } else { @@ -363,43 +399,48 @@ static const struct irq_chip ljca_gpio_irqchip = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static int ljca_gpio_probe(struct platform_device *pdev) +static int ljca_gpio_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *aux_dev_id) { + struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); struct ljca_gpio_dev *ljca_gpio; struct gpio_irq_chip *girq; int ret; - ljca_gpio = devm_kzalloc(&pdev->dev, sizeof(*ljca_gpio), GFP_KERNEL); + ljca_gpio = devm_kzalloc(&auxdev->dev, sizeof(*ljca_gpio), GFP_KERNEL); if (!ljca_gpio) return -ENOMEM; - ljca_gpio->gpio_info = dev_get_platdata(&pdev->dev); - ljca_gpio->connect_mode = devm_kcalloc(&pdev->dev, ljca_gpio->gpio_info->num, - sizeof(*ljca_gpio->connect_mode), GFP_KERNEL); + ljca_gpio->ljca = ljca; + ljca_gpio->gpio_info = dev_get_platdata(&auxdev->dev); + ljca_gpio->connect_mode = devm_kcalloc(&auxdev->dev, + ljca_gpio->gpio_info->num, + sizeof(*ljca_gpio->connect_mode), + GFP_KERNEL); if (!ljca_gpio->connect_mode) return -ENOMEM; mutex_init(&ljca_gpio->irq_lock); mutex_init(&ljca_gpio->trans_lock); - ljca_gpio->pdev = pdev; ljca_gpio->gc.direction_input = ljca_gpio_direction_input; ljca_gpio->gc.direction_output = ljca_gpio_direction_output; + ljca_gpio->gc.get_direction = ljca_gpio_get_direction; ljca_gpio->gc.get = ljca_gpio_get_value; ljca_gpio->gc.set = ljca_gpio_set_value; ljca_gpio->gc.set_config = ljca_gpio_set_config; ljca_gpio->gc.init_valid_mask = ljca_gpio_init_valid_mask; ljca_gpio->gc.can_sleep = true; - ljca_gpio->gc.parent = &pdev->dev; + ljca_gpio->gc.parent = &auxdev->dev; ljca_gpio->gc.base = -1; ljca_gpio->gc.ngpio = ljca_gpio->gpio_info->num; - ljca_gpio->gc.label = ACPI_COMPANION(&pdev->dev) ? - acpi_dev_name(ACPI_COMPANION(&pdev->dev)) : - dev_name(&pdev->dev); + ljca_gpio->gc.label = ACPI_COMPANION(&auxdev->dev) ? + acpi_dev_name(ACPI_COMPANION(&auxdev->dev)) : + dev_name(&auxdev->dev); ljca_gpio->gc.owner = THIS_MODULE; - platform_set_drvdata(pdev, ljca_gpio); - ljca_register_event_cb(ljca_gpio->gpio_info->ljca, ljca_gpio_event_cb, ljca_gpio); + auxiliary_set_drvdata(auxdev, ljca_gpio); + ljca_register_event_cb(ljca, ljca_gpio_event_cb, ljca_gpio); girq = &ljca_gpio->gc.irq; gpio_irq_chip_set_chip(girq, &ljca_gpio_irqchip); @@ -413,7 +454,7 @@ static int ljca_gpio_probe(struct platform_device *pdev) INIT_WORK(&ljca_gpio->work, ljca_gpio_async); ret = gpiochip_add_data(&ljca_gpio->gc, ljca_gpio); if (ret) { - ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca); + ljca_unregister_event_cb(ljca); mutex_destroy(&ljca_gpio->irq_lock); mutex_destroy(&ljca_gpio->trans_lock); } @@ -421,33 +462,33 @@ static int ljca_gpio_probe(struct platform_device *pdev) return ret; } -static void ljca_gpio_remove(struct platform_device *pdev) +static void ljca_gpio_remove(struct auxiliary_device *auxdev) { - struct ljca_gpio_dev *ljca_gpio = platform_get_drvdata(pdev); + struct ljca_gpio_dev *ljca_gpio = auxiliary_get_drvdata(auxdev); gpiochip_remove(&ljca_gpio->gc); - ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca); + ljca_unregister_event_cb(ljca_gpio->ljca); + cancel_work_sync(&ljca_gpio->work); mutex_destroy(&ljca_gpio->irq_lock); mutex_destroy(&ljca_gpio->trans_lock); } -#define LJCA_GPIO_DRV_NAME "ljca-gpio" -static const struct platform_device_id ljca_gpio_id[] = { - { LJCA_GPIO_DRV_NAME, 0 }, - { /* sentinel */ } +static const struct auxiliary_device_id ljca_gpio_id_table[] = { + { "usb_ljca.ljca-gpio", 0 }, + { /* sentinel */ }, }; -MODULE_DEVICE_TABLE(platform, ljca_gpio_id); +MODULE_DEVICE_TABLE(auxiliary, ljca_gpio_id_table); -static struct platform_driver ljca_gpio_driver = { - .driver.name = LJCA_GPIO_DRV_NAME, +static struct auxiliary_driver ljca_gpio_driver = { .probe = ljca_gpio_probe, - .remove_new = ljca_gpio_remove, + .remove = ljca_gpio_remove, + .id_table = ljca_gpio_id_table, }; -module_platform_driver(ljca_gpio_driver); +module_auxiliary_driver(ljca_gpio_driver); -MODULE_AUTHOR("Ye Xiang "); -MODULE_AUTHOR("Wang Zhifeng "); -MODULE_AUTHOR("Zhang Lixu "); +MODULE_AUTHOR("Wentong Wu "); +MODULE_AUTHOR("Zhifeng Wang "); +MODULE_AUTHOR("Lixu Zhang "); MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(LJCA); diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index 58b0b46a21e6..d511d17c5bdf 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -73,9 +73,10 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv, struct drm_device *dev = &hv->dev; int ret; - drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, - screen_info.lfb_size, - &hyperv_driver); + if (IS_ENABLED(CONFIG_SYSFB)) + drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, + screen_info.lfb_size, + &hyperv_driver); hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index edbb38f6956b..b33d5abd9beb 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -2100,8 +2100,10 @@ static void __maybe_unused vmbus_reserve_fb(void) if (efi_enabled(EFI_BOOT)) { /* Gen2 VM: get FB base from EFI framebuffer */ - start = screen_info.lfb_base; - size = max_t(__u32, screen_info.lfb_size, 0x800000); + if (IS_ENABLED(CONFIG_SYSFB)) { + start = screen_info.lfb_base; + size = max_t(__u32, screen_info.lfb_size, 0x800000); + } } else { /* Gen1 VM: get FB base from PCI */ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 6644eebedaf3..fd887f767675 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1264,6 +1264,17 @@ config I2C_DLN2 This driver can also be built as a module. If so, the module will be called i2c-dln2. +config I2C_LJCA + tristate "I2C functionality of Intel La Jolla Cove Adapter" + depends on USB_LJCA + default USB_LJCA + help + If you say yes to this option, I2C functionality support of Intel + La Jolla Cove Adapter (LJCA) will be included. + + This driver can also be built as a module. If so, the module + will be called i2c-ljca. + config I2C_CP2615 tristate "Silicon Labs CP2615 USB sound card and I2C adapter" depends on USB diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index af56fe2c75c0..3757b9391e60 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_I2C_GXP) += i2c-gxp.o # External I2C/SMBus adapter drivers obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o obj-$(CONFIG_I2C_DLN2) += i2c-dln2.o +obj-$(CONFIG_I2C_LJCA) += i2c-ljca.o obj-$(CONFIG_I2C_CP2615) += i2c-cp2615.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PCI1XXXX) += i2c-mchp-pci1xxxx.o diff --git a/drivers/i2c/busses/i2c-ljca.c b/drivers/i2c/busses/i2c-ljca.c new file mode 100644 index 000000000000..b4927622177c --- /dev/null +++ b/drivers/i2c/busses/i2c-ljca.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel La Jolla Cove Adapter USB-I2C driver + * + * Copyright (c) 2023, Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* I2C init flags */ +#define LJCA_I2C_INIT_FLAG_MODE BIT(0) +#define LJCA_I2C_INIT_FLAG_MODE_POLLING FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 0) +#define LJCA_I2C_INIT_FLAG_MODE_INTERRUPT FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 1) + +#define LJCA_I2C_INIT_FLAG_ADDR_16BIT BIT(0) + +#define LJCA_I2C_INIT_FLAG_FREQ GENMASK(2, 1) +#define LJCA_I2C_INIT_FLAG_FREQ_100K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 0) +#define LJCA_I2C_INIT_FLAG_FREQ_400K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 1) +#define LJCA_I2C_INIT_FLAG_FREQ_1M FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 2) + +#define LJCA_I2C_BUF_SIZE 60u +#define LJCA_I2C_MAX_XFER_SIZE (LJCA_I2C_BUF_SIZE - sizeof(struct ljca_i2c_rw_packet)) + +/* I2C commands */ +enum ljca_i2c_cmd { + LJCA_I2C_INIT = 1, + LJCA_I2C_XFER, + LJCA_I2C_START, + LJCA_I2C_STOP, + LJCA_I2C_READ, + LJCA_I2C_WRITE, +}; + +enum ljca_xfer_type { + LJCA_I2C_WRITE_XFER_TYPE, + LJCA_I2C_READ_XFER_TYPE, +}; + +/* I2C raw commands: Init/Start/Read/Write/Stop */ +struct ljca_i2c_rw_packet { + u8 id; + __le16 len; + u8 data[] __counted_by(len); +} __packed; + +struct ljca_i2c_dev { + struct ljca_client *ljca; + struct ljca_i2c_info *i2c_info; + struct i2c_adapter adap; + + u8 obuf[LJCA_I2C_BUF_SIZE]; + u8 ibuf[LJCA_I2C_BUF_SIZE]; +}; + +static int ljca_i2c_init(struct ljca_i2c_dev *ljca_i2c, u8 id) +{ + struct ljca_i2c_rw_packet *w_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; + int ret; + + w_packet->id = id; + w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); + w_packet->data[0] = LJCA_I2C_INIT_FLAG_FREQ_400K; + + ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_INIT, (u8 *)w_packet, + struct_size(w_packet, data, 1), NULL, 0); + + return ret < 0 ? ret : 0; +} + +static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr, + enum ljca_xfer_type type) +{ + struct ljca_i2c_rw_packet *w_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; + struct ljca_i2c_rw_packet *r_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; + s16 rp_len; + int ret; + + w_packet->id = ljca_i2c->i2c_info->id; + w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); + w_packet->data[0] = (slave_addr << 1) | type; + + ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_START, (u8 *)w_packet, + struct_size(w_packet, data, 1), (u8 *)r_packet, + LJCA_I2C_BUF_SIZE); + if (ret < 0 || ret < sizeof(*r_packet)) + return ret < 0 ? ret : -EIO; + + rp_len = le16_to_cpu(r_packet->len); + if (rp_len < 0 || r_packet->id != w_packet->id) { + dev_dbg(&ljca_i2c->adap.dev, + "i2c start failed len: %d id: %d %d\n", + rp_len, r_packet->id, w_packet->id); + return -EIO; + } + + return 0; +} + +static void ljca_i2c_stop(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr) +{ + struct ljca_i2c_rw_packet *w_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; + struct ljca_i2c_rw_packet *r_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; + s16 rp_len; + int ret; + + w_packet->id = ljca_i2c->i2c_info->id; + w_packet->len = cpu_to_le16(sizeof(*w_packet->data)); + w_packet->data[0] = 0; + + ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_STOP, (u8 *)w_packet, + struct_size(w_packet, data, 1), (u8 *)r_packet, + LJCA_I2C_BUF_SIZE); + if (ret < 0 || ret < sizeof(*r_packet)) { + dev_dbg(&ljca_i2c->adap.dev, + "i2c stop failed ret: %d id: %d\n", + ret, w_packet->id); + return; + } + + rp_len = le16_to_cpu(r_packet->len); + if (rp_len < 0 || r_packet->id != w_packet->id) + dev_dbg(&ljca_i2c->adap.dev, + "i2c stop failed len: %d id: %d %d\n", + rp_len, r_packet->id, w_packet->id); +} + +static int ljca_i2c_pure_read(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len) +{ + struct ljca_i2c_rw_packet *w_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; + struct ljca_i2c_rw_packet *r_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; + s16 rp_len; + int ret; + + w_packet->id = ljca_i2c->i2c_info->id; + w_packet->len = cpu_to_le16(len); + w_packet->data[0] = 0; + + ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_READ, (u8 *)w_packet, + struct_size(w_packet, data, 1), (u8 *)r_packet, + LJCA_I2C_BUF_SIZE); + if (ret < 0 || ret < sizeof(*r_packet)) + return ret < 0 ? ret : -EIO; + + rp_len = le16_to_cpu(r_packet->len); + if (rp_len != len || r_packet->id != w_packet->id) { + dev_dbg(&ljca_i2c->adap.dev, + "i2c raw read failed len: %d id: %d %d\n", + rp_len, r_packet->id, w_packet->id); + return -EIO; + } + + memcpy(data, r_packet->data, len); + + return 0; +} + +static int ljca_i2c_read(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr, u8 *data, + u8 len) +{ + int ret; + + ret = ljca_i2c_start(ljca_i2c, slave_addr, LJCA_I2C_READ_XFER_TYPE); + if (!ret) + ret = ljca_i2c_pure_read(ljca_i2c, data, len); + + ljca_i2c_stop(ljca_i2c, slave_addr); + + return ret; +} + +static int ljca_i2c_pure_write(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len) +{ + struct ljca_i2c_rw_packet *w_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->obuf; + struct ljca_i2c_rw_packet *r_packet = + (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf; + s16 rplen; + int ret; + + w_packet->id = ljca_i2c->i2c_info->id; + w_packet->len = cpu_to_le16(len); + memcpy(w_packet->data, data, len); + + ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_WRITE, (u8 *)w_packet, + struct_size(w_packet, data, len), (u8 *)r_packet, + LJCA_I2C_BUF_SIZE); + if (ret < 0 || ret < sizeof(*r_packet)) + return ret < 0 ? ret : -EIO; + + rplen = le16_to_cpu(r_packet->len); + if (rplen != len || r_packet->id != w_packet->id) { + dev_dbg(&ljca_i2c->adap.dev, + "i2c write failed len: %d id: %d/%d\n", + rplen, r_packet->id, w_packet->id); + return -EIO; + } + + return 0; +} + +static int ljca_i2c_write(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr, + u8 *data, u8 len) +{ + int ret; + + ret = ljca_i2c_start(ljca_i2c, slave_addr, LJCA_I2C_WRITE_XFER_TYPE); + if (!ret) + ret = ljca_i2c_pure_write(ljca_i2c, data, len); + + ljca_i2c_stop(ljca_i2c, slave_addr); + + return ret; +} + +static int ljca_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, + int num) +{ + struct ljca_i2c_dev *ljca_i2c; + struct i2c_msg *cur_msg; + int i, ret; + + ljca_i2c = i2c_get_adapdata(adapter); + if (!ljca_i2c) + return -EINVAL; + + for (i = 0; i < num; i++) { + cur_msg = &msg[i]; + if (cur_msg->flags & I2C_M_RD) + ret = ljca_i2c_read(ljca_i2c, cur_msg->addr, + cur_msg->buf, cur_msg->len); + else + ret = ljca_i2c_write(ljca_i2c, cur_msg->addr, + cur_msg->buf, cur_msg->len); + + if (ret) + return ret; + } + + return num; +} + +static u32 ljca_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +} + +static const struct i2c_adapter_quirks ljca_i2c_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN, + .max_read_len = LJCA_I2C_MAX_XFER_SIZE, + .max_write_len = LJCA_I2C_MAX_XFER_SIZE, +}; + +static const struct i2c_algorithm ljca_i2c_algo = { + .master_xfer = ljca_i2c_xfer, + .functionality = ljca_i2c_func, +}; + +static int ljca_i2c_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *aux_dev_id) +{ + struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); + struct ljca_i2c_dev *ljca_i2c; + int ret; + + ljca_i2c = devm_kzalloc(&auxdev->dev, sizeof(*ljca_i2c), GFP_KERNEL); + if (!ljca_i2c) + return -ENOMEM; + + ljca_i2c->ljca = ljca; + ljca_i2c->i2c_info = dev_get_platdata(&auxdev->dev); + + ljca_i2c->adap.owner = THIS_MODULE; + ljca_i2c->adap.class = I2C_CLASS_HWMON; + ljca_i2c->adap.algo = &ljca_i2c_algo; + ljca_i2c->adap.quirks = &ljca_i2c_quirks; + ljca_i2c->adap.dev.parent = &auxdev->dev; + + snprintf(ljca_i2c->adap.name, sizeof(ljca_i2c->adap.name), "%s-%s-%d", + dev_name(&auxdev->dev), dev_name(auxdev->dev.parent), + ljca_i2c->i2c_info->id); + + device_set_node(&ljca_i2c->adap.dev, dev_fwnode(&auxdev->dev)); + + i2c_set_adapdata(&ljca_i2c->adap, ljca_i2c); + auxiliary_set_drvdata(auxdev, ljca_i2c); + + ret = ljca_i2c_init(ljca_i2c, ljca_i2c->i2c_info->id); + if (ret) + return dev_err_probe(&auxdev->dev, -EIO, + "i2c init failed id: %d\n", + ljca_i2c->i2c_info->id); + + ret = devm_i2c_add_adapter(&auxdev->dev, &ljca_i2c->adap); + if (ret) + return ret; + + if (has_acpi_companion(&ljca_i2c->adap.dev)) + acpi_dev_clear_dependencies(ACPI_COMPANION(&ljca_i2c->adap.dev)); + + return 0; +} + +static void ljca_i2c_remove(struct auxiliary_device *auxdev) +{ + struct ljca_i2c_dev *ljca_i2c = auxiliary_get_drvdata(auxdev); + + i2c_del_adapter(&ljca_i2c->adap); +} + +static const struct auxiliary_device_id ljca_i2c_id_table[] = { + { "usb_ljca.ljca-i2c", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(auxiliary, ljca_i2c_id_table); + +static struct auxiliary_driver ljca_i2c_driver = { + .probe = ljca_i2c_probe, + .remove = ljca_i2c_remove, + .id_table = ljca_i2c_id_table, +}; +module_auxiliary_driver(ljca_i2c_driver); + +MODULE_AUTHOR("Wentong Wu "); +MODULE_AUTHOR("Zhifeng Wang "); +MODULE_AUTHOR("Lixu Zhang "); +MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-I2C driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(LJCA); diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 67000e4a8082..2b2f14a1b711 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -492,6 +492,8 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec, { struct cros_typec_port *port = typec->ports[port_num]; struct typec_displayport_data dp_data; + u32 cable_tbt_vdo; + u32 cable_dp_vdo; int ret; if (typec->pd_ctrl_ver < 2) { @@ -524,6 +526,32 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec, port->state.data = &dp_data; port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode)); + /* Get cable VDO for cables with DPSID to check DPAM2.1 is supported */ + cable_dp_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_DP_SID); + + /** + * Get cable VDO for thunderbolt cables and cables with DPSID but does not + * support DPAM2.1. + */ + cable_tbt_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID); + + if (cable_dp_vdo & DP_CAP_DPAM_VERSION) { + dp_data.conf |= cable_dp_vdo; + } else if (cable_tbt_vdo) { + dp_data.conf |= TBT_CABLE_SPEED(cable_tbt_vdo) << DP_CONF_SIGNALLING_SHIFT; + + /* Cable Type */ + if (cable_tbt_vdo & TBT_CABLE_OPTICAL) + dp_data.conf |= DP_CONF_CABLE_TYPE_OPTICAL << DP_CONF_CABLE_TYPE_SHIFT; + else if (cable_tbt_vdo & TBT_CABLE_RETIMER) + dp_data.conf |= DP_CONF_CABLE_TYPE_RE_TIMER << DP_CONF_CABLE_TYPE_SHIFT; + else if (cable_tbt_vdo & TBT_CABLE_ACTIVE_PASSIVE) + dp_data.conf |= DP_CONF_CABLE_TYPE_RE_DRIVER << DP_CONF_CABLE_TYPE_SHIFT; + } else if (PD_IDH_PTYPE(port->c_identity.id_header) == IDH_PTYPE_PCABLE) { + dp_data.conf |= VDO_TYPEC_CABLE_SPEED(port->c_identity.vdo[0]) << + DP_CONF_SIGNALLING_SHIFT; + } + ret = cros_typec_retimer_set(port->retimer, port->state); if (!ret) ret = typec_mux_set(port->mux, &port->state); diff --git a/drivers/power/supply/tps65217_charger.c b/drivers/power/supply/tps65217_charger.c index b3a1ba326a3e..2382749a2f53 100644 --- a/drivers/power/supply/tps65217_charger.c +++ b/drivers/power/supply/tps65217_charger.c @@ -237,7 +237,7 @@ static int tps65217_charger_probe(struct platform_device *pdev) for (i = 0; i < NUM_CHARGER_IRQS; i++) { ret = devm_request_threaded_irq(&pdev->dev, irq[i], NULL, tps65217_charger_irq, - IRQF_ONESHOT, "tps65217-charger", + IRQF_SHARED, "tps65217-charger", charger); if (ret) { dev_err(charger->dev, diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index d4ac184bce95..35dbfacecf1c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -616,6 +616,17 @@ config SPI_FSL_ESPI From MPC8536, 85xx platform uses the controller, and all P10xx, P20xx, P30xx,P40xx, P50xx uses this controller. +config SPI_LJCA + tristate "Intel La Jolla Cove Adapter SPI support" + depends on USB_LJCA + default USB_LJCA + help + Select this option to enable SPI driver for the Intel + La Jolla Cove Adapter (LJCA) board. + + This driver can also be built as a module. If so, the module + will be called spi-ljca. + config SPI_MESON_SPICC tristate "Amlogic Meson SPICC controller" depends on COMMON_CLK diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 6af54842b9fa..4ff8d725ba5e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_SPI_INTEL_PCI) += spi-intel-pci.o obj-$(CONFIG_SPI_INTEL_PLATFORM) += spi-intel-platform.o obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o obj-$(CONFIG_SPI_JCORE) += spi-jcore.o +obj-$(CONFIG_SPI_LJCA) += spi-ljca.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LOONGSON_CORE) += spi-loongson-core.o obj-$(CONFIG_SPI_LOONGSON_PCI) += spi-loongson-pci.o diff --git a/drivers/spi/spi-ljca.c b/drivers/spi/spi-ljca.c new file mode 100644 index 000000000000..c5a066c73817 --- /dev/null +++ b/drivers/spi/spi-ljca.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel La Jolla Cove Adapter USB-SPI driver + * + * Copyright (c) 2023, Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LJCA_SPI_BUS_MAX_HZ 48000000 + +#define LJCA_SPI_BUF_SIZE 60u +#define LJCA_SPI_MAX_XFER_SIZE \ + (LJCA_SPI_BUF_SIZE - sizeof(struct ljca_spi_xfer_packet)) + +#define LJCA_SPI_CLK_MODE_POLARITY BIT(0) +#define LJCA_SPI_CLK_MODE_PHASE BIT(1) + +#define LJCA_SPI_XFER_INDICATOR_ID GENMASK(5, 0) +#define LJCA_SPI_XFER_INDICATOR_CMPL BIT(6) +#define LJCA_SPI_XFER_INDICATOR_INDEX BIT(7) + +/* SPI commands */ +enum ljca_spi_cmd { + LJCA_SPI_INIT = 1, + LJCA_SPI_READ, + LJCA_SPI_WRITE, + LJCA_SPI_WRITEREAD, + LJCA_SPI_DEINIT, +}; + +enum { + LJCA_SPI_BUS_SPEED_24M, + LJCA_SPI_BUS_SPEED_12M, + LJCA_SPI_BUS_SPEED_8M, + LJCA_SPI_BUS_SPEED_6M, + LJCA_SPI_BUS_SPEED_4_8M, /*4.8MHz*/ + LJCA_SPI_BUS_SPEED_MIN = LJCA_SPI_BUS_SPEED_4_8M, +}; + +enum { + LJCA_SPI_CLOCK_LOW_POLARITY, + LJCA_SPI_CLOCK_HIGH_POLARITY, +}; + +enum { + LJCA_SPI_CLOCK_FIRST_PHASE, + LJCA_SPI_CLOCK_SECOND_PHASE, +}; + +struct ljca_spi_init_packet { + u8 index; + u8 speed; + u8 mode; +} __packed; + +struct ljca_spi_xfer_packet { + u8 indicator; + u8 len; + u8 data[] __counted_by(len); +} __packed; + +struct ljca_spi_dev { + struct ljca_client *ljca; + struct spi_controller *controller; + struct ljca_spi_info *spi_info; + u8 speed; + u8 mode; + + u8 obuf[LJCA_SPI_BUF_SIZE]; + u8 ibuf[LJCA_SPI_BUF_SIZE]; +}; + +static int ljca_spi_read_write(struct ljca_spi_dev *ljca_spi, const u8 *w_data, + u8 *r_data, int len, int id, int complete, + int cmd) +{ + struct ljca_spi_xfer_packet *w_packet = + (struct ljca_spi_xfer_packet *)ljca_spi->obuf; + struct ljca_spi_xfer_packet *r_packet = + (struct ljca_spi_xfer_packet *)ljca_spi->ibuf; + int ret; + + w_packet->indicator = FIELD_PREP(LJCA_SPI_XFER_INDICATOR_ID, id) | + FIELD_PREP(LJCA_SPI_XFER_INDICATOR_CMPL, complete) | + FIELD_PREP(LJCA_SPI_XFER_INDICATOR_INDEX, + ljca_spi->spi_info->id); + + if (cmd == LJCA_SPI_READ) { + w_packet->len = sizeof(u16); + *(__le16 *)&w_packet->data[0] = cpu_to_le16(len); + } else { + w_packet->len = len; + memcpy(w_packet->data, w_data, len); + } + + ret = ljca_transfer(ljca_spi->ljca, cmd, (u8 *)w_packet, + struct_size(w_packet, data, w_packet->len), + (u8 *)r_packet, LJCA_SPI_BUF_SIZE); + if (ret < 0) + return ret; + else if (ret < sizeof(*r_packet) || r_packet->len <= 0) + return -EIO; + + if (r_data) + memcpy(r_data, r_packet->data, r_packet->len); + + return 0; +} + +static int ljca_spi_init(struct ljca_spi_dev *ljca_spi, u8 div, u8 mode) +{ + struct ljca_spi_init_packet w_packet = {}; + int ret; + + if (ljca_spi->mode == mode && ljca_spi->speed == div) + return 0; + + w_packet.index = ljca_spi->spi_info->id; + w_packet.speed = div; + w_packet.mode = FIELD_PREP(LJCA_SPI_CLK_MODE_POLARITY, + (mode & SPI_CPOL) ? LJCA_SPI_CLOCK_HIGH_POLARITY : + LJCA_SPI_CLOCK_LOW_POLARITY) | + FIELD_PREP(LJCA_SPI_CLK_MODE_PHASE, + (mode & SPI_CPHA) ? LJCA_SPI_CLOCK_SECOND_PHASE : + LJCA_SPI_CLOCK_FIRST_PHASE); + + ret = ljca_transfer(ljca_spi->ljca, LJCA_SPI_INIT, (u8 *)&w_packet, + sizeof(w_packet), NULL, 0); + if (ret < 0) + return ret; + + ljca_spi->mode = mode; + ljca_spi->speed = div; + + return 0; +} + +static int ljca_spi_deinit(struct ljca_spi_dev *ljca_spi) +{ + struct ljca_spi_init_packet w_packet = {}; + int ret; + + w_packet.index = ljca_spi->spi_info->id; + + ret = ljca_transfer(ljca_spi->ljca, LJCA_SPI_DEINIT, (u8 *)&w_packet, + sizeof(w_packet), NULL, 0); + + return ret < 0 ? ret : 0; +} + +static inline int ljca_spi_transfer(struct ljca_spi_dev *ljca_spi, + const u8 *tx_data, u8 *rx_data, u16 len) +{ + int complete, cur_len; + int remaining = len; + int cmd, ret, i; + int offset = 0; + + if (tx_data && rx_data) + cmd = LJCA_SPI_WRITEREAD; + else if (tx_data) + cmd = LJCA_SPI_WRITE; + else if (rx_data) + cmd = LJCA_SPI_READ; + else + return -EINVAL; + + for (i = 0; remaining > 0; i++) { + cur_len = min_t(unsigned int, remaining, LJCA_SPI_MAX_XFER_SIZE); + complete = (cur_len == remaining); + + ret = ljca_spi_read_write(ljca_spi, + tx_data ? tx_data + offset : NULL, + rx_data ? rx_data + offset : NULL, + cur_len, i, complete, cmd); + if (ret) + return ret; + + offset += cur_len; + remaining -= cur_len; + } + + return 0; +} + +static int ljca_spi_transfer_one(struct spi_controller *controller, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + u8 div = DIV_ROUND_UP(controller->max_speed_hz, xfer->speed_hz) / 2 - 1; + struct ljca_spi_dev *ljca_spi = spi_controller_get_devdata(controller); + int ret; + + div = min_t(u8, LJCA_SPI_BUS_SPEED_MIN, div); + + ret = ljca_spi_init(ljca_spi, div, spi->mode); + if (ret) { + dev_err(&ljca_spi->ljca->auxdev.dev, + "cannot initialize transfer ret %d\n", ret); + return ret; + } + + ret = ljca_spi_transfer(ljca_spi, xfer->tx_buf, xfer->rx_buf, xfer->len); + if (ret) + dev_err(&ljca_spi->ljca->auxdev.dev, + "transfer failed len: %d\n", xfer->len); + + return ret; +} + +static int ljca_spi_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *aux_dev_id) +{ + struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); + struct spi_controller *controller; + struct ljca_spi_dev *ljca_spi; + int ret; + + controller = devm_spi_alloc_master(&auxdev->dev, sizeof(*ljca_spi)); + if (!controller) + return -ENOMEM; + + ljca_spi = spi_controller_get_devdata(controller); + ljca_spi->ljca = ljca; + ljca_spi->spi_info = dev_get_platdata(&auxdev->dev); + ljca_spi->controller = controller; + + controller->bus_num = -1; + controller->mode_bits = SPI_CPHA | SPI_CPOL; + controller->transfer_one = ljca_spi_transfer_one; + controller->auto_runtime_pm = false; + controller->max_speed_hz = LJCA_SPI_BUS_MAX_HZ; + + device_set_node(&ljca_spi->controller->dev, dev_fwnode(&auxdev->dev)); + auxiliary_set_drvdata(auxdev, controller); + + ret = spi_register_controller(controller); + if (ret) + dev_err(&auxdev->dev, "Failed to register controller\n"); + + return ret; +} + +static void ljca_spi_dev_remove(struct auxiliary_device *auxdev) +{ + struct spi_controller *controller = auxiliary_get_drvdata(auxdev); + struct ljca_spi_dev *ljca_spi = spi_controller_get_devdata(controller); + + spi_unregister_controller(controller); + ljca_spi_deinit(ljca_spi); +} + +static int ljca_spi_dev_suspend(struct device *dev) +{ + struct spi_controller *controller = dev_get_drvdata(dev); + + return spi_controller_suspend(controller); +} + +static int ljca_spi_dev_resume(struct device *dev) +{ + struct spi_controller *controller = dev_get_drvdata(dev); + + return spi_controller_resume(controller); +} + +static const struct dev_pm_ops ljca_spi_pm = { + SYSTEM_SLEEP_PM_OPS(ljca_spi_dev_suspend, ljca_spi_dev_resume) +}; + +static const struct auxiliary_device_id ljca_spi_id_table[] = { + { "usb_ljca.ljca-spi", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(auxiliary, ljca_spi_id_table); + +static struct auxiliary_driver ljca_spi_driver = { + .driver.pm = &ljca_spi_pm, + .probe = ljca_spi_probe, + .remove = ljca_spi_dev_remove, + .id_table = ljca_spi_id_table, +}; +module_auxiliary_driver(ljca_spi_driver); + +MODULE_AUTHOR("Wentong Wu "); +MODULE_AUTHOR("Zhifeng Wang "); +MODULE_AUTHOR("Lixu Zhang "); +MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-SPI driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(LJCA); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index fa7154ad530b..780b0f513940 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -28,8 +28,6 @@ source "drivers/staging/wlan-ng/Kconfig" source "drivers/staging/olpc_dcon/Kconfig" -source "drivers/staging/rtl8192u/Kconfig" - source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8723bs/Kconfig" @@ -76,8 +74,6 @@ source "drivers/staging/axis-fifo/Kconfig" source "drivers/staging/fieldbus/Kconfig" -source "drivers/staging/qlge/Kconfig" - source "drivers/staging/vme_user/Kconfig" endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 2ec175e5d5a8..024918a80a3c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -4,7 +4,6 @@ obj-y += media/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ -obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ obj-$(CONFIG_R8712U) += rtl8712/ @@ -28,4 +27,3 @@ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ -obj-$(CONFIG_QLGE) += qlge/ diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 2c2b5f1c1df3..f86ed9d470b8 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -310,12 +310,11 @@ static int fbtft_driver_probe_pdev(struct platform_device *pdev) \ return fbtft_probe_common(_display, NULL, pdev); \ } \ \ -static int fbtft_driver_remove_pdev(struct platform_device *pdev) \ +static void fbtft_driver_remove_pdev(struct platform_device *pdev) \ { \ struct fb_info *info = platform_get_drvdata(pdev); \ \ fbtft_remove_common(&pdev->dev, info); \ - return 0; \ } \ \ FBTFT_DT_TABLE(_compatible) \ @@ -329,7 +328,7 @@ static struct platform_driver fbtft_driver_platform_driver = { \ .of_match_table = dt_ids, \ }, \ .probe = fbtft_driver_probe_pdev, \ - .remove = fbtft_driver_remove_pdev, \ + .remove_new = fbtft_driver_remove_pdev, \ }; \ \ static int __init fbtft_driver_module_init(void) \ diff --git a/drivers/staging/fieldbus/anybuss/arcx-anybus.c b/drivers/staging/fieldbus/anybuss/arcx-anybus.c index 6f69758a8b27..34d18b09bedd 100644 --- a/drivers/staging/fieldbus/anybuss/arcx-anybus.c +++ b/drivers/staging/fieldbus/anybuss/arcx-anybus.c @@ -218,7 +218,10 @@ static const struct regulator_desc can_power_desc = { .ops = &can_power_ops, }; -static struct class *controller_class; +static const struct class controller_class = { + .name = "arcx_anybus_controller", +}; + static DEFINE_IDA(controller_index_ida); static int controller_probe(struct platform_device *pdev) @@ -301,7 +304,7 @@ static int controller_probe(struct platform_device *pdev) err = -ENOMEM; goto out_ida; } - cd->class_dev->class = controller_class; + cd->class_dev->class = &controller_class; cd->class_dev->groups = controller_attribute_groups; cd->class_dev->parent = dev; cd->class_dev->id = id; @@ -351,12 +354,12 @@ static int __init controller_init(void) { int err; - controller_class = class_create("arcx_anybus_controller"); - if (IS_ERR(controller_class)) - return PTR_ERR(controller_class); + err = class_register(&controller_class); + if (err) + return err; err = platform_driver_register(&controller_driver); if (err) - class_destroy(controller_class); + class_unregister(&controller_class); return err; } @@ -364,7 +367,7 @@ static int __init controller_init(void) static void __exit controller_exit(void) { platform_driver_unregister(&controller_driver); - class_destroy(controller_class); + class_unregister(&controller_class); ida_destroy(&controller_index_ida); } diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 32b2e817ff04..15c246d3b1a3 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -160,6 +160,7 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) while (remain) { size_t sending_len = min_t(size_t, MUX_TX_MAX_SIZE, remain); + gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, (void *)(buf + sent_len), sending_len, diff --git a/drivers/staging/greybus/audio_manager_private.h b/drivers/staging/greybus/audio_manager_private.h index 2b3a766c7de7..daca5b48b986 100644 --- a/drivers/staging/greybus/audio_manager_private.h +++ b/drivers/staging/greybus/audio_manager_private.h @@ -12,10 +12,9 @@ #include "audio_manager.h" -int gb_audio_manager_module_create( - struct gb_audio_manager_module **module, - struct kset *manager_kset, - int id, struct gb_audio_manager_module_descriptor *desc); +int gb_audio_manager_module_create(struct gb_audio_manager_module **module, + struct kset *manager_kset, int id, + struct gb_audio_manager_module_descriptor *desc); /* module destroyed via kobject_put */ diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index 7e01790a4659..b67315641d18 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -36,7 +36,10 @@ struct gb_cap { dev_t dev_num; }; -static struct class *cap_class; +static const struct class cap_class = { + .name = "gb_authenticate", +}; + static dev_t cap_dev_num; static DEFINE_IDA(cap_minors_map); static LIST_HEAD(cap_list); @@ -336,7 +339,7 @@ int gb_cap_connection_init(struct gb_connection *connection) goto err_remove_ida; /* Add a soft link to the previously added char-dev within the bundle */ - cap->class_device = device_create(cap_class, cap->parent, cap->dev_num, + cap->class_device = device_create(&cap_class, cap->parent, cap->dev_num, NULL, "gb-authenticate-%d", minor); if (IS_ERR(cap->class_device)) { ret = PTR_ERR(cap->class_device); @@ -370,7 +373,7 @@ void gb_cap_connection_exit(struct gb_connection *connection) cap = gb_connection_get_data(connection); - device_destroy(cap_class, cap->dev_num); + device_destroy(&cap_class, cap->dev_num); cdev_del(&cap->cdev); ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num)); @@ -402,9 +405,9 @@ int cap_init(void) { int ret; - cap_class = class_create("gb_authenticate"); - if (IS_ERR(cap_class)) - return PTR_ERR(cap_class); + ret = class_register(&cap_class); + if (ret) + return ret; ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS, "gb_authenticate"); @@ -414,13 +417,13 @@ int cap_init(void) return 0; err_remove_class: - class_destroy(cap_class); + class_unregister(&cap_class); return ret; } void cap_exit(void) { unregister_chrdev_region(cap_dev_num, NUM_MINORS); - class_destroy(cap_class); + class_unregister(&cap_class); ida_destroy(&cap_minors_map); } diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index a8efb86de140..79581457c4af 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -491,8 +491,6 @@ static void gb_bootrom_disconnect(struct gb_bundle *bundle) { struct gb_bootrom *bootrom = greybus_get_drvdata(bundle); - dev_dbg(&bundle->dev, "%s\n", __func__); - gb_connection_disable(bootrom->connection); /* Disable timeouts */ diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index cdbb42cd413b..a8173aa3a995 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -220,7 +220,7 @@ static int gb_camera_operation_sync_flags(struct gb_connection *connection, } static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp) + struct gb_camera_configure_streams_response *resp) { unsigned int max_pkt_size = 0; unsigned int i; @@ -267,8 +267,7 @@ static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, * Validate the stream configuration response verifying padding is correctly * set and the returned number of streams is supported */ -static const int gb_camera_configure_streams_validate_response( - struct gb_camera *gcam, +static const int gb_camera_configure_streams_validate_response(struct gb_camera *gcam, struct gb_camera_configure_streams_response *resp, unsigned int nstreams) { @@ -378,8 +377,8 @@ struct ap_csi_config_request { #define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U static int gb_camera_setup_data_connection(struct gb_camera *gcam, - struct gb_camera_configure_streams_response *resp, - struct gb_camera_csi_params *csi_params) + struct gb_camera_configure_streams_response *resp, + struct gb_camera_csi_params *csi_params) { struct ap_csi_config_request csi_cfg; struct gb_connection *conn; @@ -783,8 +782,8 @@ static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len) } static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams, - unsigned int *flags, struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params) + unsigned int *flags, struct gb_camera_stream *streams, + struct gb_camera_csi_params *csi_params) { struct gb_camera *gcam = priv; struct gb_camera_stream_config *gb_streams; diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index cd9141e4b794..93137a3c4907 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -55,7 +55,10 @@ struct fw_mgmt { */ #define NUM_MINORS U8_MAX -static struct class *fw_mgmt_class; +static const struct class fw_mgmt_class = { + .name = "gb_fw_mgmt", +}; + static dev_t fw_mgmt_dev_num; static DEFINE_IDA(fw_mgmt_minors_map); static LIST_HEAD(fw_mgmt_list); @@ -629,7 +632,7 @@ int gb_fw_mgmt_connection_init(struct gb_connection *connection) goto err_remove_ida; /* Add a soft link to the previously added char-dev within the bundle */ - fw_mgmt->class_device = device_create(fw_mgmt_class, fw_mgmt->parent, + fw_mgmt->class_device = device_create(&fw_mgmt_class, fw_mgmt->parent, fw_mgmt->dev_num, NULL, "gb-fw-mgmt-%d", minor); if (IS_ERR(fw_mgmt->class_device)) { @@ -664,7 +667,7 @@ void gb_fw_mgmt_connection_exit(struct gb_connection *connection) fw_mgmt = gb_connection_get_data(connection); - device_destroy(fw_mgmt_class, fw_mgmt->dev_num); + device_destroy(&fw_mgmt_class, fw_mgmt->dev_num); cdev_del(&fw_mgmt->cdev); ida_simple_remove(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num)); @@ -696,9 +699,9 @@ int fw_mgmt_init(void) { int ret; - fw_mgmt_class = class_create("gb_fw_mgmt"); - if (IS_ERR(fw_mgmt_class)) - return PTR_ERR(fw_mgmt_class); + ret = class_register(&fw_mgmt_class); + if (ret) + return ret; ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS, "gb_fw_mgmt"); @@ -708,13 +711,13 @@ int fw_mgmt_init(void) return 0; err_remove_class: - class_destroy(fw_mgmt_class); + class_unregister(&fw_mgmt_class); return ret; } void fw_mgmt_exit(void) { unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS); - class_destroy(fw_mgmt_class); + class_unregister(&fw_mgmt_class); ida_destroy(&fw_mgmt_minors_map); } diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c index 8bca8cb12cc6..b9c6eff7cdc1 100644 --- a/drivers/staging/greybus/raw.c +++ b/drivers/staging/greybus/raw.c @@ -29,10 +29,13 @@ struct gb_raw { struct raw_data { struct list_head entry; u32 len; - u8 data[]; + u8 data[] __counted_by(len); +}; + +static const struct class raw_class = { + .name = "gb_raw", }; -static struct class *raw_class; static int raw_major; static const struct file_operations raw_fops; static DEFINE_IDA(minors); @@ -70,7 +73,7 @@ static int receive_data(struct gb_raw *raw, u32 len, u8 *data) goto exit; } - raw_data = kmalloc(sizeof(*raw_data) + len, GFP_KERNEL); + raw_data = kmalloc(struct_size(raw_data, data, len), GFP_KERNEL); if (!raw_data) { retval = -ENOMEM; goto exit; @@ -195,7 +198,7 @@ static int gb_raw_probe(struct gb_bundle *bundle, if (retval) goto error_connection_disable; - raw->device = device_create(raw_class, &connection->bundle->dev, + raw->device = device_create(&raw_class, &connection->bundle->dev, raw->dev, raw, "gb!raw%d", minor); if (IS_ERR(raw->device)) { retval = PTR_ERR(raw->device); @@ -229,7 +232,7 @@ static void gb_raw_disconnect(struct gb_bundle *bundle) struct raw_data *temp; // FIXME - handle removing a connection when the char device node is open. - device_destroy(raw_class, raw->dev); + device_destroy(&raw_class, raw->dev); cdev_del(&raw->cdev); gb_connection_disable(connection); ida_simple_remove(&minors, MINOR(raw->dev)); @@ -340,11 +343,9 @@ static int raw_init(void) dev_t dev; int retval; - raw_class = class_create("gb_raw"); - if (IS_ERR(raw_class)) { - retval = PTR_ERR(raw_class); + retval = class_register(&raw_class); + if (retval) goto error_class; - } retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw"); if (retval < 0) @@ -361,7 +362,7 @@ static int raw_init(void) error_gb: unregister_chrdev_region(dev, NUM_MINORS); error_chrdev: - class_destroy(raw_class); + class_unregister(&raw_class); error_class: return retval; } @@ -371,7 +372,7 @@ static void __exit raw_exit(void) { greybus_deregister(&gb_raw_driver); unregister_chrdev_region(MKDEV(raw_major, 0), NUM_MINORS); - class_destroy(raw_class); + class_unregister(&raw_class); ida_destroy(&minors); } module_exit(raw_exit); diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index 9fb118e77a1f..f1d44e4955fc 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -395,9 +395,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, priv->hostt.buff[priv->hostt.qtail] = le16_to_cpu(hdr->event); priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE; - spin_lock(&priv->tx_dev.tx_dev_lock); + spin_lock_bh(&priv->tx_dev.tx_dev_lock); result = enqueue_txdev(priv, p, size, complete_handler, skb); - spin_unlock(&priv->tx_dev.tx_dev_lock); + spin_unlock_bh(&priv->tx_dev.tx_dev_lock); if (txq_has_space(priv)) queue_delayed_work(priv->wq, &priv->rw_dwork, 0); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index d5271eac14f6..08ec3aae90ea 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -777,7 +777,7 @@ static struct i2c_driver dcon_driver = { .name = "olpc_dcon", .pm = &dcon_pm_ops, }, - .class = I2C_CLASS_DDC | I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON, .id_table = dcon_idtable, .probe = dcon_probe, .remove = dcon_remove, diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c index 58887619b83f..0ec3130225db 100644 --- a/drivers/staging/pi433/pi433_if.c +++ b/drivers/staging/pi433/pi433_if.c @@ -56,7 +56,10 @@ static DEFINE_IDR(pi433_idr); static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */ static struct dentry *root_dir; /* debugfs root directory for the driver */ -static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */ +/* mainly for udev to create /dev/pi433 */ +static const struct class pi433_class = { + .name = "pi433", +}; /* * tx config is instance specific @@ -1259,7 +1262,7 @@ static int pi433_probe(struct spi_device *spi) /* create device */ device->devt = MKDEV(MAJOR(pi433_dev), device->minor); - device->dev = device_create(pi433_class, + device->dev = device_create(&pi433_class, &spi->dev, device->devt, device, @@ -1315,7 +1318,7 @@ del_cdev: cdev_failed: kthread_stop(device->tx_task_struct); send_thread_failed: - device_destroy(pi433_class, device->devt); + device_destroy(&pi433_class, device->devt); device_create_failed: pi433_free_minor(device); minor_failed: @@ -1342,7 +1345,7 @@ static void pi433_remove(struct spi_device *spi) kthread_stop(device->tx_task_struct); - device_destroy(pi433_class, device->devt); + device_destroy(&pi433_class, device->devt); cdev_del(device->cdev); @@ -1398,18 +1401,18 @@ static int __init pi433_init(void) if (status < 0) return status; - pi433_class = class_create("pi433"); - if (IS_ERR(pi433_class)) { + status = class_register(&pi433_class); + if (status) { unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); - return PTR_ERR(pi433_class); + return status; } root_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); status = spi_register_driver(&pi433_spi_driver); if (status < 0) { - class_destroy(pi433_class); + class_unregister(&pi433_class); unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); } @@ -1422,7 +1425,7 @@ module_init(pi433_init); static void __exit pi433_exit(void) { spi_unregister_driver(&pi433_spi_driver); - class_destroy(pi433_class); + class_unregister(&pi433_class); unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); debugfs_remove(root_dir); } diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig deleted file mode 100644 index 6d831ed67965..000000000000 --- a/drivers/staging/qlge/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -config QLGE - tristate "QLogic QLGE 10Gb Ethernet Driver Support" - depends on ETHERNET && PCI - select NET_DEVLINK - help - This driver supports QLogic ISP8XXX 10Gb Ethernet cards. - - To compile this driver as a module, choose M here. The module will be - called qlge. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile deleted file mode 100644 index 07c1898a512e..000000000000 --- a/drivers/staging/qlge/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the Qlogic 10GbE PCI Express ethernet driver -# - -obj-$(CONFIG_QLGE) += qlge.o - -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO deleted file mode 100644 index c76394b9451b..000000000000 --- a/drivers/staging/qlge/TODO +++ /dev/null @@ -1,33 +0,0 @@ -* commit 7c734359d350 ("qlge: Size RX buffers based on MTU.", v2.6.33-rc1) - introduced dead code in the receive routines, which should be rewritten - anyways by the admission of the author himself, see the comment above - ql_build_rx_skb(). That function is now used exclusively to handle packets - that underwent header splitting but it still contains code to handle non - split cases. -* truesize accounting is incorrect (ex: a 9000B frame has skb->truesize 10280 - while containing two frags of order-1 allocations, ie. >16K) -* while in that area, using two 8k buffers to store one 9k frame is a poor - choice of buffer size. -* in the "chain of large buffers" case, the driver uses an skb allocated with - head room but only puts data in the frags. -* rename "rx" queues to "completion" queues. Calling tx completion queues "rx - queues" is confusing. -* struct rx_ring is used for rx and tx completions, with some members relevant - to one case only -* the flow control implementation in firmware is buggy (sends a flood of pause - frames, resets the link, device and driver buffer queues become - desynchronized), disable it by default -* some structures are initialized redundantly (ex. memset 0 after - alloc_etherdev()) -* the driver has a habit of using runtime checks where compile time checks are - possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers()) -* reorder struct members to avoid holes if it doesn't impact performance -* avoid legacy/deprecated apis (ex. replace pci_dma_*, replace pci_enable_msi, - use pci_iomap) -* some "while" loops could be rewritten with simple "for", ex. - ql_wait_reg_rdy(), ql_start_rx_ring()) -* remove duplicate and useless comments -* fix weird line wrapping (all over, ex. the ql_set_routing_reg() calls in - qlge_set_multicast_list()). -* fix weird indentation (all over, ex. the for loops in qlge_get_stats()) -* fix checkpatch issues diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h deleted file mode 100644 index d0dd659834ee..000000000000 --- a/drivers/staging/qlge/qlge.h +++ /dev/null @@ -1,2293 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * QLogic QLA41xx NIC HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - */ -#ifndef _QLGE_H_ -#define _QLGE_H_ - -#include -#include -#include -#include -#include - -/* - * General definitions... - */ -#define DRV_NAME "qlge" -#define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "1.00.00.35" - -#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ - -#define QLGE_VENDOR_ID 0x1077 -#define QLGE_DEVICE_ID_8012 0x8012 -#define QLGE_DEVICE_ID_8000 0x8000 -#define QLGE_MEZZ_SSYS_ID_068 0x0068 -#define QLGE_MEZZ_SSYS_ID_180 0x0180 -#define MAX_CPUS 8 -#define MAX_TX_RINGS MAX_CPUS -#define MAX_RX_RINGS ((MAX_CPUS * 2) + 1) - -#define NUM_TX_RING_ENTRIES 256 -#define NUM_RX_RING_ENTRIES 256 - -/* Use the same len for sbq and lbq. Note that it seems like the device might - * support different sizes. - */ -#define QLGE_BQ_SHIFT 9 -#define QLGE_BQ_LEN BIT(QLGE_BQ_SHIFT) -#define QLGE_BQ_SIZE (QLGE_BQ_LEN * sizeof(__le64)) - -#define DB_PAGE_SIZE 4096 - -/* Calculate the number of (4k) pages required to - * contain a buffer queue of the given length. - */ -#define MAX_DB_PAGES_PER_BQ(x) \ - (((x * sizeof(u64)) / DB_PAGE_SIZE) + \ - (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0)) - -#define RX_RING_SHADOW_SPACE (sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN) * sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN) * sizeof(u64)) -#define LARGE_BUFFER_MAX_SIZE 8192 -#define LARGE_BUFFER_MIN_SIZE 2048 - -#define MAX_CQ 128 -#define DFLT_COALESCE_WAIT 100 /* 100 usec wait for coalescing */ -#define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ -#define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT / 2) -#define UDELAY_COUNT 3 -#define UDELAY_DELAY 100 - -#define TX_DESC_PER_IOCB 8 - -#if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0 -#define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) -#else /* all other page sizes */ -#define TX_DESC_PER_OAL 0 -#endif - -/* Word shifting for converting 64-bit - * address to a series of 16-bit words. - * This is used for some MPI firmware - * mailbox commands. - */ -#define LSW(x) ((u16)(x)) -#define MSW(x) ((u16)((u32)(x) >> 16)) -#define LSD(x) ((u32)((u64)(x))) -#define MSD(x) ((u32)((((u64)(x)) >> 32))) - -/* In some cases, the device interprets a value of 0x0000 as 65536. These - * cases are marked using the following macro. - */ -#define QLGE_FIT16(value) ((u16)(value)) - -/* MPI test register definitions. This register - * is used for determining alternate NIC function's - * PCI->func number. - */ -enum { - MPI_TEST_FUNC_PORT_CFG = 0x1002, - MPI_TEST_FUNC_PRB_CTL = 0x100e, - MPI_TEST_FUNC_PRB_EN = 0x18a20000, - MPI_TEST_FUNC_RST_STS = 0x100a, - MPI_TEST_FUNC_RST_FRC = 0x00000003, - MPI_TEST_NIC_FUNC_MASK = 0x00000007, - MPI_TEST_NIC1_FUNCTION_ENABLE = (1 << 0), - MPI_TEST_NIC1_FUNCTION_MASK = 0x0000000e, - MPI_TEST_NIC1_FUNC_SHIFT = 1, - MPI_TEST_NIC2_FUNCTION_ENABLE = (1 << 4), - MPI_TEST_NIC2_FUNCTION_MASK = 0x000000e0, - MPI_TEST_NIC2_FUNC_SHIFT = 5, - MPI_TEST_FC1_FUNCTION_ENABLE = (1 << 8), - MPI_TEST_FC1_FUNCTION_MASK = 0x00000e00, - MPI_TEST_FC1_FUNCTION_SHIFT = 9, - MPI_TEST_FC2_FUNCTION_ENABLE = (1 << 12), - MPI_TEST_FC2_FUNCTION_MASK = 0x0000e000, - MPI_TEST_FC2_FUNCTION_SHIFT = 13, - - MPI_NIC_READ = 0x00000000, - MPI_NIC_REG_BLOCK = 0x00020000, - MPI_NIC_FUNCTION_SHIFT = 6, -}; - -/* - * Processor Address Register (PROC_ADDR) bit definitions. - */ -enum { - /* Misc. stuff */ - MAILBOX_COUNT = 16, - MAILBOX_TIMEOUT = 5, - - PROC_ADDR_RDY = (1 << 31), - PROC_ADDR_R = (1 << 30), - PROC_ADDR_ERR = (1 << 29), - PROC_ADDR_DA = (1 << 28), - PROC_ADDR_FUNC0_MBI = 0x00001180, - PROC_ADDR_FUNC0_MBO = (PROC_ADDR_FUNC0_MBI + MAILBOX_COUNT), - PROC_ADDR_FUNC0_CTL = 0x000011a1, - PROC_ADDR_FUNC2_MBI = 0x00001280, - PROC_ADDR_FUNC2_MBO = (PROC_ADDR_FUNC2_MBI + MAILBOX_COUNT), - PROC_ADDR_FUNC2_CTL = 0x000012a1, - PROC_ADDR_MPI_RISC = 0x00000000, - PROC_ADDR_MDE = 0x00010000, - PROC_ADDR_REGBLOCK = 0x00020000, - PROC_ADDR_RISC_REG = 0x00030000, -}; - -/* - * System Register (SYS) bit definitions. - */ -enum { - SYS_EFE = (1 << 0), - SYS_FAE = (1 << 1), - SYS_MDC = (1 << 2), - SYS_DST = (1 << 3), - SYS_DWC = (1 << 4), - SYS_EVW = (1 << 5), - SYS_OMP_DLY_MASK = 0x3f000000, - /* - * There are no values defined as of edit #15. - */ - SYS_ODI = (1 << 14), -}; - -/* - * Reset/Failover Register (RST_FO) bit definitions. - */ -enum { - RST_FO_TFO = (1 << 0), - RST_FO_RR_MASK = 0x00060000, - RST_FO_RR_CQ_CAM = 0x00000000, - RST_FO_RR_DROP = 0x00000002, - RST_FO_RR_DQ = 0x00000004, - RST_FO_RR_RCV_FUNC_CQ = 0x00000006, - RST_FO_FRB = (1 << 12), - RST_FO_MOP = (1 << 13), - RST_FO_REG = (1 << 14), - RST_FO_FR = (1 << 15), -}; - -/* - * Function Specific Control Register (FSC) bit definitions. - */ -enum { - FSC_DBRST_MASK = 0x00070000, - FSC_DBRST_256 = 0x00000000, - FSC_DBRST_512 = 0x00000001, - FSC_DBRST_768 = 0x00000002, - FSC_DBRST_1024 = 0x00000003, - FSC_DBL_MASK = 0x00180000, - FSC_DBL_DBRST = 0x00000000, - FSC_DBL_MAX_PLD = 0x00000008, - FSC_DBL_MAX_BRST = 0x00000010, - FSC_DBL_128_BYTES = 0x00000018, - FSC_EC = (1 << 5), - FSC_EPC_MASK = 0x00c00000, - FSC_EPC_INBOUND = (1 << 6), - FSC_EPC_OUTBOUND = (1 << 7), - FSC_VM_PAGESIZE_MASK = 0x07000000, - FSC_VM_PAGE_2K = 0x00000100, - FSC_VM_PAGE_4K = 0x00000200, - FSC_VM_PAGE_8K = 0x00000300, - FSC_VM_PAGE_64K = 0x00000600, - FSC_SH = (1 << 11), - FSC_DSB = (1 << 12), - FSC_STE = (1 << 13), - FSC_FE = (1 << 15), -}; - -/* - * Host Command Status Register (CSR) bit definitions. - */ -enum { - CSR_ERR_STS_MASK = 0x0000003f, - /* - * There are no valued defined as of edit #15. - */ - CSR_RR = (1 << 8), - CSR_HRI = (1 << 9), - CSR_RP = (1 << 10), - CSR_CMD_PARM_SHIFT = 22, - CSR_CMD_NOP = 0x00000000, - CSR_CMD_SET_RST = 0x10000000, - CSR_CMD_CLR_RST = 0x20000000, - CSR_CMD_SET_PAUSE = 0x30000000, - CSR_CMD_CLR_PAUSE = 0x40000000, - CSR_CMD_SET_H2R_INT = 0x50000000, - CSR_CMD_CLR_H2R_INT = 0x60000000, - CSR_CMD_PAR_EN = 0x70000000, - CSR_CMD_SET_BAD_PAR = 0x80000000, - CSR_CMD_CLR_BAD_PAR = 0x90000000, - CSR_CMD_CLR_R2PCI_INT = 0xa0000000, -}; - -/* - * Configuration Register (CFG) bit definitions. - */ -enum { - CFG_LRQ = (1 << 0), - CFG_DRQ = (1 << 1), - CFG_LR = (1 << 2), - CFG_DR = (1 << 3), - CFG_LE = (1 << 5), - CFG_LCQ = (1 << 6), - CFG_DCQ = (1 << 7), - CFG_Q_SHIFT = 8, - CFG_Q_MASK = 0x7f000000, -}; - -/* - * Status Register (STS) bit definitions. - */ -enum { - STS_FE = (1 << 0), - STS_PI = (1 << 1), - STS_PL0 = (1 << 2), - STS_PL1 = (1 << 3), - STS_PI0 = (1 << 4), - STS_PI1 = (1 << 5), - STS_FUNC_ID_MASK = 0x000000c0, - STS_FUNC_ID_SHIFT = 6, - STS_F0E = (1 << 8), - STS_F1E = (1 << 9), - STS_F2E = (1 << 10), - STS_F3E = (1 << 11), - STS_NFE = (1 << 12), -}; - -/* - * Interrupt Enable Register (INTR_EN) bit definitions. - */ -enum { - INTR_EN_INTR_MASK = 0x007f0000, - INTR_EN_TYPE_MASK = 0x03000000, - INTR_EN_TYPE_ENABLE = 0x00000100, - INTR_EN_TYPE_DISABLE = 0x00000200, - INTR_EN_TYPE_READ = 0x00000300, - INTR_EN_IHD = (1 << 13), - INTR_EN_IHD_MASK = (INTR_EN_IHD << 16), - INTR_EN_EI = (1 << 14), - INTR_EN_EN = (1 << 15), -}; - -/* - * Interrupt Mask Register (INTR_MASK) bit definitions. - */ -enum { - INTR_MASK_PI = (1 << 0), - INTR_MASK_HL0 = (1 << 1), - INTR_MASK_LH0 = (1 << 2), - INTR_MASK_HL1 = (1 << 3), - INTR_MASK_LH1 = (1 << 4), - INTR_MASK_SE = (1 << 5), - INTR_MASK_LSC = (1 << 6), - INTR_MASK_MC = (1 << 7), - INTR_MASK_LINK_IRQS = INTR_MASK_LSC | INTR_MASK_SE | INTR_MASK_MC, -}; - -/* - * Register (REV_ID) bit definitions. - */ -enum { - REV_ID_MASK = 0x0000000f, - REV_ID_NICROLL_SHIFT = 0, - REV_ID_NICREV_SHIFT = 4, - REV_ID_XGROLL_SHIFT = 8, - REV_ID_XGREV_SHIFT = 12, - REV_ID_CHIPREV_SHIFT = 28, -}; - -/* - * Force ECC Error Register (FRC_ECC_ERR) bit definitions. - */ -enum { - FRC_ECC_ERR_VW = (1 << 12), - FRC_ECC_ERR_VB = (1 << 13), - FRC_ECC_ERR_NI = (1 << 14), - FRC_ECC_ERR_NO = (1 << 15), - FRC_ECC_PFE_SHIFT = 16, - FRC_ECC_ERR_DO = (1 << 18), - FRC_ECC_P14 = (1 << 19), -}; - -/* - * Error Status Register (ERR_STS) bit definitions. - */ -enum { - ERR_STS_NOF = (1 << 0), - ERR_STS_NIF = (1 << 1), - ERR_STS_DRP = (1 << 2), - ERR_STS_XGP = (1 << 3), - ERR_STS_FOU = (1 << 4), - ERR_STS_FOC = (1 << 5), - ERR_STS_FOF = (1 << 6), - ERR_STS_FIU = (1 << 7), - ERR_STS_FIC = (1 << 8), - ERR_STS_FIF = (1 << 9), - ERR_STS_MOF = (1 << 10), - ERR_STS_TA = (1 << 11), - ERR_STS_MA = (1 << 12), - ERR_STS_MPE = (1 << 13), - ERR_STS_SCE = (1 << 14), - ERR_STS_STE = (1 << 15), - ERR_STS_FOW = (1 << 16), - ERR_STS_UE = (1 << 17), - ERR_STS_MCH = (1 << 26), - ERR_STS_LOC_SHIFT = 27, -}; - -/* - * RAM Debug Address Register (RAM_DBG_ADDR) bit definitions. - */ -enum { - RAM_DBG_ADDR_FW = (1 << 30), - RAM_DBG_ADDR_FR = (1 << 31), -}; - -/* - * Semaphore Register (SEM) bit definitions. - */ -enum { - /* - * Example: - * reg = SEM_XGMAC0_MASK | (SEM_SET << SEM_XGMAC0_SHIFT) - */ - SEM_CLEAR = 0, - SEM_SET = 1, - SEM_FORCE = 3, - SEM_XGMAC0_SHIFT = 0, - SEM_XGMAC1_SHIFT = 2, - SEM_ICB_SHIFT = 4, - SEM_MAC_ADDR_SHIFT = 6, - SEM_FLASH_SHIFT = 8, - SEM_PROBE_SHIFT = 10, - SEM_RT_IDX_SHIFT = 12, - SEM_PROC_REG_SHIFT = 14, - SEM_XGMAC0_MASK = 0x00030000, - SEM_XGMAC1_MASK = 0x000c0000, - SEM_ICB_MASK = 0x00300000, - SEM_MAC_ADDR_MASK = 0x00c00000, - SEM_FLASH_MASK = 0x03000000, - SEM_PROBE_MASK = 0x0c000000, - SEM_RT_IDX_MASK = 0x30000000, - SEM_PROC_REG_MASK = 0xc0000000, -}; - -/* - * 10G MAC Address Register (XGMAC_ADDR) bit definitions. - */ -enum { - XGMAC_ADDR_RDY = (1 << 31), - XGMAC_ADDR_R = (1 << 30), - XGMAC_ADDR_XME = (1 << 29), - - /* XGMAC control registers */ - PAUSE_SRC_LO = 0x00000100, - PAUSE_SRC_HI = 0x00000104, - GLOBAL_CFG = 0x00000108, - GLOBAL_CFG_RESET = (1 << 0), - GLOBAL_CFG_JUMBO = (1 << 6), - GLOBAL_CFG_TX_STAT_EN = (1 << 10), - GLOBAL_CFG_RX_STAT_EN = (1 << 11), - TX_CFG = 0x0000010c, - TX_CFG_RESET = (1 << 0), - TX_CFG_EN = (1 << 1), - TX_CFG_PREAM = (1 << 2), - RX_CFG = 0x00000110, - RX_CFG_RESET = (1 << 0), - RX_CFG_EN = (1 << 1), - RX_CFG_PREAM = (1 << 2), - FLOW_CTL = 0x0000011c, - PAUSE_OPCODE = 0x00000120, - PAUSE_TIMER = 0x00000124, - PAUSE_FRM_DEST_LO = 0x00000128, - PAUSE_FRM_DEST_HI = 0x0000012c, - MAC_TX_PARAMS = 0x00000134, - MAC_TX_PARAMS_JUMBO = (1 << 31), - MAC_TX_PARAMS_SIZE_SHIFT = 16, - MAC_RX_PARAMS = 0x00000138, - MAC_SYS_INT = 0x00000144, - MAC_SYS_INT_MASK = 0x00000148, - MAC_MGMT_INT = 0x0000014c, - MAC_MGMT_IN_MASK = 0x00000150, - EXT_ARB_MODE = 0x000001fc, - - /* XGMAC TX statistics registers */ - TX_PKTS = 0x00000200, - TX_BYTES = 0x00000208, - TX_MCAST_PKTS = 0x00000210, - TX_BCAST_PKTS = 0x00000218, - TX_UCAST_PKTS = 0x00000220, - TX_CTL_PKTS = 0x00000228, - TX_PAUSE_PKTS = 0x00000230, - TX_64_PKT = 0x00000238, - TX_65_TO_127_PKT = 0x00000240, - TX_128_TO_255_PKT = 0x00000248, - TX_256_511_PKT = 0x00000250, - TX_512_TO_1023_PKT = 0x00000258, - TX_1024_TO_1518_PKT = 0x00000260, - TX_1519_TO_MAX_PKT = 0x00000268, - TX_UNDERSIZE_PKT = 0x00000270, - TX_OVERSIZE_PKT = 0x00000278, - - /* XGMAC statistics control registers */ - RX_HALF_FULL_DET = 0x000002a0, - TX_HALF_FULL_DET = 0x000002a4, - RX_OVERFLOW_DET = 0x000002a8, - TX_OVERFLOW_DET = 0x000002ac, - RX_HALF_FULL_MASK = 0x000002b0, - TX_HALF_FULL_MASK = 0x000002b4, - RX_OVERFLOW_MASK = 0x000002b8, - TX_OVERFLOW_MASK = 0x000002bc, - STAT_CNT_CTL = 0x000002c0, - STAT_CNT_CTL_CLEAR_TX = (1 << 0), - STAT_CNT_CTL_CLEAR_RX = (1 << 1), - AUX_RX_HALF_FULL_DET = 0x000002d0, - AUX_TX_HALF_FULL_DET = 0x000002d4, - AUX_RX_OVERFLOW_DET = 0x000002d8, - AUX_TX_OVERFLOW_DET = 0x000002dc, - AUX_RX_HALF_FULL_MASK = 0x000002f0, - AUX_TX_HALF_FULL_MASK = 0x000002f4, - AUX_RX_OVERFLOW_MASK = 0x000002f8, - AUX_TX_OVERFLOW_MASK = 0x000002fc, - - /* XGMAC RX statistics registers */ - RX_BYTES = 0x00000300, - RX_BYTES_OK = 0x00000308, - RX_PKTS = 0x00000310, - RX_PKTS_OK = 0x00000318, - RX_BCAST_PKTS = 0x00000320, - RX_MCAST_PKTS = 0x00000328, - RX_UCAST_PKTS = 0x00000330, - RX_UNDERSIZE_PKTS = 0x00000338, - RX_OVERSIZE_PKTS = 0x00000340, - RX_JABBER_PKTS = 0x00000348, - RX_UNDERSIZE_FCERR_PKTS = 0x00000350, - RX_DROP_EVENTS = 0x00000358, - RX_FCERR_PKTS = 0x00000360, - RX_ALIGN_ERR = 0x00000368, - RX_SYMBOL_ERR = 0x00000370, - RX_MAC_ERR = 0x00000378, - RX_CTL_PKTS = 0x00000380, - RX_PAUSE_PKTS = 0x00000388, - RX_64_PKTS = 0x00000390, - RX_65_TO_127_PKTS = 0x00000398, - RX_128_255_PKTS = 0x000003a0, - RX_256_511_PKTS = 0x000003a8, - RX_512_TO_1023_PKTS = 0x000003b0, - RX_1024_TO_1518_PKTS = 0x000003b8, - RX_1519_TO_MAX_PKTS = 0x000003c0, - RX_LEN_ERR_PKTS = 0x000003c8, - - /* XGMAC MDIO control registers */ - MDIO_TX_DATA = 0x00000400, - MDIO_RX_DATA = 0x00000410, - MDIO_CMD = 0x00000420, - MDIO_PHY_ADDR = 0x00000430, - MDIO_PORT = 0x00000440, - MDIO_STATUS = 0x00000450, - - XGMAC_REGISTER_END = 0x00000740, -}; - -/* - * Enhanced Transmission Schedule Registers (NIC_ETS,CNA_ETS) bit definitions. - */ -enum { - ETS_QUEUE_SHIFT = 29, - ETS_REF = (1 << 26), - ETS_RS = (1 << 27), - ETS_P = (1 << 28), - ETS_FC_COS_SHIFT = 23, -}; - -/* - * Flash Address Register (FLASH_ADDR) bit definitions. - */ -enum { - FLASH_ADDR_RDY = (1 << 31), - FLASH_ADDR_R = (1 << 30), - FLASH_ADDR_ERR = (1 << 29), -}; - -/* - * Stop CQ Processing Register (CQ_STOP) bit definitions. - */ -enum { - CQ_STOP_QUEUE_MASK = (0x007f0000), - CQ_STOP_TYPE_MASK = (0x03000000), - CQ_STOP_TYPE_START = 0x00000100, - CQ_STOP_TYPE_STOP = 0x00000200, - CQ_STOP_TYPE_READ = 0x00000300, - CQ_STOP_EN = (1 << 15), -}; - -/* - * MAC Protocol Address Index Register (MAC_ADDR_IDX) bit definitions. - */ -enum { - MAC_ADDR_IDX_SHIFT = 4, - MAC_ADDR_TYPE_SHIFT = 16, - MAC_ADDR_TYPE_COUNT = 10, - MAC_ADDR_TYPE_MASK = 0x000f0000, - MAC_ADDR_TYPE_CAM_MAC = 0x00000000, - MAC_ADDR_TYPE_MULTI_MAC = 0x00010000, - MAC_ADDR_TYPE_VLAN = 0x00020000, - MAC_ADDR_TYPE_MULTI_FLTR = 0x00030000, - MAC_ADDR_TYPE_FC_MAC = 0x00040000, - MAC_ADDR_TYPE_MGMT_MAC = 0x00050000, - MAC_ADDR_TYPE_MGMT_VLAN = 0x00060000, - MAC_ADDR_TYPE_MGMT_V4 = 0x00070000, - MAC_ADDR_TYPE_MGMT_V6 = 0x00080000, - MAC_ADDR_TYPE_MGMT_TU_DP = 0x00090000, - MAC_ADDR_ADR = (1 << 25), - MAC_ADDR_RS = (1 << 26), - MAC_ADDR_E = (1 << 27), - MAC_ADDR_MR = (1 << 30), - MAC_ADDR_MW = (1 << 31), - MAX_MULTICAST_ENTRIES = 32, - - /* Entry count and words per entry - * for each address type in the filter. - */ - MAC_ADDR_MAX_CAM_ENTRIES = 512, - MAC_ADDR_MAX_CAM_WCOUNT = 3, - MAC_ADDR_MAX_MULTICAST_ENTRIES = 32, - MAC_ADDR_MAX_MULTICAST_WCOUNT = 2, - MAC_ADDR_MAX_VLAN_ENTRIES = 4096, - MAC_ADDR_MAX_VLAN_WCOUNT = 1, - MAC_ADDR_MAX_MCAST_FLTR_ENTRIES = 4096, - MAC_ADDR_MAX_MCAST_FLTR_WCOUNT = 1, - MAC_ADDR_MAX_FC_MAC_ENTRIES = 4, - MAC_ADDR_MAX_FC_MAC_WCOUNT = 2, - MAC_ADDR_MAX_MGMT_MAC_ENTRIES = 8, - MAC_ADDR_MAX_MGMT_MAC_WCOUNT = 2, - MAC_ADDR_MAX_MGMT_VLAN_ENTRIES = 16, - MAC_ADDR_MAX_MGMT_VLAN_WCOUNT = 1, - MAC_ADDR_MAX_MGMT_V4_ENTRIES = 4, - MAC_ADDR_MAX_MGMT_V4_WCOUNT = 1, - MAC_ADDR_MAX_MGMT_V6_ENTRIES = 4, - MAC_ADDR_MAX_MGMT_V6_WCOUNT = 4, - MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES = 4, - MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT = 1, -}; - -/* - * MAC Protocol Address Index Register (SPLT_HDR) bit definitions. - */ -enum { - SPLT_HDR_EP = (1 << 31), -}; - -/* - * FCoE Receive Configuration Register (FC_RCV_CFG) bit definitions. - */ -enum { - FC_RCV_CFG_ECT = (1 << 15), - FC_RCV_CFG_DFH = (1 << 20), - FC_RCV_CFG_DVF = (1 << 21), - FC_RCV_CFG_RCE = (1 << 27), - FC_RCV_CFG_RFE = (1 << 28), - FC_RCV_CFG_TEE = (1 << 29), - FC_RCV_CFG_TCE = (1 << 30), - FC_RCV_CFG_TFE = (1 << 31), -}; - -/* - * NIC Receive Configuration Register (NIC_RCV_CFG) bit definitions. - */ -enum { - NIC_RCV_CFG_PPE = (1 << 0), - NIC_RCV_CFG_VLAN_MASK = 0x00060000, - NIC_RCV_CFG_VLAN_ALL = 0x00000000, - NIC_RCV_CFG_VLAN_MATCH_ONLY = 0x00000002, - NIC_RCV_CFG_VLAN_MATCH_AND_NON = 0x00000004, - NIC_RCV_CFG_VLAN_NONE_AND_NON = 0x00000006, - NIC_RCV_CFG_RV = (1 << 3), - NIC_RCV_CFG_DFQ_MASK = (0x7f000000), - NIC_RCV_CFG_DFQ_SHIFT = 8, - NIC_RCV_CFG_DFQ = 0, /* HARDCODE default queue to 0. */ -}; - -/* - * Mgmt Receive Configuration Register (MGMT_RCV_CFG) bit definitions. - */ -enum { - MGMT_RCV_CFG_ARP = (1 << 0), - MGMT_RCV_CFG_DHC = (1 << 1), - MGMT_RCV_CFG_DHS = (1 << 2), - MGMT_RCV_CFG_NP = (1 << 3), - MGMT_RCV_CFG_I6N = (1 << 4), - MGMT_RCV_CFG_I6R = (1 << 5), - MGMT_RCV_CFG_DH6 = (1 << 6), - MGMT_RCV_CFG_UD1 = (1 << 7), - MGMT_RCV_CFG_UD0 = (1 << 8), - MGMT_RCV_CFG_BCT = (1 << 9), - MGMT_RCV_CFG_MCT = (1 << 10), - MGMT_RCV_CFG_DM = (1 << 11), - MGMT_RCV_CFG_RM = (1 << 12), - MGMT_RCV_CFG_STL = (1 << 13), - MGMT_RCV_CFG_VLAN_MASK = 0xc0000000, - MGMT_RCV_CFG_VLAN_ALL = 0x00000000, - MGMT_RCV_CFG_VLAN_MATCH_ONLY = 0x00004000, - MGMT_RCV_CFG_VLAN_MATCH_AND_NON = 0x00008000, - MGMT_RCV_CFG_VLAN_NONE_AND_NON = 0x0000c000, -}; - -/* - * Routing Index Register (RT_IDX) bit definitions. - */ -enum { - RT_IDX_IDX_SHIFT = 8, - RT_IDX_TYPE_MASK = 0x000f0000, - RT_IDX_TYPE_SHIFT = 16, - RT_IDX_TYPE_RT = 0x00000000, - RT_IDX_TYPE_RT_INV = 0x00010000, - RT_IDX_TYPE_NICQ = 0x00020000, - RT_IDX_TYPE_NICQ_INV = 0x00030000, - RT_IDX_DST_MASK = 0x00700000, - RT_IDX_DST_RSS = 0x00000000, - RT_IDX_DST_CAM_Q = 0x00100000, - RT_IDX_DST_COS_Q = 0x00200000, - RT_IDX_DST_DFLT_Q = 0x00300000, - RT_IDX_DST_DEST_Q = 0x00400000, - RT_IDX_RS = (1 << 26), - RT_IDX_E = (1 << 27), - RT_IDX_MR = (1 << 30), - RT_IDX_MW = (1 << 31), - - /* Nic Queue format - type 2 bits */ - RT_IDX_BCAST = (1 << 0), - RT_IDX_MCAST = (1 << 1), - RT_IDX_MCAST_MATCH = (1 << 2), - RT_IDX_MCAST_REG_MATCH = (1 << 3), - RT_IDX_MCAST_HASH_MATCH = (1 << 4), - RT_IDX_FC_MACH = (1 << 5), - RT_IDX_ETH_FCOE = (1 << 6), - RT_IDX_CAM_HIT = (1 << 7), - RT_IDX_CAM_BIT0 = (1 << 8), - RT_IDX_CAM_BIT1 = (1 << 9), - RT_IDX_VLAN_TAG = (1 << 10), - RT_IDX_VLAN_MATCH = (1 << 11), - RT_IDX_VLAN_FILTER = (1 << 12), - RT_IDX_ETH_SKIP1 = (1 << 13), - RT_IDX_ETH_SKIP2 = (1 << 14), - RT_IDX_BCAST_MCAST_MATCH = (1 << 15), - RT_IDX_802_3 = (1 << 16), - RT_IDX_LLDP = (1 << 17), - RT_IDX_UNUSED018 = (1 << 18), - RT_IDX_UNUSED019 = (1 << 19), - RT_IDX_UNUSED20 = (1 << 20), - RT_IDX_UNUSED21 = (1 << 21), - RT_IDX_ERR = (1 << 22), - RT_IDX_VALID = (1 << 23), - RT_IDX_TU_CSUM_ERR = (1 << 24), - RT_IDX_IP_CSUM_ERR = (1 << 25), - RT_IDX_MAC_ERR = (1 << 26), - RT_IDX_RSS_TCP6 = (1 << 27), - RT_IDX_RSS_TCP4 = (1 << 28), - RT_IDX_RSS_IPV6 = (1 << 29), - RT_IDX_RSS_IPV4 = (1 << 30), - RT_IDX_RSS_MATCH = (1 << 31), - - /* Hierarchy for the NIC Queue Mask */ - RT_IDX_ALL_ERR_SLOT = 0, - RT_IDX_MAC_ERR_SLOT = 0, - RT_IDX_IP_CSUM_ERR_SLOT = 1, - RT_IDX_TCP_UDP_CSUM_ERR_SLOT = 2, - RT_IDX_BCAST_SLOT = 3, - RT_IDX_MCAST_MATCH_SLOT = 4, - RT_IDX_ALLMULTI_SLOT = 5, - RT_IDX_UNUSED6_SLOT = 6, - RT_IDX_UNUSED7_SLOT = 7, - RT_IDX_RSS_MATCH_SLOT = 8, - RT_IDX_RSS_IPV4_SLOT = 8, - RT_IDX_RSS_IPV6_SLOT = 9, - RT_IDX_RSS_TCP4_SLOT = 10, - RT_IDX_RSS_TCP6_SLOT = 11, - RT_IDX_CAM_HIT_SLOT = 12, - RT_IDX_UNUSED013 = 13, - RT_IDX_UNUSED014 = 14, - RT_IDX_PROMISCUOUS_SLOT = 15, - RT_IDX_MAX_RT_SLOTS = 8, - RT_IDX_MAX_NIC_SLOTS = 16, -}; - -/* - * Serdes Address Register (XG_SERDES_ADDR) bit definitions. - */ -enum { - XG_SERDES_ADDR_RDY = (1 << 31), - XG_SERDES_ADDR_R = (1 << 30), - - XG_SERDES_ADDR_STS = 0x00001E06, - XG_SERDES_ADDR_XFI1_PWR_UP = 0x00000005, - XG_SERDES_ADDR_XFI2_PWR_UP = 0x0000000a, - XG_SERDES_ADDR_XAUI_PWR_DOWN = 0x00000001, - - /* Serdes coredump definitions. */ - XG_SERDES_XAUI_AN_START = 0x00000000, - XG_SERDES_XAUI_AN_END = 0x00000034, - XG_SERDES_XAUI_HSS_PCS_START = 0x00000800, - XG_SERDES_XAUI_HSS_PCS_END = 0x0000880, - XG_SERDES_XFI_AN_START = 0x00001000, - XG_SERDES_XFI_AN_END = 0x00001034, - XG_SERDES_XFI_TRAIN_START = 0x10001050, - XG_SERDES_XFI_TRAIN_END = 0x1000107C, - XG_SERDES_XFI_HSS_PCS_START = 0x00001800, - XG_SERDES_XFI_HSS_PCS_END = 0x00001838, - XG_SERDES_XFI_HSS_TX_START = 0x00001c00, - XG_SERDES_XFI_HSS_TX_END = 0x00001c1f, - XG_SERDES_XFI_HSS_RX_START = 0x00001c40, - XG_SERDES_XFI_HSS_RX_END = 0x00001c5f, - XG_SERDES_XFI_HSS_PLL_START = 0x00001e00, - XG_SERDES_XFI_HSS_PLL_END = 0x00001e1f, -}; - -/* - * NIC Probe Mux Address Register (PRB_MX_ADDR) bit definitions. - */ -enum { - PRB_MX_ADDR_ARE = (1 << 16), - PRB_MX_ADDR_UP = (1 << 15), - PRB_MX_ADDR_SWP = (1 << 14), - - /* Module select values. */ - PRB_MX_ADDR_MAX_MODS = 21, - PRB_MX_ADDR_MOD_SEL_SHIFT = 9, - PRB_MX_ADDR_MOD_SEL_TBD = 0, - PRB_MX_ADDR_MOD_SEL_IDE1 = 1, - PRB_MX_ADDR_MOD_SEL_IDE2 = 2, - PRB_MX_ADDR_MOD_SEL_FRB = 3, - PRB_MX_ADDR_MOD_SEL_ODE1 = 4, - PRB_MX_ADDR_MOD_SEL_ODE2 = 5, - PRB_MX_ADDR_MOD_SEL_DA1 = 6, - PRB_MX_ADDR_MOD_SEL_DA2 = 7, - PRB_MX_ADDR_MOD_SEL_IMP1 = 8, - PRB_MX_ADDR_MOD_SEL_IMP2 = 9, - PRB_MX_ADDR_MOD_SEL_OMP1 = 10, - PRB_MX_ADDR_MOD_SEL_OMP2 = 11, - PRB_MX_ADDR_MOD_SEL_ORS1 = 12, - PRB_MX_ADDR_MOD_SEL_ORS2 = 13, - PRB_MX_ADDR_MOD_SEL_REG = 14, - PRB_MX_ADDR_MOD_SEL_MAC1 = 16, - PRB_MX_ADDR_MOD_SEL_MAC2 = 17, - PRB_MX_ADDR_MOD_SEL_VQM1 = 18, - PRB_MX_ADDR_MOD_SEL_VQM2 = 19, - PRB_MX_ADDR_MOD_SEL_MOP = 20, - /* Bit fields indicating which modules - * are valid for each clock domain. - */ - PRB_MX_ADDR_VALID_SYS_MOD = 0x000f7ff7, - PRB_MX_ADDR_VALID_PCI_MOD = 0x000040c1, - PRB_MX_ADDR_VALID_XGM_MOD = 0x00037309, - PRB_MX_ADDR_VALID_FC_MOD = 0x00003001, - PRB_MX_ADDR_VALID_TOTAL = 34, - - /* Clock domain values. */ - PRB_MX_ADDR_CLOCK_SHIFT = 6, - PRB_MX_ADDR_SYS_CLOCK = 0, - PRB_MX_ADDR_PCI_CLOCK = 2, - PRB_MX_ADDR_FC_CLOCK = 5, - PRB_MX_ADDR_XGM_CLOCK = 6, - - PRB_MX_ADDR_MAX_MUX = 64, -}; - -/* - * Control Register Set Map - */ -enum { - PROC_ADDR = 0, /* Use semaphore */ - PROC_DATA = 0x04, /* Use semaphore */ - SYS = 0x08, - RST_FO = 0x0c, - FSC = 0x10, - CSR = 0x14, - LED = 0x18, - ICB_RID = 0x1c, /* Use semaphore */ - ICB_L = 0x20, /* Use semaphore */ - ICB_H = 0x24, /* Use semaphore */ - CFG = 0x28, - BIOS_ADDR = 0x2c, - STS = 0x30, - INTR_EN = 0x34, - INTR_MASK = 0x38, - ISR1 = 0x3c, - ISR2 = 0x40, - ISR3 = 0x44, - ISR4 = 0x48, - REV_ID = 0x4c, - FRC_ECC_ERR = 0x50, - ERR_STS = 0x54, - RAM_DBG_ADDR = 0x58, - RAM_DBG_DATA = 0x5c, - ECC_ERR_CNT = 0x60, - SEM = 0x64, - GPIO_1 = 0x68, /* Use semaphore */ - GPIO_2 = 0x6c, /* Use semaphore */ - GPIO_3 = 0x70, /* Use semaphore */ - RSVD2 = 0x74, - XGMAC_ADDR = 0x78, /* Use semaphore */ - XGMAC_DATA = 0x7c, /* Use semaphore */ - NIC_ETS = 0x80, - CNA_ETS = 0x84, - FLASH_ADDR = 0x88, /* Use semaphore */ - FLASH_DATA = 0x8c, /* Use semaphore */ - CQ_STOP = 0x90, - PAGE_TBL_RID = 0x94, - WQ_PAGE_TBL_LO = 0x98, - WQ_PAGE_TBL_HI = 0x9c, - CQ_PAGE_TBL_LO = 0xa0, - CQ_PAGE_TBL_HI = 0xa4, - MAC_ADDR_IDX = 0xa8, /* Use semaphore */ - MAC_ADDR_DATA = 0xac, /* Use semaphore */ - COS_DFLT_CQ1 = 0xb0, - COS_DFLT_CQ2 = 0xb4, - ETYPE_SKIP1 = 0xb8, - ETYPE_SKIP2 = 0xbc, - SPLT_HDR = 0xc0, - FC_PAUSE_THRES = 0xc4, - NIC_PAUSE_THRES = 0xc8, - FC_ETHERTYPE = 0xcc, - FC_RCV_CFG = 0xd0, - NIC_RCV_CFG = 0xd4, - FC_COS_TAGS = 0xd8, - NIC_COS_TAGS = 0xdc, - MGMT_RCV_CFG = 0xe0, - RT_IDX = 0xe4, - RT_DATA = 0xe8, - RSVD7 = 0xec, - XG_SERDES_ADDR = 0xf0, - XG_SERDES_DATA = 0xf4, - PRB_MX_ADDR = 0xf8, /* Use semaphore */ - PRB_MX_DATA = 0xfc, /* Use semaphore */ -}; - -#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS -#define SMALL_BUFFER_SIZE 256 -#define SMALL_BUF_MAP_SIZE SMALL_BUFFER_SIZE -#define SPLT_SETTING FSC_DBRST_1024 -#define SPLT_LEN 0 -#define QLGE_SB_PAD 0 -#else -#define SMALL_BUFFER_SIZE 512 -#define SMALL_BUF_MAP_SIZE (SMALL_BUFFER_SIZE / 2) -#define SPLT_SETTING FSC_SH -#define SPLT_LEN (SPLT_HDR_EP | \ - min(SMALL_BUF_MAP_SIZE, 1023)) -#define QLGE_SB_PAD 32 -#endif - -/* - * CAM output format. - */ -enum { - CAM_OUT_ROUTE_FC = 0, - CAM_OUT_ROUTE_NIC = 1, - CAM_OUT_FUNC_SHIFT = 2, - CAM_OUT_RV = (1 << 4), - CAM_OUT_SH = (1 << 15), - CAM_OUT_CQ_ID_SHIFT = 5, -}; - -/* - * Mailbox definitions - */ -enum { - /* Asynchronous Event Notifications */ - AEN_SYS_ERR = 0x00008002, - AEN_LINK_UP = 0x00008011, - AEN_LINK_DOWN = 0x00008012, - AEN_IDC_CMPLT = 0x00008100, - AEN_IDC_REQ = 0x00008101, - AEN_IDC_EXT = 0x00008102, - AEN_DCBX_CHG = 0x00008110, - AEN_AEN_LOST = 0x00008120, - AEN_AEN_SFP_IN = 0x00008130, - AEN_AEN_SFP_OUT = 0x00008131, - AEN_FW_INIT_DONE = 0x00008400, - AEN_FW_INIT_FAIL = 0x00008401, - - /* Mailbox Command Opcodes. */ - MB_CMD_NOP = 0x00000000, - MB_CMD_EX_FW = 0x00000002, - MB_CMD_MB_TEST = 0x00000006, - MB_CMD_CSUM_TEST = 0x00000007, /* Verify Checksum */ - MB_CMD_ABOUT_FW = 0x00000008, - MB_CMD_COPY_RISC_RAM = 0x0000000a, - MB_CMD_LOAD_RISC_RAM = 0x0000000b, - MB_CMD_DUMP_RISC_RAM = 0x0000000c, - MB_CMD_WRITE_RAM = 0x0000000d, - MB_CMD_INIT_RISC_RAM = 0x0000000e, - MB_CMD_READ_RAM = 0x0000000f, - MB_CMD_STOP_FW = 0x00000014, - MB_CMD_MAKE_SYS_ERR = 0x0000002a, - MB_CMD_WRITE_SFP = 0x00000030, - MB_CMD_READ_SFP = 0x00000031, - MB_CMD_INIT_FW = 0x00000060, - MB_CMD_GET_IFCB = 0x00000061, - MB_CMD_GET_FW_STATE = 0x00000069, - MB_CMD_IDC_REQ = 0x00000100, /* Inter-Driver Communication */ - MB_CMD_IDC_ACK = 0x00000101, /* Inter-Driver Communication */ - MB_CMD_SET_WOL_MODE = 0x00000110, /* Wake On Lan */ - MB_WOL_DISABLE = 0, - MB_WOL_MAGIC_PKT = (1 << 1), - MB_WOL_FLTR = (1 << 2), - MB_WOL_UCAST = (1 << 3), - MB_WOL_MCAST = (1 << 4), - MB_WOL_BCAST = (1 << 5), - MB_WOL_LINK_UP = (1 << 6), - MB_WOL_LINK_DOWN = (1 << 7), - MB_WOL_MODE_ON = (1 << 16), /* Wake on Lan Mode on */ - MB_CMD_SET_WOL_FLTR = 0x00000111, /* Wake On Lan Filter */ - MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */ - MB_CMD_SET_WOL_MAGIC = 0x00000113, /* Wake On Lan Magic Packet */ - MB_CMD_CLEAR_WOL_MAGIC = 0x00000114,/* Wake On Lan Magic Packet */ - MB_CMD_SET_WOL_IMMED = 0x00000115, - MB_CMD_PORT_RESET = 0x00000120, - MB_CMD_SET_PORT_CFG = 0x00000122, - MB_CMD_GET_PORT_CFG = 0x00000123, - MB_CMD_GET_LINK_STS = 0x00000124, - MB_CMD_SET_LED_CFG = 0x00000125, /* Set LED Configuration Register */ - QL_LED_BLINK = 0x03e803e8, - MB_CMD_GET_LED_CFG = 0x00000126, /* Get LED Configuration Register */ - MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */ - MB_SET_MPI_TFK_STOP = (1 << 0), - MB_SET_MPI_TFK_RESUME = (1 << 1), - MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */ - MB_GET_MPI_TFK_STOPPED = (1 << 0), - MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1), - /* Sub-commands for IDC request. - * This describes the reason for the - * IDC request. - */ - MB_CMD_IOP_NONE = 0x0000, - MB_CMD_IOP_PREP_UPDATE_MPI = 0x0001, - MB_CMD_IOP_COMP_UPDATE_MPI = 0x0002, - MB_CMD_IOP_PREP_LINK_DOWN = 0x0010, - MB_CMD_IOP_DVR_START = 0x0100, - MB_CMD_IOP_FLASH_ACC = 0x0101, - MB_CMD_IOP_RESTART_MPI = 0x0102, - MB_CMD_IOP_CORE_DUMP_MPI = 0x0103, - - /* Mailbox Command Status. */ - MB_CMD_STS_GOOD = 0x00004000, /* Success. */ - MB_CMD_STS_INTRMDT = 0x00001000, /* Intermediate Complete. */ - MB_CMD_STS_INVLD_CMD = 0x00004001, /* Invalid. */ - MB_CMD_STS_XFC_ERR = 0x00004002, /* Interface Error. */ - MB_CMD_STS_CSUM_ERR = 0x00004003, /* Csum Error. */ - MB_CMD_STS_ERR = 0x00004005, /* System Error. */ - MB_CMD_STS_PARAM_ERR = 0x00004006, /* Parameter Error. */ -}; - -struct mbox_params { - u32 mbox_in[MAILBOX_COUNT]; - u32 mbox_out[MAILBOX_COUNT]; - int in_count; - int out_count; -}; - -struct flash_params_8012 { - u8 dev_id_str[4]; - __le16 size; - __le16 csum; - __le16 ver; - __le16 sub_dev_id; - u8 mac_addr[6]; - __le16 res; -}; - -/* 8000 device's flash is a different structure - * at a different offset in flash. - */ -#define FUNC0_FLASH_OFFSET 0x140200 -#define FUNC1_FLASH_OFFSET 0x140600 - -/* Flash related data structures. */ -struct flash_params_8000 { - u8 dev_id_str[4]; /* "8000" */ - __le16 ver; - __le16 size; - __le16 csum; - __le16 reserved0; - __le16 total_size; - __le16 entry_count; - u8 data_type0; - u8 data_size0; - u8 mac_addr[6]; - u8 data_type1; - u8 data_size1; - u8 mac_addr1[6]; - u8 data_type2; - u8 data_size2; - __le16 vlan_id; - u8 data_type3; - u8 data_size3; - __le16 last; - u8 reserved1[464]; - __le16 subsys_ven_id; - __le16 subsys_dev_id; - u8 reserved2[4]; -}; - -union flash_params { - struct flash_params_8012 flash_params_8012; - struct flash_params_8000 flash_params_8000; -}; - -/* - * doorbell space for the rx ring context - */ -struct rx_doorbell_context { - u32 cnsmr_idx; /* 0x00 */ - u32 valid; /* 0x04 */ - u32 reserved[4]; /* 0x08-0x14 */ - u32 lbq_prod_idx; /* 0x18 */ - u32 sbq_prod_idx; /* 0x1c */ -}; - -/* - * doorbell space for the tx ring context - */ -struct tx_doorbell_context { - u32 prod_idx; /* 0x00 */ - u32 valid; /* 0x04 */ - u32 reserved[4]; /* 0x08-0x14 */ - u32 lbq_prod_idx; /* 0x18 */ - u32 sbq_prod_idx; /* 0x1c */ -}; - -/* DATA STRUCTURES SHARED WITH HARDWARE. */ -struct tx_buf_desc { - __le64 addr; - __le32 len; -#define TX_DESC_LEN_MASK 0x000fffff -#define TX_DESC_C 0x40000000 -#define TX_DESC_E 0x80000000 -} __packed; - -/* - * IOCB Definitions... - */ - -#define OPCODE_OB_MAC_IOCB 0x01 -#define OPCODE_OB_MAC_TSO_IOCB 0x02 -#define OPCODE_IB_MAC_IOCB 0x20 -#define OPCODE_IB_MPI_IOCB 0x21 -#define OPCODE_IB_AE_IOCB 0x3f - -struct qlge_ob_mac_iocb_req { - u8 opcode; - u8 flags1; -#define OB_MAC_IOCB_REQ_OI 0x01 -#define OB_MAC_IOCB_REQ_I 0x02 -#define OB_MAC_IOCB_REQ_D 0x08 -#define OB_MAC_IOCB_REQ_F 0x10 - u8 flags2; - u8 flags3; -#define OB_MAC_IOCB_DFP 0x02 -#define OB_MAC_IOCB_V 0x04 - __le32 reserved1[2]; - __le16 frame_len; -#define OB_MAC_IOCB_LEN_MASK 0x3ffff - __le16 reserved2; - u32 tid; - u32 txq_idx; - __le32 reserved3; - __le16 vlan_tci; - __le16 reserved4; - struct tx_buf_desc tbd[TX_DESC_PER_IOCB]; -} __packed; - -struct qlge_ob_mac_iocb_rsp { - u8 opcode; /* */ - u8 flags1; /* */ -#define OB_MAC_IOCB_RSP_OI 0x01 /* */ -#define OB_MAC_IOCB_RSP_I 0x02 /* */ -#define OB_MAC_IOCB_RSP_E 0x08 /* */ -#define OB_MAC_IOCB_RSP_S 0x10 /* too Short */ -#define OB_MAC_IOCB_RSP_L 0x20 /* too Large */ -#define OB_MAC_IOCB_RSP_P 0x40 /* Padded */ - u8 flags2; /* */ - u8 flags3; /* */ -#define OB_MAC_IOCB_RSP_B 0x80 /* */ - u32 tid; - u32 txq_idx; - __le32 reserved[13]; -} __packed; - -struct qlge_ob_mac_tso_iocb_req { - u8 opcode; - u8 flags1; -#define OB_MAC_TSO_IOCB_OI 0x01 -#define OB_MAC_TSO_IOCB_I 0x02 -#define OB_MAC_TSO_IOCB_D 0x08 -#define OB_MAC_TSO_IOCB_IP4 0x40 -#define OB_MAC_TSO_IOCB_IP6 0x80 - u8 flags2; -#define OB_MAC_TSO_IOCB_LSO 0x20 -#define OB_MAC_TSO_IOCB_UC 0x40 -#define OB_MAC_TSO_IOCB_TC 0x80 - u8 flags3; -#define OB_MAC_TSO_IOCB_IC 0x01 -#define OB_MAC_TSO_IOCB_DFP 0x02 -#define OB_MAC_TSO_IOCB_V 0x04 - __le32 reserved1[2]; - __le32 frame_len; - u32 tid; - u32 txq_idx; - __le16 total_hdrs_len; - __le16 net_trans_offset; -#define OB_MAC_TRANSPORT_HDR_SHIFT 6 - __le16 vlan_tci; - __le16 mss; - struct tx_buf_desc tbd[TX_DESC_PER_IOCB]; -} __packed; - -struct qlge_ob_mac_tso_iocb_rsp { - u8 opcode; - u8 flags1; -#define OB_MAC_TSO_IOCB_RSP_OI 0x01 -#define OB_MAC_TSO_IOCB_RSP_I 0x02 -#define OB_MAC_TSO_IOCB_RSP_E 0x08 -#define OB_MAC_TSO_IOCB_RSP_S 0x10 -#define OB_MAC_TSO_IOCB_RSP_L 0x20 -#define OB_MAC_TSO_IOCB_RSP_P 0x40 - u8 flags2; /* */ - u8 flags3; /* */ -#define OB_MAC_TSO_IOCB_RSP_B 0x8000 - u32 tid; - u32 txq_idx; - __le32 reserved2[13]; -} __packed; - -struct qlge_ib_mac_iocb_rsp { - u8 opcode; /* 0x20 */ - u8 flags1; -#define IB_MAC_IOCB_RSP_OI 0x01 /* Override intr delay */ -#define IB_MAC_IOCB_RSP_I 0x02 /* Disable Intr Generation */ -#define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */ -#define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ -#define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ -#define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ -#define IB_MAC_IOCB_RSP_M_MASK 0x60 /* Multicast info */ -#define IB_MAC_IOCB_RSP_M_NONE 0x00 /* Not mcast frame */ -#define IB_MAC_IOCB_RSP_M_HASH 0x20 /* HASH mcast frame */ -#define IB_MAC_IOCB_RSP_M_REG 0x40 /* Registered mcast frame */ -#define IB_MAC_IOCB_RSP_M_PROM 0x60 /* Promiscuous mcast frame */ -#define IB_MAC_IOCB_RSP_B 0x80 /* Broadcast frame */ - u8 flags2; -#define IB_MAC_IOCB_RSP_P 0x01 /* Promiscuous frame */ -#define IB_MAC_IOCB_RSP_V 0x02 /* Vlan tag present */ -#define IB_MAC_IOCB_RSP_ERR_MASK 0x1c /* */ -#define IB_MAC_IOCB_RSP_ERR_CODE_ERR 0x04 -#define IB_MAC_IOCB_RSP_ERR_OVERSIZE 0x08 -#define IB_MAC_IOCB_RSP_ERR_UNDERSIZE 0x10 -#define IB_MAC_IOCB_RSP_ERR_PREAMBLE 0x14 -#define IB_MAC_IOCB_RSP_ERR_FRAME_LEN 0x18 -#define IB_MAC_IOCB_RSP_ERR_CRC 0x1c -#define IB_MAC_IOCB_RSP_U 0x20 /* UDP packet */ -#define IB_MAC_IOCB_RSP_T 0x40 /* TCP packet */ -#define IB_MAC_IOCB_RSP_FO 0x80 /* Failover port */ - u8 flags3; -#define IB_MAC_IOCB_RSP_RSS_MASK 0x07 /* RSS mask */ -#define IB_MAC_IOCB_RSP_M_NONE 0x00 /* No RSS match */ -#define IB_MAC_IOCB_RSP_M_IPV4 0x04 /* IPv4 RSS match */ -#define IB_MAC_IOCB_RSP_M_IPV6 0x02 /* IPv6 RSS match */ -#define IB_MAC_IOCB_RSP_M_TCP_V4 0x05 /* TCP with IPv4 */ -#define IB_MAC_IOCB_RSP_M_TCP_V6 0x03 /* TCP with IPv6 */ -#define IB_MAC_IOCB_RSP_V4 0x08 /* IPV4 */ -#define IB_MAC_IOCB_RSP_V6 0x10 /* IPV6 */ -#define IB_MAC_IOCB_RSP_IH 0x20 /* Split after IP header */ -#define IB_MAC_IOCB_RSP_DS 0x40 /* data is in small buffer */ -#define IB_MAC_IOCB_RSP_DL 0x80 /* data is in large buffer */ - __le32 data_len; /* */ - __le64 data_addr; /* */ - __le32 rss; /* */ - __le16 vlan_id; /* 12 bits */ -#define IB_MAC_IOCB_RSP_C 0x1000 /* VLAN CFI bit */ -#define IB_MAC_IOCB_RSP_COS_SHIFT 12 /* class of service value */ -#define IB_MAC_IOCB_RSP_VLAN_MASK 0x0ffff - - __le16 reserved1; - __le32 reserved2[6]; - u8 reserved3[3]; - u8 flags4; -#define IB_MAC_IOCB_RSP_HV 0x20 -#define IB_MAC_IOCB_RSP_HS 0x40 -#define IB_MAC_IOCB_RSP_HL 0x80 - __le32 hdr_len; /* */ - __le64 hdr_addr; /* */ -} __packed; - -struct qlge_ib_ae_iocb_rsp { - u8 opcode; - u8 flags1; -#define IB_AE_IOCB_RSP_OI 0x01 -#define IB_AE_IOCB_RSP_I 0x02 - u8 event; -#define LINK_UP_EVENT 0x00 -#define LINK_DOWN_EVENT 0x01 -#define CAM_LOOKUP_ERR_EVENT 0x06 -#define SOFT_ECC_ERROR_EVENT 0x07 -#define MGMT_ERR_EVENT 0x08 -#define TEN_GIG_MAC_EVENT 0x09 -#define GPI0_H2L_EVENT 0x10 -#define GPI0_L2H_EVENT 0x20 -#define GPI1_H2L_EVENT 0x11 -#define GPI1_L2H_EVENT 0x21 -#define PCI_ERR_ANON_BUF_RD 0x40 - u8 q_id; - __le32 reserved[15]; -} __packed; - -/* - * These three structures are for generic - * handling of ib and ob iocbs. - */ -struct qlge_net_rsp_iocb { - u8 opcode; - u8 flags0; - __le16 length; - __le32 tid; - __le32 reserved[14]; -} __packed; - -struct qlge_net_req_iocb { - u8 opcode; - u8 flags0; - __le16 flags1; - __le32 tid; - __le32 reserved1[30]; -} __packed; - -/* - * tx ring initialization control block for chip. - * It is defined as: - * "Work Queue Initialization Control Block" - */ -struct wqicb { - __le16 len; -#define Q_LEN_V (1 << 4) -#define Q_LEN_CPP_CONT 0x0000 -#define Q_LEN_CPP_16 0x0001 -#define Q_LEN_CPP_32 0x0002 -#define Q_LEN_CPP_64 0x0003 -#define Q_LEN_CPP_512 0x0006 - __le16 flags; -#define Q_PRI_SHIFT 1 -#define Q_FLAGS_LC 0x1000 -#define Q_FLAGS_LB 0x2000 -#define Q_FLAGS_LI 0x4000 -#define Q_FLAGS_LO 0x8000 - __le16 cq_id_rss; -#define Q_CQ_ID_RSS_RV 0x8000 - __le16 rid; - __le64 addr; - __le64 cnsmr_idx_addr; -} __packed; - -/* - * rx ring initialization control block for chip. - * It is defined as: - * "Completion Queue Initialization Control Block" - */ -struct cqicb { - u8 msix_vect; - u8 reserved1; - u8 reserved2; - u8 flags; -#define FLAGS_LV 0x08 -#define FLAGS_LS 0x10 -#define FLAGS_LL 0x20 -#define FLAGS_LI 0x40 -#define FLAGS_LC 0x80 - __le16 len; -#define LEN_V (1 << 4) -#define LEN_CPP_CONT 0x0000 -#define LEN_CPP_32 0x0001 -#define LEN_CPP_64 0x0002 -#define LEN_CPP_128 0x0003 - __le16 rid; - __le64 addr; - __le64 prod_idx_addr; - __le16 pkt_delay; - __le16 irq_delay; - __le64 lbq_addr; - __le16 lbq_buf_size; - __le16 lbq_len; /* entry count */ - __le64 sbq_addr; - __le16 sbq_buf_size; - __le16 sbq_len; /* entry count */ -} __packed; - -struct ricb { - u8 base_cq; -#define RSS_L4K 0x80 - u8 flags; -#define RSS_L6K 0x01 -#define RSS_LI 0x02 -#define RSS_LB 0x04 -#define RSS_LM 0x08 -#define RSS_RI4 0x10 -#define RSS_RT4 0x20 -#define RSS_RI6 0x40 -#define RSS_RT6 0x80 - __le16 mask; - u8 hash_cq_id[1024]; - __le32 ipv6_hash_key[10]; - __le32 ipv4_hash_key[4]; -} __packed; - -/* SOFTWARE/DRIVER DATA STRUCTURES. */ - -struct qlge_oal { - struct tx_buf_desc oal[TX_DESC_PER_OAL]; -}; - -struct map_list { - DEFINE_DMA_UNMAP_ADDR(mapaddr); - DEFINE_DMA_UNMAP_LEN(maplen); -}; - -struct tx_ring_desc { - struct sk_buff *skb; - struct qlge_ob_mac_iocb_req *queue_entry; - u32 index; - struct qlge_oal oal; - struct map_list map[MAX_SKB_FRAGS + 2]; - int map_cnt; - struct tx_ring_desc *next; -}; - -#define QL_TXQ_IDX(qdev, skb) (smp_processor_id() % (qdev->tx_ring_count)) - -struct tx_ring { - /* - * queue info. - */ - struct wqicb wqicb; /* structure used to inform chip of new queue */ - void *wq_base; /* pci_alloc:virtual addr for tx */ - dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */ - __le32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ - dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */ - u32 wq_size; /* size in bytes of queue area */ - u32 wq_len; /* number of entries in queue */ - void __iomem *prod_idx_db_reg; /* doorbell area index reg at offset 0x00 */ - void __iomem *valid_db_reg; /* doorbell area valid reg at offset 0x04 */ - u16 prod_idx; /* current value for prod idx */ - u16 cq_id; /* completion (rx) queue for tx completions */ - u8 wq_id; /* queue id for this entry */ - u8 reserved1[3]; - struct tx_ring_desc *q; /* descriptor list for the queue */ - spinlock_t lock; - atomic_t tx_count; /* counts down for every outstanding IO */ - struct delayed_work tx_work; - struct qlge_adapter *qdev; - u64 tx_packets; - u64 tx_bytes; - u64 tx_errors; -}; - -struct qlge_page_chunk { - struct page *page; - void *va; /* virt addr including offset */ - unsigned int offset; -}; - -struct qlge_bq_desc { - union { - /* for large buffers */ - struct qlge_page_chunk pg_chunk; - /* for small buffers */ - struct sk_buff *skb; - } p; - dma_addr_t dma_addr; - /* address in ring where the buffer address is written for the device */ - __le64 *buf_ptr; - u32 index; -}; - -/* buffer queue */ -struct qlge_bq { - __le64 *base; - dma_addr_t base_dma; - __le64 *base_indirect; - dma_addr_t base_indirect_dma; - struct qlge_bq_desc *queue; - /* prod_idx is the index of the first buffer that may NOT be used by - * hw, ie. one after the last. Advanced by sw. - */ - void __iomem *prod_idx_db_reg; - /* next index where sw should refill a buffer for hw */ - u16 next_to_use; - /* next index where sw expects to find a buffer filled by hw */ - u16 next_to_clean; - enum { - QLGE_SB, /* small buffer */ - QLGE_LB, /* large buffer */ - } type; -}; - -#define QLGE_BQ_CONTAINER(bq) \ -({ \ - typeof(bq) _bq = bq; \ - (struct rx_ring *)((char *)_bq - (_bq->type == QLGE_SB ? \ - offsetof(struct rx_ring, sbq) : \ - offsetof(struct rx_ring, lbq))); \ -}) - -/* Experience shows that the device ignores the low 4 bits of the tail index. - * Refill up to a x16 multiple. - */ -#define QLGE_BQ_ALIGN(index) ALIGN_DOWN(index, 16) - -#define QLGE_BQ_WRAP(index) ((index) & (QLGE_BQ_LEN - 1)) - -#define QLGE_BQ_HW_OWNED(bq) \ -({ \ - typeof(bq) _bq = bq; \ - QLGE_BQ_WRAP(QLGE_BQ_ALIGN((_bq)->next_to_use) - \ - (_bq)->next_to_clean); \ -}) - -struct rx_ring { - struct cqicb cqicb; /* The chip's completion queue init control block. */ - - /* Completion queue elements. */ - void *cq_base; - dma_addr_t cq_base_dma; - u32 cq_size; - u32 cq_len; - u16 cq_id; - __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ - dma_addr_t prod_idx_sh_reg_dma; - void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ - u32 cnsmr_idx; /* current sw idx */ - struct qlge_net_rsp_iocb *curr_entry; /* next entry on queue */ - void __iomem *valid_db_reg; /* PCI doorbell mem area + 0x04 */ - - /* Large buffer queue elements. */ - struct qlge_bq lbq; - struct qlge_page_chunk master_chunk; - dma_addr_t chunk_dma_addr; - - /* Small buffer queue elements. */ - struct qlge_bq sbq; - - /* Misc. handler elements. */ - u32 irq; /* Which vector this ring is assigned. */ - u32 cpu; /* Which CPU this should run on. */ - struct delayed_work refill_work; - char name[IFNAMSIZ + 5]; - struct napi_struct napi; - u8 reserved; - struct qlge_adapter *qdev; - u64 rx_packets; - u64 rx_multicast; - u64 rx_bytes; - u64 rx_dropped; - u64 rx_errors; -}; - -/* - * RSS Initialization Control Block - */ -struct hash_id { - u8 value[4]; -}; - -struct nic_stats { - /* - * These stats come from offset 200h to 278h - * in the XGMAC register. - */ - u64 tx_pkts; - u64 tx_bytes; - u64 tx_mcast_pkts; - u64 tx_bcast_pkts; - u64 tx_ucast_pkts; - u64 tx_ctl_pkts; - u64 tx_pause_pkts; - u64 tx_64_pkt; - u64 tx_65_to_127_pkt; - u64 tx_128_to_255_pkt; - u64 tx_256_511_pkt; - u64 tx_512_to_1023_pkt; - u64 tx_1024_to_1518_pkt; - u64 tx_1519_to_max_pkt; - u64 tx_undersize_pkt; - u64 tx_oversize_pkt; - - /* - * These stats come from offset 300h to 3C8h - * in the XGMAC register. - */ - u64 rx_bytes; - u64 rx_bytes_ok; - u64 rx_pkts; - u64 rx_pkts_ok; - u64 rx_bcast_pkts; - u64 rx_mcast_pkts; - u64 rx_ucast_pkts; - u64 rx_undersize_pkts; - u64 rx_oversize_pkts; - u64 rx_jabber_pkts; - u64 rx_undersize_fcerr_pkts; - u64 rx_drop_events; - u64 rx_fcerr_pkts; - u64 rx_align_err; - u64 rx_symbol_err; - u64 rx_mac_err; - u64 rx_ctl_pkts; - u64 rx_pause_pkts; - u64 rx_64_pkts; - u64 rx_65_to_127_pkts; - u64 rx_128_255_pkts; - u64 rx_256_511_pkts; - u64 rx_512_to_1023_pkts; - u64 rx_1024_to_1518_pkts; - u64 rx_1519_to_max_pkts; - u64 rx_len_err_pkts; - /* Receive Mac Err stats */ - u64 rx_code_err; - u64 rx_oversize_err; - u64 rx_undersize_err; - u64 rx_preamble_err; - u64 rx_frame_len_err; - u64 rx_crc_err; - u64 rx_err_count; - /* - * These stats come from offset 500h to 5C8h - * in the XGMAC register. - */ - u64 tx_cbfc_pause_frames0; - u64 tx_cbfc_pause_frames1; - u64 tx_cbfc_pause_frames2; - u64 tx_cbfc_pause_frames3; - u64 tx_cbfc_pause_frames4; - u64 tx_cbfc_pause_frames5; - u64 tx_cbfc_pause_frames6; - u64 tx_cbfc_pause_frames7; - u64 rx_cbfc_pause_frames0; - u64 rx_cbfc_pause_frames1; - u64 rx_cbfc_pause_frames2; - u64 rx_cbfc_pause_frames3; - u64 rx_cbfc_pause_frames4; - u64 rx_cbfc_pause_frames5; - u64 rx_cbfc_pause_frames6; - u64 rx_cbfc_pause_frames7; - u64 rx_nic_fifo_drop; -}; - -/* Firmware coredump internal register address/length pairs. */ -enum { - MPI_CORE_REGS_ADDR = 0x00030000, - MPI_CORE_REGS_CNT = 127, - MPI_CORE_SH_REGS_CNT = 16, - TEST_REGS_ADDR = 0x00001000, - TEST_REGS_CNT = 23, - RMII_REGS_ADDR = 0x00001040, - RMII_REGS_CNT = 64, - FCMAC1_REGS_ADDR = 0x00001080, - FCMAC2_REGS_ADDR = 0x000010c0, - FCMAC_REGS_CNT = 64, - FC1_MBX_REGS_ADDR = 0x00001100, - FC2_MBX_REGS_ADDR = 0x00001240, - FC_MBX_REGS_CNT = 64, - IDE_REGS_ADDR = 0x00001140, - IDE_REGS_CNT = 64, - NIC1_MBX_REGS_ADDR = 0x00001180, - NIC2_MBX_REGS_ADDR = 0x00001280, - NIC_MBX_REGS_CNT = 64, - SMBUS_REGS_ADDR = 0x00001200, - SMBUS_REGS_CNT = 64, - I2C_REGS_ADDR = 0x00001fc0, - I2C_REGS_CNT = 64, - MEMC_REGS_ADDR = 0x00003000, - MEMC_REGS_CNT = 256, - PBUS_REGS_ADDR = 0x00007c00, - PBUS_REGS_CNT = 256, - MDE_REGS_ADDR = 0x00010000, - MDE_REGS_CNT = 6, - CODE_RAM_ADDR = 0x00020000, - CODE_RAM_CNT = 0x2000, - MEMC_RAM_ADDR = 0x00100000, - MEMC_RAM_CNT = 0x2000, -}; - -#define MPI_COREDUMP_COOKIE 0x5555aaaa -struct mpi_coredump_global_header { - u32 cookie; - u8 id_string[16]; - u32 time_lo; - u32 time_hi; - u32 image_size; - u32 header_size; - u8 info[220]; -}; - -struct mpi_coredump_segment_header { - u32 cookie; - u32 seg_num; - u32 seg_size; - u32 extra; - u8 description[16]; -}; - -/* Firmware coredump header segment numbers. */ -enum { - CORE_SEG_NUM = 1, - TEST_LOGIC_SEG_NUM = 2, - RMII_SEG_NUM = 3, - FCMAC1_SEG_NUM = 4, - FCMAC2_SEG_NUM = 5, - FC1_MBOX_SEG_NUM = 6, - IDE_SEG_NUM = 7, - NIC1_MBOX_SEG_NUM = 8, - SMBUS_SEG_NUM = 9, - FC2_MBOX_SEG_NUM = 10, - NIC2_MBOX_SEG_NUM = 11, - I2C_SEG_NUM = 12, - MEMC_SEG_NUM = 13, - PBUS_SEG_NUM = 14, - MDE_SEG_NUM = 15, - NIC1_CONTROL_SEG_NUM = 16, - NIC2_CONTROL_SEG_NUM = 17, - NIC1_XGMAC_SEG_NUM = 18, - NIC2_XGMAC_SEG_NUM = 19, - WCS_RAM_SEG_NUM = 20, - MEMC_RAM_SEG_NUM = 21, - XAUI_AN_SEG_NUM = 22, - XAUI_HSS_PCS_SEG_NUM = 23, - XFI_AN_SEG_NUM = 24, - XFI_TRAIN_SEG_NUM = 25, - XFI_HSS_PCS_SEG_NUM = 26, - XFI_HSS_TX_SEG_NUM = 27, - XFI_HSS_RX_SEG_NUM = 28, - XFI_HSS_PLL_SEG_NUM = 29, - MISC_NIC_INFO_SEG_NUM = 30, - INTR_STATES_SEG_NUM = 31, - CAM_ENTRIES_SEG_NUM = 32, - ROUTING_WORDS_SEG_NUM = 33, - ETS_SEG_NUM = 34, - PROBE_DUMP_SEG_NUM = 35, - ROUTING_INDEX_SEG_NUM = 36, - MAC_PROTOCOL_SEG_NUM = 37, - XAUI2_AN_SEG_NUM = 38, - XAUI2_HSS_PCS_SEG_NUM = 39, - XFI2_AN_SEG_NUM = 40, - XFI2_TRAIN_SEG_NUM = 41, - XFI2_HSS_PCS_SEG_NUM = 42, - XFI2_HSS_TX_SEG_NUM = 43, - XFI2_HSS_RX_SEG_NUM = 44, - XFI2_HSS_PLL_SEG_NUM = 45, - SEM_REGS_SEG_NUM = 50 - -}; - -/* There are 64 generic NIC registers. */ -#define NIC_REGS_DUMP_WORD_COUNT 64 -/* XGMAC word count. */ -#define XGMAC_DUMP_WORD_COUNT (XGMAC_REGISTER_END / 4) -/* Word counts for the SERDES blocks. */ -#define XG_SERDES_XAUI_AN_COUNT 14 -#define XG_SERDES_XAUI_HSS_PCS_COUNT 33 -#define XG_SERDES_XFI_AN_COUNT 14 -#define XG_SERDES_XFI_TRAIN_COUNT 12 -#define XG_SERDES_XFI_HSS_PCS_COUNT 15 -#define XG_SERDES_XFI_HSS_TX_COUNT 32 -#define XG_SERDES_XFI_HSS_RX_COUNT 32 -#define XG_SERDES_XFI_HSS_PLL_COUNT 32 - -/* There are 2 CNA ETS and 8 NIC ETS registers. */ -#define ETS_REGS_DUMP_WORD_COUNT 10 - -/* Each probe mux entry stores the probe type plus 64 entries - * that are each 64-bits in length. There are a total of - * 34 (PRB_MX_ADDR_VALID_TOTAL) valid probes. - */ -#define PRB_MX_ADDR_PRB_WORD_COUNT (1 + (PRB_MX_ADDR_MAX_MUX * 2)) -#define PRB_MX_DUMP_TOT_COUNT (PRB_MX_ADDR_PRB_WORD_COUNT * \ - PRB_MX_ADDR_VALID_TOTAL) -/* Each routing entry consists of 4 32-bit words. - * They are route type, index, index word, and result. - * There are 2 route blocks with 8 entries each and - * 2 NIC blocks with 16 entries each. - * The totol entries is 48 with 4 words each. - */ -#define RT_IDX_DUMP_ENTRIES 48 -#define RT_IDX_DUMP_WORDS_PER_ENTRY 4 -#define RT_IDX_DUMP_TOT_WORDS (RT_IDX_DUMP_ENTRIES * \ - RT_IDX_DUMP_WORDS_PER_ENTRY) -/* There are 10 address blocks in filter, each with - * different entry counts and different word-count-per-entry. - */ -#define MAC_ADDR_DUMP_ENTRIES \ - ((MAC_ADDR_MAX_CAM_ENTRIES * MAC_ADDR_MAX_CAM_WCOUNT) + \ - (MAC_ADDR_MAX_MULTICAST_ENTRIES * MAC_ADDR_MAX_MULTICAST_WCOUNT) + \ - (MAC_ADDR_MAX_VLAN_ENTRIES * MAC_ADDR_MAX_VLAN_WCOUNT) + \ - (MAC_ADDR_MAX_MCAST_FLTR_ENTRIES * MAC_ADDR_MAX_MCAST_FLTR_WCOUNT) + \ - (MAC_ADDR_MAX_FC_MAC_ENTRIES * MAC_ADDR_MAX_FC_MAC_WCOUNT) + \ - (MAC_ADDR_MAX_MGMT_MAC_ENTRIES * MAC_ADDR_MAX_MGMT_MAC_WCOUNT) + \ - (MAC_ADDR_MAX_MGMT_VLAN_ENTRIES * MAC_ADDR_MAX_MGMT_VLAN_WCOUNT) + \ - (MAC_ADDR_MAX_MGMT_V4_ENTRIES * MAC_ADDR_MAX_MGMT_V4_WCOUNT) + \ - (MAC_ADDR_MAX_MGMT_V6_ENTRIES * MAC_ADDR_MAX_MGMT_V6_WCOUNT) + \ - (MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES * MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT)) -#define MAC_ADDR_DUMP_WORDS_PER_ENTRY 2 -#define MAC_ADDR_DUMP_TOT_WORDS (MAC_ADDR_DUMP_ENTRIES * \ - MAC_ADDR_DUMP_WORDS_PER_ENTRY) -/* Maximum of 4 functions whose semaphore registeres are - * in the coredump. - */ -#define MAX_SEMAPHORE_FUNCTIONS 4 -/* Defines for access the MPI shadow registers. */ -#define RISC_124 0x0003007c -#define RISC_127 0x0003007f -#define SHADOW_OFFSET 0xb0000000 -#define SHADOW_REG_SHIFT 20 - -struct qlge_nic_misc { - u32 rx_ring_count; - u32 tx_ring_count; - u32 intr_count; - u32 function; -}; - -struct qlge_reg_dump { - /* segment 0 */ - struct mpi_coredump_global_header mpi_global_header; - - /* segment 16 */ - struct mpi_coredump_segment_header nic_regs_seg_hdr; - u32 nic_regs[64]; - - /* segment 30 */ - struct mpi_coredump_segment_header misc_nic_seg_hdr; - struct qlge_nic_misc misc_nic_info; - - /* segment 31 */ - /* one interrupt state for each CQ */ - struct mpi_coredump_segment_header intr_states_seg_hdr; - u32 intr_states[MAX_CPUS]; - - /* segment 32 */ - /* 3 cam words each for 16 unicast, - * 2 cam words for each of 32 multicast. - */ - struct mpi_coredump_segment_header cam_entries_seg_hdr; - u32 cam_entries[(16 * 3) + (32 * 3)]; - - /* segment 33 */ - struct mpi_coredump_segment_header nic_routing_words_seg_hdr; - u32 nic_routing_words[16]; - - /* segment 34 */ - struct mpi_coredump_segment_header ets_seg_hdr; - u32 ets[8 + 2]; -}; - -struct qlge_mpi_coredump { - /* segment 0 */ - struct mpi_coredump_global_header mpi_global_header; - - /* segment 1 */ - struct mpi_coredump_segment_header core_regs_seg_hdr; - u32 mpi_core_regs[MPI_CORE_REGS_CNT]; - u32 mpi_core_sh_regs[MPI_CORE_SH_REGS_CNT]; - - /* segment 2 */ - struct mpi_coredump_segment_header test_logic_regs_seg_hdr; - u32 test_logic_regs[TEST_REGS_CNT]; - - /* segment 3 */ - struct mpi_coredump_segment_header rmii_regs_seg_hdr; - u32 rmii_regs[RMII_REGS_CNT]; - - /* segment 4 */ - struct mpi_coredump_segment_header fcmac1_regs_seg_hdr; - u32 fcmac1_regs[FCMAC_REGS_CNT]; - - /* segment 5 */ - struct mpi_coredump_segment_header fcmac2_regs_seg_hdr; - u32 fcmac2_regs[FCMAC_REGS_CNT]; - - /* segment 6 */ - struct mpi_coredump_segment_header fc1_mbx_regs_seg_hdr; - u32 fc1_mbx_regs[FC_MBX_REGS_CNT]; - - /* segment 7 */ - struct mpi_coredump_segment_header ide_regs_seg_hdr; - u32 ide_regs[IDE_REGS_CNT]; - - /* segment 8 */ - struct mpi_coredump_segment_header nic1_mbx_regs_seg_hdr; - u32 nic1_mbx_regs[NIC_MBX_REGS_CNT]; - - /* segment 9 */ - struct mpi_coredump_segment_header smbus_regs_seg_hdr; - u32 smbus_regs[SMBUS_REGS_CNT]; - - /* segment 10 */ - struct mpi_coredump_segment_header fc2_mbx_regs_seg_hdr; - u32 fc2_mbx_regs[FC_MBX_REGS_CNT]; - - /* segment 11 */ - struct mpi_coredump_segment_header nic2_mbx_regs_seg_hdr; - u32 nic2_mbx_regs[NIC_MBX_REGS_CNT]; - - /* segment 12 */ - struct mpi_coredump_segment_header i2c_regs_seg_hdr; - u32 i2c_regs[I2C_REGS_CNT]; - /* segment 13 */ - struct mpi_coredump_segment_header memc_regs_seg_hdr; - u32 memc_regs[MEMC_REGS_CNT]; - - /* segment 14 */ - struct mpi_coredump_segment_header pbus_regs_seg_hdr; - u32 pbus_regs[PBUS_REGS_CNT]; - - /* segment 15 */ - struct mpi_coredump_segment_header mde_regs_seg_hdr; - u32 mde_regs[MDE_REGS_CNT]; - - /* segment 16 */ - struct mpi_coredump_segment_header nic_regs_seg_hdr; - u32 nic_regs[NIC_REGS_DUMP_WORD_COUNT]; - - /* segment 17 */ - struct mpi_coredump_segment_header nic2_regs_seg_hdr; - u32 nic2_regs[NIC_REGS_DUMP_WORD_COUNT]; - - /* segment 18 */ - struct mpi_coredump_segment_header xgmac1_seg_hdr; - u32 xgmac1[XGMAC_DUMP_WORD_COUNT]; - - /* segment 19 */ - struct mpi_coredump_segment_header xgmac2_seg_hdr; - u32 xgmac2[XGMAC_DUMP_WORD_COUNT]; - - /* segment 20 */ - struct mpi_coredump_segment_header code_ram_seg_hdr; - u32 code_ram[CODE_RAM_CNT]; - - /* segment 21 */ - struct mpi_coredump_segment_header memc_ram_seg_hdr; - u32 memc_ram[MEMC_RAM_CNT]; - - /* segment 22 */ - struct mpi_coredump_segment_header xaui_an_hdr; - u32 serdes_xaui_an[XG_SERDES_XAUI_AN_COUNT]; - - /* segment 23 */ - struct mpi_coredump_segment_header xaui_hss_pcs_hdr; - u32 serdes_xaui_hss_pcs[XG_SERDES_XAUI_HSS_PCS_COUNT]; - - /* segment 24 */ - struct mpi_coredump_segment_header xfi_an_hdr; - u32 serdes_xfi_an[XG_SERDES_XFI_AN_COUNT]; - - /* segment 25 */ - struct mpi_coredump_segment_header xfi_train_hdr; - u32 serdes_xfi_train[XG_SERDES_XFI_TRAIN_COUNT]; - - /* segment 26 */ - struct mpi_coredump_segment_header xfi_hss_pcs_hdr; - u32 serdes_xfi_hss_pcs[XG_SERDES_XFI_HSS_PCS_COUNT]; - - /* segment 27 */ - struct mpi_coredump_segment_header xfi_hss_tx_hdr; - u32 serdes_xfi_hss_tx[XG_SERDES_XFI_HSS_TX_COUNT]; - - /* segment 28 */ - struct mpi_coredump_segment_header xfi_hss_rx_hdr; - u32 serdes_xfi_hss_rx[XG_SERDES_XFI_HSS_RX_COUNT]; - - /* segment 29 */ - struct mpi_coredump_segment_header xfi_hss_pll_hdr; - u32 serdes_xfi_hss_pll[XG_SERDES_XFI_HSS_PLL_COUNT]; - - /* segment 30 */ - struct mpi_coredump_segment_header misc_nic_seg_hdr; - struct qlge_nic_misc misc_nic_info; - - /* segment 31 */ - /* one interrupt state for each CQ */ - struct mpi_coredump_segment_header intr_states_seg_hdr; - u32 intr_states[MAX_RX_RINGS]; - - /* segment 32 */ - /* 3 cam words each for 16 unicast, - * 2 cam words for each of 32 multicast. - */ - struct mpi_coredump_segment_header cam_entries_seg_hdr; - u32 cam_entries[(16 * 3) + (32 * 3)]; - - /* segment 33 */ - struct mpi_coredump_segment_header nic_routing_words_seg_hdr; - u32 nic_routing_words[16]; - /* segment 34 */ - struct mpi_coredump_segment_header ets_seg_hdr; - u32 ets[ETS_REGS_DUMP_WORD_COUNT]; - - /* segment 35 */ - struct mpi_coredump_segment_header probe_dump_seg_hdr; - u32 probe_dump[PRB_MX_DUMP_TOT_COUNT]; - - /* segment 36 */ - struct mpi_coredump_segment_header routing_reg_seg_hdr; - u32 routing_regs[RT_IDX_DUMP_TOT_WORDS]; - - /* segment 37 */ - struct mpi_coredump_segment_header mac_prot_reg_seg_hdr; - u32 mac_prot_regs[MAC_ADDR_DUMP_TOT_WORDS]; - - /* segment 38 */ - struct mpi_coredump_segment_header xaui2_an_hdr; - u32 serdes2_xaui_an[XG_SERDES_XAUI_AN_COUNT]; - - /* segment 39 */ - struct mpi_coredump_segment_header xaui2_hss_pcs_hdr; - u32 serdes2_xaui_hss_pcs[XG_SERDES_XAUI_HSS_PCS_COUNT]; - - /* segment 40 */ - struct mpi_coredump_segment_header xfi2_an_hdr; - u32 serdes2_xfi_an[XG_SERDES_XFI_AN_COUNT]; - - /* segment 41 */ - struct mpi_coredump_segment_header xfi2_train_hdr; - u32 serdes2_xfi_train[XG_SERDES_XFI_TRAIN_COUNT]; - - /* segment 42 */ - struct mpi_coredump_segment_header xfi2_hss_pcs_hdr; - u32 serdes2_xfi_hss_pcs[XG_SERDES_XFI_HSS_PCS_COUNT]; - - /* segment 43 */ - struct mpi_coredump_segment_header xfi2_hss_tx_hdr; - u32 serdes2_xfi_hss_tx[XG_SERDES_XFI_HSS_TX_COUNT]; - - /* segment 44 */ - struct mpi_coredump_segment_header xfi2_hss_rx_hdr; - u32 serdes2_xfi_hss_rx[XG_SERDES_XFI_HSS_RX_COUNT]; - - /* segment 45 */ - struct mpi_coredump_segment_header xfi2_hss_pll_hdr; - u32 serdes2_xfi_hss_pll[XG_SERDES_XFI_HSS_PLL_COUNT]; - - /* segment 50 */ - /* semaphore register for all 5 functions */ - struct mpi_coredump_segment_header sem_regs_seg_hdr; - u32 sem_regs[MAX_SEMAPHORE_FUNCTIONS]; -}; - -/* - * intr_context structure is used during initialization - * to hook the interrupts. It is also used in a single - * irq environment as a context to the ISR. - */ -struct intr_context { - struct qlge_adapter *qdev; - u32 intr; - u32 irq_mask; /* Mask of which rings the vector services. */ - u32 hooked; - u32 intr_en_mask; /* value/mask used to enable this intr */ - u32 intr_dis_mask; /* value/mask used to disable this intr */ - u32 intr_read_mask; /* value/mask used to read this intr */ - char name[IFNAMSIZ * 2]; - irq_handler_t handler; -}; - -/* adapter flags definitions. */ -enum { - QL_ADAPTER_UP = 0, /* Adapter has been brought up. */ - QL_LEGACY_ENABLED = 1, - QL_MSI_ENABLED = 2, - QL_MSIX_ENABLED = 3, - QL_DMA64 = 4, - QL_PROMISCUOUS = 5, - QL_ALLMULTI = 6, - QL_PORT_CFG = 7, - QL_CAM_RT_SET = 8, - QL_SELFTEST = 9, - QL_LB_LINK_UP = 10, - QL_FRC_COREDUMP = 11, - QL_EEH_FATAL = 12, - QL_ASIC_RECOVERY = 14, /* We are in ascic recovery. */ -}; - -/* link_status bit definitions */ -enum { - STS_LOOPBACK_MASK = 0x00000700, - STS_LOOPBACK_PCS = 0x00000100, - STS_LOOPBACK_HSS = 0x00000200, - STS_LOOPBACK_EXT = 0x00000300, - STS_PAUSE_MASK = 0x000000c0, - STS_PAUSE_STD = 0x00000040, - STS_PAUSE_PRI = 0x00000080, - STS_SPEED_MASK = 0x00000038, - STS_SPEED_100Mb = 0x00000000, - STS_SPEED_1Gb = 0x00000008, - STS_SPEED_10Gb = 0x00000010, - STS_LINK_TYPE_MASK = 0x00000007, - STS_LINK_TYPE_XFI = 0x00000001, - STS_LINK_TYPE_XAUI = 0x00000002, - STS_LINK_TYPE_XFI_BP = 0x00000003, - STS_LINK_TYPE_XAUI_BP = 0x00000004, - STS_LINK_TYPE_10GBASET = 0x00000005, -}; - -/* link_config bit definitions */ -enum { - CFG_JUMBO_FRAME_SIZE = 0x00010000, - CFG_PAUSE_MASK = 0x00000060, - CFG_PAUSE_STD = 0x00000020, - CFG_PAUSE_PRI = 0x00000040, - CFG_DCBX = 0x00000010, - CFG_LOOPBACK_MASK = 0x00000007, - CFG_LOOPBACK_PCS = 0x00000002, - CFG_LOOPBACK_HSS = 0x00000004, - CFG_LOOPBACK_EXT = 0x00000006, - CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580, -}; - -struct nic_operations { - int (*get_flash)(struct qlge_adapter *qdev); - int (*port_initialize)(struct qlge_adapter *qdev); -}; - -struct qlge_netdev_priv { - struct qlge_adapter *qdev; - struct net_device *ndev; -}; - -static inline -struct qlge_adapter *netdev_to_qdev(struct net_device *ndev) -{ - struct qlge_netdev_priv *ndev_priv = netdev_priv(ndev); - - return ndev_priv->qdev; -} - -/* - * The main Adapter structure definition. - * This structure has all fields relevant to the hardware. - */ -struct qlge_adapter { - struct ricb ricb; - unsigned long flags; - u32 wol; - - struct nic_stats nic_stats; - - unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; - - /* PCI Configuration information for this device */ - struct pci_dev *pdev; - struct net_device *ndev; /* Parent NET device */ - - struct devlink_health_reporter *reporter; - /* Hardware information */ - u32 chip_rev_id; - u32 fw_rev_id; - u32 func; /* PCI function for this adapter */ - u32 alt_func; /* PCI function for alternate adapter */ - u32 port; /* Port number this adapter */ - - spinlock_t adapter_lock; - spinlock_t stats_lock; - - /* PCI Bus Relative Register Addresses */ - void __iomem *reg_base; - void __iomem *doorbell_area; - u32 doorbell_area_size; - - u32 msg_enable; - - /* Page for Shadow Registers */ - void *rx_ring_shadow_reg_area; - dma_addr_t rx_ring_shadow_reg_dma; - void *tx_ring_shadow_reg_area; - dma_addr_t tx_ring_shadow_reg_dma; - - u32 mailbox_in; - u32 mailbox_out; - struct mbox_params idc_mbc; - struct mutex mpi_mutex; - - int tx_ring_size; - int rx_ring_size; - u32 intr_count; - struct msix_entry *msi_x_entry; - struct intr_context intr_context[MAX_RX_RINGS]; - - int tx_ring_count; /* One per online CPU. */ - u32 rss_ring_count; /* One per irq vector. */ - /* - * rx_ring_count = - * (CPU count * outbound completion rx_ring) + - * (irq_vector_cnt * inbound (RSS) completion rx_ring) - */ - int rx_ring_count; - int ring_mem_size; - void *ring_mem; - - struct rx_ring rx_ring[MAX_RX_RINGS]; - struct tx_ring tx_ring[MAX_TX_RINGS]; - unsigned int lbq_buf_order; - u32 lbq_buf_size; - - int rx_csum; - u32 default_rx_queue; - - u16 rx_coalesce_usecs; /* cqicb->int_delay */ - u16 rx_max_coalesced_frames; /* cqicb->pkt_int_delay */ - u16 tx_coalesce_usecs; /* cqicb->int_delay */ - u16 tx_max_coalesced_frames; /* cqicb->pkt_int_delay */ - - u32 xg_sem_mask; - u32 port_link_up; - u32 port_init; - u32 link_status; - struct qlge_mpi_coredump *mpi_coredump; - u32 link_config; - u32 led_config; - u32 max_frame_size; - - union flash_params flash; - - struct workqueue_struct *workqueue; - struct delayed_work asic_reset_work; - struct delayed_work mpi_reset_work; - struct delayed_work mpi_work; - struct delayed_work mpi_port_cfg_work; - struct delayed_work mpi_idc_work; - struct completion ide_completion; - const struct nic_operations *nic_ops; - u16 device_id; - struct timer_list timer; - atomic_t lb_count; - /* Keep local copy of current mac address. */ - char current_mac_addr[ETH_ALEN]; -}; - -/* - * Typical Register accessor for memory mapped device. - */ -static inline u32 qlge_read32(const struct qlge_adapter *qdev, int reg) -{ - return readl(qdev->reg_base + reg); -} - -/* - * Typical Register accessor for memory mapped device. - */ -static inline void qlge_write32(const struct qlge_adapter *qdev, int reg, u32 val) -{ - writel(val, qdev->reg_base + reg); -} - -/* - * Doorbell Registers: - * Doorbell registers are virtual registers in the PCI memory space. - * The space is allocated by the chip during PCI initialization. The - * device driver finds the doorbell address in BAR 3 in PCI config space. - * The registers are used to control outbound and inbound queues. For - * example, the producer index for an outbound queue. Each queue uses - * 1 4k chunk of memory. The lower half of the space is for outbound - * queues. The upper half is for inbound queues. - */ -static inline void qlge_write_db_reg(u32 val, void __iomem *addr) -{ - writel(val, addr); -} - -/* - * Doorbell Registers: - * Doorbell registers are virtual registers in the PCI memory space. - * The space is allocated by the chip during PCI initialization. The - * device driver finds the doorbell address in BAR 3 in PCI config space. - * The registers are used to control outbound and inbound queues. For - * example, the producer index for an outbound queue. Each queue uses - * 1 4k chunk of memory. The lower half of the space is for outbound - * queues. The upper half is for inbound queues. - * Caller has to guarantee ordering. - */ -static inline void qlge_write_db_reg_relaxed(u32 val, void __iomem *addr) -{ - writel_relaxed(val, addr); -} - -/* - * Shadow Registers: - * Outbound queues have a consumer index that is maintained by the chip. - * Inbound queues have a producer index that is maintained by the chip. - * For lower overhead, these registers are "shadowed" to host memory - * which allows the device driver to track the queue progress without - * PCI reads. When an entry is placed on an inbound queue, the chip will - * update the relevant index register and then copy the value to the - * shadow register in host memory. - */ -static inline u32 qlge_read_sh_reg(__le32 *addr) -{ - u32 reg; - - reg = le32_to_cpu(*addr); - rmb(); - return reg; -} - -extern char qlge_driver_name[]; -extern const char qlge_driver_version[]; -extern const struct ethtool_ops qlge_ethtool_ops; - -int qlge_sem_spinlock(struct qlge_adapter *qdev, u32 sem_mask); -void qlge_sem_unlock(struct qlge_adapter *qdev, u32 sem_mask); -int qlge_read_xgmac_reg(struct qlge_adapter *qdev, u32 reg, u32 *data); -int qlge_get_mac_addr_reg(struct qlge_adapter *qdev, u32 type, u16 index, - u32 *value); -int qlge_get_routing_reg(struct qlge_adapter *qdev, u32 index, u32 *value); -int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, int size, u32 bit, - u16 q_id); -void qlge_queue_fw_error(struct qlge_adapter *qdev); -void qlge_mpi_work(struct work_struct *work); -void qlge_mpi_reset_work(struct work_struct *work); -int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit); -void qlge_queue_asic_error(struct qlge_adapter *qdev); -void qlge_set_ethtool_ops(struct net_device *ndev); -int qlge_read_xgmac_reg64(struct qlge_adapter *qdev, u32 reg, u64 *data); -void qlge_mpi_idc_work(struct work_struct *work); -void qlge_mpi_port_cfg_work(struct work_struct *work); -int qlge_mb_get_fw_state(struct qlge_adapter *qdev); -int qlge_cam_route_initialize(struct qlge_adapter *qdev); -int qlge_read_mpi_reg(struct qlge_adapter *qdev, u32 reg, u32 *data); -int qlge_write_mpi_reg(struct qlge_adapter *qdev, u32 reg, u32 data); -int qlge_unpause_mpi_risc(struct qlge_adapter *qdev); -int qlge_pause_mpi_risc(struct qlge_adapter *qdev); -int qlge_hard_reset_mpi_risc(struct qlge_adapter *qdev); -int qlge_soft_reset_mpi_risc(struct qlge_adapter *qdev); -int qlge_dump_risc_ram_area(struct qlge_adapter *qdev, void *buf, u32 ram_addr, - int word_count); -int qlge_core_dump(struct qlge_adapter *qdev, struct qlge_mpi_coredump *mpi_coredump); -int qlge_mb_about_fw(struct qlge_adapter *qdev); -int qlge_mb_wol_set_magic(struct qlge_adapter *qdev, u32 enable_wol); -int qlge_mb_wol_mode(struct qlge_adapter *qdev, u32 wol); -int qlge_mb_set_led_cfg(struct qlge_adapter *qdev, u32 led_config); -int qlge_mb_get_led_cfg(struct qlge_adapter *qdev); -void qlge_link_on(struct qlge_adapter *qdev); -void qlge_link_off(struct qlge_adapter *qdev); -int qlge_mb_set_mgmnt_traffic_ctl(struct qlge_adapter *qdev, u32 control); -int qlge_mb_get_port_cfg(struct qlge_adapter *qdev); -int qlge_mb_set_port_cfg(struct qlge_adapter *qdev); -int qlge_wait_fifo_empty(struct qlge_adapter *qdev); -void qlge_get_dump(struct qlge_adapter *qdev, void *buff); -netdev_tx_t qlge_lb_send(struct sk_buff *skb, struct net_device *ndev); -void qlge_check_lb_frame(struct qlge_adapter *qdev, struct sk_buff *skb); -int qlge_own_firmware(struct qlge_adapter *qdev); -int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); - -#endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c deleted file mode 100644 index c7e865f515cf..000000000000 --- a/drivers/staging/qlge/qlge_dbg.c +++ /dev/null @@ -1,1311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include - -#include "qlge.h" - -/* Read a NIC register from the alternate function. */ -static u32 qlge_read_other_func_reg(struct qlge_adapter *qdev, - u32 reg) -{ - u32 register_to_read; - u32 reg_val; - unsigned int status = 0; - - register_to_read = MPI_NIC_REG_BLOCK - | MPI_NIC_READ - | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT) - | reg; - status = qlge_read_mpi_reg(qdev, register_to_read, ®_val); - if (status != 0) - return 0xffffffff; - - return reg_val; -} - -/* Write a NIC register from the alternate function. */ -static int qlge_write_other_func_reg(struct qlge_adapter *qdev, - u32 reg, u32 reg_val) -{ - u32 register_to_read; - - register_to_read = MPI_NIC_REG_BLOCK - | MPI_NIC_READ - | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT) - | reg; - - return qlge_write_mpi_reg(qdev, register_to_read, reg_val); -} - -static int qlge_wait_other_func_reg_rdy(struct qlge_adapter *qdev, u32 reg, - u32 bit, u32 err_bit) -{ - u32 temp; - int count; - - for (count = 10; count; count--) { - temp = qlge_read_other_func_reg(qdev, reg); - - /* check for errors */ - if (temp & err_bit) - return -1; - else if (temp & bit) - return 0; - mdelay(10); - } - return -1; -} - -static int qlge_read_other_func_serdes_reg(struct qlge_adapter *qdev, u32 reg, - u32 *data) -{ - int status; - - /* wait for reg to come ready */ - status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4, - XG_SERDES_ADDR_RDY, 0); - if (status) - goto exit; - - /* set up for reg read */ - qlge_write_other_func_reg(qdev, XG_SERDES_ADDR / 4, reg | PROC_ADDR_R); - - /* wait for reg to come ready */ - status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4, - XG_SERDES_ADDR_RDY, 0); - if (status) - goto exit; - - /* get the data */ - *data = qlge_read_other_func_reg(qdev, (XG_SERDES_DATA / 4)); -exit: - return status; -} - -/* Read out the SERDES registers */ -static int qlge_read_serdes_reg(struct qlge_adapter *qdev, u32 reg, u32 *data) -{ - int status; - - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0); - if (status) - goto exit; - - /* set up for reg read */ - qlge_write32(qdev, XG_SERDES_ADDR, reg | PROC_ADDR_R); - - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0); - if (status) - goto exit; - - /* get the data */ - *data = qlge_read32(qdev, XG_SERDES_DATA); -exit: - return status; -} - -static void qlge_get_both_serdes(struct qlge_adapter *qdev, u32 addr, - u32 *direct_ptr, u32 *indirect_ptr, - bool direct_valid, bool indirect_valid) -{ - unsigned int status; - - status = 1; - if (direct_valid) - status = qlge_read_serdes_reg(qdev, addr, direct_ptr); - /* Dead fill any failures or invalids. */ - if (status) - *direct_ptr = 0xDEADBEEF; - - status = 1; - if (indirect_valid) - status = qlge_read_other_func_serdes_reg(qdev, addr, - indirect_ptr); - /* Dead fill any failures or invalids. */ - if (status) - *indirect_ptr = 0xDEADBEEF; -} - -static int qlge_get_serdes_regs(struct qlge_adapter *qdev, - struct qlge_mpi_coredump *mpi_coredump) -{ - int status; - bool xfi_direct_valid = false, xfi_indirect_valid = false; - bool xaui_direct_valid = true, xaui_indirect_valid = true; - unsigned int i; - u32 *direct_ptr, temp; - u32 *indirect_ptr; - - /* The XAUI needs to be read out per port */ - status = qlge_read_other_func_serdes_reg(qdev, - XG_SERDES_XAUI_HSS_PCS_START, - &temp); - if (status) - temp = XG_SERDES_ADDR_XAUI_PWR_DOWN; - - if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) == - XG_SERDES_ADDR_XAUI_PWR_DOWN) - xaui_indirect_valid = false; - - status = qlge_read_serdes_reg(qdev, XG_SERDES_XAUI_HSS_PCS_START, &temp); - - if (status) - temp = XG_SERDES_ADDR_XAUI_PWR_DOWN; - - if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) == - XG_SERDES_ADDR_XAUI_PWR_DOWN) - xaui_direct_valid = false; - - /* - * XFI register is shared so only need to read one - * functions and then check the bits. - */ - status = qlge_read_serdes_reg(qdev, XG_SERDES_ADDR_STS, &temp); - if (status) - temp = 0; - - if ((temp & XG_SERDES_ADDR_XFI1_PWR_UP) == - XG_SERDES_ADDR_XFI1_PWR_UP) { - /* now see if i'm NIC 1 or NIC 2 */ - if (qdev->func & 1) - /* I'm NIC 2, so the indirect (NIC1) xfi is up. */ - xfi_indirect_valid = true; - else - xfi_direct_valid = true; - } - if ((temp & XG_SERDES_ADDR_XFI2_PWR_UP) == - XG_SERDES_ADDR_XFI2_PWR_UP) { - /* now see if i'm NIC 1 or NIC 2 */ - if (qdev->func & 1) - /* I'm NIC 2, so the indirect (NIC1) xfi is up. */ - xfi_direct_valid = true; - else - xfi_indirect_valid = true; - } - - /* Get XAUI_AN register block. */ - if (qdev->func & 1) { - /* Function 2 is direct */ - direct_ptr = mpi_coredump->serdes2_xaui_an; - indirect_ptr = mpi_coredump->serdes_xaui_an; - } else { - /* Function 1 is direct */ - direct_ptr = mpi_coredump->serdes_xaui_an; - indirect_ptr = mpi_coredump->serdes2_xaui_an; - } - - for (i = 0; i <= 0x000000034; i += 4, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xaui_direct_valid, xaui_indirect_valid); - - /* Get XAUI_HSS_PCS register block. */ - if (qdev->func & 1) { - direct_ptr = - mpi_coredump->serdes2_xaui_hss_pcs; - indirect_ptr = - mpi_coredump->serdes_xaui_hss_pcs; - } else { - direct_ptr = - mpi_coredump->serdes_xaui_hss_pcs; - indirect_ptr = - mpi_coredump->serdes2_xaui_hss_pcs; - } - - for (i = 0x800; i <= 0x880; i += 4, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xaui_direct_valid, xaui_indirect_valid); - - /* Get XAUI_XFI_AN register block. */ - if (qdev->func & 1) { - direct_ptr = mpi_coredump->serdes2_xfi_an; - indirect_ptr = mpi_coredump->serdes_xfi_an; - } else { - direct_ptr = mpi_coredump->serdes_xfi_an; - indirect_ptr = mpi_coredump->serdes2_xfi_an; - } - - for (i = 0x1000; i <= 0x1034; i += 4, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - - /* Get XAUI_XFI_TRAIN register block. */ - if (qdev->func & 1) { - direct_ptr = mpi_coredump->serdes2_xfi_train; - indirect_ptr = - mpi_coredump->serdes_xfi_train; - } else { - direct_ptr = mpi_coredump->serdes_xfi_train; - indirect_ptr = - mpi_coredump->serdes2_xfi_train; - } - - for (i = 0x1050; i <= 0x107c; i += 4, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - - /* Get XAUI_XFI_HSS_PCS register block. */ - if (qdev->func & 1) { - direct_ptr = - mpi_coredump->serdes2_xfi_hss_pcs; - indirect_ptr = - mpi_coredump->serdes_xfi_hss_pcs; - } else { - direct_ptr = - mpi_coredump->serdes_xfi_hss_pcs; - indirect_ptr = - mpi_coredump->serdes2_xfi_hss_pcs; - } - - for (i = 0x1800; i <= 0x1838; i += 4, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - - /* Get XAUI_XFI_HSS_TX register block. */ - if (qdev->func & 1) { - direct_ptr = - mpi_coredump->serdes2_xfi_hss_tx; - indirect_ptr = - mpi_coredump->serdes_xfi_hss_tx; - } else { - direct_ptr = mpi_coredump->serdes_xfi_hss_tx; - indirect_ptr = - mpi_coredump->serdes2_xfi_hss_tx; - } - for (i = 0x1c00; i <= 0x1c1f; i++, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - - /* Get XAUI_XFI_HSS_RX register block. */ - if (qdev->func & 1) { - direct_ptr = - mpi_coredump->serdes2_xfi_hss_rx; - indirect_ptr = - mpi_coredump->serdes_xfi_hss_rx; - } else { - direct_ptr = mpi_coredump->serdes_xfi_hss_rx; - indirect_ptr = - mpi_coredump->serdes2_xfi_hss_rx; - } - - for (i = 0x1c40; i <= 0x1c5f; i++, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - - /* Get XAUI_XFI_HSS_PLL register block. */ - if (qdev->func & 1) { - direct_ptr = - mpi_coredump->serdes2_xfi_hss_pll; - indirect_ptr = - mpi_coredump->serdes_xfi_hss_pll; - } else { - direct_ptr = - mpi_coredump->serdes_xfi_hss_pll; - indirect_ptr = - mpi_coredump->serdes2_xfi_hss_pll; - } - for (i = 0x1e00; i <= 0x1e1f; i++, direct_ptr++, indirect_ptr++) - qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr, - xfi_direct_valid, xfi_indirect_valid); - return 0; -} - -static int qlge_read_other_func_xgmac_reg(struct qlge_adapter *qdev, u32 reg, - u32 *data) -{ - int status = 0; - - /* wait for reg to come ready */ - status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4, - XGMAC_ADDR_RDY, XGMAC_ADDR_XME); - if (status) - goto exit; - - /* set up for reg read */ - qlge_write_other_func_reg(qdev, XGMAC_ADDR / 4, reg | XGMAC_ADDR_R); - - /* wait for reg to come ready */ - status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4, - XGMAC_ADDR_RDY, XGMAC_ADDR_XME); - if (status) - goto exit; - - /* get the data */ - *data = qlge_read_other_func_reg(qdev, XGMAC_DATA / 4); -exit: - return status; -} - -/* Read the 400 xgmac control/statistics registers - * skipping unused locations. - */ -static int qlge_get_xgmac_regs(struct qlge_adapter *qdev, u32 *buf, - unsigned int other_function) -{ - int status = 0; - int i; - - for (i = PAUSE_SRC_LO; i < XGMAC_REGISTER_END; i += 4, buf++) { - /* We're reading 400 xgmac registers, but we filter out - * several locations that are non-responsive to reads. - */ - if ((i == 0x00000114) || (i == 0x00000118) || - (i == 0x0000013c) || (i == 0x00000140) || - (i > 0x00000150 && i < 0x000001fc) || - (i > 0x00000278 && i < 0x000002a0) || - (i > 0x000002c0 && i < 0x000002cf) || - (i > 0x000002dc && i < 0x000002f0) || - (i > 0x000003c8 && i < 0x00000400) || - (i > 0x00000400 && i < 0x00000410) || - (i > 0x00000410 && i < 0x00000420) || - (i > 0x00000420 && i < 0x00000430) || - (i > 0x00000430 && i < 0x00000440) || - (i > 0x00000440 && i < 0x00000450) || - (i > 0x00000450 && i < 0x00000500) || - (i > 0x0000054c && i < 0x00000568) || - (i > 0x000005c8 && i < 0x00000600)) { - if (other_function) - status = qlge_read_other_func_xgmac_reg(qdev, i, buf); - else - status = qlge_read_xgmac_reg(qdev, i, buf); - - if (status) - *buf = 0xdeadbeef; - break; - } - } - return status; -} - -static int qlge_get_ets_regs(struct qlge_adapter *qdev, u32 *buf) -{ - int i; - - for (i = 0; i < 8; i++, buf++) { - qlge_write32(qdev, NIC_ETS, i << 29 | 0x08000000); - *buf = qlge_read32(qdev, NIC_ETS); - } - - for (i = 0; i < 2; i++, buf++) { - qlge_write32(qdev, CNA_ETS, i << 29 | 0x08000000); - *buf = qlge_read32(qdev, CNA_ETS); - } - - return 0; -} - -static void qlge_get_intr_states(struct qlge_adapter *qdev, u32 *buf) -{ - int i; - - for (i = 0; i < qdev->rx_ring_count; i++, buf++) { - qlge_write32(qdev, INTR_EN, - qdev->intr_context[i].intr_read_mask); - *buf = qlge_read32(qdev, INTR_EN); - } -} - -static int qlge_get_cam_entries(struct qlge_adapter *qdev, u32 *buf) -{ - int i, status; - u32 value[3]; - - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return status; - - for (i = 0; i < 16; i++) { - status = qlge_get_mac_addr_reg(qdev, - MAC_ADDR_TYPE_CAM_MAC, i, value); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed read of mac index register\n"); - goto err; - } - *buf++ = value[0]; /* lower MAC address */ - *buf++ = value[1]; /* upper MAC address */ - *buf++ = value[2]; /* output */ - } - for (i = 0; i < 32; i++) { - status = qlge_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_MULTI_MAC, - i, value); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed read of mac index register\n"); - goto err; - } - *buf++ = value[0]; /* lower Mcast address */ - *buf++ = value[1]; /* upper Mcast address */ - } -err: - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - return status; -} - -static int qlge_get_routing_entries(struct qlge_adapter *qdev, u32 *buf) -{ - int status; - u32 value, i; - - status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK); - if (status) - return status; - - for (i = 0; i < 16; i++) { - status = qlge_get_routing_reg(qdev, i, &value); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed read of routing index register\n"); - goto err; - } else { - *buf++ = value; - } - } -err: - qlge_sem_unlock(qdev, SEM_RT_IDX_MASK); - return status; -} - -/* Read the MPI Processor shadow registers */ -static int qlge_get_mpi_shadow_regs(struct qlge_adapter *qdev, u32 *buf) -{ - u32 i; - int status; - - for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) { - status = qlge_write_mpi_reg(qdev, - RISC_124, - (SHADOW_OFFSET | i << SHADOW_REG_SHIFT)); - if (status) - goto end; - status = qlge_read_mpi_reg(qdev, RISC_127, buf); - if (status) - goto end; - } -end: - return status; -} - -/* Read the MPI Processor core registers */ -static int qlge_get_mpi_regs(struct qlge_adapter *qdev, u32 *buf, - u32 offset, u32 count) -{ - int i, status = 0; - - for (i = 0; i < count; i++, buf++) { - status = qlge_read_mpi_reg(qdev, offset + i, buf); - if (status) - return status; - } - return status; -} - -/* Read the ASIC probe dump */ -static unsigned int *qlge_get_probe(struct qlge_adapter *qdev, u32 clock, - u32 valid, u32 *buf) -{ - u32 module, mux_sel, probe, lo_val, hi_val; - - for (module = 0; module < PRB_MX_ADDR_MAX_MODS; module++) { - if (!((valid >> module) & 1)) - continue; - for (mux_sel = 0; mux_sel < PRB_MX_ADDR_MAX_MUX; mux_sel++) { - probe = clock - | PRB_MX_ADDR_ARE - | mux_sel - | (module << PRB_MX_ADDR_MOD_SEL_SHIFT); - qlge_write32(qdev, PRB_MX_ADDR, probe); - lo_val = qlge_read32(qdev, PRB_MX_DATA); - if (mux_sel == 0) { - *buf = probe; - buf++; - } - probe |= PRB_MX_ADDR_UP; - qlge_write32(qdev, PRB_MX_ADDR, probe); - hi_val = qlge_read32(qdev, PRB_MX_DATA); - *buf = lo_val; - buf++; - *buf = hi_val; - buf++; - } - } - return buf; -} - -static int qlge_get_probe_dump(struct qlge_adapter *qdev, unsigned int *buf) -{ - /* First we have to enable the probe mux */ - qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_PRB_CTL, MPI_TEST_FUNC_PRB_EN); - buf = qlge_get_probe(qdev, PRB_MX_ADDR_SYS_CLOCK, - PRB_MX_ADDR_VALID_SYS_MOD, buf); - buf = qlge_get_probe(qdev, PRB_MX_ADDR_PCI_CLOCK, - PRB_MX_ADDR_VALID_PCI_MOD, buf); - buf = qlge_get_probe(qdev, PRB_MX_ADDR_XGM_CLOCK, - PRB_MX_ADDR_VALID_XGM_MOD, buf); - buf = qlge_get_probe(qdev, PRB_MX_ADDR_FC_CLOCK, - PRB_MX_ADDR_VALID_FC_MOD, buf); - return 0; -} - -/* Read out the routing index registers */ -static int qlge_get_routing_index_registers(struct qlge_adapter *qdev, u32 *buf) -{ - int status; - u32 type, index, index_max; - u32 result_index; - u32 result_data; - u32 val; - - status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK); - if (status) - return status; - - for (type = 0; type < 4; type++) { - if (type < 2) - index_max = 8; - else - index_max = 16; - for (index = 0; index < index_max; index++) { - val = RT_IDX_RS - | (type << RT_IDX_TYPE_SHIFT) - | (index << RT_IDX_IDX_SHIFT); - qlge_write32(qdev, RT_IDX, val); - result_index = 0; - while ((result_index & RT_IDX_MR) == 0) - result_index = qlge_read32(qdev, RT_IDX); - result_data = qlge_read32(qdev, RT_DATA); - *buf = type; - buf++; - *buf = index; - buf++; - *buf = result_index; - buf++; - *buf = result_data; - buf++; - } - } - qlge_sem_unlock(qdev, SEM_RT_IDX_MASK); - return status; -} - -/* Read out the MAC protocol registers */ -static void qlge_get_mac_protocol_registers(struct qlge_adapter *qdev, u32 *buf) -{ - u32 result_index, result_data; - u32 type; - u32 index; - u32 offset; - u32 val; - u32 initial_val = MAC_ADDR_RS; - u32 max_index; - u32 max_offset; - - for (type = 0; type < MAC_ADDR_TYPE_COUNT; type++) { - switch (type) { - case 0: /* CAM */ - initial_val |= MAC_ADDR_ADR; - max_index = MAC_ADDR_MAX_CAM_ENTRIES; - max_offset = MAC_ADDR_MAX_CAM_WCOUNT; - break; - case 1: /* Multicast MAC Address */ - max_index = MAC_ADDR_MAX_CAM_WCOUNT; - max_offset = MAC_ADDR_MAX_CAM_WCOUNT; - break; - case 2: /* VLAN filter mask */ - case 3: /* MC filter mask */ - max_index = MAC_ADDR_MAX_CAM_WCOUNT; - max_offset = MAC_ADDR_MAX_CAM_WCOUNT; - break; - case 4: /* FC MAC addresses */ - max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES; - max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT; - break; - case 5: /* Mgmt MAC addresses */ - max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES; - max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT; - break; - case 6: /* Mgmt VLAN addresses */ - max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES; - max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT; - break; - case 7: /* Mgmt IPv4 address */ - max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES; - max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT; - break; - case 8: /* Mgmt IPv6 address */ - max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES; - max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT; - break; - case 9: /* Mgmt TCP/UDP Dest port */ - max_index = MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES; - max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT; - break; - default: - netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type); - max_index = 0; - max_offset = 0; - break; - } - for (index = 0; index < max_index; index++) { - for (offset = 0; offset < max_offset; offset++) { - val = initial_val - | (type << MAC_ADDR_TYPE_SHIFT) - | (index << MAC_ADDR_IDX_SHIFT) - | (offset); - qlge_write32(qdev, MAC_ADDR_IDX, val); - result_index = 0; - while ((result_index & MAC_ADDR_MR) == 0) { - result_index = qlge_read32(qdev, - MAC_ADDR_IDX); - } - result_data = qlge_read32(qdev, MAC_ADDR_DATA); - *buf = result_index; - buf++; - *buf = result_data; - buf++; - } - } - } -} - -static void qlge_get_sem_registers(struct qlge_adapter *qdev, u32 *buf) -{ - u32 func_num, reg, reg_val; - int status; - - for (func_num = 0; func_num < MAX_SEMAPHORE_FUNCTIONS ; func_num++) { - reg = MPI_NIC_REG_BLOCK - | (func_num << MPI_NIC_FUNCTION_SHIFT) - | (SEM / 4); - status = qlge_read_mpi_reg(qdev, reg, ®_val); - *buf = reg_val; - /* if the read failed then dead fill the element. */ - if (!status) - *buf = 0xdeadbeef; - buf++; - } -} - -/* Create a coredump segment header */ -static void qlge_build_coredump_seg_header(struct mpi_coredump_segment_header *seg_hdr, - u32 seg_number, u32 seg_size, u8 *desc) -{ - memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header)); - seg_hdr->cookie = MPI_COREDUMP_COOKIE; - seg_hdr->seg_num = seg_number; - seg_hdr->seg_size = seg_size; - strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1); -} - -/* - * This function should be called when a coredump / probedump - * is to be extracted from the HBA. It is assumed there is a - * qdev structure that contains the base address of the register - * space for this function as well as a coredump structure that - * will contain the dump. - */ -int qlge_core_dump(struct qlge_adapter *qdev, struct qlge_mpi_coredump *mpi_coredump) -{ - int status; - int i; - - if (!mpi_coredump) { - netif_err(qdev, drv, qdev->ndev, "No memory allocated\n"); - return -EINVAL; - } - - /* Try to get the spinlock, but dont worry if - * it isn't available. If the firmware died it - * might be holding the sem. - */ - qlge_sem_spinlock(qdev, SEM_PROC_REG_MASK); - - status = qlge_pause_mpi_risc(qdev); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed RISC pause. Status = 0x%.08x\n", status); - goto err; - } - - /* Insert the global header */ - memset(&mpi_coredump->mpi_global_header, 0, - sizeof(struct mpi_coredump_global_header)); - mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE; - mpi_coredump->mpi_global_header.header_size = - sizeof(struct mpi_coredump_global_header); - mpi_coredump->mpi_global_header.image_size = - sizeof(struct qlge_mpi_coredump); - strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump", - sizeof(mpi_coredump->mpi_global_header.id_string)); - - /* Get generic NIC reg dump */ - qlge_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr, - NIC1_CONTROL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->nic_regs), "NIC1 Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->nic2_regs_seg_hdr, - NIC2_CONTROL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->nic2_regs), "NIC2 Registers"); - - /* Get XGMac registers. (Segment 18, Rev C. step 21) */ - qlge_build_coredump_seg_header(&mpi_coredump->xgmac1_seg_hdr, - NIC1_XGMAC_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->xgmac1), "NIC1 XGMac Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xgmac2_seg_hdr, - NIC2_XGMAC_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->xgmac2), "NIC2 XGMac Registers"); - - if (qdev->func & 1) { - /* Odd means our function is NIC 2 */ - for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++) - mpi_coredump->nic2_regs[i] = - qlge_read32(qdev, i * sizeof(u32)); - - for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++) - mpi_coredump->nic_regs[i] = - qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4); - - qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 0); - qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 1); - } else { - /* Even means our function is NIC 1 */ - for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++) - mpi_coredump->nic_regs[i] = - qlge_read32(qdev, i * sizeof(u32)); - for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++) - mpi_coredump->nic2_regs[i] = - qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4); - - qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 0); - qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 1); - } - - /* Rev C. Step 20a */ - qlge_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr, - XAUI_AN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xaui_an), - "XAUI AN Registers"); - - /* Rev C. Step 20b */ - qlge_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr, - XAUI_HSS_PCS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xaui_hss_pcs), - "XAUI HSS PCS Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr, XFI_AN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_an), - "XFI AN Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr, - XFI_TRAIN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_train), - "XFI TRAIN Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr, - XFI_HSS_PCS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_hss_pcs), - "XFI HSS PCS Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr, - XFI_HSS_TX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_hss_tx), - "XFI HSS TX Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr, - XFI_HSS_RX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_hss_rx), - "XFI HSS RX Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr, - XFI_HSS_PLL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes_xfi_hss_pll), - "XFI HSS PLL Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xaui2_an_hdr, - XAUI2_AN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xaui_an), - "XAUI2 AN Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xaui2_hss_pcs_hdr, - XAUI2_HSS_PCS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xaui_hss_pcs), - "XAUI2 HSS PCS Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_an_hdr, - XFI2_AN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_an), - "XFI2 AN Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_train_hdr, - XFI2_TRAIN_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_train), - "XFI2 TRAIN Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pcs_hdr, - XFI2_HSS_PCS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_hss_pcs), - "XFI2 HSS PCS Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_tx_hdr, - XFI2_HSS_TX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_hss_tx), - "XFI2 HSS TX Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_rx_hdr, - XFI2_HSS_RX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_hss_rx), - "XFI2 HSS RX Registers"); - - qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pll_hdr, - XFI2_HSS_PLL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->serdes2_xfi_hss_pll), - "XFI2 HSS PLL Registers"); - - status = qlge_get_serdes_regs(qdev, mpi_coredump); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed Dump of Serdes Registers. Status = 0x%.08x\n", - status); - goto err; - } - - qlge_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr, - CORE_SEG_NUM, - sizeof(mpi_coredump->core_regs_seg_hdr) + - sizeof(mpi_coredump->mpi_core_regs) + - sizeof(mpi_coredump->mpi_core_sh_regs), - "Core Registers"); - - /* Get the MPI Core Registers */ - status = qlge_get_mpi_regs(qdev, &mpi_coredump->mpi_core_regs[0], - MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT); - if (status) - goto err; - /* Get the 16 MPI shadow registers */ - status = qlge_get_mpi_shadow_regs(qdev, - &mpi_coredump->mpi_core_sh_regs[0]); - if (status) - goto err; - - /* Get the Test Logic Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr, - TEST_LOGIC_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->test_logic_regs), - "Test Logic Regs"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->test_logic_regs[0], - TEST_REGS_ADDR, TEST_REGS_CNT); - if (status) - goto err; - - /* Get the RMII Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr, - RMII_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->rmii_regs), - "RMII Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->rmii_regs[0], - RMII_REGS_ADDR, RMII_REGS_CNT); - if (status) - goto err; - - /* Get the FCMAC1 Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr, - FCMAC1_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->fcmac1_regs), - "FCMAC1 Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac1_regs[0], - FCMAC1_REGS_ADDR, FCMAC_REGS_CNT); - if (status) - goto err; - - /* Get the FCMAC2 Registers */ - - qlge_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr, - FCMAC2_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->fcmac2_regs), - "FCMAC2 Registers"); - - status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac2_regs[0], - FCMAC2_REGS_ADDR, FCMAC_REGS_CNT); - if (status) - goto err; - - /* Get the FC1 MBX Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr, - FC1_MBOX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->fc1_mbx_regs), - "FC1 MBox Regs"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->fc1_mbx_regs[0], - FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT); - if (status) - goto err; - - /* Get the IDE Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr, - IDE_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->ide_regs), - "IDE Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->ide_regs[0], - IDE_REGS_ADDR, IDE_REGS_CNT); - if (status) - goto err; - - /* Get the NIC1 MBX Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr, - NIC1_MBOX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->nic1_mbx_regs), - "NIC1 MBox Regs"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->nic1_mbx_regs[0], - NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT); - if (status) - goto err; - - /* Get the SMBus Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr, - SMBUS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->smbus_regs), - "SMBus Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->smbus_regs[0], - SMBUS_REGS_ADDR, SMBUS_REGS_CNT); - if (status) - goto err; - - /* Get the FC2 MBX Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr, - FC2_MBOX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->fc2_mbx_regs), - "FC2 MBox Regs"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->fc2_mbx_regs[0], - FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT); - if (status) - goto err; - - /* Get the NIC2 MBX Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr, - NIC2_MBOX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->nic2_mbx_regs), - "NIC2 MBox Regs"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->nic2_mbx_regs[0], - NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT); - if (status) - goto err; - - /* Get the I2C Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr, - I2C_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->i2c_regs), - "I2C Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->i2c_regs[0], - I2C_REGS_ADDR, I2C_REGS_CNT); - if (status) - goto err; - - /* Get the MEMC Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr, - MEMC_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->memc_regs), - "MEMC Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->memc_regs[0], - MEMC_REGS_ADDR, MEMC_REGS_CNT); - if (status) - goto err; - - /* Get the PBus Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr, - PBUS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->pbus_regs), - "PBUS Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->pbus_regs[0], - PBUS_REGS_ADDR, PBUS_REGS_CNT); - if (status) - goto err; - - /* Get the MDE Registers */ - qlge_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr, - MDE_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->mde_regs), - "MDE Registers"); - status = qlge_get_mpi_regs(qdev, &mpi_coredump->mde_regs[0], - MDE_REGS_ADDR, MDE_REGS_CNT); - if (status) - goto err; - - qlge_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr, - MISC_NIC_INFO_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->misc_nic_info), - "MISC NIC INFO"); - mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count; - mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count; - mpi_coredump->misc_nic_info.intr_count = qdev->intr_count; - mpi_coredump->misc_nic_info.function = qdev->func; - - /* Segment 31 */ - /* Get indexed register values. */ - qlge_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr, - INTR_STATES_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->intr_states), - "INTR States"); - qlge_get_intr_states(qdev, &mpi_coredump->intr_states[0]); - - qlge_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr, - CAM_ENTRIES_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->cam_entries), - "CAM Entries"); - status = qlge_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]); - if (status) - goto err; - - qlge_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr, - ROUTING_WORDS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->nic_routing_words), - "Routing Words"); - status = qlge_get_routing_entries(qdev, - &mpi_coredump->nic_routing_words[0]); - if (status) - goto err; - - /* Segment 34 (Rev C. step 23) */ - qlge_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr, - ETS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->ets), - "ETS Registers"); - status = qlge_get_ets_regs(qdev, &mpi_coredump->ets[0]); - if (status) - goto err; - - qlge_build_coredump_seg_header(&mpi_coredump->probe_dump_seg_hdr, - PROBE_DUMP_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->probe_dump), - "Probe Dump"); - qlge_get_probe_dump(qdev, &mpi_coredump->probe_dump[0]); - - qlge_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr, - ROUTING_INDEX_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->routing_regs), - "Routing Regs"); - status = qlge_get_routing_index_registers(qdev, - &mpi_coredump->routing_regs[0]); - if (status) - goto err; - - qlge_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr, - MAC_PROTOCOL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->mac_prot_regs), - "MAC Prot Regs"); - qlge_get_mac_protocol_registers(qdev, &mpi_coredump->mac_prot_regs[0]); - - /* Get the semaphore registers for all 5 functions */ - qlge_build_coredump_seg_header(&mpi_coredump->sem_regs_seg_hdr, - SEM_REGS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) + - sizeof(mpi_coredump->sem_regs), "Sem Registers"); - - qlge_get_sem_registers(qdev, &mpi_coredump->sem_regs[0]); - - /* Prevent the mpi restarting while we dump the memory.*/ - qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_RST_STS, MPI_TEST_FUNC_RST_FRC); - - /* clear the pause */ - status = qlge_unpause_mpi_risc(qdev); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed RISC unpause. Status = 0x%.08x\n", status); - goto err; - } - - /* Reset the RISC so we can dump RAM */ - status = qlge_hard_reset_mpi_risc(qdev); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed RISC reset. Status = 0x%.08x\n", status); - goto err; - } - - qlge_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr, - WCS_RAM_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->code_ram), - "WCS RAM"); - status = qlge_dump_risc_ram_area(qdev, &mpi_coredump->code_ram[0], - CODE_RAM_ADDR, CODE_RAM_CNT); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed Dump of CODE RAM. Status = 0x%.08x\n", - status); - goto err; - } - - /* Insert the segment header */ - qlge_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr, - MEMC_RAM_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->memc_ram), - "MEMC RAM"); - status = qlge_dump_risc_ram_area(qdev, &mpi_coredump->memc_ram[0], - MEMC_RAM_ADDR, MEMC_RAM_CNT); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Failed Dump of MEMC RAM. Status = 0x%.08x\n", - status); - goto err; - } -err: - qlge_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */ - return status; -} - -static void qlge_get_core_dump(struct qlge_adapter *qdev) -{ - if (!qlge_own_firmware(qdev)) { - netif_err(qdev, drv, qdev->ndev, "Don't own firmware!\n"); - return; - } - - if (!netif_running(qdev->ndev)) { - netif_err(qdev, ifup, qdev->ndev, - "Force Coredump can only be done from interface that is up\n"); - return; - } - qlge_queue_fw_error(qdev); -} - -static void qlge_gen_reg_dump(struct qlge_adapter *qdev, - struct qlge_reg_dump *mpi_coredump) -{ - int i, status; - - memset(&mpi_coredump->mpi_global_header, 0, - sizeof(struct mpi_coredump_global_header)); - mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE; - mpi_coredump->mpi_global_header.header_size = - sizeof(struct mpi_coredump_global_header); - mpi_coredump->mpi_global_header.image_size = - sizeof(struct qlge_reg_dump); - strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump", - sizeof(mpi_coredump->mpi_global_header.id_string)); - - /* segment 16 */ - qlge_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr, - MISC_NIC_INFO_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->misc_nic_info), - "MISC NIC INFO"); - mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count; - mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count; - mpi_coredump->misc_nic_info.intr_count = qdev->intr_count; - mpi_coredump->misc_nic_info.function = qdev->func; - - /* Segment 16, Rev C. Step 18 */ - qlge_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr, - NIC1_CONTROL_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->nic_regs), - "NIC Registers"); - /* Get generic reg dump */ - for (i = 0; i < 64; i++) - mpi_coredump->nic_regs[i] = qlge_read32(qdev, i * sizeof(u32)); - - /* Segment 31 */ - /* Get indexed register values. */ - qlge_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr, - INTR_STATES_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->intr_states), - "INTR States"); - qlge_get_intr_states(qdev, &mpi_coredump->intr_states[0]); - - qlge_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr, - CAM_ENTRIES_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->cam_entries), - "CAM Entries"); - status = qlge_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]); - if (status) - return; - - qlge_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr, - ROUTING_WORDS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->nic_routing_words), - "Routing Words"); - status = qlge_get_routing_entries(qdev, - &mpi_coredump->nic_routing_words[0]); - if (status) - return; - - /* Segment 34 (Rev C. step 23) */ - qlge_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr, - ETS_SEG_NUM, - sizeof(struct mpi_coredump_segment_header) - + sizeof(mpi_coredump->ets), - "ETS Registers"); - status = qlge_get_ets_regs(qdev, &mpi_coredump->ets[0]); - if (status) - return; -} - -void qlge_get_dump(struct qlge_adapter *qdev, void *buff) -{ - /* - * If the dump has already been taken and is stored - * in our internal buffer and if force dump is set then - * just start the spool to dump it to the log file - * and also, take a snapshot of the general regs - * to the user's buffer or else take complete dump - * to the user's buffer if force is not set. - */ - - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) { - if (!qlge_core_dump(qdev, buff)) - qlge_soft_reset_mpi_risc(qdev); - else - netif_err(qdev, drv, qdev->ndev, "coredump failed!\n"); - } else { - qlge_gen_reg_dump(qdev, buff); - qlge_get_core_dump(qdev); - } -} diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c deleted file mode 100644 index 0b19363ca2e9..000000000000 --- a/drivers/staging/qlge/qlge_devlink.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#include "qlge.h" -#include "qlge_devlink.h" - -static void qlge_fill_seg_(struct devlink_fmsg *fmsg, - struct mpi_coredump_segment_header *seg_header, - u32 *reg_data) -{ - int regs_num = (seg_header->seg_size - - sizeof(struct mpi_coredump_segment_header)) / sizeof(u32); - int i; - - devlink_fmsg_pair_nest_start(fmsg, seg_header->description); - devlink_fmsg_obj_nest_start(fmsg); - devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); - devlink_fmsg_arr_pair_nest_start(fmsg, "values"); - for (i = 0; i < regs_num; i++) { - devlink_fmsg_u32_put(fmsg, *reg_data); - reg_data++; - } - devlink_fmsg_obj_nest_end(fmsg); - devlink_fmsg_arr_pair_nest_end(fmsg); - devlink_fmsg_pair_nest_end(fmsg); -} - -#define FILL_SEG(seg_hdr, seg_regs) \ - qlge_fill_seg_(fmsg, &dump->seg_hdr, dump->seg_regs) - -static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) -{ - int err = 0; - - struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); - struct qlge_mpi_coredump *dump; - wait_queue_head_t wait; - - if (!netif_running(qdev->ndev)) - return 0; - - if (test_bit(QL_FRC_COREDUMP, &qdev->flags)) { - if (qlge_own_firmware(qdev)) { - qlge_queue_fw_error(qdev); - init_waitqueue_head(&wait); - wait_event_timeout(wait, 0, 5 * HZ); - } else { - netif_err(qdev, ifup, qdev->ndev, - "Force Coredump failed because this NIC function doesn't own the firmware\n"); - return -EPERM; - } - } - - dump = kvmalloc(sizeof(*dump), GFP_KERNEL); - if (!dump) - return -ENOMEM; - - err = qlge_core_dump(qdev, dump); - if (err) { - kvfree(dump); - return err; - } - - qlge_soft_reset_mpi_risc(qdev); - - FILL_SEG(core_regs_seg_hdr, mpi_core_regs); - FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs); - FILL_SEG(rmii_regs_seg_hdr, rmii_regs); - FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs); - FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs); - FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); - FILL_SEG(ide_regs_seg_hdr, ide_regs); - FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); - FILL_SEG(smbus_regs_seg_hdr, smbus_regs); - FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); - FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); - FILL_SEG(i2c_regs_seg_hdr, i2c_regs); - FILL_SEG(memc_regs_seg_hdr, memc_regs); - FILL_SEG(pbus_regs_seg_hdr, pbus_regs); - FILL_SEG(mde_regs_seg_hdr, mde_regs); - FILL_SEG(nic_regs_seg_hdr, nic_regs); - FILL_SEG(nic2_regs_seg_hdr, nic2_regs); - FILL_SEG(xgmac1_seg_hdr, xgmac1); - FILL_SEG(xgmac2_seg_hdr, xgmac2); - FILL_SEG(code_ram_seg_hdr, code_ram); - FILL_SEG(memc_ram_seg_hdr, memc_ram); - FILL_SEG(xaui_an_hdr, serdes_xaui_an); - FILL_SEG(xaui_hss_pcs_hdr, serdes_xaui_hss_pcs); - FILL_SEG(xfi_an_hdr, serdes_xfi_an); - FILL_SEG(xfi_train_hdr, serdes_xfi_train); - FILL_SEG(xfi_hss_pcs_hdr, serdes_xfi_hss_pcs); - FILL_SEG(xfi_hss_tx_hdr, serdes_xfi_hss_tx); - FILL_SEG(xfi_hss_rx_hdr, serdes_xfi_hss_rx); - FILL_SEG(xfi_hss_pll_hdr, serdes_xfi_hss_pll); - qlge_fill_seg_(fmsg, &dump->misc_nic_seg_hdr, - (u32 *)&dump->misc_nic_info); - FILL_SEG(intr_states_seg_hdr, intr_states); - FILL_SEG(cam_entries_seg_hdr, cam_entries); - FILL_SEG(nic_routing_words_seg_hdr, nic_routing_words); - FILL_SEG(ets_seg_hdr, ets); - FILL_SEG(probe_dump_seg_hdr, probe_dump); - FILL_SEG(routing_reg_seg_hdr, routing_regs); - FILL_SEG(mac_prot_reg_seg_hdr, mac_prot_regs); - FILL_SEG(xaui2_an_hdr, serdes2_xaui_an); - FILL_SEG(xaui2_hss_pcs_hdr, serdes2_xaui_hss_pcs); - FILL_SEG(xfi2_an_hdr, serdes2_xfi_an); - FILL_SEG(xfi2_train_hdr, serdes2_xfi_train); - FILL_SEG(xfi2_hss_pcs_hdr, serdes2_xfi_hss_pcs); - FILL_SEG(xfi2_hss_tx_hdr, serdes2_xfi_hss_tx); - FILL_SEG(xfi2_hss_rx_hdr, serdes2_xfi_hss_rx); - FILL_SEG(xfi2_hss_pll_hdr, serdes2_xfi_hss_pll); - FILL_SEG(sem_regs_seg_hdr, sem_regs); - - kvfree(dump); - return 0; -} - -static const struct devlink_health_reporter_ops qlge_reporter_ops = { - .name = "coredump", - .dump = qlge_reporter_coredump, -}; - -long qlge_health_create_reporters(struct qlge_adapter *priv) -{ - struct devlink *devlink; - long err = 0; - - devlink = priv_to_devlink(priv); - priv->reporter = - devlink_health_reporter_create(devlink, &qlge_reporter_ops, - 0, priv); - if (IS_ERR(priv->reporter)) { - err = PTR_ERR(priv->reporter); - netdev_warn(priv->ndev, - "Failed to create reporter, err = %ld\n", - err); - } - return err; -} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h deleted file mode 100644 index 94538e923f2f..000000000000 --- a/drivers/staging/qlge/qlge_devlink.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef QLGE_DEVLINK_H -#define QLGE_DEVLINK_H - -#include - -long qlge_health_create_reporters(struct qlge_adapter *priv); - -#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c deleted file mode 100644 index 12efcd1057ba..000000000000 --- a/drivers/staging/qlge/qlge_ethtool.c +++ /dev/null @@ -1,746 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qlge.h" - -struct qlge_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; - -#define QL_SIZEOF(m) sizeof_field(struct qlge_adapter, m) -#define QL_OFF(m) offsetof(struct qlge_adapter, m) - -static const struct qlge_stats qlge_gstrings_stats[] = { - {"tx_pkts", QL_SIZEOF(nic_stats.tx_pkts), QL_OFF(nic_stats.tx_pkts)}, - {"tx_bytes", QL_SIZEOF(nic_stats.tx_bytes), QL_OFF(nic_stats.tx_bytes)}, - {"tx_mcast_pkts", QL_SIZEOF(nic_stats.tx_mcast_pkts), - QL_OFF(nic_stats.tx_mcast_pkts)}, - {"tx_bcast_pkts", QL_SIZEOF(nic_stats.tx_bcast_pkts), - QL_OFF(nic_stats.tx_bcast_pkts)}, - {"tx_ucast_pkts", QL_SIZEOF(nic_stats.tx_ucast_pkts), - QL_OFF(nic_stats.tx_ucast_pkts)}, - {"tx_ctl_pkts", QL_SIZEOF(nic_stats.tx_ctl_pkts), - QL_OFF(nic_stats.tx_ctl_pkts)}, - {"tx_pause_pkts", QL_SIZEOF(nic_stats.tx_pause_pkts), - QL_OFF(nic_stats.tx_pause_pkts)}, - {"tx_64_pkts", QL_SIZEOF(nic_stats.tx_64_pkt), - QL_OFF(nic_stats.tx_64_pkt)}, - {"tx_65_to_127_pkts", QL_SIZEOF(nic_stats.tx_65_to_127_pkt), - QL_OFF(nic_stats.tx_65_to_127_pkt)}, - {"tx_128_to_255_pkts", QL_SIZEOF(nic_stats.tx_128_to_255_pkt), - QL_OFF(nic_stats.tx_128_to_255_pkt)}, - {"tx_256_511_pkts", QL_SIZEOF(nic_stats.tx_256_511_pkt), - QL_OFF(nic_stats.tx_256_511_pkt)}, - {"tx_512_to_1023_pkts", QL_SIZEOF(nic_stats.tx_512_to_1023_pkt), - QL_OFF(nic_stats.tx_512_to_1023_pkt)}, - {"tx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.tx_1024_to_1518_pkt), - QL_OFF(nic_stats.tx_1024_to_1518_pkt)}, - {"tx_1519_to_max_pkts", QL_SIZEOF(nic_stats.tx_1519_to_max_pkt), - QL_OFF(nic_stats.tx_1519_to_max_pkt)}, - {"tx_undersize_pkts", QL_SIZEOF(nic_stats.tx_undersize_pkt), - QL_OFF(nic_stats.tx_undersize_pkt)}, - {"tx_oversize_pkts", QL_SIZEOF(nic_stats.tx_oversize_pkt), - QL_OFF(nic_stats.tx_oversize_pkt)}, - {"rx_bytes", QL_SIZEOF(nic_stats.rx_bytes), QL_OFF(nic_stats.rx_bytes)}, - {"rx_bytes_ok", QL_SIZEOF(nic_stats.rx_bytes_ok), - QL_OFF(nic_stats.rx_bytes_ok)}, - {"rx_pkts", QL_SIZEOF(nic_stats.rx_pkts), QL_OFF(nic_stats.rx_pkts)}, - {"rx_pkts_ok", QL_SIZEOF(nic_stats.rx_pkts_ok), - QL_OFF(nic_stats.rx_pkts_ok)}, - {"rx_bcast_pkts", QL_SIZEOF(nic_stats.rx_bcast_pkts), - QL_OFF(nic_stats.rx_bcast_pkts)}, - {"rx_mcast_pkts", QL_SIZEOF(nic_stats.rx_mcast_pkts), - QL_OFF(nic_stats.rx_mcast_pkts)}, - {"rx_ucast_pkts", QL_SIZEOF(nic_stats.rx_ucast_pkts), - QL_OFF(nic_stats.rx_ucast_pkts)}, - {"rx_undersize_pkts", QL_SIZEOF(nic_stats.rx_undersize_pkts), - QL_OFF(nic_stats.rx_undersize_pkts)}, - {"rx_oversize_pkts", QL_SIZEOF(nic_stats.rx_oversize_pkts), - QL_OFF(nic_stats.rx_oversize_pkts)}, - {"rx_jabber_pkts", QL_SIZEOF(nic_stats.rx_jabber_pkts), - QL_OFF(nic_stats.rx_jabber_pkts)}, - {"rx_undersize_fcerr_pkts", - QL_SIZEOF(nic_stats.rx_undersize_fcerr_pkts), - QL_OFF(nic_stats.rx_undersize_fcerr_pkts)}, - {"rx_drop_events", QL_SIZEOF(nic_stats.rx_drop_events), - QL_OFF(nic_stats.rx_drop_events)}, - {"rx_fcerr_pkts", QL_SIZEOF(nic_stats.rx_fcerr_pkts), - QL_OFF(nic_stats.rx_fcerr_pkts)}, - {"rx_align_err", QL_SIZEOF(nic_stats.rx_align_err), - QL_OFF(nic_stats.rx_align_err)}, - {"rx_symbol_err", QL_SIZEOF(nic_stats.rx_symbol_err), - QL_OFF(nic_stats.rx_symbol_err)}, - {"rx_mac_err", QL_SIZEOF(nic_stats.rx_mac_err), - QL_OFF(nic_stats.rx_mac_err)}, - {"rx_ctl_pkts", QL_SIZEOF(nic_stats.rx_ctl_pkts), - QL_OFF(nic_stats.rx_ctl_pkts)}, - {"rx_pause_pkts", QL_SIZEOF(nic_stats.rx_pause_pkts), - QL_OFF(nic_stats.rx_pause_pkts)}, - {"rx_64_pkts", QL_SIZEOF(nic_stats.rx_64_pkts), - QL_OFF(nic_stats.rx_64_pkts)}, - {"rx_65_to_127_pkts", QL_SIZEOF(nic_stats.rx_65_to_127_pkts), - QL_OFF(nic_stats.rx_65_to_127_pkts)}, - {"rx_128_255_pkts", QL_SIZEOF(nic_stats.rx_128_255_pkts), - QL_OFF(nic_stats.rx_128_255_pkts)}, - {"rx_256_511_pkts", QL_SIZEOF(nic_stats.rx_256_511_pkts), - QL_OFF(nic_stats.rx_256_511_pkts)}, - {"rx_512_to_1023_pkts", QL_SIZEOF(nic_stats.rx_512_to_1023_pkts), - QL_OFF(nic_stats.rx_512_to_1023_pkts)}, - {"rx_1024_to_1518_pkts", QL_SIZEOF(nic_stats.rx_1024_to_1518_pkts), - QL_OFF(nic_stats.rx_1024_to_1518_pkts)}, - {"rx_1519_to_max_pkts", QL_SIZEOF(nic_stats.rx_1519_to_max_pkts), - QL_OFF(nic_stats.rx_1519_to_max_pkts)}, - {"rx_len_err_pkts", QL_SIZEOF(nic_stats.rx_len_err_pkts), - QL_OFF(nic_stats.rx_len_err_pkts)}, - {"rx_code_err", QL_SIZEOF(nic_stats.rx_code_err), - QL_OFF(nic_stats.rx_code_err)}, - {"rx_oversize_err", QL_SIZEOF(nic_stats.rx_oversize_err), - QL_OFF(nic_stats.rx_oversize_err)}, - {"rx_undersize_err", QL_SIZEOF(nic_stats.rx_undersize_err), - QL_OFF(nic_stats.rx_undersize_err)}, - {"rx_preamble_err", QL_SIZEOF(nic_stats.rx_preamble_err), - QL_OFF(nic_stats.rx_preamble_err)}, - {"rx_frame_len_err", QL_SIZEOF(nic_stats.rx_frame_len_err), - QL_OFF(nic_stats.rx_frame_len_err)}, - {"rx_crc_err", QL_SIZEOF(nic_stats.rx_crc_err), - QL_OFF(nic_stats.rx_crc_err)}, - {"rx_err_count", QL_SIZEOF(nic_stats.rx_err_count), - QL_OFF(nic_stats.rx_err_count)}, - {"tx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames0), - QL_OFF(nic_stats.tx_cbfc_pause_frames0)}, - {"tx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames1), - QL_OFF(nic_stats.tx_cbfc_pause_frames1)}, - {"tx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames2), - QL_OFF(nic_stats.tx_cbfc_pause_frames2)}, - {"tx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames3), - QL_OFF(nic_stats.tx_cbfc_pause_frames3)}, - {"tx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames4), - QL_OFF(nic_stats.tx_cbfc_pause_frames4)}, - {"tx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames5), - QL_OFF(nic_stats.tx_cbfc_pause_frames5)}, - {"tx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames6), - QL_OFF(nic_stats.tx_cbfc_pause_frames6)}, - {"tx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.tx_cbfc_pause_frames7), - QL_OFF(nic_stats.tx_cbfc_pause_frames7)}, - {"rx_cbfc_pause_frames0", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames0), - QL_OFF(nic_stats.rx_cbfc_pause_frames0)}, - {"rx_cbfc_pause_frames1", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames1), - QL_OFF(nic_stats.rx_cbfc_pause_frames1)}, - {"rx_cbfc_pause_frames2", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames2), - QL_OFF(nic_stats.rx_cbfc_pause_frames2)}, - {"rx_cbfc_pause_frames3", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames3), - QL_OFF(nic_stats.rx_cbfc_pause_frames3)}, - {"rx_cbfc_pause_frames4", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames4), - QL_OFF(nic_stats.rx_cbfc_pause_frames4)}, - {"rx_cbfc_pause_frames5", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames5), - QL_OFF(nic_stats.rx_cbfc_pause_frames5)}, - {"rx_cbfc_pause_frames6", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames6), - QL_OFF(nic_stats.rx_cbfc_pause_frames6)}, - {"rx_cbfc_pause_frames7", QL_SIZEOF(nic_stats.rx_cbfc_pause_frames7), - QL_OFF(nic_stats.rx_cbfc_pause_frames7)}, - {"rx_nic_fifo_drop", QL_SIZEOF(nic_stats.rx_nic_fifo_drop), - QL_OFF(nic_stats.rx_nic_fifo_drop)}, -}; - -static const char qlge_gstrings_test[][ETH_GSTRING_LEN] = { - "Loopback test (offline)" -}; - -#define QLGE_TEST_LEN (sizeof(qlge_gstrings_test) / ETH_GSTRING_LEN) -#define QLGE_STATS_LEN ARRAY_SIZE(qlge_gstrings_stats) -#define QLGE_RCV_MAC_ERR_STATS 7 - -static int qlge_update_ring_coalescing(struct qlge_adapter *qdev) -{ - int i, status = 0; - struct rx_ring *rx_ring; - struct cqicb *cqicb; - - if (!netif_running(qdev->ndev)) - return status; - - /* Skip the default queue, and update the outbound handler - * queues if they changed. - */ - cqicb = (struct cqicb *)&qdev->rx_ring[qdev->rss_ring_count]; - if (le16_to_cpu(cqicb->irq_delay) != qdev->tx_coalesce_usecs || - le16_to_cpu(cqicb->pkt_delay) != qdev->tx_max_coalesced_frames) { - for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) { - rx_ring = &qdev->rx_ring[i]; - cqicb = (struct cqicb *)rx_ring; - cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs); - cqicb->pkt_delay = - cpu_to_le16(qdev->tx_max_coalesced_frames); - cqicb->flags = FLAGS_LI; - status = qlge_write_cfg(qdev, cqicb, sizeof(*cqicb), - CFG_LCQ, rx_ring->cq_id); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to load CQICB.\n"); - goto exit; - } - } - } - - /* Update the inbound (RSS) handler queues if they changed. */ - cqicb = (struct cqicb *)&qdev->rx_ring[0]; - if (le16_to_cpu(cqicb->irq_delay) != qdev->rx_coalesce_usecs || - le16_to_cpu(cqicb->pkt_delay) != qdev->rx_max_coalesced_frames) { - for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) { - rx_ring = &qdev->rx_ring[i]; - cqicb = (struct cqicb *)rx_ring; - cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs); - cqicb->pkt_delay = - cpu_to_le16(qdev->rx_max_coalesced_frames); - cqicb->flags = FLAGS_LI; - status = qlge_write_cfg(qdev, cqicb, sizeof(*cqicb), - CFG_LCQ, rx_ring->cq_id); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to load CQICB.\n"); - goto exit; - } - } - } -exit: - return status; -} - -static void qlge_update_stats(struct qlge_adapter *qdev) -{ - u32 i; - u64 data; - u64 *iter = &qdev->nic_stats.tx_pkts; - - spin_lock(&qdev->stats_lock); - if (qlge_sem_spinlock(qdev, qdev->xg_sem_mask)) { - netif_err(qdev, drv, qdev->ndev, - "Couldn't get xgmac sem.\n"); - goto quit; - } - /* - * Get TX statistics. - */ - for (i = 0x200; i < 0x280; i += 8) { - if (qlge_read_xgmac_reg64(qdev, i, &data)) { - netif_err(qdev, drv, qdev->ndev, - "Error reading status register 0x%.04x.\n", - i); - goto end; - } else { - *iter = data; - } - iter++; - } - - /* - * Get RX statistics. - */ - for (i = 0x300; i < 0x3d0; i += 8) { - if (qlge_read_xgmac_reg64(qdev, i, &data)) { - netif_err(qdev, drv, qdev->ndev, - "Error reading status register 0x%.04x.\n", - i); - goto end; - } else { - *iter = data; - } - iter++; - } - - /* Update receive mac error statistics */ - iter += QLGE_RCV_MAC_ERR_STATS; - - /* - * Get Per-priority TX pause frame counter statistics. - */ - for (i = 0x500; i < 0x540; i += 8) { - if (qlge_read_xgmac_reg64(qdev, i, &data)) { - netif_err(qdev, drv, qdev->ndev, - "Error reading status register 0x%.04x.\n", - i); - goto end; - } else { - *iter = data; - } - iter++; - } - - /* - * Get Per-priority RX pause frame counter statistics. - */ - for (i = 0x568; i < 0x5a8; i += 8) { - if (qlge_read_xgmac_reg64(qdev, i, &data)) { - netif_err(qdev, drv, qdev->ndev, - "Error reading status register 0x%.04x.\n", - i); - goto end; - } else { - *iter = data; - } - iter++; - } - - /* - * Get RX NIC FIFO DROP statistics. - */ - if (qlge_read_xgmac_reg64(qdev, 0x5b8, &data)) { - netif_err(qdev, drv, qdev->ndev, - "Error reading status register 0x%.04x.\n", i); - goto end; - } else { - *iter = data; - } -end: - qlge_sem_unlock(qdev, qdev->xg_sem_mask); -quit: - spin_unlock(&qdev->stats_lock); -} - -static void qlge_get_strings(struct net_device *dev, u32 stringset, u8 *buf) -{ - int index; - - switch (stringset) { - case ETH_SS_TEST: - memcpy(buf, *qlge_gstrings_test, QLGE_TEST_LEN * ETH_GSTRING_LEN); - break; - case ETH_SS_STATS: - for (index = 0; index < QLGE_STATS_LEN; index++) { - memcpy(buf + index * ETH_GSTRING_LEN, - qlge_gstrings_stats[index].stat_string, - ETH_GSTRING_LEN); - } - break; - } -} - -static int qlge_get_sset_count(struct net_device *dev, int sset) -{ - switch (sset) { - case ETH_SS_TEST: - return QLGE_TEST_LEN; - case ETH_SS_STATS: - return QLGE_STATS_LEN; - default: - return -EOPNOTSUPP; - } -} - -static void -qlge_get_ethtool_stats(struct net_device *ndev, - struct ethtool_stats *stats, u64 *data) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int index, length; - - length = QLGE_STATS_LEN; - qlge_update_stats(qdev); - - for (index = 0; index < length; index++) { - char *p = (char *)qdev + - qlge_gstrings_stats[index].stat_offset; - *data++ = (qlge_gstrings_stats[index].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : (*(u32 *)p); - } -} - -static int qlge_get_link_ksettings(struct net_device *ndev, - struct ethtool_link_ksettings *ecmd) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - u32 supported, advertising; - - supported = SUPPORTED_10000baseT_Full; - advertising = ADVERTISED_10000baseT_Full; - - if ((qdev->link_status & STS_LINK_TYPE_MASK) == - STS_LINK_TYPE_10GBASET) { - supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); - advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); - ecmd->base.port = PORT_TP; - ecmd->base.autoneg = AUTONEG_ENABLE; - } else { - supported |= SUPPORTED_FIBRE; - advertising |= ADVERTISED_FIBRE; - ecmd->base.port = PORT_FIBRE; - } - - ecmd->base.speed = SPEED_10000; - ecmd->base.duplex = DUPLEX_FULL; - - ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported, - supported); - ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising, - advertising); - - return 0; -} - -static void qlge_get_drvinfo(struct net_device *ndev, - struct ethtool_drvinfo *drvinfo) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - strscpy(drvinfo->driver, qlge_driver_name, sizeof(drvinfo->driver)); - strscpy(drvinfo->version, qlge_driver_version, - sizeof(drvinfo->version)); - snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "v%d.%d.%d", - (qdev->fw_rev_id & 0x00ff0000) >> 16, - (qdev->fw_rev_id & 0x0000ff00) >> 8, - (qdev->fw_rev_id & 0x000000ff)); - strscpy(drvinfo->bus_info, pci_name(qdev->pdev), - sizeof(drvinfo->bus_info)); -} - -static void qlge_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - unsigned short ssys_dev = qdev->pdev->subsystem_device; - - /* WOL is only supported for mezz card. */ - if (ssys_dev == QLGE_MEZZ_SSYS_ID_068 || - ssys_dev == QLGE_MEZZ_SSYS_ID_180) { - wol->supported = WAKE_MAGIC; - wol->wolopts = qdev->wol; - } -} - -static int qlge_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - unsigned short ssys_dev = qdev->pdev->subsystem_device; - - /* WOL is only supported for mezz card. */ - if (ssys_dev != QLGE_MEZZ_SSYS_ID_068 && - ssys_dev != QLGE_MEZZ_SSYS_ID_180) { - netif_info(qdev, drv, qdev->ndev, - "WOL is only supported for mezz card\n"); - return -EOPNOTSUPP; - } - if (wol->wolopts & ~WAKE_MAGIC) - return -EINVAL; - qdev->wol = wol->wolopts; - - netif_info(qdev, drv, qdev->ndev, "Set wol option 0x%x\n", qdev->wol); - return 0; -} - -static int qlge_set_phys_id(struct net_device *ndev, - enum ethtool_phys_id_state state) - -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - switch (state) { - case ETHTOOL_ID_ACTIVE: - /* Save the current LED settings */ - if (qlge_mb_get_led_cfg(qdev)) - return -EIO; - - /* Start blinking */ - qlge_mb_set_led_cfg(qdev, QL_LED_BLINK); - return 0; - - case ETHTOOL_ID_INACTIVE: - /* Restore LED settings */ - if (qlge_mb_set_led_cfg(qdev, qdev->led_config)) - return -EIO; - return 0; - - default: - return -EINVAL; - } -} - -static int qlge_start_loopback(struct qlge_adapter *qdev) -{ - if (netif_carrier_ok(qdev->ndev)) { - set_bit(QL_LB_LINK_UP, &qdev->flags); - netif_carrier_off(qdev->ndev); - } else { - clear_bit(QL_LB_LINK_UP, &qdev->flags); - } - qdev->link_config |= CFG_LOOPBACK_PCS; - return qlge_mb_set_port_cfg(qdev); -} - -static void qlge_stop_loopback(struct qlge_adapter *qdev) -{ - qdev->link_config &= ~CFG_LOOPBACK_PCS; - qlge_mb_set_port_cfg(qdev); - if (test_bit(QL_LB_LINK_UP, &qdev->flags)) { - netif_carrier_on(qdev->ndev); - clear_bit(QL_LB_LINK_UP, &qdev->flags); - } -} - -static void qlge_create_lb_frame(struct sk_buff *skb, - unsigned int frame_size) -{ - memset(skb->data, 0xFF, frame_size); - frame_size &= ~1; - memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); - skb->data[frame_size / 2 + 10] = (unsigned char)0xBE; - skb->data[frame_size / 2 + 12] = (unsigned char)0xAF; -} - -void qlge_check_lb_frame(struct qlge_adapter *qdev, - struct sk_buff *skb) -{ - unsigned int frame_size = skb->len; - - if ((*(skb->data + 3) == 0xFF) && - (*(skb->data + frame_size / 2 + 10) == 0xBE) && - (*(skb->data + frame_size / 2 + 12) == 0xAF)) { - atomic_dec(&qdev->lb_count); - return; - } -} - -static int qlge_run_loopback_test(struct qlge_adapter *qdev) -{ - int i; - netdev_tx_t rc; - struct sk_buff *skb; - unsigned int size = SMALL_BUF_MAP_SIZE; - - for (i = 0; i < 64; i++) { - skb = netdev_alloc_skb(qdev->ndev, size); - if (!skb) - return -ENOMEM; - - skb->queue_mapping = 0; - skb_put(skb, size); - qlge_create_lb_frame(skb, size); - rc = qlge_lb_send(skb, qdev->ndev); - if (rc != NETDEV_TX_OK) - return -EPIPE; - atomic_inc(&qdev->lb_count); - } - /* Give queue time to settle before testing results. */ - usleep_range(2000, 2100); - qlge_clean_lb_rx_ring(&qdev->rx_ring[0], 128); - return atomic_read(&qdev->lb_count) ? -EIO : 0; -} - -static int qlge_loopback_test(struct qlge_adapter *qdev, u64 *data) -{ - *data = qlge_start_loopback(qdev); - if (*data) - goto out; - *data = qlge_run_loopback_test(qdev); -out: - qlge_stop_loopback(qdev); - return *data; -} - -static void qlge_self_test(struct net_device *ndev, - struct ethtool_test *eth_test, u64 *data) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - memset(data, 0, sizeof(u64) * QLGE_TEST_LEN); - - if (netif_running(ndev)) { - set_bit(QL_SELFTEST, &qdev->flags); - if (eth_test->flags == ETH_TEST_FL_OFFLINE) { - /* Offline tests */ - if (qlge_loopback_test(qdev, &data[0])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - } else { - /* Online tests */ - data[0] = 0; - } - clear_bit(QL_SELFTEST, &qdev->flags); - /* Give link time to come up after - * port configuration changes. - */ - msleep_interruptible(4 * 1000); - } else { - netif_err(qdev, drv, qdev->ndev, - "is down, Loopback test will fail.\n"); - eth_test->flags |= ETH_TEST_FL_FAILED; - } -} - -static int qlge_get_regs_len(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) - return sizeof(struct qlge_mpi_coredump); - else - return sizeof(struct qlge_reg_dump); -} - -static void qlge_get_regs(struct net_device *ndev, - struct ethtool_regs *regs, void *p) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - qlge_get_dump(qdev, p); - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) - regs->len = sizeof(struct qlge_mpi_coredump); - else - regs->len = sizeof(struct qlge_reg_dump); -} - -static int qlge_get_coalesce(struct net_device *ndev, - struct ethtool_coalesce *c, - struct kernel_ethtool_coalesce *kernel_coal, - struct netlink_ext_ack *extack) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - c->rx_coalesce_usecs = qdev->rx_coalesce_usecs; - c->tx_coalesce_usecs = qdev->tx_coalesce_usecs; - - /* This chip coalesces as follows: - * If a packet arrives, hold off interrupts until - * cqicb->int_delay expires, but if no other packets arrive don't - * wait longer than cqicb->pkt_int_delay. But ethtool doesn't use a - * timer to coalesce on a frame basis. So, we have to take ethtool's - * max_coalesced_frames value and convert it to a delay in microseconds. - * We do this by using a basic thoughput of 1,000,000 frames per - * second @ (1024 bytes). This means one frame per usec. So it's a - * simple one to one ratio. - */ - c->rx_max_coalesced_frames = qdev->rx_max_coalesced_frames; - c->tx_max_coalesced_frames = qdev->tx_max_coalesced_frames; - - return 0; -} - -static int qlge_set_coalesce(struct net_device *ndev, - struct ethtool_coalesce *c, - struct kernel_ethtool_coalesce *kernel_coal, - struct netlink_ext_ack *extack) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - /* Validate user parameters. */ - if (c->rx_coalesce_usecs > qdev->rx_ring_size / 2) - return -EINVAL; - /* Don't wait more than 10 usec. */ - if (c->rx_max_coalesced_frames > MAX_INTER_FRAME_WAIT) - return -EINVAL; - if (c->tx_coalesce_usecs > qdev->tx_ring_size / 2) - return -EINVAL; - if (c->tx_max_coalesced_frames > MAX_INTER_FRAME_WAIT) - return -EINVAL; - - /* Verify a change took place before updating the hardware. */ - if (qdev->rx_coalesce_usecs == c->rx_coalesce_usecs && - qdev->tx_coalesce_usecs == c->tx_coalesce_usecs && - qdev->rx_max_coalesced_frames == c->rx_max_coalesced_frames && - qdev->tx_max_coalesced_frames == c->tx_max_coalesced_frames) - return 0; - - qdev->rx_coalesce_usecs = c->rx_coalesce_usecs; - qdev->tx_coalesce_usecs = c->tx_coalesce_usecs; - qdev->rx_max_coalesced_frames = c->rx_max_coalesced_frames; - qdev->tx_max_coalesced_frames = c->tx_max_coalesced_frames; - - return qlge_update_ring_coalescing(qdev); -} - -static void qlge_get_pauseparam(struct net_device *ndev, - struct ethtool_pauseparam *pause) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - qlge_mb_get_port_cfg(qdev); - if (qdev->link_config & CFG_PAUSE_STD) { - pause->rx_pause = 1; - pause->tx_pause = 1; - } -} - -static int qlge_set_pauseparam(struct net_device *ndev, - struct ethtool_pauseparam *pause) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - if ((pause->rx_pause) && (pause->tx_pause)) - qdev->link_config |= CFG_PAUSE_STD; - else if (!pause->rx_pause && !pause->tx_pause) - qdev->link_config &= ~CFG_PAUSE_STD; - else - return -EINVAL; - - return qlge_mb_set_port_cfg(qdev); -} - -static u32 qlge_get_msglevel(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - return qdev->msg_enable; -} - -static void qlge_set_msglevel(struct net_device *ndev, u32 value) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - qdev->msg_enable = value; -} - -const struct ethtool_ops qlge_ethtool_ops = { - .supported_coalesce_params = ETHTOOL_COALESCE_USECS | - ETHTOOL_COALESCE_MAX_FRAMES, - .get_drvinfo = qlge_get_drvinfo, - .get_wol = qlge_get_wol, - .set_wol = qlge_set_wol, - .get_regs_len = qlge_get_regs_len, - .get_regs = qlge_get_regs, - .get_msglevel = qlge_get_msglevel, - .set_msglevel = qlge_set_msglevel, - .get_link = ethtool_op_get_link, - .set_phys_id = qlge_set_phys_id, - .self_test = qlge_self_test, - .get_pauseparam = qlge_get_pauseparam, - .set_pauseparam = qlge_set_pauseparam, - .get_coalesce = qlge_get_coalesce, - .set_coalesce = qlge_set_coalesce, - .get_sset_count = qlge_get_sset_count, - .get_strings = qlge_get_strings, - .get_ethtool_stats = qlge_get_ethtool_stats, - .get_link_ksettings = qlge_get_link_ksettings, -}; - diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c deleted file mode 100644 index 1ead7793062a..000000000000 --- a/drivers/staging/qlge/qlge_main.c +++ /dev/null @@ -1,4845 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * QLogic qlge NIC HBA Driver - * Copyright (c) 2003-2008 QLogic Corporation - * Author: Linux qlge network device driver by - * Ron Mercer - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qlge.h" -#include "qlge_devlink.h" - -char qlge_driver_name[] = DRV_NAME; -const char qlge_driver_version[] = DRV_VERSION; - -MODULE_AUTHOR("Ron Mercer "); -MODULE_DESCRIPTION(DRV_STRING " "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -static const u32 default_msg = - NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | - NETIF_MSG_IFDOWN | - NETIF_MSG_IFUP | - NETIF_MSG_RX_ERR | - NETIF_MSG_TX_ERR | - NETIF_MSG_HW | NETIF_MSG_WOL | 0; - -static int debug = -1; /* defaults above */ -module_param(debug, int, 0664); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -#define MSIX_IRQ 0 -#define MSI_IRQ 1 -#define LEG_IRQ 2 -static int qlge_irq_type = MSIX_IRQ; -module_param(qlge_irq_type, int, 0664); -MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); - -static int qlge_mpi_coredump; -module_param(qlge_mpi_coredump, int, 0); -MODULE_PARM_DESC(qlge_mpi_coredump, - "Option to enable MPI firmware dump. Default is OFF - Do Not allocate memory. "); - -static int qlge_force_coredump; -module_param(qlge_force_coredump, int, 0); -MODULE_PARM_DESC(qlge_force_coredump, - "Option to allow force of firmware core dump. Default is OFF - Do not allow."); - -static const struct pci_device_id qlge_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)}, - {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)}, - /* required last entry */ - {0,} -}; - -MODULE_DEVICE_TABLE(pci, qlge_pci_tbl); - -static int qlge_wol(struct qlge_adapter *); -static void qlge_set_multicast_list(struct net_device *); -static int qlge_adapter_down(struct qlge_adapter *); -static int qlge_adapter_up(struct qlge_adapter *); - -/* This hardware semaphore causes exclusive access to - * resources shared between the NIC driver, MPI firmware, - * FCOE firmware and the FC driver. - */ -static int qlge_sem_trylock(struct qlge_adapter *qdev, u32 sem_mask) -{ - u32 sem_bits = 0; - - switch (sem_mask) { - case SEM_XGMAC0_MASK: - sem_bits = SEM_SET << SEM_XGMAC0_SHIFT; - break; - case SEM_XGMAC1_MASK: - sem_bits = SEM_SET << SEM_XGMAC1_SHIFT; - break; - case SEM_ICB_MASK: - sem_bits = SEM_SET << SEM_ICB_SHIFT; - break; - case SEM_MAC_ADDR_MASK: - sem_bits = SEM_SET << SEM_MAC_ADDR_SHIFT; - break; - case SEM_FLASH_MASK: - sem_bits = SEM_SET << SEM_FLASH_SHIFT; - break; - case SEM_PROBE_MASK: - sem_bits = SEM_SET << SEM_PROBE_SHIFT; - break; - case SEM_RT_IDX_MASK: - sem_bits = SEM_SET << SEM_RT_IDX_SHIFT; - break; - case SEM_PROC_REG_MASK: - sem_bits = SEM_SET << SEM_PROC_REG_SHIFT; - break; - default: - netif_alert(qdev, probe, qdev->ndev, "bad Semaphore mask!.\n"); - return -EINVAL; - } - - qlge_write32(qdev, SEM, sem_bits | sem_mask); - return !(qlge_read32(qdev, SEM) & sem_bits); -} - -int qlge_sem_spinlock(struct qlge_adapter *qdev, u32 sem_mask) -{ - unsigned int wait_count = 30; - - do { - if (!qlge_sem_trylock(qdev, sem_mask)) - return 0; - udelay(100); - } while (--wait_count); - return -ETIMEDOUT; -} - -void qlge_sem_unlock(struct qlge_adapter *qdev, u32 sem_mask) -{ - qlge_write32(qdev, SEM, sem_mask); - qlge_read32(qdev, SEM); /* flush */ -} - -/* This function waits for a specific bit to come ready - * in a given register. It is used mostly by the initialize - * process, but is also used in kernel thread API such as - * netdev->set_multi, netdev->set_mac_address, netdev->vlan_rx_add_vid. - */ -int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 err_bit) -{ - u32 temp; - int count; - - for (count = 0; count < UDELAY_COUNT; count++) { - temp = qlge_read32(qdev, reg); - - /* check for errors */ - if (temp & err_bit) { - netif_alert(qdev, probe, qdev->ndev, - "register 0x%.08x access error, value = 0x%.08x!.\n", - reg, temp); - return -EIO; - } else if (temp & bit) { - return 0; - } - udelay(UDELAY_DELAY); - } - netif_alert(qdev, probe, qdev->ndev, - "Timed out waiting for reg %x to come ready.\n", reg); - return -ETIMEDOUT; -} - -/* The CFG register is used to download TX and RX control blocks - * to the chip. This function waits for an operation to complete. - */ -static int qlge_wait_cfg(struct qlge_adapter *qdev, u32 bit) -{ - int count; - u32 temp; - - for (count = 0; count < UDELAY_COUNT; count++) { - temp = qlge_read32(qdev, CFG); - if (temp & CFG_LE) - return -EIO; - if (!(temp & bit)) - return 0; - udelay(UDELAY_DELAY); - } - return -ETIMEDOUT; -} - -/* Used to issue init control blocks to hw. Maps control block, - * sets address, triggers download, waits for completion. - */ -int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, int size, u32 bit, - u16 q_id) -{ - u64 map; - int status = 0; - int direction; - u32 mask; - u32 value; - - if (bit & (CFG_LRQ | CFG_LR | CFG_LCQ)) - direction = DMA_TO_DEVICE; - else - direction = DMA_FROM_DEVICE; - - map = dma_map_single(&qdev->pdev->dev, ptr, size, direction); - if (dma_mapping_error(&qdev->pdev->dev, map)) { - netif_err(qdev, ifup, qdev->ndev, "Couldn't map DMA area.\n"); - return -ENOMEM; - } - - status = qlge_sem_spinlock(qdev, SEM_ICB_MASK); - if (status) - goto lock_failed; - - status = qlge_wait_cfg(qdev, bit); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Timed out waiting for CFG to come ready.\n"); - goto exit; - } - - qlge_write32(qdev, ICB_L, (u32)map); - qlge_write32(qdev, ICB_H, (u32)(map >> 32)); - - mask = CFG_Q_MASK | (bit << 16); - value = bit | (q_id << CFG_Q_SHIFT); - qlge_write32(qdev, CFG, (mask | value)); - - /* - * Wait for the bit to clear after signaling hw. - */ - status = qlge_wait_cfg(qdev, bit); -exit: - qlge_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */ -lock_failed: - dma_unmap_single(&qdev->pdev->dev, map, size, direction); - return status; -} - -/* Get a specific MAC address from the CAM. Used for debug and reg dump. */ -int qlge_get_mac_addr_reg(struct qlge_adapter *qdev, u32 type, u16 index, - u32 *value) -{ - u32 offset = 0; - int status; - - switch (type) { - case MAC_ADDR_TYPE_MULTI_MAC: - case MAC_ADDR_TYPE_CAM_MAC: { - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - MAC_ADDR_ADR | MAC_ADDR_RS | - type); /* type */ - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MR, 0); - if (status) - break; - *value++ = qlge_read32(qdev, MAC_ADDR_DATA); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - MAC_ADDR_ADR | MAC_ADDR_RS | - type); /* type */ - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MR, 0); - if (status) - break; - *value++ = qlge_read32(qdev, MAC_ADDR_DATA); - if (type == MAC_ADDR_TYPE_CAM_MAC) { - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, - MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | /* offset */ - (index - << MAC_ADDR_IDX_SHIFT) | /* index */ - MAC_ADDR_ADR | - MAC_ADDR_RS | type); /* type */ - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, - MAC_ADDR_MR, 0); - if (status) - break; - *value++ = qlge_read32(qdev, MAC_ADDR_DATA); - } - break; - } - case MAC_ADDR_TYPE_VLAN: - case MAC_ADDR_TYPE_MULTI_FLTR: - default: - netif_crit(qdev, ifup, qdev->ndev, - "Address type %d not yet supported.\n", type); - status = -EPERM; - } - return status; -} - -/* Set up a MAC, multicast or VLAN address for the - * inbound frame matching. - */ -static int qlge_set_mac_addr_reg(struct qlge_adapter *qdev, const u8 *addr, - u32 type, u16 index) -{ - u32 offset = 0; - int status = 0; - - switch (type) { - case MAC_ADDR_TYPE_MULTI_MAC: { - u32 upper = (addr[0] << 8) | addr[1]; - u32 lower = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | - (addr[5]); - - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | (index << MAC_ADDR_IDX_SHIFT) | type | - MAC_ADDR_E); - qlge_write32(qdev, MAC_ADDR_DATA, lower); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | (index << MAC_ADDR_IDX_SHIFT) | type | - MAC_ADDR_E); - - qlge_write32(qdev, MAC_ADDR_DATA, upper); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - break; - } - case MAC_ADDR_TYPE_CAM_MAC: { - u32 cam_output; - u32 upper = (addr[0] << 8) | addr[1]; - u32 lower = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | - (addr[5]); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - type); /* type */ - qlge_write32(qdev, MAC_ADDR_DATA, lower); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset++) | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - type); /* type */ - qlge_write32(qdev, MAC_ADDR_DATA, upper); - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - (offset) | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - type); /* type */ - /* This field should also include the queue id - * and possibly the function id. Right now we hardcode - * the route field to NIC core. - */ - cam_output = (CAM_OUT_ROUTE_NIC | - (qdev->func << CAM_OUT_FUNC_SHIFT) | - (0 << CAM_OUT_CQ_ID_SHIFT)); - if (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) - cam_output |= CAM_OUT_RV; - /* route to NIC core */ - qlge_write32(qdev, MAC_ADDR_DATA, cam_output); - break; - } - case MAC_ADDR_TYPE_VLAN: { - u32 enable_bit = *((u32 *)&addr[0]); - /* For VLAN, the addr actually holds a bit that - * either enables or disables the vlan id we are - * addressing. It's either MAC_ADDR_E on or off. - * That's bit-27 we're talking about. - */ - status = qlge_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); - if (status) - break; - qlge_write32(qdev, MAC_ADDR_IDX, - offset | /* offset */ - (index << MAC_ADDR_IDX_SHIFT) | /* index */ - type | /* type */ - enable_bit); /* enable/disable */ - break; - } - case MAC_ADDR_TYPE_MULTI_FLTR: - default: - netif_crit(qdev, ifup, qdev->ndev, - "Address type %d not yet supported.\n", type); - status = -EPERM; - } - return status; -} - -/* Set or clear MAC address in hardware. We sometimes - * have to clear it to prevent wrong frame routing - * especially in a bonding environment. - */ -static int qlge_set_mac_addr(struct qlge_adapter *qdev, int set) -{ - int status; - char zero_mac_addr[ETH_ALEN]; - char *addr; - - if (set) { - addr = &qdev->current_mac_addr[0]; - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Set Mac addr %pM\n", addr); - } else { - eth_zero_addr(zero_mac_addr); - addr = &zero_mac_addr[0]; - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Clearing MAC address\n"); - } - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return status; - status = qlge_set_mac_addr_reg(qdev, (const u8 *)addr, - MAC_ADDR_TYPE_CAM_MAC, - qdev->func * MAX_CQ); - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - netif_err(qdev, ifup, qdev->ndev, - "Failed to init mac address.\n"); - return status; -} - -void qlge_link_on(struct qlge_adapter *qdev) -{ - netif_err(qdev, link, qdev->ndev, "Link is up.\n"); - netif_carrier_on(qdev->ndev); - qlge_set_mac_addr(qdev, 1); -} - -void qlge_link_off(struct qlge_adapter *qdev) -{ - netif_err(qdev, link, qdev->ndev, "Link is down.\n"); - netif_carrier_off(qdev->ndev); - qlge_set_mac_addr(qdev, 0); -} - -/* Get a specific frame routing value from the CAM. - * Used for debug and reg dump. - */ -int qlge_get_routing_reg(struct qlge_adapter *qdev, u32 index, u32 *value) -{ - int status = 0; - - status = qlge_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0); - if (status) - goto exit; - - qlge_write32(qdev, RT_IDX, - RT_IDX_TYPE_NICQ | RT_IDX_RS | (index << RT_IDX_IDX_SHIFT)); - status = qlge_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MR, 0); - if (status) - goto exit; - *value = qlge_read32(qdev, RT_DATA); -exit: - return status; -} - -/* The NIC function for this chip has 16 routing indexes. Each one can be used - * to route different frame types to various inbound queues. We send broadcast/ - * multicast/error frames to the default queue for slow handling, - * and CAM hit/RSS frames to the fast handling queues. - */ -static int qlge_set_routing_reg(struct qlge_adapter *qdev, u32 index, u32 mask, - int enable) -{ - int status = -EINVAL; /* Return error if no mask match. */ - u32 value = 0; - - switch (mask) { - case RT_IDX_CAM_HIT: - { - value = RT_IDX_DST_CAM_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_CAM_HIT_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_VALID: /* Promiscuous Mode frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_PROMISCUOUS_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_ERR: /* Pass up MAC,IP,TCP/UDP error frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_ALL_ERR_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_IP_CSUM_ERR: /* Pass up IP CSUM error frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_IP_CSUM_ERR_SLOT << - RT_IDX_IDX_SHIFT); /* index */ - break; - } - case RT_IDX_TU_CSUM_ERR: /* Pass up TCP/UDP CSUM error frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_TCP_UDP_CSUM_ERR_SLOT << - RT_IDX_IDX_SHIFT); /* index */ - break; - } - case RT_IDX_BCAST: /* Pass up Broadcast frames to default Q. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_BCAST_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_MCAST: /* Pass up All Multicast frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case RT_IDX_RSS_MATCH: /* Pass up matched RSS frames. */ - { - value = RT_IDX_DST_RSS | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (RT_IDX_RSS_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ - break; - } - case 0: /* Clear the E-bit on an entry. */ - { - value = RT_IDX_DST_DFLT_Q | /* dest */ - RT_IDX_TYPE_NICQ | /* type */ - (index << RT_IDX_IDX_SHIFT);/* index */ - break; - } - default: - netif_err(qdev, ifup, qdev->ndev, - "Mask type %d not yet supported.\n", mask); - status = -EPERM; - goto exit; - } - - if (value) { - status = qlge_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0); - if (status) - goto exit; - value |= (enable ? RT_IDX_E : 0); - qlge_write32(qdev, RT_IDX, value); - qlge_write32(qdev, RT_DATA, enable ? mask : 0); - } -exit: - return status; -} - -static void qlge_enable_interrupts(struct qlge_adapter *qdev) -{ - qlge_write32(qdev, INTR_EN, (INTR_EN_EI << 16) | INTR_EN_EI); -} - -static void qlge_disable_interrupts(struct qlge_adapter *qdev) -{ - qlge_write32(qdev, INTR_EN, (INTR_EN_EI << 16)); -} - -static void qlge_enable_completion_interrupt(struct qlge_adapter *qdev, u32 intr) -{ - struct intr_context *ctx = &qdev->intr_context[intr]; - - qlge_write32(qdev, INTR_EN, ctx->intr_en_mask); -} - -static void qlge_disable_completion_interrupt(struct qlge_adapter *qdev, u32 intr) -{ - struct intr_context *ctx = &qdev->intr_context[intr]; - - qlge_write32(qdev, INTR_EN, ctx->intr_dis_mask); -} - -static void qlge_enable_all_completion_interrupts(struct qlge_adapter *qdev) -{ - int i; - - for (i = 0; i < qdev->intr_count; i++) - qlge_enable_completion_interrupt(qdev, i); -} - -static int qlge_validate_flash(struct qlge_adapter *qdev, u32 size, const char *str) -{ - int status, i; - u16 csum = 0; - __le16 *flash = (__le16 *)&qdev->flash; - - status = strncmp((char *)&qdev->flash, str, 4); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Invalid flash signature.\n"); - return status; - } - - for (i = 0; i < size; i++) - csum += le16_to_cpu(*flash++); - - if (csum) - netif_err(qdev, ifup, qdev->ndev, - "Invalid flash checksum, csum = 0x%.04x.\n", csum); - - return csum; -} - -static int qlge_read_flash_word(struct qlge_adapter *qdev, int offset, __le32 *data) -{ - int status = 0; - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, - FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR); - if (status) - goto exit; - /* set up for reg read */ - qlge_write32(qdev, FLASH_ADDR, FLASH_ADDR_R | offset); - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, - FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR); - if (status) - goto exit; - /* This data is stored on flash as an array of - * __le32. Since qlge_read32() returns cpu endian - * we need to swap it back. - */ - *data = cpu_to_le32(qlge_read32(qdev, FLASH_DATA)); -exit: - return status; -} - -static int qlge_get_8000_flash_params(struct qlge_adapter *qdev) -{ - u32 i, size; - int status; - __le32 *p = (__le32 *)&qdev->flash; - u32 offset; - u8 mac_addr[6]; - - /* Get flash offset for function and adjust - * for dword access. - */ - if (!qdev->port) - offset = FUNC0_FLASH_OFFSET / sizeof(u32); - else - offset = FUNC1_FLASH_OFFSET / sizeof(u32); - - if (qlge_sem_spinlock(qdev, SEM_FLASH_MASK)) - return -ETIMEDOUT; - - size = sizeof(struct flash_params_8000) / sizeof(u32); - for (i = 0; i < size; i++, p++) { - status = qlge_read_flash_word(qdev, i + offset, p); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Error reading flash.\n"); - goto exit; - } - } - - status = qlge_validate_flash(qdev, - sizeof(struct flash_params_8000) / - sizeof(u16), - "8000"); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n"); - status = -EINVAL; - goto exit; - } - - /* Extract either manufacturer or BOFM modified - * MAC address. - */ - if (qdev->flash.flash_params_8000.data_type1 == 2) - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr1, - qdev->ndev->addr_len); - else - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr, - qdev->ndev->addr_len); - - if (!is_valid_ether_addr(mac_addr)) { - netif_err(qdev, ifup, qdev->ndev, "Invalid MAC address.\n"); - status = -EINVAL; - goto exit; - } - - eth_hw_addr_set(qdev->ndev, mac_addr); - -exit: - qlge_sem_unlock(qdev, SEM_FLASH_MASK); - return status; -} - -static int qlge_get_8012_flash_params(struct qlge_adapter *qdev) -{ - int i; - int status; - __le32 *p = (__le32 *)&qdev->flash; - u32 offset = 0; - u32 size = sizeof(struct flash_params_8012) / sizeof(u32); - - /* Second function's parameters follow the first - * function's. - */ - if (qdev->port) - offset = size; - - if (qlge_sem_spinlock(qdev, SEM_FLASH_MASK)) - return -ETIMEDOUT; - - for (i = 0; i < size; i++, p++) { - status = qlge_read_flash_word(qdev, i + offset, p); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Error reading flash.\n"); - goto exit; - } - } - - status = qlge_validate_flash(qdev, - sizeof(struct flash_params_8012) / - sizeof(u16), - "8012"); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Invalid flash.\n"); - status = -EINVAL; - goto exit; - } - - if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) { - status = -EINVAL; - goto exit; - } - - eth_hw_addr_set(qdev->ndev, qdev->flash.flash_params_8012.mac_addr); - -exit: - qlge_sem_unlock(qdev, SEM_FLASH_MASK); - return status; -} - -/* xgmac register are located behind the xgmac_addr and xgmac_data - * register pair. Each read/write requires us to wait for the ready - * bit before reading/writing the data. - */ -static int qlge_write_xgmac_reg(struct qlge_adapter *qdev, u32 reg, u32 data) -{ - int status; - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, - XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME); - if (status) - return status; - /* write the data to the data reg */ - qlge_write32(qdev, XGMAC_DATA, data); - /* trigger the write */ - qlge_write32(qdev, XGMAC_ADDR, reg); - return status; -} - -/* xgmac register are located behind the xgmac_addr and xgmac_data - * register pair. Each read/write requires us to wait for the ready - * bit before reading/writing the data. - */ -int qlge_read_xgmac_reg(struct qlge_adapter *qdev, u32 reg, u32 *data) -{ - int status = 0; - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, - XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME); - if (status) - goto exit; - /* set up for reg read */ - qlge_write32(qdev, XGMAC_ADDR, reg | XGMAC_ADDR_R); - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, - XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME); - if (status) - goto exit; - /* get the data */ - *data = qlge_read32(qdev, XGMAC_DATA); -exit: - return status; -} - -/* This is used for reading the 64-bit statistics regs. */ -int qlge_read_xgmac_reg64(struct qlge_adapter *qdev, u32 reg, u64 *data) -{ - int status = 0; - u32 hi = 0; - u32 lo = 0; - - status = qlge_read_xgmac_reg(qdev, reg, &lo); - if (status) - goto exit; - - status = qlge_read_xgmac_reg(qdev, reg + 4, &hi); - if (status) - goto exit; - - *data = (u64)lo | ((u64)hi << 32); - -exit: - return status; -} - -static int qlge_8000_port_initialize(struct qlge_adapter *qdev) -{ - int status; - /* - * Get MPI firmware version for driver banner - * and ethool info. - */ - status = qlge_mb_about_fw(qdev); - if (status) - goto exit; - status = qlge_mb_get_fw_state(qdev); - if (status) - goto exit; - /* Wake up a worker to get/set the TX/RX frame sizes. */ - queue_delayed_work(qdev->workqueue, &qdev->mpi_port_cfg_work, 0); -exit: - return status; -} - -/* Take the MAC Core out of reset. - * Enable statistics counting. - * Take the transmitter/receiver out of reset. - * This functionality may be done in the MPI firmware at a - * later date. - */ -static int qlge_8012_port_initialize(struct qlge_adapter *qdev) -{ - int status = 0; - u32 data; - - if (qlge_sem_trylock(qdev, qdev->xg_sem_mask)) { - /* Another function has the semaphore, so - * wait for the port init bit to come ready. - */ - netif_info(qdev, link, qdev->ndev, - "Another function has the semaphore, so wait for the port init bit to come ready.\n"); - status = qlge_wait_reg_rdy(qdev, STS, qdev->port_init, 0); - if (status) { - netif_crit(qdev, link, qdev->ndev, - "Port initialize timed out.\n"); - } - return status; - } - - netif_info(qdev, link, qdev->ndev, "Got xgmac semaphore!.\n"); - /* Set the core reset. */ - status = qlge_read_xgmac_reg(qdev, GLOBAL_CFG, &data); - if (status) - goto end; - data |= GLOBAL_CFG_RESET; - status = qlge_write_xgmac_reg(qdev, GLOBAL_CFG, data); - if (status) - goto end; - - /* Clear the core reset and turn on jumbo for receiver. */ - data &= ~GLOBAL_CFG_RESET; /* Clear core reset. */ - data |= GLOBAL_CFG_JUMBO; /* Turn on jumbo. */ - data |= GLOBAL_CFG_TX_STAT_EN; - data |= GLOBAL_CFG_RX_STAT_EN; - status = qlge_write_xgmac_reg(qdev, GLOBAL_CFG, data); - if (status) - goto end; - - /* Enable transmitter, and clear it's reset. */ - status = qlge_read_xgmac_reg(qdev, TX_CFG, &data); - if (status) - goto end; - data &= ~TX_CFG_RESET; /* Clear the TX MAC reset. */ - data |= TX_CFG_EN; /* Enable the transmitter. */ - status = qlge_write_xgmac_reg(qdev, TX_CFG, data); - if (status) - goto end; - - /* Enable receiver and clear it's reset. */ - status = qlge_read_xgmac_reg(qdev, RX_CFG, &data); - if (status) - goto end; - data &= ~RX_CFG_RESET; /* Clear the RX MAC reset. */ - data |= RX_CFG_EN; /* Enable the receiver. */ - status = qlge_write_xgmac_reg(qdev, RX_CFG, data); - if (status) - goto end; - - /* Turn on jumbo. */ - status = - qlge_write_xgmac_reg(qdev, MAC_TX_PARAMS, MAC_TX_PARAMS_JUMBO | (0x2580 << 16)); - if (status) - goto end; - status = - qlge_write_xgmac_reg(qdev, MAC_RX_PARAMS, 0x2580); - if (status) - goto end; - - /* Signal to the world that the port is enabled. */ - qlge_write32(qdev, STS, ((qdev->port_init << 16) | qdev->port_init)); -end: - qlge_sem_unlock(qdev, qdev->xg_sem_mask); - return status; -} - -static inline unsigned int qlge_lbq_block_size(struct qlge_adapter *qdev) -{ - return PAGE_SIZE << qdev->lbq_buf_order; -} - -static struct qlge_bq_desc *qlge_get_curr_buf(struct qlge_bq *bq) -{ - struct qlge_bq_desc *bq_desc; - - bq_desc = &bq->queue[bq->next_to_clean]; - bq->next_to_clean = QLGE_BQ_WRAP(bq->next_to_clean + 1); - - return bq_desc; -} - -static struct qlge_bq_desc *qlge_get_curr_lchunk(struct qlge_adapter *qdev, - struct rx_ring *rx_ring) -{ - struct qlge_bq_desc *lbq_desc = qlge_get_curr_buf(&rx_ring->lbq); - - dma_sync_single_for_cpu(&qdev->pdev->dev, lbq_desc->dma_addr, - qdev->lbq_buf_size, DMA_FROM_DEVICE); - - if ((lbq_desc->p.pg_chunk.offset + qdev->lbq_buf_size) == - qlge_lbq_block_size(qdev)) { - /* last chunk of the master page */ - dma_unmap_page(&qdev->pdev->dev, lbq_desc->dma_addr, - qlge_lbq_block_size(qdev), DMA_FROM_DEVICE); - } - - return lbq_desc; -} - -/* Update an rx ring index. */ -static void qlge_update_cq(struct rx_ring *rx_ring) -{ - rx_ring->cnsmr_idx++; - rx_ring->curr_entry++; - if (unlikely(rx_ring->cnsmr_idx == rx_ring->cq_len)) { - rx_ring->cnsmr_idx = 0; - rx_ring->curr_entry = rx_ring->cq_base; - } -} - -static void qlge_write_cq_idx(struct rx_ring *rx_ring) -{ - qlge_write_db_reg(rx_ring->cnsmr_idx, rx_ring->cnsmr_idx_db_reg); -} - -static const char * const bq_type_name[] = { - [QLGE_SB] = "sbq", - [QLGE_LB] = "lbq", -}; - -/* return 0 or negative error */ -static int qlge_refill_sb(struct rx_ring *rx_ring, - struct qlge_bq_desc *sbq_desc, gfp_t gfp) -{ - struct qlge_adapter *qdev = rx_ring->qdev; - struct sk_buff *skb; - - if (sbq_desc->p.skb) - return 0; - - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "ring %u sbq: getting new skb for index %d.\n", - rx_ring->cq_id, sbq_desc->index); - - skb = __netdev_alloc_skb(qdev->ndev, SMALL_BUFFER_SIZE, gfp); - if (!skb) - return -ENOMEM; - skb_reserve(skb, QLGE_SB_PAD); - - sbq_desc->dma_addr = dma_map_single(&qdev->pdev->dev, skb->data, - SMALL_BUF_MAP_SIZE, - DMA_FROM_DEVICE); - if (dma_mapping_error(&qdev->pdev->dev, sbq_desc->dma_addr)) { - netif_err(qdev, ifup, qdev->ndev, "PCI mapping failed.\n"); - dev_kfree_skb_any(skb); - return -EIO; - } - *sbq_desc->buf_ptr = cpu_to_le64(sbq_desc->dma_addr); - - sbq_desc->p.skb = skb; - return 0; -} - -/* return 0 or negative error */ -static int qlge_refill_lb(struct rx_ring *rx_ring, - struct qlge_bq_desc *lbq_desc, gfp_t gfp) -{ - struct qlge_adapter *qdev = rx_ring->qdev; - struct qlge_page_chunk *master_chunk = &rx_ring->master_chunk; - - if (!master_chunk->page) { - struct page *page; - dma_addr_t dma_addr; - - page = alloc_pages(gfp | __GFP_COMP, qdev->lbq_buf_order); - if (unlikely(!page)) - return -ENOMEM; - dma_addr = dma_map_page(&qdev->pdev->dev, page, 0, - qlge_lbq_block_size(qdev), - DMA_FROM_DEVICE); - if (dma_mapping_error(&qdev->pdev->dev, dma_addr)) { - __free_pages(page, qdev->lbq_buf_order); - netif_err(qdev, drv, qdev->ndev, - "PCI mapping failed.\n"); - return -EIO; - } - master_chunk->page = page; - master_chunk->va = page_address(page); - master_chunk->offset = 0; - rx_ring->chunk_dma_addr = dma_addr; - } - - lbq_desc->p.pg_chunk = *master_chunk; - lbq_desc->dma_addr = rx_ring->chunk_dma_addr; - *lbq_desc->buf_ptr = cpu_to_le64(lbq_desc->dma_addr + - lbq_desc->p.pg_chunk.offset); - - /* Adjust the master page chunk for next - * buffer get. - */ - master_chunk->offset += qdev->lbq_buf_size; - if (master_chunk->offset == qlge_lbq_block_size(qdev)) { - master_chunk->page = NULL; - } else { - master_chunk->va += qdev->lbq_buf_size; - get_page(master_chunk->page); - } - - return 0; -} - -/* return 0 or negative error */ -static int qlge_refill_bq(struct qlge_bq *bq, gfp_t gfp) -{ - struct rx_ring *rx_ring = QLGE_BQ_CONTAINER(bq); - struct qlge_adapter *qdev = rx_ring->qdev; - struct qlge_bq_desc *bq_desc; - int refill_count; - int retval; - int i; - - refill_count = QLGE_BQ_WRAP(QLGE_BQ_ALIGN(bq->next_to_clean - 1) - - bq->next_to_use); - if (!refill_count) - return 0; - - i = bq->next_to_use; - bq_desc = &bq->queue[i]; - i -= QLGE_BQ_LEN; - do { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "ring %u %s: try cleaning idx %d\n", - rx_ring->cq_id, bq_type_name[bq->type], i); - - if (bq->type == QLGE_SB) - retval = qlge_refill_sb(rx_ring, bq_desc, gfp); - else - retval = qlge_refill_lb(rx_ring, bq_desc, gfp); - if (retval < 0) { - netif_err(qdev, ifup, qdev->ndev, - "ring %u %s: Could not get a page chunk, idx %d\n", - rx_ring->cq_id, bq_type_name[bq->type], i); - break; - } - - bq_desc++; - i++; - if (unlikely(!i)) { - bq_desc = &bq->queue[0]; - i -= QLGE_BQ_LEN; - } - refill_count--; - } while (refill_count); - i += QLGE_BQ_LEN; - - if (bq->next_to_use != i) { - if (QLGE_BQ_ALIGN(bq->next_to_use) != QLGE_BQ_ALIGN(i)) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "ring %u %s: updating prod idx = %d.\n", - rx_ring->cq_id, bq_type_name[bq->type], - i); - qlge_write_db_reg(i, bq->prod_idx_db_reg); - } - bq->next_to_use = i; - } - - return retval; -} - -static void qlge_update_buffer_queues(struct rx_ring *rx_ring, gfp_t gfp, - unsigned long delay) -{ - bool sbq_fail, lbq_fail; - - sbq_fail = !!qlge_refill_bq(&rx_ring->sbq, gfp); - lbq_fail = !!qlge_refill_bq(&rx_ring->lbq, gfp); - - /* Minimum number of buffers needed to be able to receive at least one - * frame of any format: - * sbq: 1 for header + 1 for data - * lbq: mtu 9000 / lb size - * Below this, the queue might stall. - */ - if ((sbq_fail && QLGE_BQ_HW_OWNED(&rx_ring->sbq) < 2) || - (lbq_fail && QLGE_BQ_HW_OWNED(&rx_ring->lbq) < - DIV_ROUND_UP(9000, LARGE_BUFFER_MAX_SIZE))) - /* Allocations can take a long time in certain cases (ex. - * reclaim). Therefore, use a workqueue for long-running - * work items. - */ - queue_delayed_work_on(smp_processor_id(), system_long_wq, - &rx_ring->refill_work, delay); -} - -static void qlge_slow_refill(struct work_struct *work) -{ - struct rx_ring *rx_ring = container_of(work, struct rx_ring, - refill_work.work); - struct napi_struct *napi = &rx_ring->napi; - - napi_disable(napi); - qlge_update_buffer_queues(rx_ring, GFP_KERNEL, HZ / 2); - napi_enable(napi); - - local_bh_disable(); - /* napi_disable() might have prevented incomplete napi work from being - * rescheduled. - */ - napi_schedule(napi); - /* trigger softirq processing */ - local_bh_enable(); -} - -/* Unmaps tx buffers. Can be called from send() if a pci mapping - * fails at some stage, or from the interrupt when a tx completes. - */ -static void qlge_unmap_send(struct qlge_adapter *qdev, - struct tx_ring_desc *tx_ring_desc, int mapped) -{ - int i; - - for (i = 0; i < mapped; i++) { - if (i == 0 || (i == 7 && mapped > 7)) { - /* - * Unmap the skb->data area, or the - * external sglist (AKA the Outbound - * Address List (OAL)). - * If its the zeroeth element, then it's - * the skb->data area. If it's the 7th - * element and there is more than 6 frags, - * then its an OAL. - */ - if (i == 7) { - netif_printk(qdev, tx_done, KERN_DEBUG, - qdev->ndev, - "unmapping OAL area.\n"); - } - dma_unmap_single(&qdev->pdev->dev, - dma_unmap_addr(&tx_ring_desc->map[i], - mapaddr), - dma_unmap_len(&tx_ring_desc->map[i], - maplen), - DMA_TO_DEVICE); - } else { - netif_printk(qdev, tx_done, KERN_DEBUG, qdev->ndev, - "unmapping frag %d.\n", i); - dma_unmap_page(&qdev->pdev->dev, - dma_unmap_addr(&tx_ring_desc->map[i], - mapaddr), - dma_unmap_len(&tx_ring_desc->map[i], - maplen), DMA_TO_DEVICE); - } - } -} - -/* Map the buffers for this transmit. This will return - * NETDEV_TX_BUSY or NETDEV_TX_OK based on success. - */ -static int qlge_map_send(struct qlge_adapter *qdev, - struct qlge_ob_mac_iocb_req *mac_iocb_ptr, - struct sk_buff *skb, struct tx_ring_desc *tx_ring_desc) -{ - int len = skb_headlen(skb); - dma_addr_t map; - int frag_idx, err, map_idx = 0; - struct tx_buf_desc *tbd = mac_iocb_ptr->tbd; - int frag_cnt = skb_shinfo(skb)->nr_frags; - - if (frag_cnt) { - netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, - "frag_cnt = %d.\n", frag_cnt); - } - /* - * Map the skb buffer first. - */ - map = dma_map_single(&qdev->pdev->dev, skb->data, len, DMA_TO_DEVICE); - - err = dma_mapping_error(&qdev->pdev->dev, map); - if (err) { - netif_err(qdev, tx_queued, qdev->ndev, - "PCI mapping failed with error: %d\n", err); - - return NETDEV_TX_BUSY; - } - - tbd->len = cpu_to_le32(len); - tbd->addr = cpu_to_le64(map); - dma_unmap_addr_set(&tx_ring_desc->map[map_idx], mapaddr, map); - dma_unmap_len_set(&tx_ring_desc->map[map_idx], maplen, len); - map_idx++; - - /* - * This loop fills the remainder of the 8 address descriptors - * in the IOCB. If there are more than 7 fragments, then the - * eighth address desc will point to an external list (OAL). - * When this happens, the remainder of the frags will be stored - * in this list. - */ - for (frag_idx = 0; frag_idx < frag_cnt; frag_idx++, map_idx++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[frag_idx]; - - tbd++; - if (frag_idx == 6 && frag_cnt > 7) { - /* Let's tack on an sglist. - * Our control block will now - * look like this: - * iocb->seg[0] = skb->data - * iocb->seg[1] = frag[0] - * iocb->seg[2] = frag[1] - * iocb->seg[3] = frag[2] - * iocb->seg[4] = frag[3] - * iocb->seg[5] = frag[4] - * iocb->seg[6] = frag[5] - * iocb->seg[7] = ptr to OAL (external sglist) - * oal->seg[0] = frag[6] - * oal->seg[1] = frag[7] - * oal->seg[2] = frag[8] - * oal->seg[3] = frag[9] - * oal->seg[4] = frag[10] - * etc... - */ - /* Tack on the OAL in the eighth segment of IOCB. */ - map = dma_map_single(&qdev->pdev->dev, &tx_ring_desc->oal, - sizeof(struct qlge_oal), - DMA_TO_DEVICE); - err = dma_mapping_error(&qdev->pdev->dev, map); - if (err) { - netif_err(qdev, tx_queued, qdev->ndev, - "PCI mapping outbound address list with error: %d\n", - err); - goto map_error; - } - - tbd->addr = cpu_to_le64(map); - /* - * The length is the number of fragments - * that remain to be mapped times the length - * of our sglist (OAL). - */ - tbd->len = - cpu_to_le32((sizeof(struct tx_buf_desc) * - (frag_cnt - frag_idx)) | TX_DESC_C); - dma_unmap_addr_set(&tx_ring_desc->map[map_idx], mapaddr, - map); - dma_unmap_len_set(&tx_ring_desc->map[map_idx], maplen, - sizeof(struct qlge_oal)); - tbd = (struct tx_buf_desc *)&tx_ring_desc->oal; - map_idx++; - } - - map = skb_frag_dma_map(&qdev->pdev->dev, frag, 0, skb_frag_size(frag), - DMA_TO_DEVICE); - - err = dma_mapping_error(&qdev->pdev->dev, map); - if (err) { - netif_err(qdev, tx_queued, qdev->ndev, - "PCI mapping frags failed with error: %d.\n", - err); - goto map_error; - } - - tbd->addr = cpu_to_le64(map); - tbd->len = cpu_to_le32(skb_frag_size(frag)); - dma_unmap_addr_set(&tx_ring_desc->map[map_idx], mapaddr, map); - dma_unmap_len_set(&tx_ring_desc->map[map_idx], maplen, - skb_frag_size(frag)); - } - /* Save the number of segments we've mapped. */ - tx_ring_desc->map_cnt = map_idx; - /* Terminate the last segment. */ - tbd->len = cpu_to_le32(le32_to_cpu(tbd->len) | TX_DESC_E); - return NETDEV_TX_OK; - -map_error: - /* - * If the first frag mapping failed, then i will be zero. - * This causes the unmap of the skb->data area. Otherwise - * we pass in the number of frags that mapped successfully - * so they can be umapped. - */ - qlge_unmap_send(qdev, tx_ring_desc, map_idx); - return NETDEV_TX_BUSY; -} - -/* Categorizing receive firmware frame errors */ -static void qlge_categorize_rx_err(struct qlge_adapter *qdev, u8 rx_err, - struct rx_ring *rx_ring) -{ - struct nic_stats *stats = &qdev->nic_stats; - - stats->rx_err_count++; - rx_ring->rx_errors++; - - switch (rx_err & IB_MAC_IOCB_RSP_ERR_MASK) { - case IB_MAC_IOCB_RSP_ERR_CODE_ERR: - stats->rx_code_err++; - break; - case IB_MAC_IOCB_RSP_ERR_OVERSIZE: - stats->rx_oversize_err++; - break; - case IB_MAC_IOCB_RSP_ERR_UNDERSIZE: - stats->rx_undersize_err++; - break; - case IB_MAC_IOCB_RSP_ERR_PREAMBLE: - stats->rx_preamble_err++; - break; - case IB_MAC_IOCB_RSP_ERR_FRAME_LEN: - stats->rx_frame_len_err++; - break; - case IB_MAC_IOCB_RSP_ERR_CRC: - stats->rx_crc_err++; - break; - default: - break; - } -} - -/* - * qlge_update_mac_hdr_len - helper routine to update the mac header length - * based on vlan tags if present - */ -static void qlge_update_mac_hdr_len(struct qlge_adapter *qdev, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp, - void *page, size_t *len) -{ - u16 *tags; - - if (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) - return; - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) { - tags = (u16 *)page; - /* Look for stacked vlan tags in ethertype field */ - if (tags[6] == ETH_P_8021Q && - tags[8] == ETH_P_8021Q) - *len += 2 * VLAN_HLEN; - else - *len += VLAN_HLEN; - } -} - -/* Process an inbound completion from an rx ring. */ -static void qlge_process_mac_rx_gro_page(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp, - u32 length, u16 vlan_id) -{ - struct sk_buff *skb; - struct qlge_bq_desc *lbq_desc = qlge_get_curr_lchunk(qdev, rx_ring); - struct napi_struct *napi = &rx_ring->napi; - - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - qlge_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - put_page(lbq_desc->p.pg_chunk.page); - return; - } - napi->dev = qdev->ndev; - - skb = napi_get_frags(napi); - if (!skb) { - netif_err(qdev, drv, qdev->ndev, - "Couldn't get an skb, exiting.\n"); - rx_ring->rx_dropped++; - put_page(lbq_desc->p.pg_chunk.page); - return; - } - prefetch(lbq_desc->p.pg_chunk.va); - __skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, - lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset, - length); - - skb->len += length; - skb->data_len += length; - skb->truesize += length; - skb_shinfo(skb)->nr_frags++; - - rx_ring->rx_packets++; - rx_ring->rx_bytes += length; - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb_record_rx_queue(skb, rx_ring->cq_id); - if (vlan_id != 0xffff) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_id); - napi_gro_frags(napi); -} - -/* Process an inbound completion from an rx ring. */ -static void qlge_process_mac_rx_page(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp, - u32 length, u16 vlan_id) -{ - struct net_device *ndev = qdev->ndev; - struct sk_buff *skb = NULL; - void *addr; - struct qlge_bq_desc *lbq_desc = qlge_get_curr_lchunk(qdev, rx_ring); - struct napi_struct *napi = &rx_ring->napi; - size_t hlen = ETH_HLEN; - - skb = netdev_alloc_skb(ndev, length); - if (!skb) { - rx_ring->rx_dropped++; - put_page(lbq_desc->p.pg_chunk.page); - return; - } - - addr = lbq_desc->p.pg_chunk.va; - prefetch(addr); - - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - qlge_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - goto err_out; - } - - /* Update the MAC header length*/ - qlge_update_mac_hdr_len(qdev, ib_mac_rsp, addr, &hlen); - - /* The max framesize filter on this chip is set higher than - * MTU since FCoE uses 2k frames. - */ - if (skb->len > ndev->mtu + hlen) { - netif_err(qdev, drv, qdev->ndev, - "Segment too small, dropping.\n"); - rx_ring->rx_dropped++; - goto err_out; - } - skb_put_data(skb, addr, hlen); - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", - length); - skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset + hlen, length - hlen); - skb->len += length - hlen; - skb->data_len += length - hlen; - skb->truesize += length - hlen; - - rx_ring->rx_packets++; - rx_ring->rx_bytes += skb->len; - skb->protocol = eth_type_trans(skb, ndev); - skb_checksum_none_assert(skb); - - if ((ndev->features & NETIF_F_RXCSUM) && - !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { - /* TCP frame. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && - (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { - /* Unfragmented ipv4 UDP frame. */ - struct iphdr *iph = - (struct iphdr *)((u8 *)addr + hlen); - if (!(iph->frag_off & - htons(IP_MF | IP_OFFSET))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_printk(qdev, rx_status, KERN_DEBUG, - qdev->ndev, - "UDP checksum done!\n"); - } - } - } - - skb_record_rx_queue(skb, rx_ring->cq_id); - if (vlan_id != 0xffff) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - napi_gro_receive(napi, skb); - else - netif_receive_skb(skb); - return; -err_out: - dev_kfree_skb_any(skb); - put_page(lbq_desc->p.pg_chunk.page); -} - -/* Process an inbound completion from an rx ring. */ -static void qlge_process_mac_rx_skb(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp, - u32 length, u16 vlan_id) -{ - struct qlge_bq_desc *sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); - struct net_device *ndev = qdev->ndev; - struct sk_buff *skb, *new_skb; - - skb = sbq_desc->p.skb; - /* Allocate new_skb and copy */ - new_skb = netdev_alloc_skb(qdev->ndev, length + NET_IP_ALIGN); - if (!new_skb) { - rx_ring->rx_dropped++; - return; - } - skb_reserve(new_skb, NET_IP_ALIGN); - - dma_sync_single_for_cpu(&qdev->pdev->dev, sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, DMA_FROM_DEVICE); - - skb_put_data(new_skb, skb->data, length); - - skb = new_skb; - - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - qlge_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - - /* loopback self test for ethtool */ - if (test_bit(QL_SELFTEST, &qdev->flags)) { - qlge_check_lb_frame(qdev, skb); - dev_kfree_skb_any(skb); - return; - } - - /* The max framesize filter on this chip is set higher than - * MTU since FCoE uses 2k frames. - */ - if (skb->len > ndev->mtu + ETH_HLEN) { - dev_kfree_skb_any(skb); - rx_ring->rx_dropped++; - return; - } - - prefetch(skb->data); - if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "%s Multicast.\n", - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_HASH ? "Hash" : - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_REG ? "Registered" : - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : ""); - } - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Promiscuous Packet.\n"); - - rx_ring->rx_packets++; - rx_ring->rx_bytes += skb->len; - skb->protocol = eth_type_trans(skb, ndev); - skb_checksum_none_assert(skb); - - /* If rx checksum is on, and there are no - * csum or frame errors. - */ - if ((ndev->features & NETIF_F_RXCSUM) && - !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { - /* TCP frame. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && - (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { - /* Unfragmented ipv4 UDP frame. */ - struct iphdr *iph = (struct iphdr *)skb->data; - - if (!(iph->frag_off & - htons(IP_MF | IP_OFFSET))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_printk(qdev, rx_status, KERN_DEBUG, - qdev->ndev, - "UDP checksum done!\n"); - } - } - } - - skb_record_rx_queue(skb, rx_ring->cq_id); - if (vlan_id != 0xffff) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - napi_gro_receive(&rx_ring->napi, skb); - else - netif_receive_skb(skb); -} - -static void qlge_realign_skb(struct sk_buff *skb, int len) -{ - void *temp_addr = skb->data; - - /* Undo the skb_reserve(skb,32) we did before - * giving to hardware, and realign data on - * a 2-byte boundary. - */ - skb->data -= QLGE_SB_PAD - NET_IP_ALIGN; - skb->tail -= QLGE_SB_PAD - NET_IP_ALIGN; - memmove(skb->data, temp_addr, len); -} - -/* - * This function builds an skb for the given inbound - * completion. It will be rewritten for readability in the near - * future, but for not it works well. - */ -static struct sk_buff *qlge_build_rx_skb(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp) -{ - u32 length = le32_to_cpu(ib_mac_rsp->data_len); - u32 hdr_len = le32_to_cpu(ib_mac_rsp->hdr_len); - struct qlge_bq_desc *lbq_desc, *sbq_desc; - struct sk_buff *skb = NULL; - size_t hlen = ETH_HLEN; - - /* - * Handle the header buffer if present. - */ - if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV && - ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Header of %d bytes in small buffer.\n", hdr_len); - /* - * Headers fit nicely into a small buffer. - */ - sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); - dma_unmap_single(&qdev->pdev->dev, sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, DMA_FROM_DEVICE); - skb = sbq_desc->p.skb; - qlge_realign_skb(skb, hdr_len); - skb_put(skb, hdr_len); - sbq_desc->p.skb = NULL; - } - - /* - * Handle the data buffer(s). - */ - if (unlikely(!length)) { /* Is there data too? */ - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "No Data buffer in this packet.\n"); - return skb; - } - - if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) { - if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Headers in small, data of %d bytes in small, combine them.\n", - length); - /* - * Data is less than small buffer size so it's - * stuffed in a small buffer. - * For this case we append the data - * from the "data" small buffer to the "header" small - * buffer. - */ - sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); - dma_sync_single_for_cpu(&qdev->pdev->dev, - sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, - DMA_FROM_DEVICE); - skb_put_data(skb, sbq_desc->p.skb->data, length); - } else { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "%d bytes in a single small buffer.\n", - length); - sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); - skb = sbq_desc->p.skb; - qlge_realign_skb(skb, length); - skb_put(skb, length); - dma_unmap_single(&qdev->pdev->dev, sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, - DMA_FROM_DEVICE); - sbq_desc->p.skb = NULL; - } - } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) { - if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Header in small, %d bytes in large. Chain large to small!\n", - length); - /* - * The data is in a single large buffer. We - * chain it to the header buffer's skb and let - * it rip. - */ - lbq_desc = qlge_get_curr_lchunk(qdev, rx_ring); - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Chaining page at offset = %d, for %d bytes to skb.\n", - lbq_desc->p.pg_chunk.offset, length); - skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset, length); - skb->len += length; - skb->data_len += length; - skb->truesize += length; - } else { - /* - * The headers and data are in a single large buffer. We - * copy it to a new skb and let it go. This can happen with - * jumbo mtu on a non-TCP/UDP frame. - */ - lbq_desc = qlge_get_curr_lchunk(qdev, rx_ring); - skb = netdev_alloc_skb(qdev->ndev, length); - if (!skb) { - netif_printk(qdev, probe, KERN_DEBUG, qdev->ndev, - "No skb available, drop the packet.\n"); - return NULL; - } - dma_unmap_page(&qdev->pdev->dev, lbq_desc->dma_addr, - qdev->lbq_buf_size, - DMA_FROM_DEVICE); - skb_reserve(skb, NET_IP_ALIGN); - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", - length); - skb_fill_page_desc(skb, 0, lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset, - length); - skb->len += length; - skb->data_len += length; - skb->truesize += length; - qlge_update_mac_hdr_len(qdev, ib_mac_rsp, - lbq_desc->p.pg_chunk.va, - &hlen); - __pskb_pull_tail(skb, hlen); - } - } else { - /* - * The data is in a chain of large buffers - * pointed to by a small buffer. We loop - * thru and chain them to the our small header - * buffer's skb. - * frags: There are 18 max frags and our small - * buffer will hold 32 of them. The thing is, - * we'll use 3 max for our 9000 byte jumbo - * frames. If the MTU goes up we could - * eventually be in trouble. - */ - int size, i = 0; - - sbq_desc = qlge_get_curr_buf(&rx_ring->sbq); - dma_unmap_single(&qdev->pdev->dev, sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, DMA_FROM_DEVICE); - if (!(ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS)) { - /* - * This is an non TCP/UDP IP frame, so - * the headers aren't split into a small - * buffer. We have to use the small buffer - * that contains our sg list as our skb to - * send upstairs. Copy the sg list here to - * a local buffer and use it to find the - * pages to chain. - */ - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "%d bytes of headers & data in chain of large.\n", - length); - skb = sbq_desc->p.skb; - sbq_desc->p.skb = NULL; - skb_reserve(skb, NET_IP_ALIGN); - } - do { - lbq_desc = qlge_get_curr_lchunk(qdev, rx_ring); - size = min(length, qdev->lbq_buf_size); - - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Adding page %d to skb for %d bytes.\n", - i, size); - skb_fill_page_desc(skb, i, - lbq_desc->p.pg_chunk.page, - lbq_desc->p.pg_chunk.offset, size); - skb->len += size; - skb->data_len += size; - skb->truesize += size; - length -= size; - i++; - } while (length > 0); - qlge_update_mac_hdr_len(qdev, ib_mac_rsp, lbq_desc->p.pg_chunk.va, - &hlen); - __pskb_pull_tail(skb, hlen); - } - return skb; -} - -/* Process an inbound completion from an rx ring. */ -static void qlge_process_mac_split_rx_intr(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp, - u16 vlan_id) -{ - struct net_device *ndev = qdev->ndev; - struct sk_buff *skb = NULL; - - skb = qlge_build_rx_skb(qdev, rx_ring, ib_mac_rsp); - if (unlikely(!skb)) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "No skb available, drop packet.\n"); - rx_ring->rx_dropped++; - return; - } - - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - qlge_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - - /* The max framesize filter on this chip is set higher than - * MTU since FCoE uses 2k frames. - */ - if (skb->len > ndev->mtu + ETH_HLEN) { - dev_kfree_skb_any(skb); - rx_ring->rx_dropped++; - return; - } - - /* loopback self test for ethtool */ - if (test_bit(QL_SELFTEST, &qdev->flags)) { - qlge_check_lb_frame(qdev, skb); - dev_kfree_skb_any(skb); - return; - } - - prefetch(skb->data); - if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "%s Multicast.\n", - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_HASH ? "Hash" : - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_REG ? "Registered" : - (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) == - IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : ""); - rx_ring->rx_multicast++; - } - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Promiscuous Packet.\n"); - } - - skb->protocol = eth_type_trans(skb, ndev); - skb_checksum_none_assert(skb); - - /* If rx checksum is on, and there are no - * csum or frame errors. - */ - if ((ndev->features & NETIF_F_RXCSUM) && - !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { - /* TCP frame. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && - (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { - /* Unfragmented ipv4 UDP frame. */ - struct iphdr *iph = (struct iphdr *)skb->data; - - if (!(iph->frag_off & - htons(IP_MF | IP_OFFSET))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); - } - } - } - - rx_ring->rx_packets++; - rx_ring->rx_bytes += skb->len; - skb_record_rx_queue(skb, rx_ring->cq_id); - if (vlan_id != 0xffff) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_id); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) - napi_gro_receive(&rx_ring->napi, skb); - else - netif_receive_skb(skb); -} - -/* Process an inbound completion from an rx ring. */ -static unsigned long qlge_process_mac_rx_intr(struct qlge_adapter *qdev, - struct rx_ring *rx_ring, - struct qlge_ib_mac_iocb_rsp *ib_mac_rsp) -{ - u32 length = le32_to_cpu(ib_mac_rsp->data_len); - u16 vlan_id = ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) && - (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)) ? - ((le16_to_cpu(ib_mac_rsp->vlan_id) & - IB_MAC_IOCB_RSP_VLAN_MASK)) : 0xffff; - - if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { - /* The data and headers are split into - * separate buffers. - */ - qlge_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp, - vlan_id); - } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) { - /* The data fit in a single small buffer. - * Allocate a new skb, copy the data and - * return the buffer to the free pool. - */ - qlge_process_mac_rx_skb(qdev, rx_ring, ib_mac_rsp, length, - vlan_id); - } else if ((ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) && - !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK) && - (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T)) { - /* TCP packet in a page chunk that's been checksummed. - * Tack it on to our GRO skb and let it go. - */ - qlge_process_mac_rx_gro_page(qdev, rx_ring, ib_mac_rsp, length, - vlan_id); - } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) { - /* Non-TCP packet in a page chunk. Allocate an - * skb, tack it on frags, and send it up. - */ - qlge_process_mac_rx_page(qdev, rx_ring, ib_mac_rsp, length, - vlan_id); - } else { - /* Non-TCP/UDP large frames that span multiple buffers - * can be processed correctly by the split frame logic. - */ - qlge_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp, - vlan_id); - } - - return (unsigned long)length; -} - -/* Process an outbound completion from an rx ring. */ -static void qlge_process_mac_tx_intr(struct qlge_adapter *qdev, - struct qlge_ob_mac_iocb_rsp *mac_rsp) -{ - struct tx_ring *tx_ring; - struct tx_ring_desc *tx_ring_desc; - - tx_ring = &qdev->tx_ring[mac_rsp->txq_idx]; - tx_ring_desc = &tx_ring->q[mac_rsp->tid]; - qlge_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt); - tx_ring->tx_bytes += (tx_ring_desc->skb)->len; - tx_ring->tx_packets++; - dev_kfree_skb(tx_ring_desc->skb); - tx_ring_desc->skb = NULL; - - if (unlikely(mac_rsp->flags1 & (OB_MAC_IOCB_RSP_E | - OB_MAC_IOCB_RSP_S | - OB_MAC_IOCB_RSP_L | - OB_MAC_IOCB_RSP_P | OB_MAC_IOCB_RSP_B))) { - if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_E) { - netif_warn(qdev, tx_done, qdev->ndev, - "Total descriptor length did not match transfer length.\n"); - } - if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_S) { - netif_warn(qdev, tx_done, qdev->ndev, - "Frame too short to be valid, not sent.\n"); - } - if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_L) { - netif_warn(qdev, tx_done, qdev->ndev, - "Frame too long, but sent anyway.\n"); - } - if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_B) { - netif_warn(qdev, tx_done, qdev->ndev, - "PCI backplane error. Frame not sent.\n"); - } - } - atomic_inc(&tx_ring->tx_count); -} - -/* Fire up a handler to reset the MPI processor. */ -void qlge_queue_fw_error(struct qlge_adapter *qdev) -{ - qlge_link_off(qdev); - queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0); -} - -void qlge_queue_asic_error(struct qlge_adapter *qdev) -{ - qlge_link_off(qdev); - qlge_disable_interrupts(qdev); - /* Clear adapter up bit to signal the recovery - * process that it shouldn't kill the reset worker - * thread - */ - clear_bit(QL_ADAPTER_UP, &qdev->flags); - /* Set asic recovery bit to indicate reset process that we are - * in fatal error recovery process rather than normal close - */ - set_bit(QL_ASIC_RECOVERY, &qdev->flags); - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); -} - -static void qlge_process_chip_ae_intr(struct qlge_adapter *qdev, - struct qlge_ib_ae_iocb_rsp *ib_ae_rsp) -{ - switch (ib_ae_rsp->event) { - case MGMT_ERR_EVENT: - netif_err(qdev, rx_err, qdev->ndev, - "Management Processor Fatal Error.\n"); - qlge_queue_fw_error(qdev); - return; - - case CAM_LOOKUP_ERR_EVENT: - netdev_err(qdev->ndev, "Multiple CAM hits lookup occurred.\n"); - netdev_err(qdev->ndev, "This event shouldn't occur.\n"); - qlge_queue_asic_error(qdev); - return; - - case SOFT_ECC_ERROR_EVENT: - netdev_err(qdev->ndev, "Soft ECC error detected.\n"); - qlge_queue_asic_error(qdev); - break; - - case PCI_ERR_ANON_BUF_RD: - netdev_err(qdev->ndev, - "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", - ib_ae_rsp->q_id); - qlge_queue_asic_error(qdev); - break; - - default: - netif_err(qdev, drv, qdev->ndev, "Unexpected event %d.\n", - ib_ae_rsp->event); - qlge_queue_asic_error(qdev); - break; - } -} - -static int qlge_clean_outbound_rx_ring(struct rx_ring *rx_ring) -{ - struct qlge_adapter *qdev = rx_ring->qdev; - u32 prod = qlge_read_sh_reg(rx_ring->prod_idx_sh_reg); - struct qlge_ob_mac_iocb_rsp *net_rsp = NULL; - int count = 0; - - struct tx_ring *tx_ring; - /* While there are entries in the completion queue. */ - while (prod != rx_ring->cnsmr_idx) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "cq_id = %d, prod = %d, cnsmr = %d\n", - rx_ring->cq_id, prod, rx_ring->cnsmr_idx); - - net_rsp = (struct qlge_ob_mac_iocb_rsp *)rx_ring->curr_entry; - rmb(); - switch (net_rsp->opcode) { - case OPCODE_OB_MAC_TSO_IOCB: - case OPCODE_OB_MAC_IOCB: - qlge_process_mac_tx_intr(qdev, net_rsp); - break; - default: - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Hit default case, not handled! dropping the packet, opcode = %x.\n", - net_rsp->opcode); - } - count++; - qlge_update_cq(rx_ring); - prod = qlge_read_sh_reg(rx_ring->prod_idx_sh_reg); - } - if (!net_rsp) - return 0; - qlge_write_cq_idx(rx_ring); - tx_ring = &qdev->tx_ring[net_rsp->txq_idx]; - if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) { - if ((atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) - /* - * The queue got stopped because the tx_ring was full. - * Wake it up, because it's now at least 25% empty. - */ - netif_wake_subqueue(qdev->ndev, tx_ring->wq_id); - } - - return count; -} - -static int qlge_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) -{ - struct qlge_adapter *qdev = rx_ring->qdev; - u32 prod = qlge_read_sh_reg(rx_ring->prod_idx_sh_reg); - struct qlge_net_rsp_iocb *net_rsp; - int count = 0; - - /* While there are entries in the completion queue. */ - while (prod != rx_ring->cnsmr_idx) { - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "cq_id = %d, prod = %d, cnsmr = %d\n", - rx_ring->cq_id, prod, rx_ring->cnsmr_idx); - - net_rsp = rx_ring->curr_entry; - rmb(); - switch (net_rsp->opcode) { - case OPCODE_IB_MAC_IOCB: - qlge_process_mac_rx_intr(qdev, rx_ring, - (struct qlge_ib_mac_iocb_rsp *) - net_rsp); - break; - - case OPCODE_IB_AE_IOCB: - qlge_process_chip_ae_intr(qdev, (struct qlge_ib_ae_iocb_rsp *) - net_rsp); - break; - default: - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Hit default case, not handled! dropping the packet, opcode = %x.\n", - net_rsp->opcode); - break; - } - count++; - qlge_update_cq(rx_ring); - prod = qlge_read_sh_reg(rx_ring->prod_idx_sh_reg); - if (count == budget) - break; - } - qlge_update_buffer_queues(rx_ring, GFP_ATOMIC, 0); - qlge_write_cq_idx(rx_ring); - return count; -} - -static int qlge_napi_poll_msix(struct napi_struct *napi, int budget) -{ - struct rx_ring *rx_ring = container_of(napi, struct rx_ring, napi); - struct qlge_adapter *qdev = rx_ring->qdev; - struct rx_ring *trx_ring; - int i, work_done = 0; - struct intr_context *ctx = &qdev->intr_context[rx_ring->cq_id]; - - netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "Enter, NAPI POLL cq_id = %d.\n", rx_ring->cq_id); - - /* Service the TX rings first. They start - * right after the RSS rings. - */ - for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) { - trx_ring = &qdev->rx_ring[i]; - /* If this TX completion ring belongs to this vector and - * it's not empty then service it. - */ - if ((ctx->irq_mask & (1 << trx_ring->cq_id)) && - (qlge_read_sh_reg(trx_ring->prod_idx_sh_reg) != - trx_ring->cnsmr_idx)) { - netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev, - "%s: Servicing TX completion ring %d.\n", - __func__, trx_ring->cq_id); - qlge_clean_outbound_rx_ring(trx_ring); - } - } - - /* - * Now service the RSS ring if it's active. - */ - if (qlge_read_sh_reg(rx_ring->prod_idx_sh_reg) != - rx_ring->cnsmr_idx) { - netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev, - "%s: Servicing RX completion ring %d.\n", - __func__, rx_ring->cq_id); - work_done = qlge_clean_inbound_rx_ring(rx_ring, budget); - } - - if (work_done < budget) { - napi_complete_done(napi, work_done); - qlge_enable_completion_interrupt(qdev, rx_ring->irq); - } - return work_done; -} - -static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - if (features & NETIF_F_HW_VLAN_CTAG_RX) { - qlge_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK | - NIC_RCV_CFG_VLAN_MATCH_AND_NON); - } else { - qlge_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK); - } -} - -/* - * qlge_update_hw_vlan_features - helper routine to reinitialize the adapter - * based on the features to enable/disable hardware vlan accel - */ -static int qlge_update_hw_vlan_features(struct net_device *ndev, - netdev_features_t features) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - bool need_restart = netif_running(ndev); - int status = 0; - - if (need_restart) { - status = qlge_adapter_down(qdev); - if (status) { - netif_err(qdev, link, qdev->ndev, - "Failed to bring down the adapter\n"); - return status; - } - } - - /* update the features with resent change */ - ndev->features = features; - - if (need_restart) { - status = qlge_adapter_up(qdev); - if (status) { - netif_err(qdev, link, qdev->ndev, - "Failed to bring up the adapter\n"); - return status; - } - } - - return status; -} - -static int qlge_set_features(struct net_device *ndev, - netdev_features_t features) -{ - netdev_features_t changed = ndev->features ^ features; - int err; - - if (changed & NETIF_F_HW_VLAN_CTAG_RX) { - /* Update the behavior of vlan accel in the adapter */ - err = qlge_update_hw_vlan_features(ndev, features); - if (err) - return err; - - qlge_vlan_mode(ndev, features); - } - - return 0; -} - -static int __qlge_vlan_rx_add_vid(struct qlge_adapter *qdev, u16 vid) -{ - u32 enable_bit = MAC_ADDR_E; - int err; - - err = qlge_set_mac_addr_reg(qdev, (u8 *)&enable_bit, - MAC_ADDR_TYPE_VLAN, vid); - if (err) - netif_err(qdev, ifup, qdev->ndev, - "Failed to init vlan address.\n"); - return err; -} - -static int qlge_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int status; - int err; - - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return status; - - err = __qlge_vlan_rx_add_vid(qdev, vid); - set_bit(vid, qdev->active_vlans); - - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - - return err; -} - -static int __qlge_vlan_rx_kill_vid(struct qlge_adapter *qdev, u16 vid) -{ - u32 enable_bit = 0; - int err; - - err = qlge_set_mac_addr_reg(qdev, (u8 *)&enable_bit, - MAC_ADDR_TYPE_VLAN, vid); - if (err) - netif_err(qdev, ifup, qdev->ndev, - "Failed to clear vlan address.\n"); - return err; -} - -static int qlge_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int status; - int err; - - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return status; - - err = __qlge_vlan_rx_kill_vid(qdev, vid); - clear_bit(vid, qdev->active_vlans); - - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - - return err; -} - -static void qlge_restore_vlan(struct qlge_adapter *qdev) -{ - int status; - u16 vid; - - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return; - - for_each_set_bit(vid, qdev->active_vlans, VLAN_N_VID) - __qlge_vlan_rx_add_vid(qdev, vid); - - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); -} - -/* MSI-X Multiple Vector Interrupt Handler for inbound completions. */ -static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id) -{ - struct rx_ring *rx_ring = dev_id; - - napi_schedule(&rx_ring->napi); - return IRQ_HANDLED; -} - -/* This handles a fatal error, MPI activity, and the default - * rx_ring in an MSI-X multiple vector environment. - * In MSI/Legacy environment it also process the rest of - * the rx_rings. - */ -static irqreturn_t qlge_isr(int irq, void *dev_id) -{ - struct rx_ring *rx_ring = dev_id; - struct qlge_adapter *qdev = rx_ring->qdev; - struct intr_context *intr_context = &qdev->intr_context[0]; - u32 var; - int work_done = 0; - - /* Experience shows that when using INTx interrupts, interrupts must - * be masked manually. - * When using MSI mode, INTR_EN_EN must be explicitly disabled - * (even though it is auto-masked), otherwise a later command to - * enable it is not effective. - */ - if (!test_bit(QL_MSIX_ENABLED, &qdev->flags)) - qlge_disable_completion_interrupt(qdev, 0); - - var = qlge_read32(qdev, STS); - - /* - * Check for fatal error. - */ - if (var & STS_FE) { - qlge_disable_completion_interrupt(qdev, 0); - qlge_queue_asic_error(qdev); - netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); - var = qlge_read32(qdev, ERR_STS); - netdev_err(qdev->ndev, "Resetting chip. Error Status Register = 0x%x\n", var); - return IRQ_HANDLED; - } - - /* - * Check MPI processor activity. - */ - if ((var & STS_PI) && - (qlge_read32(qdev, INTR_MASK) & INTR_MASK_PI)) { - /* - * We've got an async event or mailbox completion. - * Handle it and clear the source of the interrupt. - */ - netif_err(qdev, intr, qdev->ndev, - "Got MPI processor interrupt.\n"); - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); - queue_delayed_work_on(smp_processor_id(), - qdev->workqueue, &qdev->mpi_work, 0); - work_done++; - } - - /* - * Get the bit-mask that shows the active queues for this - * pass. Compare it to the queues that this irq services - * and call napi if there's a match. - */ - var = qlge_read32(qdev, ISR1); - if (var & intr_context->irq_mask) { - netif_info(qdev, intr, qdev->ndev, - "Waking handler for rx_ring[0].\n"); - napi_schedule(&rx_ring->napi); - work_done++; - } else { - /* Experience shows that the device sometimes signals an - * interrupt but no work is scheduled from this function. - * Nevertheless, the interrupt is auto-masked. Therefore, we - * systematically re-enable the interrupt if we didn't - * schedule napi. - */ - qlge_enable_completion_interrupt(qdev, 0); - } - - return work_done ? IRQ_HANDLED : IRQ_NONE; -} - -static int qlge_tso(struct sk_buff *skb, struct qlge_ob_mac_tso_iocb_req *mac_iocb_ptr) -{ - if (skb_is_gso(skb)) { - int err; - __be16 l3_proto = vlan_get_protocol(skb); - - err = skb_cow_head(skb, 0); - if (err < 0) - return err; - - mac_iocb_ptr->opcode = OPCODE_OB_MAC_TSO_IOCB; - mac_iocb_ptr->flags3 |= OB_MAC_TSO_IOCB_IC; - mac_iocb_ptr->frame_len = cpu_to_le32((u32)skb->len); - mac_iocb_ptr->total_hdrs_len = - cpu_to_le16(skb_tcp_all_headers(skb)); - mac_iocb_ptr->net_trans_offset = - cpu_to_le16(skb_network_offset(skb) | - skb_transport_offset(skb) - << OB_MAC_TRANSPORT_HDR_SHIFT); - mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO; - if (likely(l3_proto == htons(ETH_P_IP))) { - struct iphdr *iph = ip_hdr(skb); - - iph->check = 0; - mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4; - tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); - } else if (l3_proto == htons(ETH_P_IPV6)) { - mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6; - tcp_hdr(skb)->check = - ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); - } - return 1; - } - return 0; -} - -static void qlge_hw_csum_setup(struct sk_buff *skb, - struct qlge_ob_mac_tso_iocb_req *mac_iocb_ptr) -{ - int len; - struct iphdr *iph = ip_hdr(skb); - __sum16 *check; - - mac_iocb_ptr->opcode = OPCODE_OB_MAC_TSO_IOCB; - mac_iocb_ptr->frame_len = cpu_to_le32((u32)skb->len); - mac_iocb_ptr->net_trans_offset = - cpu_to_le16(skb_network_offset(skb) | - skb_transport_offset(skb) << OB_MAC_TRANSPORT_HDR_SHIFT); - - mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4; - len = (ntohs(iph->tot_len) - (iph->ihl << 2)); - if (likely(iph->protocol == IPPROTO_TCP)) { - check = &(tcp_hdr(skb)->check); - mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_TC; - mac_iocb_ptr->total_hdrs_len = - cpu_to_le16(skb_transport_offset(skb) + - (tcp_hdr(skb)->doff << 2)); - } else { - check = &(udp_hdr(skb)->check); - mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_UC; - mac_iocb_ptr->total_hdrs_len = - cpu_to_le16(skb_transport_offset(skb) + - sizeof(struct udphdr)); - } - *check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, len, iph->protocol, 0); -} - -static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - struct qlge_ob_mac_iocb_req *mac_iocb_ptr; - struct tx_ring_desc *tx_ring_desc; - int tso; - struct tx_ring *tx_ring; - u32 tx_ring_idx = (u32)skb->queue_mapping; - - tx_ring = &qdev->tx_ring[tx_ring_idx]; - - if (skb_padto(skb, ETH_ZLEN)) - return NETDEV_TX_OK; - - if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) { - netif_info(qdev, tx_queued, qdev->ndev, - "%s: BUG! shutting down tx queue %d due to lack of resources.\n", - __func__, tx_ring_idx); - netif_stop_subqueue(ndev, tx_ring->wq_id); - tx_ring->tx_errors++; - return NETDEV_TX_BUSY; - } - tx_ring_desc = &tx_ring->q[tx_ring->prod_idx]; - mac_iocb_ptr = tx_ring_desc->queue_entry; - memset((void *)mac_iocb_ptr, 0, sizeof(*mac_iocb_ptr)); - - mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB; - mac_iocb_ptr->tid = tx_ring_desc->index; - /* We use the upper 32-bits to store the tx queue for this IO. - * When we get the completion we can use it to establish the context. - */ - mac_iocb_ptr->txq_idx = tx_ring_idx; - tx_ring_desc->skb = skb; - - mac_iocb_ptr->frame_len = cpu_to_le16((u16)skb->len); - - if (skb_vlan_tag_present(skb)) { - netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, - "Adding a vlan tag %d.\n", skb_vlan_tag_get(skb)); - mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V; - mac_iocb_ptr->vlan_tci = cpu_to_le16(skb_vlan_tag_get(skb)); - } - tso = qlge_tso(skb, (struct qlge_ob_mac_tso_iocb_req *)mac_iocb_ptr); - if (tso < 0) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } else if (unlikely(!tso) && (skb->ip_summed == CHECKSUM_PARTIAL)) { - qlge_hw_csum_setup(skb, - (struct qlge_ob_mac_tso_iocb_req *)mac_iocb_ptr); - } - if (qlge_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != - NETDEV_TX_OK) { - netif_err(qdev, tx_queued, qdev->ndev, - "Could not map the segments.\n"); - tx_ring->tx_errors++; - return NETDEV_TX_BUSY; - } - - tx_ring->prod_idx++; - if (tx_ring->prod_idx == tx_ring->wq_len) - tx_ring->prod_idx = 0; - wmb(); - - qlge_write_db_reg_relaxed(tx_ring->prod_idx, tx_ring->prod_idx_db_reg); - netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, - "tx queued, slot %d, len %d\n", - tx_ring->prod_idx, skb->len); - - atomic_dec(&tx_ring->tx_count); - - if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) { - netif_stop_subqueue(ndev, tx_ring->wq_id); - if ((atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) - /* - * The queue got stopped because the tx_ring was full. - * Wake it up, because it's now at least 25% empty. - */ - netif_wake_subqueue(qdev->ndev, tx_ring->wq_id); - } - return NETDEV_TX_OK; -} - -static void qlge_free_shadow_space(struct qlge_adapter *qdev) -{ - if (qdev->rx_ring_shadow_reg_area) { - dma_free_coherent(&qdev->pdev->dev, - PAGE_SIZE, - qdev->rx_ring_shadow_reg_area, - qdev->rx_ring_shadow_reg_dma); - qdev->rx_ring_shadow_reg_area = NULL; - } - if (qdev->tx_ring_shadow_reg_area) { - dma_free_coherent(&qdev->pdev->dev, - PAGE_SIZE, - qdev->tx_ring_shadow_reg_area, - qdev->tx_ring_shadow_reg_dma); - qdev->tx_ring_shadow_reg_area = NULL; - } -} - -static int qlge_alloc_shadow_space(struct qlge_adapter *qdev) -{ - qdev->rx_ring_shadow_reg_area = - dma_alloc_coherent(&qdev->pdev->dev, PAGE_SIZE, - &qdev->rx_ring_shadow_reg_dma, GFP_ATOMIC); - if (!qdev->rx_ring_shadow_reg_area) { - netif_err(qdev, ifup, qdev->ndev, - "Allocation of RX shadow space failed.\n"); - return -ENOMEM; - } - - qdev->tx_ring_shadow_reg_area = - dma_alloc_coherent(&qdev->pdev->dev, PAGE_SIZE, - &qdev->tx_ring_shadow_reg_dma, GFP_ATOMIC); - if (!qdev->tx_ring_shadow_reg_area) { - netif_err(qdev, ifup, qdev->ndev, - "Allocation of TX shadow space failed.\n"); - goto err_wqp_sh_area; - } - return 0; - -err_wqp_sh_area: - dma_free_coherent(&qdev->pdev->dev, - PAGE_SIZE, - qdev->rx_ring_shadow_reg_area, - qdev->rx_ring_shadow_reg_dma); - return -ENOMEM; -} - -static void qlge_init_tx_ring(struct qlge_adapter *qdev, struct tx_ring *tx_ring) -{ - struct tx_ring_desc *tx_ring_desc; - int i; - struct qlge_ob_mac_iocb_req *mac_iocb_ptr; - - mac_iocb_ptr = tx_ring->wq_base; - tx_ring_desc = tx_ring->q; - for (i = 0; i < tx_ring->wq_len; i++) { - tx_ring_desc->index = i; - tx_ring_desc->skb = NULL; - tx_ring_desc->queue_entry = mac_iocb_ptr; - mac_iocb_ptr++; - tx_ring_desc++; - } - atomic_set(&tx_ring->tx_count, tx_ring->wq_len); -} - -static void qlge_free_tx_resources(struct qlge_adapter *qdev, - struct tx_ring *tx_ring) -{ - if (tx_ring->wq_base) { - dma_free_coherent(&qdev->pdev->dev, tx_ring->wq_size, - tx_ring->wq_base, tx_ring->wq_base_dma); - tx_ring->wq_base = NULL; - } - kfree(tx_ring->q); - tx_ring->q = NULL; -} - -static int qlge_alloc_tx_resources(struct qlge_adapter *qdev, - struct tx_ring *tx_ring) -{ - tx_ring->wq_base = - dma_alloc_coherent(&qdev->pdev->dev, tx_ring->wq_size, - &tx_ring->wq_base_dma, GFP_ATOMIC); - - if (!tx_ring->wq_base || - tx_ring->wq_base_dma & WQ_ADDR_ALIGN) - goto pci_alloc_err; - - tx_ring->q = - kmalloc_array(tx_ring->wq_len, sizeof(struct tx_ring_desc), - GFP_KERNEL); - if (!tx_ring->q) - goto err; - - return 0; -err: - dma_free_coherent(&qdev->pdev->dev, tx_ring->wq_size, - tx_ring->wq_base, tx_ring->wq_base_dma); - tx_ring->wq_base = NULL; -pci_alloc_err: - netif_err(qdev, ifup, qdev->ndev, "tx_ring alloc failed.\n"); - return -ENOMEM; -} - -static void qlge_free_lbq_buffers(struct qlge_adapter *qdev, struct rx_ring *rx_ring) -{ - struct qlge_bq *lbq = &rx_ring->lbq; - unsigned int last_offset; - - last_offset = qlge_lbq_block_size(qdev) - qdev->lbq_buf_size; - while (lbq->next_to_clean != lbq->next_to_use) { - struct qlge_bq_desc *lbq_desc = - &lbq->queue[lbq->next_to_clean]; - - if (lbq_desc->p.pg_chunk.offset == last_offset) - dma_unmap_page(&qdev->pdev->dev, lbq_desc->dma_addr, - qlge_lbq_block_size(qdev), - DMA_FROM_DEVICE); - put_page(lbq_desc->p.pg_chunk.page); - - lbq->next_to_clean = QLGE_BQ_WRAP(lbq->next_to_clean + 1); - } - - if (rx_ring->master_chunk.page) { - dma_unmap_page(&qdev->pdev->dev, rx_ring->chunk_dma_addr, - qlge_lbq_block_size(qdev), DMA_FROM_DEVICE); - put_page(rx_ring->master_chunk.page); - rx_ring->master_chunk.page = NULL; - } -} - -static void qlge_free_sbq_buffers(struct qlge_adapter *qdev, struct rx_ring *rx_ring) -{ - int i; - - for (i = 0; i < QLGE_BQ_LEN; i++) { - struct qlge_bq_desc *sbq_desc = &rx_ring->sbq.queue[i]; - - if (!sbq_desc) { - netif_err(qdev, ifup, qdev->ndev, - "sbq_desc %d is NULL.\n", i); - return; - } - if (sbq_desc->p.skb) { - dma_unmap_single(&qdev->pdev->dev, sbq_desc->dma_addr, - SMALL_BUF_MAP_SIZE, - DMA_FROM_DEVICE); - dev_kfree_skb(sbq_desc->p.skb); - sbq_desc->p.skb = NULL; - } - } -} - -/* Free all large and small rx buffers associated - * with the completion queues for this device. - */ -static void qlge_free_rx_buffers(struct qlge_adapter *qdev) -{ - int i; - - for (i = 0; i < qdev->rx_ring_count; i++) { - struct rx_ring *rx_ring = &qdev->rx_ring[i]; - - if (rx_ring->lbq.queue) - qlge_free_lbq_buffers(qdev, rx_ring); - if (rx_ring->sbq.queue) - qlge_free_sbq_buffers(qdev, rx_ring); - } -} - -static void qlge_alloc_rx_buffers(struct qlge_adapter *qdev) -{ - int i; - - for (i = 0; i < qdev->rss_ring_count; i++) - qlge_update_buffer_queues(&qdev->rx_ring[i], GFP_KERNEL, - HZ / 2); -} - -static int qlge_init_bq(struct qlge_bq *bq) -{ - struct rx_ring *rx_ring = QLGE_BQ_CONTAINER(bq); - struct qlge_adapter *qdev = rx_ring->qdev; - struct qlge_bq_desc *bq_desc; - __le64 *buf_ptr; - int i; - - bq->base = dma_alloc_coherent(&qdev->pdev->dev, QLGE_BQ_SIZE, - &bq->base_dma, GFP_ATOMIC); - if (!bq->base) - return -ENOMEM; - - bq->queue = kmalloc_array(QLGE_BQ_LEN, sizeof(struct qlge_bq_desc), - GFP_KERNEL); - if (!bq->queue) - return -ENOMEM; - - buf_ptr = bq->base; - bq_desc = &bq->queue[0]; - for (i = 0; i < QLGE_BQ_LEN; i++, buf_ptr++, bq_desc++) { - bq_desc->p.skb = NULL; - bq_desc->index = i; - bq_desc->buf_ptr = buf_ptr; - } - - return 0; -} - -static void qlge_free_rx_resources(struct qlge_adapter *qdev, - struct rx_ring *rx_ring) -{ - /* Free the small buffer queue. */ - if (rx_ring->sbq.base) { - dma_free_coherent(&qdev->pdev->dev, QLGE_BQ_SIZE, - rx_ring->sbq.base, rx_ring->sbq.base_dma); - rx_ring->sbq.base = NULL; - } - - /* Free the small buffer queue control blocks. */ - kfree(rx_ring->sbq.queue); - rx_ring->sbq.queue = NULL; - - /* Free the large buffer queue. */ - if (rx_ring->lbq.base) { - dma_free_coherent(&qdev->pdev->dev, QLGE_BQ_SIZE, - rx_ring->lbq.base, rx_ring->lbq.base_dma); - rx_ring->lbq.base = NULL; - } - - /* Free the large buffer queue control blocks. */ - kfree(rx_ring->lbq.queue); - rx_ring->lbq.queue = NULL; - - /* Free the rx queue. */ - if (rx_ring->cq_base) { - dma_free_coherent(&qdev->pdev->dev, - rx_ring->cq_size, - rx_ring->cq_base, rx_ring->cq_base_dma); - rx_ring->cq_base = NULL; - } -} - -/* Allocate queues and buffers for this completions queue based - * on the values in the parameter structure. - */ -static int qlge_alloc_rx_resources(struct qlge_adapter *qdev, - struct rx_ring *rx_ring) -{ - /* - * Allocate the completion queue for this rx_ring. - */ - rx_ring->cq_base = - dma_alloc_coherent(&qdev->pdev->dev, rx_ring->cq_size, - &rx_ring->cq_base_dma, GFP_ATOMIC); - - if (!rx_ring->cq_base) { - netif_err(qdev, ifup, qdev->ndev, "rx_ring alloc failed.\n"); - return -ENOMEM; - } - - if (rx_ring->cq_id < qdev->rss_ring_count && - (qlge_init_bq(&rx_ring->sbq) || qlge_init_bq(&rx_ring->lbq))) { - qlge_free_rx_resources(qdev, rx_ring); - return -ENOMEM; - } - - return 0; -} - -static void qlge_tx_ring_clean(struct qlge_adapter *qdev) -{ - struct tx_ring *tx_ring; - struct tx_ring_desc *tx_ring_desc; - int i, j; - - /* - * Loop through all queues and free - * any resources. - */ - for (j = 0; j < qdev->tx_ring_count; j++) { - tx_ring = &qdev->tx_ring[j]; - for (i = 0; i < tx_ring->wq_len; i++) { - tx_ring_desc = &tx_ring->q[i]; - if (tx_ring_desc && tx_ring_desc->skb) { - netif_err(qdev, ifdown, qdev->ndev, - "Freeing lost SKB %p, from queue %d, index %d.\n", - tx_ring_desc->skb, j, - tx_ring_desc->index); - qlge_unmap_send(qdev, tx_ring_desc, - tx_ring_desc->map_cnt); - dev_kfree_skb(tx_ring_desc->skb); - tx_ring_desc->skb = NULL; - } - } - } -} - -static void qlge_free_mem_resources(struct qlge_adapter *qdev) -{ - int i; - - for (i = 0; i < qdev->tx_ring_count; i++) - qlge_free_tx_resources(qdev, &qdev->tx_ring[i]); - for (i = 0; i < qdev->rx_ring_count; i++) - qlge_free_rx_resources(qdev, &qdev->rx_ring[i]); - qlge_free_shadow_space(qdev); -} - -static int qlge_alloc_mem_resources(struct qlge_adapter *qdev) -{ - int i; - - /* Allocate space for our shadow registers and such. */ - if (qlge_alloc_shadow_space(qdev)) - return -ENOMEM; - - for (i = 0; i < qdev->rx_ring_count; i++) { - if (qlge_alloc_rx_resources(qdev, &qdev->rx_ring[i]) != 0) { - netif_err(qdev, ifup, qdev->ndev, - "RX resource allocation failed.\n"); - goto err_mem; - } - } - /* Allocate tx queue resources */ - for (i = 0; i < qdev->tx_ring_count; i++) { - if (qlge_alloc_tx_resources(qdev, &qdev->tx_ring[i]) != 0) { - netif_err(qdev, ifup, qdev->ndev, - "TX resource allocation failed.\n"); - goto err_mem; - } - } - return 0; - -err_mem: - qlge_free_mem_resources(qdev); - return -ENOMEM; -} - -/* Set up the rx ring control block and pass it to the chip. - * The control block is defined as - * "Completion Queue Initialization Control Block", or cqicb. - */ -static int qlge_start_rx_ring(struct qlge_adapter *qdev, struct rx_ring *rx_ring) -{ - struct cqicb *cqicb = &rx_ring->cqicb; - void *shadow_reg = qdev->rx_ring_shadow_reg_area + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); - u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); - void __iomem *doorbell_area = - qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id)); - int err = 0; - u64 dma; - __le64 *base_indirect_ptr; - int page_entries; - - /* Set up the shadow registers for this ring. */ - rx_ring->prod_idx_sh_reg = shadow_reg; - rx_ring->prod_idx_sh_reg_dma = shadow_reg_dma; - *rx_ring->prod_idx_sh_reg = 0; - shadow_reg += sizeof(u64); - shadow_reg_dma += sizeof(u64); - rx_ring->lbq.base_indirect = shadow_reg; - rx_ring->lbq.base_indirect_dma = shadow_reg_dma; - shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN)); - shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN)); - rx_ring->sbq.base_indirect = shadow_reg; - rx_ring->sbq.base_indirect_dma = shadow_reg_dma; - - /* PCI doorbell mem area + 0x00 for consumer index register */ - rx_ring->cnsmr_idx_db_reg = (u32 __iomem *)doorbell_area; - rx_ring->cnsmr_idx = 0; - rx_ring->curr_entry = rx_ring->cq_base; - - /* PCI doorbell mem area + 0x04 for valid register */ - rx_ring->valid_db_reg = doorbell_area + 0x04; - - /* PCI doorbell mem area + 0x18 for large buffer consumer */ - rx_ring->lbq.prod_idx_db_reg = (u32 __iomem *)(doorbell_area + 0x18); - - /* PCI doorbell mem area + 0x1c */ - rx_ring->sbq.prod_idx_db_reg = (u32 __iomem *)(doorbell_area + 0x1c); - - memset((void *)cqicb, 0, sizeof(struct cqicb)); - cqicb->msix_vect = rx_ring->irq; - - cqicb->len = cpu_to_le16(QLGE_FIT16(rx_ring->cq_len) | LEN_V | - LEN_CPP_CONT); - - cqicb->addr = cpu_to_le64(rx_ring->cq_base_dma); - - cqicb->prod_idx_addr = cpu_to_le64(rx_ring->prod_idx_sh_reg_dma); - - /* - * Set up the control block load flags. - */ - cqicb->flags = FLAGS_LC | /* Load queue base address */ - FLAGS_LV | /* Load MSI-X vector */ - FLAGS_LI; /* Load irq delay values */ - if (rx_ring->cq_id < qdev->rss_ring_count) { - cqicb->flags |= FLAGS_LL; /* Load lbq values */ - dma = (u64)rx_ring->lbq.base_dma; - base_indirect_ptr = rx_ring->lbq.base_indirect; - - for (page_entries = 0; - page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN); - page_entries++) { - base_indirect_ptr[page_entries] = cpu_to_le64(dma); - dma += DB_PAGE_SIZE; - } - cqicb->lbq_addr = cpu_to_le64(rx_ring->lbq.base_indirect_dma); - cqicb->lbq_buf_size = - cpu_to_le16(QLGE_FIT16(qdev->lbq_buf_size)); - cqicb->lbq_len = cpu_to_le16(QLGE_FIT16(QLGE_BQ_LEN)); - rx_ring->lbq.next_to_use = 0; - rx_ring->lbq.next_to_clean = 0; - - cqicb->flags |= FLAGS_LS; /* Load sbq values */ - dma = (u64)rx_ring->sbq.base_dma; - base_indirect_ptr = rx_ring->sbq.base_indirect; - - for (page_entries = 0; - page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN); - page_entries++) { - base_indirect_ptr[page_entries] = cpu_to_le64(dma); - dma += DB_PAGE_SIZE; - } - cqicb->sbq_addr = - cpu_to_le64(rx_ring->sbq.base_indirect_dma); - cqicb->sbq_buf_size = cpu_to_le16(SMALL_BUFFER_SIZE); - cqicb->sbq_len = cpu_to_le16(QLGE_FIT16(QLGE_BQ_LEN)); - rx_ring->sbq.next_to_use = 0; - rx_ring->sbq.next_to_clean = 0; - } - if (rx_ring->cq_id < qdev->rss_ring_count) { - /* Inbound completion handling rx_rings run in - * separate NAPI contexts. - */ - netif_napi_add(qdev->ndev, &rx_ring->napi, - qlge_napi_poll_msix); - cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs); - cqicb->pkt_delay = cpu_to_le16(qdev->rx_max_coalesced_frames); - } else { - cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs); - cqicb->pkt_delay = cpu_to_le16(qdev->tx_max_coalesced_frames); - } - err = qlge_write_cfg(qdev, cqicb, sizeof(struct cqicb), - CFG_LCQ, rx_ring->cq_id); - if (err) { - netif_err(qdev, ifup, qdev->ndev, "Failed to load CQICB.\n"); - return err; - } - return err; -} - -static int qlge_start_tx_ring(struct qlge_adapter *qdev, struct tx_ring *tx_ring) -{ - struct wqicb *wqicb = (struct wqicb *)tx_ring; - void __iomem *doorbell_area = - qdev->doorbell_area + (DB_PAGE_SIZE * tx_ring->wq_id); - void *shadow_reg = qdev->tx_ring_shadow_reg_area + - (tx_ring->wq_id * sizeof(u64)); - u64 shadow_reg_dma = qdev->tx_ring_shadow_reg_dma + - (tx_ring->wq_id * sizeof(u64)); - int err = 0; - - /* - * Assign doorbell registers for this tx_ring. - */ - /* TX PCI doorbell mem area for tx producer index */ - tx_ring->prod_idx_db_reg = (u32 __iomem *)doorbell_area; - tx_ring->prod_idx = 0; - /* TX PCI doorbell mem area + 0x04 */ - tx_ring->valid_db_reg = doorbell_area + 0x04; - - /* - * Assign shadow registers for this tx_ring. - */ - tx_ring->cnsmr_idx_sh_reg = shadow_reg; - tx_ring->cnsmr_idx_sh_reg_dma = shadow_reg_dma; - - wqicb->len = cpu_to_le16(tx_ring->wq_len | Q_LEN_V | Q_LEN_CPP_CONT); - wqicb->flags = cpu_to_le16(Q_FLAGS_LC | - Q_FLAGS_LB | Q_FLAGS_LI | Q_FLAGS_LO); - wqicb->cq_id_rss = cpu_to_le16(tx_ring->cq_id); - wqicb->rid = 0; - wqicb->addr = cpu_to_le64(tx_ring->wq_base_dma); - - wqicb->cnsmr_idx_addr = cpu_to_le64(tx_ring->cnsmr_idx_sh_reg_dma); - - qlge_init_tx_ring(qdev, tx_ring); - - err = qlge_write_cfg(qdev, wqicb, sizeof(*wqicb), CFG_LRQ, - (u16)tx_ring->wq_id); - if (err) { - netif_err(qdev, ifup, qdev->ndev, "Failed to load tx_ring.\n"); - return err; - } - return err; -} - -static void qlge_disable_msix(struct qlge_adapter *qdev) -{ - if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) { - pci_disable_msix(qdev->pdev); - clear_bit(QL_MSIX_ENABLED, &qdev->flags); - kfree(qdev->msi_x_entry); - qdev->msi_x_entry = NULL; - } else if (test_bit(QL_MSI_ENABLED, &qdev->flags)) { - pci_disable_msi(qdev->pdev); - clear_bit(QL_MSI_ENABLED, &qdev->flags); - } -} - -/* We start by trying to get the number of vectors - * stored in qdev->intr_count. If we don't get that - * many then we reduce the count and try again. - */ -static void qlge_enable_msix(struct qlge_adapter *qdev) -{ - int i, err; - - /* Get the MSIX vectors. */ - if (qlge_irq_type == MSIX_IRQ) { - /* Try to alloc space for the msix struct, - * if it fails then go to MSI/legacy. - */ - qdev->msi_x_entry = kcalloc(qdev->intr_count, - sizeof(struct msix_entry), - GFP_KERNEL); - if (!qdev->msi_x_entry) { - qlge_irq_type = MSI_IRQ; - goto msi; - } - - for (i = 0; i < qdev->intr_count; i++) - qdev->msi_x_entry[i].entry = i; - - err = pci_enable_msix_range(qdev->pdev, qdev->msi_x_entry, - 1, qdev->intr_count); - if (err < 0) { - kfree(qdev->msi_x_entry); - qdev->msi_x_entry = NULL; - netif_warn(qdev, ifup, qdev->ndev, - "MSI-X Enable failed, trying MSI.\n"); - qlge_irq_type = MSI_IRQ; - } else { - qdev->intr_count = err; - set_bit(QL_MSIX_ENABLED, &qdev->flags); - netif_info(qdev, ifup, qdev->ndev, - "MSI-X Enabled, got %d vectors.\n", - qdev->intr_count); - return; - } - } -msi: - qdev->intr_count = 1; - if (qlge_irq_type == MSI_IRQ) { - if (pci_alloc_irq_vectors(qdev->pdev, 1, 1, PCI_IRQ_MSI) >= 0) { - set_bit(QL_MSI_ENABLED, &qdev->flags); - netif_info(qdev, ifup, qdev->ndev, - "Running with MSI interrupts.\n"); - return; - } - } - qlge_irq_type = LEG_IRQ; - set_bit(QL_LEGACY_ENABLED, &qdev->flags); - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Running with legacy interrupts.\n"); -} - -/* Each vector services 1 RSS ring and 1 or more - * TX completion rings. This function loops through - * the TX completion rings and assigns the vector that - * will service it. An example would be if there are - * 2 vectors (so 2 RSS rings) and 8 TX completion rings. - * This would mean that vector 0 would service RSS ring 0 - * and TX completion rings 0,1,2 and 3. Vector 1 would - * service RSS ring 1 and TX completion rings 4,5,6 and 7. - */ -static void qlge_set_tx_vect(struct qlge_adapter *qdev) -{ - int i, j, vect; - u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count; - - if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) { - /* Assign irq vectors to TX rx_rings.*/ - for (vect = 0, j = 0, i = qdev->rss_ring_count; - i < qdev->rx_ring_count; i++) { - if (j == tx_rings_per_vector) { - vect++; - j = 0; - } - qdev->rx_ring[i].irq = vect; - j++; - } - } else { - /* For single vector all rings have an irq - * of zero. - */ - for (i = 0; i < qdev->rx_ring_count; i++) - qdev->rx_ring[i].irq = 0; - } -} - -/* Set the interrupt mask for this vector. Each vector - * will service 1 RSS ring and 1 or more TX completion - * rings. This function sets up a bit mask per vector - * that indicates which rings it services. - */ -static void qlge_set_irq_mask(struct qlge_adapter *qdev, struct intr_context *ctx) -{ - int j, vect = ctx->intr; - u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count; - - if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) { - /* Add the RSS ring serviced by this vector - * to the mask. - */ - ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id); - /* Add the TX ring(s) serviced by this vector - * to the mask. - */ - for (j = 0; j < tx_rings_per_vector; j++) { - ctx->irq_mask |= - (1 << qdev->rx_ring[qdev->rss_ring_count + - (vect * tx_rings_per_vector) + j].cq_id); - } - } else { - /* For single vector we just shift each queue's - * ID into the mask. - */ - for (j = 0; j < qdev->rx_ring_count; j++) - ctx->irq_mask |= (1 << qdev->rx_ring[j].cq_id); - } -} - -/* - * Here we build the intr_context structures based on - * our rx_ring count and intr vector count. - * The intr_context structure is used to hook each vector - * to possibly different handlers. - */ -static void qlge_resolve_queues_to_irqs(struct qlge_adapter *qdev) -{ - int i = 0; - struct intr_context *intr_context = &qdev->intr_context[0]; - - if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) { - /* Each rx_ring has it's - * own intr_context since we have separate - * vectors for each queue. - */ - for (i = 0; i < qdev->intr_count; i++, intr_context++) { - qdev->rx_ring[i].irq = i; - intr_context->intr = i; - intr_context->qdev = qdev; - /* Set up this vector's bit-mask that indicates - * which queues it services. - */ - qlge_set_irq_mask(qdev, intr_context); - /* - * We set up each vectors enable/disable/read bits so - * there's no bit/mask calculations in the critical path. - */ - intr_context->intr_en_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | - INTR_EN_TYPE_ENABLE | INTR_EN_IHD_MASK | INTR_EN_IHD - | i; - intr_context->intr_dis_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | - INTR_EN_TYPE_DISABLE | INTR_EN_IHD_MASK | - INTR_EN_IHD | i; - intr_context->intr_read_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | - INTR_EN_TYPE_READ | INTR_EN_IHD_MASK | INTR_EN_IHD | - i; - if (i == 0) { - /* The first vector/queue handles - * broadcast/multicast, fatal errors, - * and firmware events. This in addition - * to normal inbound NAPI processing. - */ - intr_context->handler = qlge_isr; - sprintf(intr_context->name, "%s-rx-%d", - qdev->ndev->name, i); - } else { - /* - * Inbound queues handle unicast frames only. - */ - intr_context->handler = qlge_msix_rx_isr; - sprintf(intr_context->name, "%s-rx-%d", - qdev->ndev->name, i); - } - } - } else { - /* - * All rx_rings use the same intr_context since - * there is only one vector. - */ - intr_context->intr = 0; - intr_context->qdev = qdev; - /* - * We set up each vectors enable/disable/read bits so - * there's no bit/mask calculations in the critical path. - */ - intr_context->intr_en_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | INTR_EN_TYPE_ENABLE; - intr_context->intr_dis_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | - INTR_EN_TYPE_DISABLE; - if (test_bit(QL_LEGACY_ENABLED, &qdev->flags)) { - /* Experience shows that when using INTx interrupts, - * the device does not always auto-mask INTR_EN_EN. - * Moreover, masking INTR_EN_EN manually does not - * immediately prevent interrupt generation. - */ - intr_context->intr_en_mask |= INTR_EN_EI << 16 | - INTR_EN_EI; - intr_context->intr_dis_mask |= INTR_EN_EI << 16; - } - intr_context->intr_read_mask = - INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK | INTR_EN_TYPE_READ; - /* - * Single interrupt means one handler for all rings. - */ - intr_context->handler = qlge_isr; - sprintf(intr_context->name, "%s-single_irq", qdev->ndev->name); - /* Set up this vector's bit-mask that indicates - * which queues it services. In this case there is - * a single vector so it will service all RSS and - * TX completion rings. - */ - qlge_set_irq_mask(qdev, intr_context); - } - /* Tell the TX completion rings which MSIx vector - * they will be using. - */ - qlge_set_tx_vect(qdev); -} - -static void qlge_free_irq(struct qlge_adapter *qdev) -{ - int i; - struct intr_context *intr_context = &qdev->intr_context[0]; - - for (i = 0; i < qdev->intr_count; i++, intr_context++) { - if (intr_context->hooked) { - if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) { - free_irq(qdev->msi_x_entry[i].vector, - &qdev->rx_ring[i]); - } else { - free_irq(qdev->pdev->irq, &qdev->rx_ring[0]); - } - } - } - qlge_disable_msix(qdev); -} - -static int qlge_request_irq(struct qlge_adapter *qdev) -{ - int i; - int status = 0; - struct pci_dev *pdev = qdev->pdev; - struct intr_context *intr_context = &qdev->intr_context[0]; - - qlge_resolve_queues_to_irqs(qdev); - - for (i = 0; i < qdev->intr_count; i++, intr_context++) { - if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) { - status = request_irq(qdev->msi_x_entry[i].vector, - intr_context->handler, - 0, - intr_context->name, - &qdev->rx_ring[i]); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed request for MSIX interrupt %d.\n", - i); - goto err_irq; - } - } else { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "trying msi or legacy interrupts.\n"); - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "%s: irq = %d.\n", __func__, pdev->irq); - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "%s: context->name = %s.\n", __func__, - intr_context->name); - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "%s: dev_id = 0x%p.\n", __func__, - &qdev->rx_ring[0]); - status = - request_irq(pdev->irq, qlge_isr, - test_bit(QL_MSI_ENABLED, &qdev->flags) - ? 0 - : IRQF_SHARED, - intr_context->name, &qdev->rx_ring[0]); - if (status) - goto err_irq; - - netif_err(qdev, ifup, qdev->ndev, - "Hooked intr 0, queue type RX_Q, with name %s.\n", - intr_context->name); - } - intr_context->hooked = 1; - } - return status; -err_irq: - netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!\n"); - qlge_free_irq(qdev); - return status; -} - -static int qlge_start_rss(struct qlge_adapter *qdev) -{ - static const u8 init_hash_seed[] = { - 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, - 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, - 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, - 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa - }; - struct ricb *ricb = &qdev->ricb; - int status = 0; - int i; - u8 *hash_id = (u8 *)ricb->hash_cq_id; - - memset((void *)ricb, 0, sizeof(*ricb)); - - ricb->base_cq = RSS_L4K; - ricb->flags = - (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6); - ricb->mask = cpu_to_le16((u16)(0x3ff)); - - /* - * Fill out the Indirection Table. - */ - for (i = 0; i < 1024; i++) - hash_id[i] = (i & (qdev->rss_ring_count - 1)); - - memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40); - memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16); - - status = qlge_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Failed to load RICB.\n"); - return status; - } - return status; -} - -static int qlge_clear_routing_entries(struct qlge_adapter *qdev) -{ - int i, status = 0; - - status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK); - if (status) - return status; - /* Clear all the entries in the routing table. */ - for (i = 0; i < 16; i++) { - status = qlge_set_routing_reg(qdev, i, 0, 0); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for CAM packets.\n"); - break; - } - } - qlge_sem_unlock(qdev, SEM_RT_IDX_MASK); - return status; -} - -/* Initialize the frame-to-queue routing. */ -static int qlge_route_initialize(struct qlge_adapter *qdev) -{ - int status = 0; - - /* Clear all the entries in the routing table. */ - status = qlge_clear_routing_entries(qdev); - if (status) - return status; - - status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK); - if (status) - return status; - - status = qlge_set_routing_reg(qdev, RT_IDX_IP_CSUM_ERR_SLOT, - RT_IDX_IP_CSUM_ERR, 1); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for IP CSUM error packets.\n"); - goto exit; - } - status = qlge_set_routing_reg(qdev, RT_IDX_TCP_UDP_CSUM_ERR_SLOT, - RT_IDX_TU_CSUM_ERR, 1); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for TCP/UDP CSUM error packets.\n"); - goto exit; - } - status = qlge_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for broadcast packets.\n"); - goto exit; - } - /* If we have more than one inbound queue, then turn on RSS in the - * routing block. - */ - if (qdev->rss_ring_count > 1) { - status = qlge_set_routing_reg(qdev, RT_IDX_RSS_MATCH_SLOT, - RT_IDX_RSS_MATCH, 1); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for MATCH RSS packets.\n"); - goto exit; - } - } - - status = qlge_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT, - RT_IDX_CAM_HIT, 1); - if (status) - netif_err(qdev, ifup, qdev->ndev, - "Failed to init routing register for CAM packets.\n"); -exit: - qlge_sem_unlock(qdev, SEM_RT_IDX_MASK); - return status; -} - -int qlge_cam_route_initialize(struct qlge_adapter *qdev) -{ - int status, set; - - /* If check if the link is up and use to - * determine if we are setting or clearing - * the MAC address in the CAM. - */ - set = qlge_read32(qdev, STS); - set &= qdev->port_link_up; - status = qlge_set_mac_addr(qdev, set); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Failed to init mac address.\n"); - return status; - } - - status = qlge_route_initialize(qdev); - if (status) - netif_err(qdev, ifup, qdev->ndev, "Failed to init routing table.\n"); - - return status; -} - -static int qlge_adapter_initialize(struct qlge_adapter *qdev) -{ - u32 value, mask; - int i; - int status = 0; - - /* - * Set up the System register to halt on errors. - */ - value = SYS_EFE | SYS_FAE; - mask = value << 16; - qlge_write32(qdev, SYS, mask | value); - - /* Set the default queue, and VLAN behavior. */ - value = NIC_RCV_CFG_DFQ; - mask = NIC_RCV_CFG_DFQ_MASK; - if (qdev->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) { - value |= NIC_RCV_CFG_RV; - mask |= (NIC_RCV_CFG_RV << 16); - } - qlge_write32(qdev, NIC_RCV_CFG, (mask | value)); - - /* Set the MPI interrupt to enabled. */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); - - /* Enable the function, set pagesize, enable error checking. */ - value = FSC_FE | FSC_EPC_INBOUND | FSC_EPC_OUTBOUND | - FSC_EC | FSC_VM_PAGE_4K; - value |= SPLT_SETTING; - - /* Set/clear header splitting. */ - mask = FSC_VM_PAGESIZE_MASK | - FSC_DBL_MASK | FSC_DBRST_MASK | (value << 16); - qlge_write32(qdev, FSC, mask | value); - - qlge_write32(qdev, SPLT_HDR, SPLT_LEN); - - /* Set RX packet routing to use port/pci function on which the - * packet arrived on in addition to usual frame routing. - * This is helpful on bonding where both interfaces can have - * the same MAC address. - */ - qlge_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ); - /* Reroute all packets to our Interface. - * They may have been routed to MPI firmware - * due to WOL. - */ - value = qlge_read32(qdev, MGMT_RCV_CFG); - value &= ~MGMT_RCV_CFG_RM; - mask = 0xffff0000; - - /* Sticky reg needs clearing due to WOL. */ - qlge_write32(qdev, MGMT_RCV_CFG, mask); - qlge_write32(qdev, MGMT_RCV_CFG, mask | value); - - /* Default WOL is enable on Mezz cards */ - if (qdev->pdev->subsystem_device == 0x0068 || - qdev->pdev->subsystem_device == 0x0180) - qdev->wol = WAKE_MAGIC; - - /* Start up the rx queues. */ - for (i = 0; i < qdev->rx_ring_count; i++) { - status = qlge_start_rx_ring(qdev, &qdev->rx_ring[i]); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to start rx ring[%d].\n", i); - return status; - } - } - - /* If there is more than one inbound completion queue - * then download a RICB to configure RSS. - */ - if (qdev->rss_ring_count > 1) { - status = qlge_start_rss(qdev); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Failed to start RSS.\n"); - return status; - } - } - - /* Start up the tx queues. */ - for (i = 0; i < qdev->tx_ring_count; i++) { - status = qlge_start_tx_ring(qdev, &qdev->tx_ring[i]); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to start tx ring[%d].\n", i); - return status; - } - } - - /* Initialize the port and set the max framesize. */ - status = qdev->nic_ops->port_initialize(qdev); - if (status) - netif_err(qdev, ifup, qdev->ndev, "Failed to start port.\n"); - - /* Set up the MAC address and frame routing filter. */ - status = qlge_cam_route_initialize(qdev); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init CAM/Routing tables.\n"); - return status; - } - - /* Start NAPI for the RSS queues. */ - for (i = 0; i < qdev->rss_ring_count; i++) - napi_enable(&qdev->rx_ring[i].napi); - - return status; -} - -/* Issue soft reset to chip. */ -static int qlge_adapter_reset(struct qlge_adapter *qdev) -{ - u32 value; - int status = 0; - unsigned long end_jiffies; - - /* Clear all the entries in the routing table. */ - status = qlge_clear_routing_entries(qdev); - if (status) { - netif_err(qdev, ifup, qdev->ndev, "Failed to clear routing bits.\n"); - return status; - } - - /* Check if bit is set then skip the mailbox command and - * clear the bit, else we are in normal reset process. - */ - if (!test_bit(QL_ASIC_RECOVERY, &qdev->flags)) { - /* Stop management traffic. */ - qlge_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); - - /* Wait for the NIC and MGMNT FIFOs to empty. */ - qlge_wait_fifo_empty(qdev); - } else { - clear_bit(QL_ASIC_RECOVERY, &qdev->flags); - } - - qlge_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); - - end_jiffies = jiffies + usecs_to_jiffies(30); - do { - value = qlge_read32(qdev, RST_FO); - if ((value & RST_FO_FR) == 0) - break; - cpu_relax(); - } while (time_before(jiffies, end_jiffies)); - - if (value & RST_FO_FR) { - netif_err(qdev, ifdown, qdev->ndev, - "ETIMEDOUT!!! errored out of resetting the chip!\n"); - status = -ETIMEDOUT; - } - - /* Resume management traffic. */ - qlge_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME); - return status; -} - -static void qlge_display_dev_info(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - netif_info(qdev, probe, qdev->ndev, - "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, XG Roll = %d, XG Rev = %d.\n", - qdev->func, - qdev->port, - qdev->chip_rev_id & 0x0000000f, - qdev->chip_rev_id >> 4 & 0x0000000f, - qdev->chip_rev_id >> 8 & 0x0000000f, - qdev->chip_rev_id >> 12 & 0x0000000f); - netif_info(qdev, probe, qdev->ndev, - "MAC address %pM\n", ndev->dev_addr); -} - -static int qlge_wol(struct qlge_adapter *qdev) -{ - int status = 0; - u32 wol = MB_WOL_DISABLE; - - /* The CAM is still intact after a reset, but if we - * are doing WOL, then we may need to program the - * routing regs. We would also need to issue the mailbox - * commands to instruct the MPI what to do per the ethtool - * settings. - */ - - if (qdev->wol & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY | WAKE_UCAST | - WAKE_MCAST | WAKE_BCAST)) { - netif_err(qdev, ifdown, qdev->ndev, - "Unsupported WOL parameter. qdev->wol = 0x%x.\n", - qdev->wol); - return -EINVAL; - } - - if (qdev->wol & WAKE_MAGIC) { - status = qlge_mb_wol_set_magic(qdev, 1); - if (status) { - netif_err(qdev, ifdown, qdev->ndev, - "Failed to set magic packet on %s.\n", - qdev->ndev->name); - return status; - } - netif_info(qdev, drv, qdev->ndev, - "Enabled magic packet successfully on %s.\n", - qdev->ndev->name); - - wol |= MB_WOL_MAGIC_PKT; - } - - if (qdev->wol) { - wol |= MB_WOL_MODE_ON; - status = qlge_mb_wol_mode(qdev, wol); - netif_err(qdev, drv, qdev->ndev, - "WOL %s (wol code 0x%x) on %s\n", - (status == 0) ? "Successfully set" : "Failed", - wol, qdev->ndev->name); - } - - return status; -} - -static void qlge_cancel_all_work_sync(struct qlge_adapter *qdev) -{ - /* Don't kill the reset worker thread if we - * are in the process of recovery. - */ - if (test_bit(QL_ADAPTER_UP, &qdev->flags)) - cancel_delayed_work_sync(&qdev->asic_reset_work); - cancel_delayed_work_sync(&qdev->mpi_reset_work); - cancel_delayed_work_sync(&qdev->mpi_work); - cancel_delayed_work_sync(&qdev->mpi_idc_work); - cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); -} - -static int qlge_adapter_down(struct qlge_adapter *qdev) -{ - int i, status = 0; - - qlge_link_off(qdev); - - qlge_cancel_all_work_sync(qdev); - - for (i = 0; i < qdev->rss_ring_count; i++) - napi_disable(&qdev->rx_ring[i].napi); - - clear_bit(QL_ADAPTER_UP, &qdev->flags); - - qlge_disable_interrupts(qdev); - - qlge_tx_ring_clean(qdev); - - /* Call netif_napi_del() from common point. */ - for (i = 0; i < qdev->rss_ring_count; i++) - netif_napi_del(&qdev->rx_ring[i].napi); - - status = qlge_adapter_reset(qdev); - if (status) - netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", - qdev->func); - qlge_free_rx_buffers(qdev); - - return status; -} - -static int qlge_adapter_up(struct qlge_adapter *qdev) -{ - int err = 0; - - err = qlge_adapter_initialize(qdev); - if (err) { - netif_info(qdev, ifup, qdev->ndev, "Unable to initialize adapter.\n"); - goto err_init; - } - set_bit(QL_ADAPTER_UP, &qdev->flags); - qlge_alloc_rx_buffers(qdev); - /* If the port is initialized and the - * link is up the turn on the carrier. - */ - if ((qlge_read32(qdev, STS) & qdev->port_init) && - (qlge_read32(qdev, STS) & qdev->port_link_up)) - qlge_link_on(qdev); - /* Restore rx mode. */ - clear_bit(QL_ALLMULTI, &qdev->flags); - clear_bit(QL_PROMISCUOUS, &qdev->flags); - qlge_set_multicast_list(qdev->ndev); - - /* Restore vlan setting. */ - qlge_restore_vlan(qdev); - - qlge_enable_interrupts(qdev); - qlge_enable_all_completion_interrupts(qdev); - netif_tx_start_all_queues(qdev->ndev); - - return 0; -err_init: - qlge_adapter_reset(qdev); - return err; -} - -static void qlge_release_adapter_resources(struct qlge_adapter *qdev) -{ - qlge_free_mem_resources(qdev); - qlge_free_irq(qdev); -} - -static int qlge_get_adapter_resources(struct qlge_adapter *qdev) -{ - if (qlge_alloc_mem_resources(qdev)) { - netif_err(qdev, ifup, qdev->ndev, "Unable to allocate memory.\n"); - return -ENOMEM; - } - return qlge_request_irq(qdev); -} - -static int qlge_close(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int i; - - /* If we hit pci_channel_io_perm_failure - * failure condition, then we already - * brought the adapter down. - */ - if (test_bit(QL_EEH_FATAL, &qdev->flags)) { - netif_err(qdev, drv, qdev->ndev, "EEH fatal did unload.\n"); - clear_bit(QL_EEH_FATAL, &qdev->flags); - return 0; - } - - /* - * Wait for device to recover from a reset. - * (Rarely happens, but possible.) - */ - while (!test_bit(QL_ADAPTER_UP, &qdev->flags)) - msleep(1); - - /* Make sure refill_work doesn't re-enable napi */ - for (i = 0; i < qdev->rss_ring_count; i++) - cancel_delayed_work_sync(&qdev->rx_ring[i].refill_work); - - qlge_adapter_down(qdev); - qlge_release_adapter_resources(qdev); - return 0; -} - -static void qlge_set_lb_size(struct qlge_adapter *qdev) -{ - if (qdev->ndev->mtu <= 1500) - qdev->lbq_buf_size = LARGE_BUFFER_MIN_SIZE; - else - qdev->lbq_buf_size = LARGE_BUFFER_MAX_SIZE; - qdev->lbq_buf_order = get_order(qdev->lbq_buf_size); -} - -static int qlge_configure_rings(struct qlge_adapter *qdev) -{ - int i; - struct rx_ring *rx_ring; - struct tx_ring *tx_ring; - int cpu_cnt = min_t(int, MAX_CPUS, num_online_cpus()); - - /* In a perfect world we have one RSS ring for each CPU - * and each has it's own vector. To do that we ask for - * cpu_cnt vectors. qlge_enable_msix() will adjust the - * vector count to what we actually get. We then - * allocate an RSS ring for each. - * Essentially, we are doing min(cpu_count, msix_vector_count). - */ - qdev->intr_count = cpu_cnt; - qlge_enable_msix(qdev); - /* Adjust the RSS ring count to the actual vector count. */ - qdev->rss_ring_count = qdev->intr_count; - qdev->tx_ring_count = cpu_cnt; - qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count; - - for (i = 0; i < qdev->tx_ring_count; i++) { - tx_ring = &qdev->tx_ring[i]; - memset((void *)tx_ring, 0, sizeof(*tx_ring)); - tx_ring->qdev = qdev; - tx_ring->wq_id = i; - tx_ring->wq_len = qdev->tx_ring_size; - tx_ring->wq_size = - tx_ring->wq_len * sizeof(struct qlge_ob_mac_iocb_req); - - /* - * The completion queue ID for the tx rings start - * immediately after the rss rings. - */ - tx_ring->cq_id = qdev->rss_ring_count + i; - } - - for (i = 0; i < qdev->rx_ring_count; i++) { - rx_ring = &qdev->rx_ring[i]; - memset((void *)rx_ring, 0, sizeof(*rx_ring)); - rx_ring->qdev = qdev; - rx_ring->cq_id = i; - rx_ring->cpu = i % cpu_cnt; /* CPU to run handler on. */ - if (i < qdev->rss_ring_count) { - /* - * Inbound (RSS) queues. - */ - rx_ring->cq_len = qdev->rx_ring_size; - rx_ring->cq_size = - rx_ring->cq_len * sizeof(struct qlge_net_rsp_iocb); - rx_ring->lbq.type = QLGE_LB; - rx_ring->sbq.type = QLGE_SB; - INIT_DELAYED_WORK(&rx_ring->refill_work, - &qlge_slow_refill); - } else { - /* - * Outbound queue handles outbound completions only. - */ - /* outbound cq is same size as tx_ring it services. */ - rx_ring->cq_len = qdev->tx_ring_size; - rx_ring->cq_size = - rx_ring->cq_len * sizeof(struct qlge_net_rsp_iocb); - } - } - return 0; -} - -static int qlge_open(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int err = 0; - - err = qlge_adapter_reset(qdev); - if (err) - return err; - - qlge_set_lb_size(qdev); - err = qlge_configure_rings(qdev); - if (err) - return err; - - err = qlge_get_adapter_resources(qdev); - if (err) - goto error_up; - - err = qlge_adapter_up(qdev); - if (err) - goto error_up; - - return err; - -error_up: - qlge_release_adapter_resources(qdev); - return err; -} - -static int qlge_change_rx_buffers(struct qlge_adapter *qdev) -{ - int status; - - /* Wait for an outstanding reset to complete. */ - if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) { - int i = 4; - - while (--i && !test_bit(QL_ADAPTER_UP, &qdev->flags)) { - netif_err(qdev, ifup, qdev->ndev, - "Waiting for adapter UP...\n"); - ssleep(1); - } - - if (!i) { - netif_err(qdev, ifup, qdev->ndev, - "Timed out waiting for adapter UP\n"); - return -ETIMEDOUT; - } - } - - status = qlge_adapter_down(qdev); - if (status) - goto error; - - qlge_set_lb_size(qdev); - - status = qlge_adapter_up(qdev); - if (status) - goto error; - - return status; -error: - netif_alert(qdev, ifup, qdev->ndev, - "Driver up/down cycle failed, closing device.\n"); - set_bit(QL_ADAPTER_UP, &qdev->flags); - dev_close(qdev->ndev); - return status; -} - -static int qlge_change_mtu(struct net_device *ndev, int new_mtu) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int status; - - if (ndev->mtu == 1500 && new_mtu == 9000) - netif_err(qdev, ifup, qdev->ndev, "Changing to jumbo MTU.\n"); - else if (ndev->mtu == 9000 && new_mtu == 1500) - netif_err(qdev, ifup, qdev->ndev, "Changing to normal MTU.\n"); - else - return -EINVAL; - - queue_delayed_work(qdev->workqueue, - &qdev->mpi_port_cfg_work, 3 * HZ); - - ndev->mtu = new_mtu; - - if (!netif_running(qdev->ndev)) - return 0; - - status = qlge_change_rx_buffers(qdev); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Changing MTU failed.\n"); - } - - return status; -} - -static struct net_device_stats *qlge_get_stats(struct net_device - *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - struct rx_ring *rx_ring = &qdev->rx_ring[0]; - struct tx_ring *tx_ring = &qdev->tx_ring[0]; - unsigned long pkts, mcast, dropped, errors, bytes; - int i; - - /* Get RX stats. */ - pkts = mcast = dropped = errors = bytes = 0; - for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) { - pkts += rx_ring->rx_packets; - bytes += rx_ring->rx_bytes; - dropped += rx_ring->rx_dropped; - errors += rx_ring->rx_errors; - mcast += rx_ring->rx_multicast; - } - ndev->stats.rx_packets = pkts; - ndev->stats.rx_bytes = bytes; - ndev->stats.rx_dropped = dropped; - ndev->stats.rx_errors = errors; - ndev->stats.multicast = mcast; - - /* Get TX stats. */ - pkts = errors = bytes = 0; - for (i = 0; i < qdev->tx_ring_count; i++, tx_ring++) { - pkts += tx_ring->tx_packets; - bytes += tx_ring->tx_bytes; - errors += tx_ring->tx_errors; - } - ndev->stats.tx_packets = pkts; - ndev->stats.tx_bytes = bytes; - ndev->stats.tx_errors = errors; - return &ndev->stats; -} - -static void qlge_set_multicast_list(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - struct netdev_hw_addr *ha; - int i, status; - - status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK); - if (status) - return; - /* - * Set or clear promiscuous mode if a - * transition is taking place. - */ - if (ndev->flags & IFF_PROMISC) { - if (!test_bit(QL_PROMISCUOUS, &qdev->flags)) { - if (qlge_set_routing_reg - (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 1)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to set promiscuous mode.\n"); - } else { - set_bit(QL_PROMISCUOUS, &qdev->flags); - } - } - } else { - if (test_bit(QL_PROMISCUOUS, &qdev->flags)) { - if (qlge_set_routing_reg - (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 0)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to clear promiscuous mode.\n"); - } else { - clear_bit(QL_PROMISCUOUS, &qdev->flags); - } - } - } - - /* - * Set or clear all multicast mode if a - * transition is taking place. - */ - if ((ndev->flags & IFF_ALLMULTI) || - (netdev_mc_count(ndev) > MAX_MULTICAST_ENTRIES)) { - if (!test_bit(QL_ALLMULTI, &qdev->flags)) { - if (qlge_set_routing_reg - (qdev, RT_IDX_ALLMULTI_SLOT, RT_IDX_MCAST, 1)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to set all-multi mode.\n"); - } else { - set_bit(QL_ALLMULTI, &qdev->flags); - } - } - } else { - if (test_bit(QL_ALLMULTI, &qdev->flags)) { - if (qlge_set_routing_reg - (qdev, RT_IDX_ALLMULTI_SLOT, RT_IDX_MCAST, 0)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to clear all-multi mode.\n"); - } else { - clear_bit(QL_ALLMULTI, &qdev->flags); - } - } - } - - if (!netdev_mc_empty(ndev)) { - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - goto exit; - i = 0; - netdev_for_each_mc_addr(ha, ndev) { - if (qlge_set_mac_addr_reg(qdev, (u8 *)ha->addr, - MAC_ADDR_TYPE_MULTI_MAC, i)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to loadmulticast address.\n"); - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - goto exit; - } - i++; - } - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - if (qlge_set_routing_reg - (qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) { - netif_err(qdev, hw, qdev->ndev, - "Failed to set multicast match mode.\n"); - } else { - set_bit(QL_ALLMULTI, &qdev->flags); - } - } -exit: - qlge_sem_unlock(qdev, SEM_RT_IDX_MASK); -} - -static int qlge_set_mac_address(struct net_device *ndev, void *p) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - struct sockaddr *addr = p; - int status; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - eth_hw_addr_set(ndev, addr->sa_data); - /* Update local copy of current mac address. */ - memcpy(qdev->current_mac_addr, ndev->dev_addr, ndev->addr_len); - - status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); - if (status) - return status; - status = qlge_set_mac_addr_reg(qdev, (const u8 *)ndev->dev_addr, - MAC_ADDR_TYPE_CAM_MAC, - qdev->func * MAX_CQ); - if (status) - netif_err(qdev, hw, qdev->ndev, "Failed to load MAC address.\n"); - qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK); - return status; -} - -static void qlge_tx_timeout(struct net_device *ndev, unsigned int txqueue) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - - qlge_queue_asic_error(qdev); -} - -static void qlge_asic_reset_work(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, asic_reset_work.work); - int status; - - rtnl_lock(); - status = qlge_adapter_down(qdev); - if (status) - goto error; - - status = qlge_adapter_up(qdev); - if (status) - goto error; - - /* Restore rx mode. */ - clear_bit(QL_ALLMULTI, &qdev->flags); - clear_bit(QL_PROMISCUOUS, &qdev->flags); - qlge_set_multicast_list(qdev->ndev); - - rtnl_unlock(); - return; -error: - netif_alert(qdev, ifup, qdev->ndev, - "Driver up/down cycle failed, closing device\n"); - - set_bit(QL_ADAPTER_UP, &qdev->flags); - dev_close(qdev->ndev); - rtnl_unlock(); -} - -static const struct nic_operations qla8012_nic_ops = { - .get_flash = qlge_get_8012_flash_params, - .port_initialize = qlge_8012_port_initialize, -}; - -static const struct nic_operations qla8000_nic_ops = { - .get_flash = qlge_get_8000_flash_params, - .port_initialize = qlge_8000_port_initialize, -}; - -/* Find the pcie function number for the other NIC - * on this chip. Since both NIC functions share a - * common firmware we have the lowest enabled function - * do any common work. Examples would be resetting - * after a fatal firmware error, or doing a firmware - * coredump. - */ -static int qlge_get_alt_pcie_func(struct qlge_adapter *qdev) -{ - int status = 0; - u32 temp; - u32 nic_func1, nic_func2; - - status = qlge_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG, - &temp); - if (status) - return status; - - nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - - if (qdev->func == nic_func1) - qdev->alt_func = nic_func2; - else if (qdev->func == nic_func2) - qdev->alt_func = nic_func1; - else - status = -EIO; - - return status; -} - -static int qlge_get_board_info(struct qlge_adapter *qdev) -{ - int status; - - qdev->func = - (qlge_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; - if (qdev->func > 3) - return -EIO; - - status = qlge_get_alt_pcie_func(qdev); - if (status) - return status; - - qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1; - if (qdev->port) { - qdev->xg_sem_mask = SEM_XGMAC1_MASK; - qdev->port_link_up = STS_PL1; - qdev->port_init = STS_PI1; - qdev->mailbox_in = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC2_MBI; - qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC2_MBO; - } else { - qdev->xg_sem_mask = SEM_XGMAC0_MASK; - qdev->port_link_up = STS_PL0; - qdev->port_init = STS_PI0; - qdev->mailbox_in = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBI; - qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO; - } - qdev->chip_rev_id = qlge_read32(qdev, REV_ID); - qdev->device_id = qdev->pdev->device; - if (qdev->device_id == QLGE_DEVICE_ID_8012) - qdev->nic_ops = &qla8012_nic_ops; - else if (qdev->device_id == QLGE_DEVICE_ID_8000) - qdev->nic_ops = &qla8000_nic_ops; - return status; -} - -static void qlge_release_all(struct pci_dev *pdev) -{ - struct qlge_adapter *qdev = pci_get_drvdata(pdev); - - if (qdev->workqueue) { - destroy_workqueue(qdev->workqueue); - qdev->workqueue = NULL; - } - - if (qdev->reg_base) - iounmap(qdev->reg_base); - if (qdev->doorbell_area) - iounmap(qdev->doorbell_area); - vfree(qdev->mpi_coredump); - pci_release_regions(pdev); -} - -static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, - int cards_found) -{ - struct net_device *ndev = qdev->ndev; - int err = 0; - - err = pci_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "PCI device enable failed.\n"); - return err; - } - - qdev->pdev = pdev; - pci_set_drvdata(pdev, qdev); - - /* Set PCIe read request size */ - err = pcie_set_readrq(pdev, 4096); - if (err) { - dev_err(&pdev->dev, "Set readrq failed.\n"); - goto err_disable_pci; - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - dev_err(&pdev->dev, "PCI region request failed.\n"); - goto err_disable_pci; - } - - pci_set_master(pdev); - if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { - set_bit(QL_DMA64, &qdev->flags); - err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); - } else { - err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (!err) - err = dma_set_coherent_mask(&pdev->dev, - DMA_BIT_MASK(32)); - } - - if (err) { - dev_err(&pdev->dev, "No usable DMA configuration.\n"); - goto err_release_pci; - } - - /* Set PCIe reset type for EEH to fundamental. */ - pdev->needs_freset = 1; - pci_save_state(pdev); - qdev->reg_base = - ioremap(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); - if (!qdev->reg_base) { - dev_err(&pdev->dev, "Register mapping failed.\n"); - err = -ENOMEM; - goto err_release_pci; - } - - qdev->doorbell_area_size = pci_resource_len(pdev, 3); - qdev->doorbell_area = - ioremap(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); - if (!qdev->doorbell_area) { - dev_err(&pdev->dev, "Doorbell register mapping failed.\n"); - err = -ENOMEM; - goto err_iounmap_base; - } - - err = qlge_get_board_info(qdev); - if (err) { - dev_err(&pdev->dev, "Register access failed.\n"); - err = -EIO; - goto err_iounmap_doorbell; - } - qdev->msg_enable = netif_msg_init(debug, default_msg); - spin_lock_init(&qdev->stats_lock); - - if (qlge_mpi_coredump) { - qdev->mpi_coredump = - vmalloc(sizeof(struct qlge_mpi_coredump)); - if (!qdev->mpi_coredump) { - err = -ENOMEM; - goto err_iounmap_doorbell; - } - if (qlge_force_coredump) - set_bit(QL_FRC_COREDUMP, &qdev->flags); - } - /* make sure the EEPROM is good */ - err = qdev->nic_ops->get_flash(qdev); - if (err) { - dev_err(&pdev->dev, "Invalid FLASH.\n"); - goto err_free_mpi_coredump; - } - - /* Keep local copy of current mac address. */ - memcpy(qdev->current_mac_addr, ndev->dev_addr, ndev->addr_len); - - /* Set up the default ring sizes. */ - qdev->tx_ring_size = NUM_TX_RING_ENTRIES; - qdev->rx_ring_size = NUM_RX_RING_ENTRIES; - - /* Set up the coalescing parameters. */ - qdev->rx_coalesce_usecs = DFLT_COALESCE_WAIT; - qdev->tx_coalesce_usecs = DFLT_COALESCE_WAIT; - qdev->rx_max_coalesced_frames = DFLT_INTER_FRAME_WAIT; - qdev->tx_max_coalesced_frames = DFLT_INTER_FRAME_WAIT; - - /* - * Set up the operating parameters. - */ - qdev->workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, - ndev->name); - if (!qdev->workqueue) { - err = -ENOMEM; - goto err_free_mpi_coredump; - } - - INIT_DELAYED_WORK(&qdev->asic_reset_work, qlge_asic_reset_work); - INIT_DELAYED_WORK(&qdev->mpi_reset_work, qlge_mpi_reset_work); - INIT_DELAYED_WORK(&qdev->mpi_work, qlge_mpi_work); - INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, qlge_mpi_port_cfg_work); - INIT_DELAYED_WORK(&qdev->mpi_idc_work, qlge_mpi_idc_work); - init_completion(&qdev->ide_completion); - mutex_init(&qdev->mpi_mutex); - - if (!cards_found) { - dev_info(&pdev->dev, "%s\n", DRV_STRING); - dev_info(&pdev->dev, "Driver name: %s, Version: %s.\n", - DRV_NAME, DRV_VERSION); - } - return 0; - -err_free_mpi_coredump: - vfree(qdev->mpi_coredump); -err_iounmap_doorbell: - iounmap(qdev->doorbell_area); -err_iounmap_base: - iounmap(qdev->reg_base); -err_release_pci: - pci_release_regions(pdev); -err_disable_pci: - pci_disable_device(pdev); - - return err; -} - -static const struct net_device_ops qlge_netdev_ops = { - .ndo_open = qlge_open, - .ndo_stop = qlge_close, - .ndo_start_xmit = qlge_send, - .ndo_change_mtu = qlge_change_mtu, - .ndo_get_stats = qlge_get_stats, - .ndo_set_rx_mode = qlge_set_multicast_list, - .ndo_set_mac_address = qlge_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_tx_timeout = qlge_tx_timeout, - .ndo_set_features = qlge_set_features, - .ndo_vlan_rx_add_vid = qlge_vlan_rx_add_vid, - .ndo_vlan_rx_kill_vid = qlge_vlan_rx_kill_vid, -}; - -static void qlge_timer(struct timer_list *t) -{ - struct qlge_adapter *qdev = from_timer(qdev, t, timer); - u32 var = 0; - - var = qlge_read32(qdev, STS); - if (pci_channel_offline(qdev->pdev)) { - netif_err(qdev, ifup, qdev->ndev, "EEH STS = 0x%.08x.\n", var); - return; - } - - mod_timer(&qdev->timer, jiffies + (5 * HZ)); -} - -static const struct devlink_ops qlge_devlink_ops; - -static int qlge_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_entry) -{ - struct qlge_netdev_priv *ndev_priv; - struct qlge_adapter *qdev = NULL; - struct net_device *ndev = NULL; - struct devlink *devlink; - static int cards_found; - int err; - - devlink = devlink_alloc(&qlge_devlink_ops, sizeof(struct qlge_adapter), - &pdev->dev); - if (!devlink) - return -ENOMEM; - - qdev = devlink_priv(devlink); - - ndev = alloc_etherdev_mq(sizeof(struct qlge_netdev_priv), - min(MAX_CPUS, - netif_get_num_default_rss_queues())); - if (!ndev) { - err = -ENOMEM; - goto devlink_free; - } - - ndev_priv = netdev_priv(ndev); - ndev_priv->qdev = qdev; - ndev_priv->ndev = ndev; - qdev->ndev = ndev; - err = qlge_init_device(pdev, qdev, cards_found); - if (err < 0) - goto netdev_free; - - SET_NETDEV_DEV(ndev, &pdev->dev); - ndev->hw_features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_TSO | - NETIF_F_TSO_ECN | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_RXCSUM; - ndev->features = ndev->hw_features; - ndev->vlan_features = ndev->hw_features; - /* vlan gets same features (except vlan filter) */ - ndev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX); - - if (test_bit(QL_DMA64, &qdev->flags)) - ndev->features |= NETIF_F_HIGHDMA; - - /* - * Set up net_device structure. - */ - ndev->tx_queue_len = qdev->tx_ring_size; - ndev->irq = pdev->irq; - - ndev->netdev_ops = &qlge_netdev_ops; - ndev->ethtool_ops = &qlge_ethtool_ops; - ndev->watchdog_timeo = 10 * HZ; - - /* MTU range: this driver only supports 1500 or 9000, so this only - * filters out values above or below, and we'll rely on - * qlge_change_mtu to make sure only 1500 or 9000 are allowed - */ - ndev->min_mtu = ETH_DATA_LEN; - ndev->max_mtu = 9000; - - err = register_netdev(ndev); - if (err) { - dev_err(&pdev->dev, "net device registration failed.\n"); - goto cleanup_pdev; - } - - err = qlge_health_create_reporters(qdev); - if (err) - goto unregister_netdev; - - /* Start up the timer to trigger EEH if - * the bus goes dead - */ - timer_setup(&qdev->timer, qlge_timer, TIMER_DEFERRABLE); - mod_timer(&qdev->timer, jiffies + (5 * HZ)); - qlge_link_off(qdev); - qlge_display_dev_info(ndev); - atomic_set(&qdev->lb_count, 0); - cards_found++; - devlink_register(devlink); - return 0; - -unregister_netdev: - unregister_netdev(ndev); -cleanup_pdev: - qlge_release_all(pdev); - pci_disable_device(pdev); -netdev_free: - free_netdev(ndev); -devlink_free: - devlink_free(devlink); - - return err; -} - -netdev_tx_t qlge_lb_send(struct sk_buff *skb, struct net_device *ndev) -{ - return qlge_send(skb, ndev); -} - -int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget) -{ - return qlge_clean_inbound_rx_ring(rx_ring, budget); -} - -static void qlge_remove(struct pci_dev *pdev) -{ - struct qlge_adapter *qdev = pci_get_drvdata(pdev); - struct net_device *ndev = qdev->ndev; - struct devlink *devlink = priv_to_devlink(qdev); - - devlink_unregister(devlink); - del_timer_sync(&qdev->timer); - qlge_cancel_all_work_sync(qdev); - unregister_netdev(ndev); - qlge_release_all(pdev); - pci_disable_device(pdev); - devlink_health_reporter_destroy(qdev->reporter); - devlink_free(devlink); - free_netdev(ndev); -} - -/* Clean up resources without touching hardware. */ -static void qlge_eeh_close(struct net_device *ndev) -{ - struct qlge_adapter *qdev = netdev_to_qdev(ndev); - int i; - - if (netif_carrier_ok(ndev)) { - netif_carrier_off(ndev); - netif_stop_queue(ndev); - } - - /* Disabling the timer */ - qlge_cancel_all_work_sync(qdev); - - for (i = 0; i < qdev->rss_ring_count; i++) - netif_napi_del(&qdev->rx_ring[i].napi); - - clear_bit(QL_ADAPTER_UP, &qdev->flags); - qlge_tx_ring_clean(qdev); - qlge_free_rx_buffers(qdev); - qlge_release_adapter_resources(qdev); -} - -/* - * This callback is called by the PCI subsystem whenever - * a PCI bus error is detected. - */ -static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ - struct qlge_adapter *qdev = pci_get_drvdata(pdev); - struct net_device *ndev = qdev->ndev; - - switch (state) { - case pci_channel_io_normal: - return PCI_ERS_RESULT_CAN_RECOVER; - case pci_channel_io_frozen: - netif_device_detach(ndev); - del_timer_sync(&qdev->timer); - if (netif_running(ndev)) - qlge_eeh_close(ndev); - pci_disable_device(pdev); - return PCI_ERS_RESULT_NEED_RESET; - case pci_channel_io_perm_failure: - dev_err(&pdev->dev, - "%s: pci_channel_io_perm_failure.\n", __func__); - del_timer_sync(&qdev->timer); - qlge_eeh_close(ndev); - set_bit(QL_EEH_FATAL, &qdev->flags); - return PCI_ERS_RESULT_DISCONNECT; - } - - /* Request a slot reset. */ - return PCI_ERS_RESULT_NEED_RESET; -} - -/* - * This callback is called after the PCI buss has been reset. - * Basically, this tries to restart the card from scratch. - * This is a shortened version of the device probe/discovery code, - * it resembles the first-half of the () routine. - */ -static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev) -{ - struct qlge_adapter *qdev = pci_get_drvdata(pdev); - - pdev->error_state = pci_channel_io_normal; - - pci_restore_state(pdev); - if (pci_enable_device(pdev)) { - netif_err(qdev, ifup, qdev->ndev, - "Cannot re-enable PCI device after reset.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - pci_set_master(pdev); - - if (qlge_adapter_reset(qdev)) { - netif_err(qdev, drv, qdev->ndev, "reset FAILED!\n"); - set_bit(QL_EEH_FATAL, &qdev->flags); - return PCI_ERS_RESULT_DISCONNECT; - } - - return PCI_ERS_RESULT_RECOVERED; -} - -static void qlge_io_resume(struct pci_dev *pdev) -{ - struct qlge_adapter *qdev = pci_get_drvdata(pdev); - struct net_device *ndev = qdev->ndev; - int err = 0; - - if (netif_running(ndev)) { - err = qlge_open(ndev); - if (err) { - netif_err(qdev, ifup, qdev->ndev, - "Device initialization failed after reset.\n"); - return; - } - } else { - netif_err(qdev, ifup, qdev->ndev, - "Device was not running prior to EEH.\n"); - } - mod_timer(&qdev->timer, jiffies + (5 * HZ)); - netif_device_attach(ndev); -} - -static const struct pci_error_handlers qlge_err_handler = { - .error_detected = qlge_io_error_detected, - .slot_reset = qlge_io_slot_reset, - .resume = qlge_io_resume, -}; - -static int __maybe_unused qlge_suspend(struct device *dev_d) -{ - struct pci_dev *pdev = to_pci_dev(dev_d); - struct qlge_adapter *qdev; - struct net_device *ndev; - int err; - - qdev = pci_get_drvdata(pdev); - ndev = qdev->ndev; - netif_device_detach(ndev); - del_timer_sync(&qdev->timer); - - if (netif_running(ndev)) { - err = qlge_adapter_down(qdev); - if (!err) - return err; - } - - qlge_wol(qdev); - - return 0; -} - -static int __maybe_unused qlge_resume(struct device *dev_d) -{ - struct pci_dev *pdev = to_pci_dev(dev_d); - struct qlge_adapter *qdev; - struct net_device *ndev; - int err; - - qdev = pci_get_drvdata(pdev); - ndev = qdev->ndev; - - pci_set_master(pdev); - - device_wakeup_disable(dev_d); - - if (netif_running(ndev)) { - err = qlge_adapter_up(qdev); - if (err) - return err; - } - - mod_timer(&qdev->timer, jiffies + (5 * HZ)); - netif_device_attach(ndev); - - return 0; -} - -static void qlge_shutdown(struct pci_dev *pdev) -{ - qlge_suspend(&pdev->dev); -} - -static SIMPLE_DEV_PM_OPS(qlge_pm_ops, qlge_suspend, qlge_resume); - -static struct pci_driver qlge_driver = { - .name = DRV_NAME, - .id_table = qlge_pci_tbl, - .probe = qlge_probe, - .remove = qlge_remove, - .driver.pm = &qlge_pm_ops, - .shutdown = qlge_shutdown, - .err_handler = &qlge_err_handler -}; - -module_pci_driver(qlge_driver); diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c deleted file mode 100644 index 96a4de6d2b34..000000000000 --- a/drivers/staging/qlge/qlge_mpi.c +++ /dev/null @@ -1,1273 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "qlge.h" - -int qlge_unpause_mpi_risc(struct qlge_adapter *qdev) -{ - u32 tmp; - - /* Un-pause the RISC */ - tmp = qlge_read32(qdev, CSR); - if (!(tmp & CSR_RP)) - return -EIO; - - qlge_write32(qdev, CSR, CSR_CMD_CLR_PAUSE); - return 0; -} - -int qlge_pause_mpi_risc(struct qlge_adapter *qdev) -{ - u32 tmp; - int count; - - /* Pause the RISC */ - qlge_write32(qdev, CSR, CSR_CMD_SET_PAUSE); - for (count = UDELAY_COUNT; count; count--) { - tmp = qlge_read32(qdev, CSR); - if (tmp & CSR_RP) - break; - mdelay(UDELAY_DELAY); - } - return (count == 0) ? -ETIMEDOUT : 0; -} - -int qlge_hard_reset_mpi_risc(struct qlge_adapter *qdev) -{ - u32 tmp; - int count; - - /* Reset the RISC */ - qlge_write32(qdev, CSR, CSR_CMD_SET_RST); - for (count = UDELAY_COUNT; count; count--) { - tmp = qlge_read32(qdev, CSR); - if (tmp & CSR_RR) { - qlge_write32(qdev, CSR, CSR_CMD_CLR_RST); - break; - } - mdelay(UDELAY_DELAY); - } - return (count == 0) ? -ETIMEDOUT : 0; -} - -int qlge_read_mpi_reg(struct qlge_adapter *qdev, u32 reg, u32 *data) -{ - int status; - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); - if (status) - goto exit; - /* set up for reg read */ - qlge_write32(qdev, PROC_ADDR, reg | PROC_ADDR_R); - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); - if (status) - goto exit; - /* get the data */ - *data = qlge_read32(qdev, PROC_DATA); -exit: - return status; -} - -int qlge_write_mpi_reg(struct qlge_adapter *qdev, u32 reg, u32 data) -{ - int status = 0; - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); - if (status) - goto exit; - /* write the data to the data reg */ - qlge_write32(qdev, PROC_DATA, data); - /* trigger the write */ - qlge_write32(qdev, PROC_ADDR, reg); - /* wait for reg to come ready */ - status = qlge_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR); - if (status) - goto exit; -exit: - return status; -} - -int qlge_soft_reset_mpi_risc(struct qlge_adapter *qdev) -{ - return qlge_write_mpi_reg(qdev, 0x00001010, 1); -} - -/* Determine if we are in charge of the firmware. If - * we are the lower of the 2 NIC pcie functions, or if - * we are the higher function and the lower function - * is not enabled. - */ -int qlge_own_firmware(struct qlge_adapter *qdev) -{ - u32 temp; - - /* If we are the lower of the 2 NIC functions - * on the chip the we are responsible for - * core dump and firmware reset after an error. - */ - if (qdev->func < qdev->alt_func) - return 1; - - /* If we are the higher of the 2 NIC functions - * on the chip and the lower function is not - * enabled, then we are responsible for - * core dump and firmware reset after an error. - */ - temp = qlge_read32(qdev, STS); - if (!(temp & (1 << (8 + qdev->alt_func)))) - return 1; - - return 0; -} - -static int qlge_get_mb_sts(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int i, status; - - status = qlge_sem_spinlock(qdev, SEM_PROC_REG_MASK); - if (status) - return -EBUSY; - for (i = 0; i < mbcp->out_count; i++) { - status = - qlge_read_mpi_reg(qdev, qdev->mailbox_out + i, - &mbcp->mbox_out[i]); - if (status) { - netif_err(qdev, drv, qdev->ndev, "Failed mailbox read.\n"); - break; - } - } - qlge_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */ - return status; -} - -/* Wait for a single mailbox command to complete. - * Returns zero on success. - */ -static int qlge_wait_mbx_cmd_cmplt(struct qlge_adapter *qdev) -{ - int count; - u32 value; - - for (count = 100; count; count--) { - value = qlge_read32(qdev, STS); - if (value & STS_PI) - return 0; - mdelay(UDELAY_DELAY); /* 100ms */ - } - return -ETIMEDOUT; -} - -/* Execute a single mailbox command. - * Caller must hold PROC_ADDR semaphore. - */ -static int qlge_exec_mb_cmd(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int i, status; - - /* - * Make sure there's nothing pending. - * This shouldn't happen. - */ - if (qlge_read32(qdev, CSR) & CSR_HRI) - return -EIO; - - status = qlge_sem_spinlock(qdev, SEM_PROC_REG_MASK); - if (status) - return status; - - /* - * Fill the outbound mailboxes. - */ - for (i = 0; i < mbcp->in_count; i++) { - status = qlge_write_mpi_reg(qdev, qdev->mailbox_in + i, - mbcp->mbox_in[i]); - if (status) - goto end; - } - /* - * Wake up the MPI firmware. - */ - qlge_write32(qdev, CSR, CSR_CMD_SET_H2R_INT); -end: - qlge_sem_unlock(qdev, SEM_PROC_REG_MASK); - return status; -} - -/* We are being asked by firmware to accept - * a change to the port. This is only - * a change to max frame sizes (Tx/Rx), pause - * parameters, or loopback mode. We wake up a worker - * to handler processing this since a mailbox command - * will need to be sent to ACK the request. - */ -static int qlge_idc_req_aen(struct qlge_adapter *qdev) -{ - int status; - struct mbox_params *mbcp = &qdev->idc_mbc; - - netif_err(qdev, drv, qdev->ndev, "Enter!\n"); - /* Get the status data and start up a thread to - * handle the request. - */ - mbcp->out_count = 4; - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Could not read MPI, resetting ASIC!\n"); - qlge_queue_asic_error(qdev); - } else { - /* Begin polled mode early so - * we don't get another interrupt - * when we leave mpi_worker. - */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); - queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0); - } - return status; -} - -/* Process an inter-device event completion. - * If good, signal the caller's completion. - */ -static int qlge_idc_cmplt_aen(struct qlge_adapter *qdev) -{ - int status; - struct mbox_params *mbcp = &qdev->idc_mbc; - - mbcp->out_count = 4; - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Could not read MPI, resetting RISC!\n"); - qlge_queue_fw_error(qdev); - } else { - /* Wake up the sleeping mpi_idc_work thread that is - * waiting for this event. - */ - complete(&qdev->ide_completion); - } - return status; -} - -static void qlge_link_up(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 2; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "%s: Could not get mailbox status.\n", __func__); - return; - } - - qdev->link_status = mbcp->mbox_out[1]; - netif_err(qdev, drv, qdev->ndev, "Link Up.\n"); - - /* If we're coming back from an IDC event - * then set up the CAM and frame routing. - */ - if (test_bit(QL_CAM_RT_SET, &qdev->flags)) { - status = qlge_cam_route_initialize(qdev); - if (status) { - netif_err(qdev, ifup, qdev->ndev, - "Failed to init CAM/Routing tables.\n"); - return; - } - clear_bit(QL_CAM_RT_SET, &qdev->flags); - } - - /* Queue up a worker to check the frame - * size information, and fix it if it's not - * to our liking. - */ - if (!test_bit(QL_PORT_CFG, &qdev->flags)) { - netif_err(qdev, drv, qdev->ndev, "Queue Port Config Worker!\n"); - set_bit(QL_PORT_CFG, &qdev->flags); - /* Begin polled mode early so - * we don't get another interrupt - * when we leave mpi_worker dpc. - */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); - queue_delayed_work(qdev->workqueue, - &qdev->mpi_port_cfg_work, 0); - } - - qlge_link_on(qdev); -} - -static void qlge_link_down(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 3; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) - netif_err(qdev, drv, qdev->ndev, "Link down AEN broken!\n"); - - qlge_link_off(qdev); -} - -static int qlge_sfp_in(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 5; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) - netif_err(qdev, drv, qdev->ndev, "SFP in AEN broken!\n"); - else - netif_err(qdev, drv, qdev->ndev, "SFP insertion detected.\n"); - - return status; -} - -static int qlge_sfp_out(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 1; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) - netif_err(qdev, drv, qdev->ndev, "SFP out AEN broken!\n"); - else - netif_err(qdev, drv, qdev->ndev, "SFP removal detected.\n"); - - return status; -} - -static int qlge_aen_lost(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 6; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, "Lost AEN broken!\n"); - } else { - int i; - - netif_err(qdev, drv, qdev->ndev, "Lost AEN detected.\n"); - for (i = 0; i < mbcp->out_count; i++) - netif_err(qdev, drv, qdev->ndev, "mbox_out[%d] = 0x%.08x.\n", - i, mbcp->mbox_out[i]); - } - - return status; -} - -static void qlge_init_fw_done(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - - mbcp->out_count = 2; - - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, "Firmware did not initialize!\n"); - } else { - netif_err(qdev, drv, qdev->ndev, "Firmware Revision = 0x%.08x.\n", - mbcp->mbox_out[1]); - qdev->fw_rev_id = mbcp->mbox_out[1]; - status = qlge_cam_route_initialize(qdev); - if (status) - netif_err(qdev, ifup, qdev->ndev, - "Failed to init CAM/Routing tables.\n"); - } -} - -/* Process an async event and clear it unless it's an - * error condition. - * This can get called iteratively from the mpi_work thread - * when events arrive via an interrupt. - * It also gets called when a mailbox command is polling for - * it's completion. - */ -static int qlge_mpi_handler(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - int orig_count = mbcp->out_count; - - /* Just get mailbox zero for now. */ - mbcp->out_count = 1; - status = qlge_get_mb_sts(qdev, mbcp); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Could not read MPI, resetting ASIC!\n"); - qlge_queue_asic_error(qdev); - goto end; - } - - switch (mbcp->mbox_out[0]) { - /* This case is only active when we arrive here - * as a result of issuing a mailbox command to - * the firmware. - */ - case MB_CMD_STS_INTRMDT: - case MB_CMD_STS_GOOD: - case MB_CMD_STS_INVLD_CMD: - case MB_CMD_STS_XFC_ERR: - case MB_CMD_STS_CSUM_ERR: - case MB_CMD_STS_ERR: - case MB_CMD_STS_PARAM_ERR: - /* We can only get mailbox status if we're polling from an - * unfinished command. Get the rest of the status data and - * return back to the caller. - * We only end up here when we're polling for a mailbox - * command completion. - */ - mbcp->out_count = orig_count; - status = qlge_get_mb_sts(qdev, mbcp); - return status; - - /* We are being asked by firmware to accept - * a change to the port. This is only - * a change to max frame sizes (Tx/Rx), pause - * parameters, or loopback mode. - */ - case AEN_IDC_REQ: - status = qlge_idc_req_aen(qdev); - break; - - /* Process and inbound IDC event. - * This will happen when we're trying to - * change tx/rx max frame size, change pause - * parameters or loopback mode. - */ - case AEN_IDC_CMPLT: - case AEN_IDC_EXT: - status = qlge_idc_cmplt_aen(qdev); - break; - - case AEN_LINK_UP: - qlge_link_up(qdev, mbcp); - break; - - case AEN_LINK_DOWN: - qlge_link_down(qdev, mbcp); - break; - - case AEN_FW_INIT_DONE: - /* If we're in process on executing the firmware, - * then convert the status to normal mailbox status. - */ - if (mbcp->mbox_in[0] == MB_CMD_EX_FW) { - mbcp->out_count = orig_count; - status = qlge_get_mb_sts(qdev, mbcp); - mbcp->mbox_out[0] = MB_CMD_STS_GOOD; - return status; - } - qlge_init_fw_done(qdev, mbcp); - break; - - case AEN_AEN_SFP_IN: - qlge_sfp_in(qdev, mbcp); - break; - - case AEN_AEN_SFP_OUT: - qlge_sfp_out(qdev, mbcp); - break; - - /* This event can arrive at boot time or after an - * MPI reset if the firmware failed to initialize. - */ - case AEN_FW_INIT_FAIL: - /* If we're in process on executing the firmware, - * then convert the status to normal mailbox status. - */ - if (mbcp->mbox_in[0] == MB_CMD_EX_FW) { - mbcp->out_count = orig_count; - status = qlge_get_mb_sts(qdev, mbcp); - mbcp->mbox_out[0] = MB_CMD_STS_ERR; - return status; - } - netif_err(qdev, drv, qdev->ndev, - "Firmware initialization failed.\n"); - status = -EIO; - qlge_queue_fw_error(qdev); - break; - - case AEN_SYS_ERR: - netif_err(qdev, drv, qdev->ndev, "System Error.\n"); - qlge_queue_fw_error(qdev); - status = -EIO; - break; - - case AEN_AEN_LOST: - qlge_aen_lost(qdev, mbcp); - break; - - case AEN_DCBX_CHG: - /* Need to support AEN 8110 */ - break; - default: - netif_err(qdev, drv, qdev->ndev, - "Unsupported AE %.08x.\n", mbcp->mbox_out[0]); - /* Clear the MPI firmware status. */ - } -end: - qlge_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); - /* Restore the original mailbox count to - * what the caller asked for. This can get - * changed when a mailbox command is waiting - * for a response and an AEN arrives and - * is handled. - */ - mbcp->out_count = orig_count; - return status; -} - -/* Execute a single mailbox command. - * mbcp is a pointer to an array of u32. Each - * element in the array contains the value for it's - * respective mailbox register. - */ -static int qlge_mailbox_command(struct qlge_adapter *qdev, struct mbox_params *mbcp) -{ - int status; - unsigned long count; - - mutex_lock(&qdev->mpi_mutex); - - /* Begin polled mode for MPI */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); - - /* Load the mailbox registers and wake up MPI RISC. */ - status = qlge_exec_mb_cmd(qdev, mbcp); - if (status) - goto end; - - /* If we're generating a system error, then there's nothing - * to wait for. - */ - if (mbcp->mbox_in[0] == MB_CMD_MAKE_SYS_ERR) - goto end; - - /* Wait for the command to complete. We loop - * here because some AEN might arrive while - * we're waiting for the mailbox command to - * complete. If more than 5 seconds expire we can - * assume something is wrong. - */ - count = jiffies + HZ * MAILBOX_TIMEOUT; - do { - /* Wait for the interrupt to come in. */ - status = qlge_wait_mbx_cmd_cmplt(qdev); - if (status) - continue; - - /* Process the event. If it's an AEN, it - * will be handled in-line or a worker - * will be spawned. If it's our completion - * we will catch it below. - */ - status = qlge_mpi_handler(qdev, mbcp); - if (status) - goto end; - - /* It's either the completion for our mailbox - * command complete or an AEN. If it's our - * completion then get out. - */ - if (((mbcp->mbox_out[0] & 0x0000f000) == - MB_CMD_STS_GOOD) || - ((mbcp->mbox_out[0] & 0x0000f000) == - MB_CMD_STS_INTRMDT)) - goto done; - } while (time_before(jiffies, count)); - - netif_err(qdev, drv, qdev->ndev, - "Timed out waiting for mailbox complete.\n"); - status = -ETIMEDOUT; - goto end; - -done: - - /* Now we can clear the interrupt condition - * and look at our status. - */ - qlge_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); - - if (((mbcp->mbox_out[0] & 0x0000f000) != - MB_CMD_STS_GOOD) && - ((mbcp->mbox_out[0] & 0x0000f000) != - MB_CMD_STS_INTRMDT)) { - status = -EIO; - } -end: - /* End polled mode for MPI */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); - mutex_unlock(&qdev->mpi_mutex); - return status; -} - -/* Get MPI firmware version. This will be used for - * driver banner and for ethtool info. - * Returns zero on success. - */ -int qlge_mb_about_fw(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 3; - - mbcp->mbox_in[0] = MB_CMD_ABOUT_FW; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed about firmware command\n"); - status = -EIO; - } - - /* Store the firmware version */ - qdev->fw_rev_id = mbcp->mbox_out[1]; - - return status; -} - -/* Get functional state for MPI firmware. - * Returns zero on success. - */ -int qlge_mb_get_fw_state(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 2; - - mbcp->mbox_in[0] = MB_CMD_GET_FW_STATE; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed Get Firmware State.\n"); - status = -EIO; - } - - /* If bit zero is set in mbx 1 then the firmware is - * running, but not initialized. This should never - * happen. - */ - if (mbcp->mbox_out[1] & 1) { - netif_err(qdev, drv, qdev->ndev, - "Firmware waiting for initialization.\n"); - status = -EIO; - } - - return status; -} - -/* Send and ACK mailbox command to the firmware to - * let it continue with the change. - */ -static int qlge_mb_idc_ack(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 5; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_IDC_ACK; - mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1]; - mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2]; - mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3]; - mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4]; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, "Failed IDC ACK send.\n"); - status = -EIO; - } - return status; -} - -/* Get link settings and maximum frame size settings - * for the current port. - * Most likely will block. - */ -int qlge_mb_set_port_cfg(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 3; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_SET_PORT_CFG; - mbcp->mbox_in[1] = qdev->link_config; - mbcp->mbox_in[2] = qdev->max_frame_size; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) { - netif_err(qdev, drv, qdev->ndev, - "Port Config sent, wait for IDC.\n"); - } else if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed Set Port Configuration.\n"); - status = -EIO; - } - return status; -} - -static int qlge_mb_dump_ram(struct qlge_adapter *qdev, u64 req_dma, u32 addr, - u32 size) -{ - int status = 0; - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 9; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_DUMP_RISC_RAM; - mbcp->mbox_in[1] = LSW(addr); - mbcp->mbox_in[2] = MSW(req_dma); - mbcp->mbox_in[3] = LSW(req_dma); - mbcp->mbox_in[4] = MSW(size); - mbcp->mbox_in[5] = LSW(size); - mbcp->mbox_in[6] = MSW(MSD(req_dma)); - mbcp->mbox_in[7] = LSW(MSD(req_dma)); - mbcp->mbox_in[8] = MSW(addr); - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, "Failed to dump risc RAM.\n"); - status = -EIO; - } - return status; -} - -/* Issue a mailbox command to dump RISC RAM. */ -int qlge_dump_risc_ram_area(struct qlge_adapter *qdev, void *buf, - u32 ram_addr, int word_count) -{ - int status; - char *my_buf; - dma_addr_t buf_dma; - - my_buf = dma_alloc_coherent(&qdev->pdev->dev, - word_count * sizeof(u32), &buf_dma, - GFP_ATOMIC); - if (!my_buf) - return -EIO; - - status = qlge_mb_dump_ram(qdev, buf_dma, ram_addr, word_count); - if (!status) - memcpy(buf, my_buf, word_count * sizeof(u32)); - - dma_free_coherent(&qdev->pdev->dev, word_count * sizeof(u32), my_buf, - buf_dma); - return status; -} - -/* Get link settings and maximum frame size settings - * for the current port. - * Most likely will block. - */ -int qlge_mb_get_port_cfg(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 3; - - mbcp->mbox_in[0] = MB_CMD_GET_PORT_CFG; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed Get Port Configuration.\n"); - status = -EIO; - } else { - netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev, - "Passed Get Port Configuration.\n"); - qdev->link_config = mbcp->mbox_out[1]; - qdev->max_frame_size = mbcp->mbox_out[2]; - } - return status; -} - -int qlge_mb_wol_mode(struct qlge_adapter *qdev, u32 wol) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 2; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_SET_WOL_MODE; - mbcp->mbox_in[1] = wol; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, "Failed to set WOL mode.\n"); - status = -EIO; - } - return status; -} - -int qlge_mb_wol_set_magic(struct qlge_adapter *qdev, u32 enable_wol) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - const u8 *addr = qdev->ndev->dev_addr; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 8; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_SET_WOL_MAGIC; - if (enable_wol) { - mbcp->mbox_in[1] = (u32)addr[0]; - mbcp->mbox_in[2] = (u32)addr[1]; - mbcp->mbox_in[3] = (u32)addr[2]; - mbcp->mbox_in[4] = (u32)addr[3]; - mbcp->mbox_in[5] = (u32)addr[4]; - mbcp->mbox_in[6] = (u32)addr[5]; - mbcp->mbox_in[7] = 0; - } else { - mbcp->mbox_in[1] = 0; - mbcp->mbox_in[2] = 1; - mbcp->mbox_in[3] = 1; - mbcp->mbox_in[4] = 1; - mbcp->mbox_in[5] = 1; - mbcp->mbox_in[6] = 1; - mbcp->mbox_in[7] = 0; - } - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, "Failed to set WOL mode.\n"); - status = -EIO; - } - return status; -} - -/* IDC - Inter Device Communication... - * Some firmware commands require consent of adjacent FCOE - * function. This function waits for the OK, or a - * counter-request for a little more time.i - * The firmware will complete the request if the other - * function doesn't respond. - */ -static int qlge_idc_wait(struct qlge_adapter *qdev) -{ - int status = -ETIMEDOUT; - struct mbox_params *mbcp = &qdev->idc_mbc; - long wait_time; - - for (wait_time = 1 * HZ; wait_time;) { - /* Wait here for the command to complete - * via the IDC process. - */ - wait_time = - wait_for_completion_timeout(&qdev->ide_completion, - wait_time); - if (!wait_time) { - netif_err(qdev, drv, qdev->ndev, "IDC Timeout.\n"); - break; - } - /* Now examine the response from the IDC process. - * We might have a good completion or a request for - * more wait time. - */ - if (mbcp->mbox_out[0] == AEN_IDC_EXT) { - netif_err(qdev, drv, qdev->ndev, - "IDC Time Extension from function.\n"); - wait_time += (mbcp->mbox_out[1] >> 8) & 0x0000000f; - } else if (mbcp->mbox_out[0] == AEN_IDC_CMPLT) { - netif_err(qdev, drv, qdev->ndev, "IDC Success.\n"); - status = 0; - break; - } else { - netif_err(qdev, drv, qdev->ndev, - "IDC: Invalid State 0x%.04x.\n", - mbcp->mbox_out[0]); - status = -EIO; - break; - } - } - - return status; -} - -int qlge_mb_set_led_cfg(struct qlge_adapter *qdev, u32 led_config) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 2; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_SET_LED_CFG; - mbcp->mbox_in[1] = led_config; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed to set LED Configuration.\n"); - status = -EIO; - } - - return status; -} - -int qlge_mb_get_led_cfg(struct qlge_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 2; - - mbcp->mbox_in[0] = MB_CMD_GET_LED_CFG; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - netif_err(qdev, drv, qdev->ndev, - "Failed to get LED Configuration.\n"); - status = -EIO; - } else { - qdev->led_config = mbcp->mbox_out[1]; - } - return status; -} - -int qlge_mb_set_mgmnt_traffic_ctl(struct qlge_adapter *qdev, u32 control) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 2; - - mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL; - mbcp->mbox_in[1] = control; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) - return status; - - if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) { - netif_err(qdev, drv, qdev->ndev, - "Command not supported by firmware.\n"); - status = -EINVAL; - } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) { - /* This indicates that the firmware is - * already in the state we are trying to - * change it to. - */ - netif_err(qdev, drv, qdev->ndev, - "Command parameters make no change.\n"); - } - return status; -} - -/* Returns a negative error code or the mailbox command status. */ -static int qlge_mb_get_mgmnt_traffic_ctl(struct qlge_adapter *qdev, u32 *control) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status; - - memset(mbcp, 0, sizeof(struct mbox_params)); - *control = 0; - - mbcp->in_count = 1; - mbcp->out_count = 1; - - mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL; - - status = qlge_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) { - *control = mbcp->mbox_in[1]; - return status; - } - - if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) { - netif_err(qdev, drv, qdev->ndev, - "Command not supported by firmware.\n"); - status = -EINVAL; - } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) { - netif_err(qdev, drv, qdev->ndev, - "Failed to get MPI traffic control.\n"); - status = -EIO; - } - return status; -} - -int qlge_wait_fifo_empty(struct qlge_adapter *qdev) -{ - int count; - u32 mgmnt_fifo_empty; - u32 nic_fifo_empty; - - for (count = 6; count; count--) { - nic_fifo_empty = qlge_read32(qdev, STS) & STS_NFE; - qlge_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty); - mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY; - if (nic_fifo_empty && mgmnt_fifo_empty) - return 0; - msleep(100); - } - return -ETIMEDOUT; -} - -/* API called in work thread context to set new TX/RX - * maximum frame size values to match MTU. - */ -static int qlge_set_port_cfg(struct qlge_adapter *qdev) -{ - int status; - - status = qlge_mb_set_port_cfg(qdev); - if (status) - return status; - status = qlge_idc_wait(qdev); - return status; -} - -/* The following routines are worker threads that process - * events that may sleep waiting for completion. - */ - -/* This thread gets the maximum TX and RX frame size values - * from the firmware and, if necessary, changes them to match - * the MTU setting. - */ -void qlge_mpi_port_cfg_work(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_port_cfg_work.work); - int status; - - status = qlge_mb_get_port_cfg(qdev); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Bug: Failed to get port config data.\n"); - goto err; - } - - if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && - qdev->max_frame_size == CFG_DEFAULT_MAX_FRAME_SIZE) - goto end; - - qdev->link_config |= CFG_JUMBO_FRAME_SIZE; - qdev->max_frame_size = CFG_DEFAULT_MAX_FRAME_SIZE; - status = qlge_set_port_cfg(qdev); - if (status) { - netif_err(qdev, drv, qdev->ndev, - "Bug: Failed to set port config data.\n"); - goto err; - } -end: - clear_bit(QL_PORT_CFG, &qdev->flags); - return; -err: - qlge_queue_fw_error(qdev); - goto end; -} - -/* Process an inter-device request. This is issues by - * the firmware in response to another function requesting - * a change to the port. We set a flag to indicate a change - * has been made and then send a mailbox command ACKing - * the change request. - */ -void qlge_mpi_idc_work(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_idc_work.work); - int status; - struct mbox_params *mbcp = &qdev->idc_mbc; - u32 aen; - int timeout; - - aen = mbcp->mbox_out[1] >> 16; - timeout = (mbcp->mbox_out[1] >> 8) & 0xf; - - switch (aen) { - default: - netif_err(qdev, drv, qdev->ndev, - "Bug: Unhandled IDC action.\n"); - break; - case MB_CMD_PORT_RESET: - case MB_CMD_STOP_FW: - qlge_link_off(qdev); - fallthrough; - case MB_CMD_SET_PORT_CFG: - /* Signal the resulting link up AEN - * that the frame routing and mac addr - * needs to be set. - */ - set_bit(QL_CAM_RT_SET, &qdev->flags); - /* Do ACK if required */ - if (timeout) { - status = qlge_mb_idc_ack(qdev); - if (status) - netif_err(qdev, drv, qdev->ndev, - "Bug: No pending IDC!\n"); - } else { - netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev, - "IDC ACK not required\n"); - status = 0; /* success */ - } - break; - - /* These sub-commands issued by another (FCoE) - * function are requesting to do an operation - * on the shared resource (MPI environment). - * We currently don't issue these so we just - * ACK the request. - */ - case MB_CMD_IOP_RESTART_MPI: - case MB_CMD_IOP_PREP_LINK_DOWN: - /* Drop the link, reload the routing - * table when link comes up. - */ - qlge_link_off(qdev); - set_bit(QL_CAM_RT_SET, &qdev->flags); - fallthrough; - case MB_CMD_IOP_DVR_START: - case MB_CMD_IOP_FLASH_ACC: - case MB_CMD_IOP_CORE_DUMP_MPI: - case MB_CMD_IOP_PREP_UPDATE_MPI: - case MB_CMD_IOP_COMP_UPDATE_MPI: - case MB_CMD_IOP_NONE: /* an IDC without params */ - /* Do ACK if required */ - if (timeout) { - status = qlge_mb_idc_ack(qdev); - if (status) - netif_err(qdev, drv, qdev->ndev, - "Bug: No pending IDC!\n"); - } else { - netif_printk(qdev, drv, KERN_DEBUG, qdev->ndev, - "IDC ACK not required\n"); - status = 0; /* success */ - } - break; - } -} - -void qlge_mpi_work(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_work.work); - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int err = 0; - - mutex_lock(&qdev->mpi_mutex); - /* Begin polled mode for MPI */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); - - while (qlge_read32(qdev, STS) & STS_PI) { - memset(mbcp, 0, sizeof(struct mbox_params)); - mbcp->out_count = 1; - /* Don't continue if an async event - * did not complete properly. - */ - err = qlge_mpi_handler(qdev, mbcp); - if (err) - break; - } - - /* End polled mode for MPI */ - qlge_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); - mutex_unlock(&qdev->mpi_mutex); -} - -void qlge_mpi_reset_work(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_reset_work.work); - cancel_delayed_work_sync(&qdev->mpi_work); - cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); - cancel_delayed_work_sync(&qdev->mpi_idc_work); - /* If we're not the dominant NIC function, - * then there is nothing to do. - */ - if (!qlge_own_firmware(qdev)) { - netif_err(qdev, drv, qdev->ndev, "Don't own firmware!\n"); - return; - } - - qlge_soft_reset_mpi_risc(qdev); -} diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c index 82c11caeee7a..d0b7332645be 100644 --- a/drivers/staging/rtl8192e/dot11d.c +++ b/drivers/staging/rtl8192e/dot11d.c @@ -73,19 +73,16 @@ void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee) for (i = 12; i <= 14; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; ieee->bss_start_channel = 10; - ieee->ibss_maxjoin_chal = 11; break; case COUNTRY_CODE_WORLD_WIDE_13: for (i = 12; i <= 13; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 2; ieee->bss_start_channel = 10; - ieee->ibss_maxjoin_chal = 11; break; default: ieee->bss_start_channel = 1; - ieee->ibss_maxjoin_chal = 14; break; } } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h index c229fd244a48..8c85f1c866d3 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h @@ -11,8 +11,6 @@ #define MAX_SILENT_RESET_RX_SLOT_NUM 10 -#define RX_MPDU_QUEUE 0 - enum rtl819x_loopback { RTL819X_NO_LOOPBACK = 0, RTL819X_MAC_LOOPBACK = 1, diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 58e90b7772ef..e93394c51264 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -18,30 +18,6 @@ static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; -void rtl92e_start_beacon(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - struct rtllib_network *net = &priv->rtllib->current_network; - u16 BcnTimeCfg = 0; - u16 BcnCW = 6; - u16 BcnIFS = 0xf; - - rtl92e_irq_disable(dev); - - rtl92e_writew(dev, ATIMWND, 2); - - rtl92e_writew(dev, BCN_INTERVAL, net->beacon_interval); - rtl92e_writew(dev, BCN_DRV_EARLY_INT, 10); - rtl92e_writew(dev, BCN_DMATIME, 256); - - rtl92e_writeb(dev, BCN_ERR_THRESH, 100); - - BcnTimeCfg |= BcnCW << BCN_TCFG_CW_SHIFT; - BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS; - rtl92e_writew(dev, BCN_TCFG, BcnTimeCfg); - rtl92e_irq_enable(dev); -} - static void _rtl92e_update_msr(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); @@ -55,10 +31,6 @@ static void _rtl92e_update_msr(struct net_device *dev) if (priv->rtllib->link_state == MAC80211_LINKED) msr |= MSR_LINK_MANAGED; break; - case IW_MODE_ADHOC: - if (priv->rtllib->link_state == MAC80211_LINKED) - msr |= MSR_LINK_ADHOC; - break; default: break; } @@ -513,10 +485,10 @@ bool rtl92e_start_adapter(struct net_device *dev) start: rtl92e_reset_desc_ring(dev); priv->rf_mode = RF_OP_By_SW_3wire; - if (priv->rst_progress == RESET_TYPE_NORESET) { - rtl92e_writeb(dev, ANAPAR, 0x37); - mdelay(500); - } + + rtl92e_writeb(dev, ANAPAR, 0x37); + mdelay(500); + priv->fw_info->status = FW_STATUS_0_INIT; ulRegRead = rtl92e_readl(dev, CPU_GEN); @@ -546,21 +518,20 @@ start: } priv->loopback_mode = RTL819X_NO_LOOPBACK; - if (priv->rst_progress == RESET_TYPE_NORESET) { - ulRegRead = rtl92e_readl(dev, CPU_GEN); - if (priv->loopback_mode == RTL819X_NO_LOOPBACK) - ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | - CPU_GEN_NO_LOOPBACK_SET; - else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK) - ulRegRead |= CPU_CCK_LOOPBACK; - else - netdev_err(dev, "%s: Invalid loopback mode setting.\n", - __func__); + ulRegRead = rtl92e_readl(dev, CPU_GEN); + if (priv->loopback_mode == RTL819X_NO_LOOPBACK) + ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | + CPU_GEN_NO_LOOPBACK_SET; + else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK) + ulRegRead |= CPU_CCK_LOOPBACK; + else + netdev_err(dev, "%s: Invalid loopback mode setting.\n", + __func__); - rtl92e_writel(dev, CPU_GEN, ulRegRead); + rtl92e_writel(dev, CPU_GEN, ulRegRead); + + udelay(500); - udelay(500); - } _rtl92e_hwconfig(dev); rtl92e_writeb(dev, CMDR, CR_RE | CR_TE); @@ -595,8 +566,7 @@ start: rtl92e_writeb(dev, ACK_TIMEOUT, 0x30); - if (priv->rst_progress == RESET_TYPE_NORESET) - rtl92e_set_wireless_mode(dev, priv->rtllib->mode); + rtl92e_set_wireless_mode(dev, priv->rtllib->mode); rtl92e_cam_reset(dev); { u8 SECR_value = 0x0; @@ -635,12 +605,10 @@ start: } } - if (priv->rst_progress == RESET_TYPE_NORESET) { - rtStatus = rtl92e_config_rf(dev); - if (!rtStatus) { - netdev_info(dev, "RF Config failed\n"); - return rtStatus; - } + rtStatus = rtl92e_config_rf(dev); + if (!rtStatus) { + netdev_info(dev, "RF Config failed\n"); + return rtStatus; } rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); @@ -662,39 +630,37 @@ start: else priv->rf_mode = RF_OP_By_SW_3wire; - if (priv->rst_progress == RESET_TYPE_NORESET) { - rtl92e_dm_init_txpower_tracking(dev); + rtl92e_dm_init_txpower_tracking(dev); - if (priv->ic_cut >= IC_VersionCut_D) { - tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, - bMaskDWord); - rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord); + if (priv->ic_cut >= IC_VersionCut_D) { + tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord); + rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord); - for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) { - if (tmpRegA == dm_tx_bb_gain[i]) { - priv->rfa_txpowertrackingindex = i; - priv->rfa_txpowertrackingindex_real = i; - priv->rfa_txpowertracking_default = - priv->rfa_txpowertrackingindex; - break; - } + for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) { + if (tmpRegA == dm_tx_bb_gain[i]) { + priv->rfa_txpowertrackingindex = i; + priv->rfa_txpowertrackingindex_real = i; + priv->rfa_txpowertracking_default = + priv->rfa_txpowertrackingindex; + break; } - - TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, - bMaskByte2); - - for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) { - if (TempCCk == dm_cck_tx_bb_gain[i][0]) { - priv->cck_present_attn_20m_def = i; - break; - } - } - priv->cck_present_attn_40m_def = 0; - priv->cck_present_attn_diff = 0; - priv->cck_present_attn = - priv->cck_present_attn_20m_def; - priv->btxpower_tracking = false; } + + TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, + bMaskByte2); + + for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) { + if (TempCCk == dm_cck_tx_bb_gain[i][0]) { + priv->cck_present_attn_20m_def = i; + break; + } + } + priv->cck_present_attn_40m_def = 0; + priv->cck_present_attn_diff = 0; + priv->cck_present_attn = + priv->cck_present_attn_20m_def; + priv->btxpower_tracking = false; } rtl92e_irq_enable(dev); end: @@ -706,7 +672,6 @@ static void _rtl92e_net_update(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rtllib_network *net; - u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; u16 rate_config = 0; net = &priv->rtllib->current_network; @@ -715,19 +680,6 @@ static void _rtl92e_net_update(struct net_device *dev) priv->basic_rate = rate_config &= 0x15f; rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid); rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2)); - - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - rtl92e_writew(dev, ATIMWND, 2); - rtl92e_writew(dev, BCN_DMATIME, 256); - rtl92e_writew(dev, BCN_INTERVAL, net->beacon_interval); - rtl92e_writew(dev, BCN_DRV_EARLY_INT, 10); - rtl92e_writeb(dev, BCN_ERR_THRESH, 100); - - BcnTimeCfg |= (BcnCW << BCN_TCFG_CW_SHIFT); - BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS; - - rtl92e_writew(dev, BCN_TCFG, BcnTimeCfg); - } } void rtl92e_link_change(struct net_device *dev) @@ -749,15 +701,12 @@ void rtl92e_link_change(struct net_device *dev) } _rtl92e_update_msr(dev); - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { + if (ieee->iw_mode == IW_MODE_INFRA) { u32 reg; reg = rtl92e_readl(dev, RCR); if (priv->rtllib->link_state == MAC80211_LINKED) { - if (ieee->intel_promiscuous_md_info.promiscuous_on) - ; - else - priv->receive_config = reg |= RCR_CBSSID; + priv->receive_config = reg |= RCR_CBSSID; } else { priv->receive_config = reg &= ~RCR_CBSSID; } @@ -1411,12 +1360,12 @@ static void _rtl92e_process_phyinfo(struct r8192_priv *priv, u8 *buffer, static u32 slide_beacon_adc_pwdb_index; static u32 slide_beacon_adc_pwdb_statistics; static u32 last_beacon_adc_pwdb; - struct rtllib_hdr_3addr *hdr; + struct ieee80211_hdr_3addr *hdr; u16 sc; unsigned int seq; - hdr = (struct rtllib_hdr_3addr *)buffer; - sc = le16_to_cpu(hdr->seq_ctl); + hdr = (struct ieee80211_hdr_3addr *)buffer; + sc = le16_to_cpu(hdr->seq_ctrl); seq = WLAN_GET_SEQ_SEQ(sc); curr_st->Seq_Num = seq; if (!prev_st->bIsAMPDU) @@ -1561,7 +1510,7 @@ static void _rtl92e_translate_rx_signal_stats(struct net_device *dev, struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); bool bpacket_match_bssid, bpacket_toself; bool bPacketBeacon = false; - struct rtllib_hdr_3addr *hdr; + struct ieee80211_hdr_3addr *hdr; bool bToSelfBA = false; static struct rtllib_rx_stats previous_stats; u16 fc, type; @@ -1570,21 +1519,21 @@ static void _rtl92e_translate_rx_signal_stats(struct net_device *dev, tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift; - hdr = (struct rtllib_hdr_3addr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_ctl); + hdr = (struct ieee80211_hdr_3addr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; bpacket_match_bssid = ((type != RTLLIB_FTYPE_CTL) && ether_addr_equal(priv->rtllib->current_network.bssid, - (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 : - (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 : + (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : + (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3) && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV)); bpacket_toself = bpacket_match_bssid && /* check this */ ether_addr_equal(praddr, priv->rtllib->dev->dev_addr); - if (WLAN_FC_GET_FRAMETYPE(fc) == RTLLIB_STYPE_BEACON) + if (ieee80211_is_beacon(hdr->frame_control)) bPacketBeacon = true; _rtl92e_process_phyinfo(priv, tmp_buf, &previous_stats, pstats); _rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, @@ -1870,7 +1819,7 @@ rtl92e_init_variables(struct net_device *dev) priv->bfirst_after_down = false; } -void rtl92e_enable_irq(struct net_device *dev) +void rtl92e_irq_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); @@ -1879,7 +1828,7 @@ void rtl92e_enable_irq(struct net_device *dev) rtl92e_writel(dev, INTA_MASK, priv->irq_mask[0]); } -void rtl92e_disable_irq(struct net_device *dev) +void rtl92e_irq_disable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); @@ -1892,7 +1841,7 @@ void rtl92e_enable_rx(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); - rtl92e_writel(dev, RDQDA, priv->rx_ring_dma[RX_MPDU_QUEUE]); + rtl92e_writel(dev, RDQDA, priv->rx_ring_dma); } static const u32 TX_DESC_BASE[] = { diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h index 11366fda4ec3..878c96236824 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h @@ -16,10 +16,7 @@ bool rtl92e_is_rx_stuck(struct net_device *dev); void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta); void rtl92e_enable_rx(struct net_device *dev); void rtl92e_enable_tx(struct net_device *dev); -void rtl92e_enable_irq(struct net_device *dev); -void rtl92e_disable_irq(struct net_device *dev); void rtl92e_init_variables(struct net_device *dev); -void rtl92e_start_beacon(struct net_device *dev); void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val); void rtl92e_get_eeprom_size(struct net_device *dev); bool rtl92e_start_adapter(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h index 09f8c76b7e65..1b444529b59c 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h @@ -43,7 +43,7 @@ enum _RTL8192PCI_HW { PMR = 0x00c, EPROM_CMD = 0x00e, -#define EPROM_CMD_9356SEL BIT4 +#define EPROM_CMD_9356SEL BIT(4) #define EPROM_CMD_OPERATING_MODE_SHIFT 6 #define EPROM_CMD_NORMAL 0 #define EPROM_CMD_PROGRAM 2 @@ -61,16 +61,16 @@ enum _RTL8192PCI_HW { #define CR_TE 0x04 SIFS = 0x03E, RCR = 0x044, -#define RCR_ONLYERLPKT BIT31 -#define RCR_CBSSID BIT23 -#define RCR_ADD3 BIT21 -#define RCR_AMF BIT20 -#define RCR_ADF BIT18 -#define RCR_AICV BIT12 -#define RCR_AB BIT3 -#define RCR_AM BIT2 -#define RCR_APM BIT1 -#define RCR_AAP BIT0 +#define RCR_ONLYERLPKT BIT(31) +#define RCR_CBSSID BIT(23) +#define RCR_ADD3 BIT(21) +#define RCR_AMF BIT(20) +#define RCR_ADF BIT(18) +#define RCR_AICV BIT(12) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) #define RCR_MXDMA_OFFSET 8 #define RCR_FIFO_OFFSET 13 SLOT_TIME = 0x049, @@ -95,34 +95,34 @@ enum _RTL8192PCI_HW { #define TOTAL_CAM_ENTRY 32 WCAMI = 0x0A4, SECR = 0x0B0, -#define SCR_TxUseDK BIT0 -#define SCR_RxUseDK BIT1 -#define SCR_TxEncEnable BIT2 -#define SCR_RxDecEnable BIT3 -#define SCR_NoSKMC BIT5 +#define SCR_TxUseDK BIT(0) +#define SCR_RxUseDK BIT(1) +#define SCR_TxEncEnable BIT(2) +#define SCR_RxDecEnable BIT(3) +#define SCR_NoSKMC BIT(5) SWREGULATOR = 0x0BD, INTA_MASK = 0x0f4, -#define IMR_TBDOK BIT27 -#define IMR_TBDER BIT26 -#define IMR_TXFOVW BIT15 -#define IMR_TIMEOUT0 BIT14 -#define IMR_BcnInt BIT13 -#define IMR_RXFOVW BIT12 -#define IMR_RDU BIT11 -#define IMR_RXCMDOK BIT10 -#define IMR_BDOK BIT9 -#define IMR_HIGHDOK BIT8 -#define IMR_COMDOK BIT7 -#define IMR_MGNTDOK BIT6 -#define IMR_HCCADOK BIT5 -#define IMR_BKDOK BIT4 -#define IMR_BEDOK BIT3 -#define IMR_VIDOK BIT2 -#define IMR_VODOK BIT1 -#define IMR_ROK BIT0 +#define IMR_TBDOK BIT(27) +#define IMR_TBDER BIT(26) +#define IMR_TXFOVW BIT(15) +#define IMR_TIMEOUT0 BIT(14) +#define IMR_BcnInt BIT(13) +#define IMR_RXFOVW BIT(12) +#define IMR_RDU BIT(11) +#define IMR_RXCMDOK BIT(10) +#define IMR_BDOK BIT(9) +#define IMR_HIGHDOK BIT(8) +#define IMR_COMDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_HCCADOK BIT(5) +#define IMR_BKDOK BIT(4) +#define IMR_BEDOK BIT(3) +#define IMR_VIDOK BIT(2) +#define IMR_VODOK BIT(1) +#define IMR_ROK BIT(0) ISR = 0x0f8, TP_POLL = 0x0fd, -#define TP_POLL_CQ BIT5 +#define TP_POLL_CQ BIT(5) PSR = 0x0ff, CPU_GEN = 0x100, #define CPU_CCK_LOOPBACK 0x00030000 @@ -136,9 +136,9 @@ enum _RTL8192PCI_HW { #define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF #define CPU_GEN_NO_LOOPBACK_SET 0x00080000 ACM_HW_CTRL = 0x171, -#define ACM_HW_BEQ_EN BIT1 -#define ACM_HW_VIQ_EN BIT2 -#define ACM_HW_VOQ_EN BIT3 +#define ACM_HW_BEQ_EN BIT(1) +#define ACM_HW_VIQ_EN BIT(2) +#define ACM_HW_VOQ_EN BIT(3) RQPN1 = 0x180, RQPN2 = 0x184, RQPN3 = 0x188, @@ -159,7 +159,7 @@ enum _RTL8192PCI_HW { WFCRC2 = 0x2f8, BW_OPMODE = 0x300, -#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_20MHZ BIT(2) IC_VERRSION = 0x301, MSR = 0x303, #define MSR_LINK_MASK (BIT(1) | BIT(0)) @@ -178,19 +178,19 @@ enum _RTL8192PCI_HW { TSFR = 0x308, RRSR = 0x310, #define RRSR_SHORT_OFFSET 23 -#define RRSR_1M BIT0 -#define RRSR_2M BIT1 -#define RRSR_5_5M BIT2 -#define RRSR_11M BIT3 -#define RRSR_6M BIT4 -#define RRSR_9M BIT5 -#define RRSR_12M BIT6 -#define RRSR_18M BIT7 -#define RRSR_24M BIT8 -#define RRSR_36M BIT9 -#define RRSR_48M BIT10 -#define RRSR_54M BIT11 -#define BRSR_AckShortPmb BIT23 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define BRSR_AckShortPmb BIT(23) UFWP = 0x318, RATR0 = 0x320, #define RATR_1M 0x00000001 diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 875540a2079d..4d12d7385041 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -513,7 +513,7 @@ static u8 _rtl92e_phy_set_sw_chnl_cmd_array(struct net_device *dev, { struct sw_chnl_cmd *pCmd; - if (CmdTable == NULL) { + if (!CmdTable) { netdev_err(dev, "%s(): CmdTable cannot be NULL.\n", __func__); return false; } @@ -920,9 +920,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation) case IG_Backup: initial_gain = SCAN_RX_INITIAL_GAIN; BitMask = bMaskByte0; - if (dm_digtable.dig_algorithm == - DIG_ALGO_BY_FALSE_ALARM) - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); priv->initgain_backup.xaagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask); @@ -947,10 +944,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation) break; case IG_Restore: BitMask = 0x7f; - if (dm_digtable.dig_algorithm == - DIG_ALGO_BY_FALSE_ALARM) - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); - rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1); rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, BitMask, @@ -965,10 +958,6 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation) rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel); - - if (dm_digtable.dig_algorithm == - DIG_ALGO_BY_FALSE_ALARM) - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); break; } } @@ -976,7 +965,7 @@ void rtl92e_init_gain(struct net_device *dev, u8 Operation) void rtl92e_set_rf_off(struct net_device *dev) { - rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); + rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4), 0x0); rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0); rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0); @@ -1027,7 +1016,7 @@ static bool _rtl92e_set_rf_power_state(struct net_device *dev, 0x4, 0x1); priv->hw_rf_off_action = 0; rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, - BIT4, 0x1); + BIT(4), 0x1); rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3); rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h index 24fb0ca539ea..c48c56869c19 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h @@ -248,75 +248,15 @@ #define bPAEnd 0xf #define bTREnd 0x0f000000 #define bRFEnd 0x000f0000 -/* T2R */ -#define bCCAMask 0x000000f0 -#define bR2RCCAMask 0x00000f00 -#define bHSSI_R2TDelay 0xf8000000 -#define bHSSI_T2RDelay 0xf80000 /* Channel gain at continue TX. */ -#define bContTxHSSI 0x400 -#define bIGFromCCK 0x200 -#define bAGCAddress 0x3f -#define bRxHPTx 0x7000 -#define bRxHPT2R 0x38000 -#define bRxHPCCKIni 0xc0000 -#define bAGCTxCode 0xc00000 -#define bAGCRxCode 0x300000 #define b3WireDataLength 0x800 #define b3WireAddressLength 0x400 -#define b3WireRFPowerDown 0x1 -/*#define bHWSISelect 0x8 */ -#define b2GPAPEPolarity 0x80000000 -#define bRFSW_TxDefaultAnt 0x3 -#define bRFSW_TxOptionAnt 0x30 -#define bRFSW_RxDefaultAnt 0x300 -#define bRFSW_RxOptionAnt 0x3000 -#define bRFSI_3WireData 0x1 -#define bRFSI_3WireClock 0x2 -#define bRFSI_3WireLoad 0x4 -#define bRFSI_3WireRW 0x8 /* 3-wire total control */ -#define bRFSI_3Wire 0xf #define bRFSI_RFENV 0x10 -#define bRFSI_TRSW 0x20 -#define bRFSI_TRSWB 0x40 -#define bRFSI_ANTSW 0x100 -#define bRFSI_ANTSWB 0x200 -#define bRFSI_PAPE 0x400 -#define bBandSelect 0x1 -#define bHTSIG2_GI 0x80 -#define bHTSIG2_Smoothing 0x01 -#define bHTSIG2_Sounding 0x02 -#define bHTSIG2_Aggreaton 0x08 -#define bHTSIG2_STBC 0x30 -#define bHTSIG2_AdvCoding 0x40 -#define bHTSIG2_NumOfHTLTF 0x300 -#define bHTSIG2_CRC8 0x3fc -#define bHTSIG1_MCS 0x7f -#define bHTSIG1_BandWidth 0x80 -#define bHTSIG1_HTLength 0xffff -#define bLSIG_Rate 0xf -#define bLSIG_Reserved 0x10 -#define bLSIG_Length 0x1fffe -#define bLSIG_Parity 0x20 -#define bCCKRxPhase 0x4 #define bLSSIReadAddress 0x3f000000 /* LSSI "read" address */ #define bLSSIReadEdge 0x80000000 /* LSSI "read" edge signal */ #define bLSSIReadBackData 0xfff -#define bLSSIReadOKFlag 0x1000 -#define bCCKSampleRate 0x8 /* 0: 44 MHz, 1: 88MHz */ -#define bRegulator0Standby 0x1 -#define bRegulatorPLLStandby 0x2 -#define bRegulator1Standby 0x4 -#define bPLLPowerUp 0x8 -#define bDPLLPowerUp 0x10 -#define bDA10PowerUp 0x20 -#define bAD7PowerUp 0x200 -#define bDA6PowerUp 0x2000 -#define bXtalPowerUp 0x4000 -#define b40MDClkPowerUP 0x8000 -#define bDA6DebugMode 0x20000 #define bDA6Swing 0x380000 #define bADClkPhase 0x4000000 #define b80MClkDelay 0x18000000 diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index 944cc73fb2b6..69298c7c129a 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -17,7 +17,7 @@ void rtl92e_cam_reset(struct net_device *dev) { u32 ulcommand = 0; - ulcommand |= BIT31 | BIT30; + ulcommand |= BIT(31) | BIT(30); rtl92e_writel(dev, RWCAM, ulcommand); } @@ -33,11 +33,6 @@ void rtl92e_enable_hw_security_config(struct net_device *dev) (priv->rtllib->auth_mode != 2)) { SECR_value |= SCR_RxUseDK; SECR_value |= SCR_TxUseDK; - } else if ((ieee->iw_mode == IW_MODE_ADHOC) && - (ieee->pairwise_key_type & (KEY_TYPE_CCMP | - KEY_TYPE_TKIP))) { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; } ieee->hwsec_active = 1; @@ -94,13 +89,13 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, } if (DefaultKey) - usConfig |= BIT15 | (KeyType << 2); + usConfig |= BIT(15) | (KeyType << 2); else - usConfig |= BIT15 | (KeyType << 2) | KeyIndex; + usConfig |= BIT(15) | (KeyType << 2) | KeyIndex; for (i = 0; i < CAM_CONTENT_COUNT; i++) { TargetCommand = i + CAM_CONTENT_COUNT * EntryNo; - TargetCommand |= BIT31 | BIT16; + TargetCommand |= BIT(31) | BIT(16); if (i == 0) { TargetContent = (u32)(*(MacAddr + 0)) << 16 | @@ -117,7 +112,7 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, rtl92e_writel(dev, WCAMI, TargetContent); rtl92e_writel(dev, RWCAM, TargetCommand); } else { - if (KeyContent != NULL) { + if (KeyContent) { rtl92e_writel(dev, WCAMI, (u32)(*(KeyContent + i - 2))); rtl92e_writel(dev, RWCAM, TargetCommand); @@ -126,108 +121,3 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, } } } - -void rtl92e_cam_restore(struct net_device *dev) -{ - u8 EntryId = 0; - struct r8192_priv *priv = rtllib_priv(dev); - u8 *MacAddr = priv->rtllib->current_network.bssid; - - static u8 CAM_CONST_ADDR[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} - }; - static u8 CAM_CONST_BROAD[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) || - (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) { - for (EntryId = 0; EntryId < 4; EntryId++) { - MacAddr = CAM_CONST_ADDR[EntryId]; - if (priv->rtllib->swcamtable[EntryId].bused) { - rtl92e_set_key(dev, EntryId, EntryId, - priv->rtllib->pairwise_key_type, - MacAddr, 0, - (u32 *)(&priv->rtllib->swcamtable - [EntryId].key_buf[0])); - } - } - - } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) { - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - rtl92e_set_key(dev, 4, 0, - priv->rtllib->pairwise_key_type, - (const u8 *)dev->dev_addr, 0, - (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); - } else { - rtl92e_set_key(dev, 4, 0, - priv->rtllib->pairwise_key_type, - MacAddr, 0, - (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); - } - - } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) { - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - rtl92e_set_key(dev, 4, 0, - priv->rtllib->pairwise_key_type, - (const u8 *)dev->dev_addr, 0, - (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); - } else { - rtl92e_set_key(dev, 4, 0, - priv->rtllib->pairwise_key_type, MacAddr, - 0, (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); - } - } - - if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) { - MacAddr = CAM_CONST_BROAD; - for (EntryId = 1; EntryId < 4; EntryId++) { - if (priv->rtllib->swcamtable[EntryId].bused) { - rtl92e_set_key(dev, EntryId, EntryId, - priv->rtllib->group_key_type, - MacAddr, 0, - (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0])); - } - } - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - if (priv->rtllib->swcamtable[0].bused) { - rtl92e_set_key(dev, 0, 0, - priv->rtllib->group_key_type, - CAM_CONST_ADDR[0], 0, - (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0])); - } else { - netdev_warn(dev, - "%s(): ADHOC TKIP: missing key entry.\n", - __func__); - return; - } - } - } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) { - MacAddr = CAM_CONST_BROAD; - for (EntryId = 1; EntryId < 4; EntryId++) { - if (priv->rtllib->swcamtable[EntryId].bused) { - rtl92e_set_key(dev, EntryId, EntryId, - priv->rtllib->group_key_type, - MacAddr, 0, - (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0])); - } - } - - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { - if (priv->rtllib->swcamtable[0].bused) { - rtl92e_set_key(dev, 0, 0, - priv->rtllib->group_key_type, - CAM_CONST_ADDR[0], 0, - (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0])); - } else { - netdev_warn(dev, - "%s(): ADHOC CCMP: missing key entry.\n", - __func__); - return; - } - } - } -} diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h index bd33ef105107..615b84bca9b8 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h @@ -20,6 +20,5 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u32 *KeyContent); void rtl92e_set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u32 *KeyContent); -void rtl92e_cam_restore(struct net_device *dev); #endif diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 50eb8f3494ec..995daab906c9 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -61,7 +61,7 @@ static short _rtl92e_pci_initdescring(struct net_device *dev); static void _rtl92e_irq_tx_tasklet(struct tasklet_struct *t); static void _rtl92e_irq_rx_tasklet(struct tasklet_struct *t); static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv); -static int _rtl92e_up(struct net_device *dev, bool is_silent_reset); +static int _rtl92e_up(struct net_device *dev); static int _rtl92e_try_up(struct net_device *dev); static int _rtl92e_down(struct net_device *dev, bool shutdownrf); static void _rtl92e_restart(void *data); @@ -165,8 +165,7 @@ bool rtl92e_set_rf_state(struct net_device *dev, case rf_off: - if ((priv->rtllib->iw_mode == IW_MODE_INFRA) || - (priv->rtllib->iw_mode == IW_MODE_ADHOC)) { + if (priv->rtllib->iw_mode == IW_MODE_INFRA) { if ((priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) || (change_source > RF_CHANGE_BY_IPS)) { if (ieee->link_state == MAC80211_LINKED) @@ -227,24 +226,6 @@ static void _rtl92e_tx_timeout(struct net_device *dev, unsigned int txqueue) netdev_info(dev, "TXTIMEOUT"); } -void rtl92e_irq_enable(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - priv->irq_enabled = 1; - - rtl92e_enable_irq(dev); -} - -void rtl92e_irq_disable(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_disable_irq(dev); - - priv->irq_enabled = 0; -} - static void _rtl92e_set_chan(struct net_device *dev, short ch) { struct r8192_priv *priv = rtllib_priv(dev); @@ -313,7 +294,7 @@ static void _rtl92e_update_beacon(void *data) struct rtllib_device *ieee = priv->rtllib; struct rtllib_network *net = &ieee->current_network; - if (ieee->ht_info->bCurrentHTSupport) + if (ieee->ht_info->current_ht_support) HT_update_self_and_peer_setting(ieee, net); ieee->ht_info->current_rt2rt_long_slot_time = net->bssht.bd_rt2rt_long_slot_time; ieee->ht_info->RT2RT_HT_Mode = net->bssht.rt2rt_ht_mode; @@ -477,10 +458,6 @@ static void _rtl92e_prepare_beacon(struct tasklet_struct *t) pdesc->OWN = 1; } -static void _rtl92e_stop_beacon(struct net_device *dev) -{ -} - void rtl92e_config_rate(struct net_device *dev, u16 *rate_config) { struct r8192_priv *priv = rtllib_priv(dev); @@ -611,7 +588,7 @@ void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) _rtl92e_refresh_support_rate(priv); } -static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) +static int _rtl92e_sta_up(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) @@ -634,7 +611,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) rtl92e_check_rfctrl_gpio_timer(&priv->gpio_polling_timer); if (priv->rtllib->link_state != MAC80211_LINKED) - rtllib_softmac_start_protocol(priv->rtllib, 0); + rtllib_softmac_start_protocol(priv->rtllib); rtllib_reset_queue(priv->rtllib); _rtl92e_watchdog_timer_cb(&priv->watch_dog_timer); @@ -678,7 +655,7 @@ static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) _rtl92e_cancel_deferred_work(priv); cancel_delayed_work(&priv->rtllib->hw_wakeup_wq); - rtllib_softmac_stop_protocol(priv->rtllib, 0, true); + rtllib_softmac_stop_protocol(priv->rtllib); spin_lock_irqsave(&priv->rf_ps_lock, flags); while (priv->rf_change_in_progress) { spin_unlock_irqrestore(&priv->rf_ps_lock, flags); @@ -719,9 +696,6 @@ static void _rtl92e_init_priv_handler(struct net_device *dev) priv->rtllib->set_bw_mode_handler = rtl92e_set_bw_mode; priv->rf_set_chan = rtl92e_set_channel; - priv->rtllib->start_send_beacons = rtl92e_start_beacon; - priv->rtllib->stop_send_beacons = _rtl92e_stop_beacon; - priv->rtllib->sta_wake_up = rtl92e_hw_wakeup; priv->rtllib->enter_sleep_state = rtl92e_enter_sleep; priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty; @@ -738,15 +712,6 @@ static void _rtl92e_init_priv_handler(struct net_device *dev) priv->rtllib->ScanOperationBackupHandler = rtl92e_scan_op_backup; } -static void _rtl92e_init_priv_constant(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - &priv->rtllib->pwr_save_ctrl; - - psc->reg_max_lps_awake_intvl = 5; -} - static void _rtl92e_init_priv_variable(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); @@ -765,10 +730,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->chan = 1; priv->rtllib->mode = WIRELESS_MODE_AUTO; priv->rtllib->iw_mode = IW_MODE_INFRA; - priv->rtllib->net_promiscuous_md = false; - priv->rtllib->intel_promiscuous_md_info.promiscuous_on = false; - priv->rtllib->intel_promiscuous_md_info.fltr_src_sta_frame = - false; priv->rtllib->ieee_up = 0; priv->retry_rts = DEFAULT_RETRY_RTS; priv->retry_data = DEFAULT_RETRY_DATA; @@ -778,10 +739,7 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->bcck_in_ch14 = false; priv->cck_present_attn = 0; priv->rfa_txpowertrackingindex = 0; - priv->rfc_txpowertrackingindex = 0; priv->cck_pwr_enl = 6; - priv->rst_progress = RESET_TYPE_NORESET; - priv->force_reset = false; memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); priv->rx_ctr = 0; priv->rtllib->wx_set_enc = 0; @@ -797,7 +755,6 @@ static void _rtl92e_init_priv_variable(struct net_device *dev) priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; priv->rtllib->iw_mode = IW_MODE_INFRA; - priv->rtllib->active_scan = 1; priv->rtllib->be_scan_inprogress = false; priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; @@ -871,7 +828,6 @@ static short _rtl92e_init(struct net_device *dev) memset(&priv->stats, 0, sizeof(struct rt_stats)); _rtl92e_init_priv_handler(dev); - _rtl92e_init_priv_constant(dev); _rtl92e_init_priv_variable(dev); _rtl92e_init_priv_lock(priv); _rtl92e_init_priv_task(dev); @@ -984,7 +940,7 @@ static enum reset_type _rtl92e_rx_check_stuck(struct net_device *dev) return RESET_TYPE_NORESET; } -static enum reset_type _rtl92e_if_check_reset(struct net_device *dev) +static void _rtl92e_if_check_reset(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); enum reset_type TxResetType = RESET_TYPE_NORESET; @@ -1001,133 +957,12 @@ static enum reset_type _rtl92e_if_check_reset(struct net_device *dev) (priv->rtllib->link_state == MAC80211_LINKED)) RxResetType = _rtl92e_rx_check_stuck(dev); - if (TxResetType == RESET_TYPE_NORMAL || - RxResetType == RESET_TYPE_NORMAL) { - netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n", - __func__, TxResetType, RxResetType); - return RESET_TYPE_NORMAL; - } else if (TxResetType == RESET_TYPE_SILENT || + if (TxResetType == RESET_TYPE_SILENT || RxResetType == RESET_TYPE_SILENT) { netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n", __func__, TxResetType, RxResetType); - return RESET_TYPE_SILENT; - } else { - return RESET_TYPE_NORESET; - } -} - -static void _rtl92e_if_silent_reset(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 reset_times = 0; - int reset_status = 0; - struct rtllib_device *ieee = priv->rtllib; - unsigned long flag; - - if (priv->rst_progress == RESET_TYPE_NORESET) { - priv->rst_progress = RESET_TYPE_SILENT; - - spin_lock_irqsave(&priv->rf_ps_lock, flag); - if (priv->rf_change_in_progress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - goto END; - } - priv->rf_change_in_progress = true; - priv->reset_in_progress = true; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - -RESET_START: - - mutex_lock(&priv->wx_mutex); - - if (priv->rtllib->link_state == MAC80211_LINKED) - rtl92e_leisure_ps_leave(dev); - - if (priv->up) { - netdev_info(dev, "%s():the driver is not up.\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return; - } - priv->up = 0; - - mdelay(1000); - - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - - rtl92e_irq_disable(dev); - del_timer_sync(&priv->watch_dog_timer); - _rtl92e_cancel_deferred_work(priv); - rtl92e_dm_deinit(dev); - rtllib_stop_scan_syncro(ieee); - - if (ieee->link_state == MAC80211_LINKED) { - mutex_lock(&ieee->wx_mutex); - netdev_info(dev, "ieee->link_state is MAC80211_LINKED\n"); - rtllib_stop_send_beacons(priv->rtllib); - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - rtllib_stop_scan(ieee); - netif_carrier_off(dev); - mutex_unlock(&ieee->wx_mutex); - } else { - netdev_info(dev, "ieee->link_state is NOT LINKED\n"); - rtllib_softmac_stop_protocol(priv->rtllib, 0, true); - } - - rtl92e_dm_backup_state(dev); - - mutex_unlock(&priv->wx_mutex); - reset_status = _rtl92e_up(dev, true); - - if (reset_status == -1) { - if (reset_times < 3) { - reset_times++; - goto RESET_START; - } else { - netdev_warn(dev, "%s(): Reset Failed\n", - __func__); - } - } - - ieee->is_silent_reset = 1; - - spin_lock_irqsave(&priv->rf_ps_lock, flag); - priv->rf_change_in_progress = false; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - - rtl92e_enable_hw_security_config(dev); - - if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode == - IW_MODE_INFRA) { - ieee->set_chan(ieee->dev, - ieee->current_network.channel); - - schedule_work(&ieee->associate_complete_wq); - - } else if (ieee->link_state == MAC80211_LINKED && ieee->iw_mode == - IW_MODE_ADHOC) { - ieee->set_chan(ieee->dev, - ieee->current_network.channel); - ieee->link_change(ieee->dev); - - notify_wx_assoc_event(ieee); - - rtllib_start_send_beacons(ieee); - - netif_carrier_on(ieee->dev); - } - - rtl92e_cam_restore(dev); - rtl92e_dm_restore_state(dev); -END: - priv->rst_progress = RESET_TYPE_NORESET; - priv->reset_count++; - priv->reset_in_progress = false; - - rtl92e_writeb(dev, UFWP, 1); } + return; } static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, @@ -1157,7 +992,6 @@ static void _rtl92e_watchdog_wq_cb(void *data) struct r8192_priv, watch_dog_wq); struct net_device *dev = priv->rtllib->dev; struct rtllib_device *ieee = priv->rtllib; - enum reset_type ResetType = RESET_TYPE_NORESET; static u8 check_reset_cnt; unsigned long flags; struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) @@ -1184,15 +1018,12 @@ static void _rtl92e_watchdog_wq_cb(void *data) MAC80211_NOLINK) && (ieee->rf_power_state == rf_on) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc) { - if ((ieee->pwr_save_ctrl.ReturnPoint == - IPS_CALLBACK_NONE) && - (!ieee->net_promiscuous_md)) { + if (ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE) { rtl92e_ips_enter(dev); } } } - if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode == - IW_MODE_INFRA) && (!ieee->net_promiscuous_md)) { + if ((ieee->link_state == MAC80211_LINKED) && (ieee->iw_mode == IW_MODE_INFRA)) { if (ieee->link_detect_info.NumRxOkInPeriod > 100 || ieee->link_detect_info.NumTxOkInPeriod > 100) bBusyTraffic = true; @@ -1275,20 +1106,10 @@ static void _rtl92e_watchdog_wq_cb(void *data) spin_lock_irqsave(&priv->tx_lock, flags); if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) && (!priv->rf_change_in_progress) && (!psc->bSwRfProcessing)) { - ResetType = _rtl92e_if_check_reset(dev); + _rtl92e_if_check_reset(dev); check_reset_cnt = 3; } spin_unlock_irqrestore(&priv->tx_lock, flags); - - if (ResetType == RESET_TYPE_NORMAL) { - priv->rst_progress = RESET_TYPE_NORMAL; - return; - } - - if ((priv->force_reset || ResetType == RESET_TYPE_SILENT)) - _rtl92e_if_silent_reset(dev); - priv->force_reset = false; - priv->reset_in_progress = false; } static void _rtl92e_watchdog_timer_cb(struct timer_list *t) @@ -1320,28 +1141,25 @@ void rtl92e_tx_enable(struct net_device *dev) static void _rtl92e_free_rx_ring(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - int i, rx_queue_idx; + int i; - for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; - rx_queue_idx++) { - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = priv->rx_buf[rx_queue_idx][i]; + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = priv->rx_buf[i]; - if (!skb) - continue; + if (!skb) + continue; - dma_unmap_single(&priv->pdev->dev, - *((dma_addr_t *)skb->cb), - priv->rxbuffersize, DMA_FROM_DEVICE); - kfree_skb(skb); - } - - dma_free_coherent(&priv->pdev->dev, - sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount, - priv->rx_ring[rx_queue_idx], - priv->rx_ring_dma[rx_queue_idx]); - priv->rx_ring[rx_queue_idx] = NULL; + dma_unmap_single(&priv->pdev->dev, + *((dma_addr_t *)skb->cb), + priv->rxbuffersize, DMA_FROM_DEVICE); + kfree_skb(skb); } + + dma_free_coherent(&priv->pdev->dev, + sizeof(*priv->rx_ring) * priv->rxringcount, + priv->rx_ring, + priv->rx_ring_dma); + priv->rx_ring = NULL; } static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio) @@ -1374,8 +1192,7 @@ static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; - if ((priv->rtllib->rf_power_state == rf_off) || !priv->up || - priv->reset_in_progress) { + if ((priv->rtllib->rf_power_state == rf_off) || !priv->up) { kfree_skb(skb); return; } @@ -1408,7 +1225,7 @@ static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (queue_index != TXCMD_QUEUE) { if ((priv->rtllib->rf_power_state == rf_off) || - !priv->up || priv->reset_in_progress) { + !priv->up) { kfree_skb(skb); return 0; } @@ -1488,7 +1305,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); struct tx_desc *pdesc = NULL; - struct rtllib_hdr_1addr *header = NULL; + struct ieee80211_hdr *header = NULL; u8 *pda_addr = NULL; int idx; u32 fwinfo_size = 0; @@ -1497,7 +1314,7 @@ static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) fwinfo_size = sizeof(struct tx_fwinfo_8190pci); - header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); + header = (struct ieee80211_hdr *)(((u8 *)skb->data) + fwinfo_size); pda_addr = header->addr1; if (!is_broadcast_ether_addr(pda_addr) && !is_multicast_ether_addr(pda_addr)) @@ -1533,47 +1350,44 @@ static short _rtl92e_alloc_rx_ring(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); struct rx_desc *entry = NULL; - int i, rx_queue_idx; + int i; - for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { - priv->rx_ring[rx_queue_idx] = dma_alloc_coherent(&priv->pdev->dev, - sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount, - &priv->rx_ring_dma[rx_queue_idx], - GFP_ATOMIC); - if (!priv->rx_ring[rx_queue_idx] || - (unsigned long)priv->rx_ring[rx_queue_idx] & 0xFF) { - netdev_warn(dev, "Cannot allocate RX ring\n"); - return -ENOMEM; - } - - priv->rx_idx[rx_queue_idx] = 0; - - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); - dma_addr_t *mapping; - - entry = &priv->rx_ring[rx_queue_idx][i]; - if (!skb) - return 0; - skb->dev = dev; - priv->rx_buf[rx_queue_idx][i] = skb; - mapping = (dma_addr_t *)skb->cb; - *mapping = dma_map_single(&priv->pdev->dev, - skb_tail_pointer(skb), - priv->rxbuffersize, DMA_FROM_DEVICE); - if (dma_mapping_error(&priv->pdev->dev, *mapping)) { - dev_kfree_skb_any(skb); - return -1; - } - entry->BufferAddress = *mapping; - - entry->Length = priv->rxbuffersize; - entry->OWN = 1; - } - - if (entry) - entry->EOR = 1; + priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev, + sizeof(*priv->rx_ring) * priv->rxringcount, + &priv->rx_ring_dma, + GFP_ATOMIC); + if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { + netdev_warn(dev, "Cannot allocate RX ring\n"); + return -ENOMEM; } + + priv->rx_idx = 0; + + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); + dma_addr_t *mapping; + + entry = &priv->rx_ring[i]; + if (!skb) + return 0; + skb->dev = dev; + priv->rx_buf[i] = skb; + mapping = (dma_addr_t *)skb->cb; + *mapping = dma_map_single(&priv->pdev->dev, + skb_tail_pointer(skb), + priv->rxbuffersize, DMA_FROM_DEVICE); + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + dev_kfree_skb_any(skb); + return -1; + } + entry->BufferAddress = *mapping; + + entry->Length = priv->rxbuffersize; + entry->OWN = 1; + } + + if (entry) + entry->EOR = 1; return 0; } @@ -1635,19 +1449,17 @@ err_free_rings: void rtl92e_reset_desc_ring(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - int i, rx_queue_idx; + int i; unsigned long flags = 0; - for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { - if (priv->rx_ring[rx_queue_idx]) { - struct rx_desc *entry = NULL; + if (priv->rx_ring) { + struct rx_desc *entry = NULL; - for (i = 0; i < priv->rxringcount; i++) { - entry = &priv->rx_ring[rx_queue_idx][i]; - entry->OWN = 1; - } - priv->rx_idx[rx_queue_idx] = 0; + for (i = 0; i < priv->rxringcount; i++) { + entry = &priv->rx_ring[i]; + entry->OWN = 1; } + priv->rx_idx = 0; } spin_lock_irqsave(&priv->irq_th_lock, flags); @@ -1743,10 +1555,9 @@ void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats, static void _rtl92e_rx_normal(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_hdr_1addr *rtllib_hdr = NULL; + struct ieee80211_hdr *rtllib_hdr = NULL; bool unicast_packet = false; u32 skb_len = 0; - int rx_queue_idx = RX_MPDU_QUEUE; struct rtllib_rx_stats stats = { .signal = 0, @@ -1758,10 +1569,10 @@ static void _rtl92e_rx_normal(struct net_device *dev) stats.nic_type = NIC_8192E; while (count--) { - struct rx_desc *pdesc = &priv->rx_ring[rx_queue_idx] - [priv->rx_idx[rx_queue_idx]]; - struct sk_buff *skb = priv->rx_buf[rx_queue_idx] - [priv->rx_idx[rx_queue_idx]]; + struct rx_desc *pdesc = &priv->rx_ring + [priv->rx_idx]; + struct sk_buff *skb = priv->rx_buf + [priv->rx_idx]; struct sk_buff *new_skb; if (pdesc->OWN) @@ -1782,7 +1593,7 @@ static void _rtl92e_rx_normal(struct net_device *dev) skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift); skb_trim(skb, skb->len - S_CRC_LEN); - rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data; + rtllib_hdr = (struct ieee80211_hdr *)skb->data; if (!is_multicast_ether_addr(rtllib_hdr->addr1)) { /* unicast packet */ unicast_packet = true; @@ -1799,8 +1610,7 @@ static void _rtl92e_rx_normal(struct net_device *dev) skb = new_skb; skb->dev = dev; - priv->rx_buf[rx_queue_idx][priv->rx_idx[rx_queue_idx]] = - skb; + priv->rx_buf[priv->rx_idx] = skb; *((dma_addr_t *)skb->cb) = dma_map_single(&priv->pdev->dev, skb_tail_pointer(skb), priv->rxbuffersize, DMA_FROM_DEVICE); @@ -1812,9 +1622,9 @@ done: pdesc->BufferAddress = *((dma_addr_t *)skb->cb); pdesc->OWN = 1; pdesc->Length = priv->rxbuffersize; - if (priv->rx_idx[rx_queue_idx] == priv->rxringcount - 1) + if (priv->rx_idx == priv->rxringcount - 1) pdesc->EOR = 1; - priv->rx_idx[rx_queue_idx] = (priv->rx_idx[rx_queue_idx] + 1) % + priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount; } } @@ -1865,9 +1675,9 @@ static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv) cancel_work_sync(&priv->qos_activate); } -static int _rtl92e_up(struct net_device *dev, bool is_silent_reset) +static int _rtl92e_up(struct net_device *dev) { - if (_rtl92e_sta_up(dev, is_silent_reset) == -1) + if (_rtl92e_sta_up(dev) == -1) return -1; return 0; } @@ -1889,7 +1699,7 @@ static int _rtl92e_try_up(struct net_device *dev) if (priv->up == 1) return -1; - return _rtl92e_up(dev, false); + return _rtl92e_up(dev); } static int _rtl92e_close(struct net_device *dev) @@ -1925,10 +1735,10 @@ void rtl92e_commit(struct net_device *dev) if (priv->up == 0) return; - rtllib_softmac_stop_protocol(priv->rtllib, 0, true); + rtllib_softmac_stop_protocol(priv->rtllib); rtl92e_irq_disable(dev); rtl92e_stop_adapter(dev, true); - _rtl92e_up(dev, false); + _rtl92e_up(dev); } static void _rtl92e_restart(void *data) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index fa82a0667813..a4afbf3e934d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -91,8 +91,6 @@ #define MAX_TX_QUEUE 9 -#define MAX_RX_QUEUE 1 - #define MAX_RX_COUNT 64 #define MAX_TX_QUEUE_COUNT 9 @@ -132,7 +130,6 @@ enum rt_customer_id { enum reset_type { RESET_TYPE_NORESET = 0x00, - RESET_TYPE_NORMAL = 0x01, RESET_TYPE_SILENT = 0x02 }; @@ -233,10 +230,10 @@ struct r8192_priv { u8 (*rf_set_chan)(struct net_device *dev, u8 ch); - struct rx_desc *rx_ring[MAX_RX_QUEUE]; - struct sk_buff *rx_buf[MAX_RX_QUEUE][MAX_RX_COUNT]; - dma_addr_t rx_ring_dma[MAX_RX_QUEUE]; - unsigned int rx_idx[MAX_RX_QUEUE]; + struct rx_desc *rx_ring; + struct sk_buff *rx_buf[MAX_RX_COUNT]; + dma_addr_t rx_ring_dma; + unsigned int rx_idx; int rxringcount; u16 rxbuffersize; @@ -264,7 +261,6 @@ struct r8192_priv { short promisc; short chan; - bool ps_force; u32 irq_mask[2]; @@ -345,7 +341,6 @@ struct r8192_priv { u8 rfa_txpowertrackingindex; u8 rfa_txpowertrackingindex_real; u8 rfa_txpowertracking_default; - u8 rfc_txpowertrackingindex; bool btxpower_tracking; bool bcck_in_ch14; @@ -369,14 +364,9 @@ struct r8192_priv { u32 continue_diff_count; bool bswitch_fsync; u8 framesync; - u32 reset_count; - enum reset_type rst_progress; u16 tx_counter; u16 rx_ctr; - bool reset_in_progress; - bool force_reset; - bool force_lps; }; extern const struct ethtool_ops rtl819x_ethtool_ops; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index dbf765d601b3..330dafd62656 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -161,12 +161,9 @@ static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev); static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev); -static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev); static void _rtl92e_dm_dig_init(struct net_device *dev); static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev); -static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev); -static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev); static void _rtl92e_dm_initial_gain(struct net_device *dev); static void _rtl92e_dm_pd_th(struct net_device *dev); static void _rtl92e_dm_cs_ratio(struct net_device *dev); @@ -285,9 +282,6 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) if (!priv->up) return; - if (pra->rate_adaptive_disabled) - return; - if (priv->rtllib->mode != WIRELESS_MODE_N_24G) return; @@ -298,25 +292,25 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) ht_info->bCurShortGI20MHz); pra->upper_rssi_threshold_ratr = - (pra->upper_rssi_threshold_ratr & (~BIT31)) | - ((bshort_gi_enabled) ? BIT31 : 0); + (pra->upper_rssi_threshold_ratr & (~BIT(31))) | + ((bshort_gi_enabled) ? BIT(31) : 0); pra->middle_rssi_threshold_ratr = - (pra->middle_rssi_threshold_ratr & (~BIT31)) | - ((bshort_gi_enabled) ? BIT31 : 0); + (pra->middle_rssi_threshold_ratr & (~BIT(31))) | + ((bshort_gi_enabled) ? BIT(31) : 0); if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) { pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | - ((bshort_gi_enabled) ? BIT31 : 0); + (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) | + ((bshort_gi_enabled) ? BIT(31) : 0); } else { pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | - ((bshort_gi_enabled) ? BIT31 : 0); + (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) | + ((bshort_gi_enabled) ? BIT(31) : 0); } pra->ping_rssi_ratr = - (pra->ping_rssi_ratr & (~BIT31)) | - ((bshort_gi_enabled) ? BIT31 : 0); + (pra->ping_rssi_ratr & (~BIT(31))) | + ((bshort_gi_enabled) ? BIT(31) : 0); if (pra->ratr_state == DM_RATR_STA_HIGH) { high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra; @@ -371,8 +365,6 @@ static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev) ratr_value &= ~(RATE_ALL_OFDM_2SS); rtl92e_writel(dev, RATR0, ratr_value); rtl92e_writeb(dev, UFWP, 1); - - pra->last_ratr = target_ratr; } } else { @@ -530,11 +522,6 @@ static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev) if (Pwr_Flag == 0) { mdelay(1); - if (priv->reset_in_progress) { - rtl92e_writeb(dev, Pw_Track_Flag, 0); - rtl92e_writeb(dev, FW_Busy_Flag, 0); - return; - } if (priv->rtllib->rf_power_state != rf_on) { rtl92e_writeb(dev, Pw_Track_Flag, 0); rtl92e_writeb(dev, FW_Busy_Flag, 0); @@ -920,95 +907,10 @@ void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14) _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14); } -static void _rtl92e_dm_tx_power_reset_recovery(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, - dm_tx_bb_gain[priv->rfa_txpowertrackingindex]); - rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - - rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, - dm_tx_bb_gain[priv->rfc_txpowertrackingindex]); -} - -void rtl92e_dm_restore_state(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 reg_ratr = priv->rate_adaptive.last_ratr; - u32 ratr_value; - - if (!priv->up) - return; - - if (priv->rate_adaptive.rate_adaptive_disabled) - return; - if (priv->rtllib->mode != WIRELESS_MODE_N_24G) - return; - ratr_value = reg_ratr; - ratr_value &= ~(RATE_ALL_OFDM_2SS); - rtl92e_writel(dev, RATR0, ratr_value); - rtl92e_writeb(dev, UFWP, 1); - if (priv->tx_pwr_tracking_init && priv->btxpower_tracking) - _rtl92e_dm_tx_power_reset_recovery(dev); - - _rtl92e_dm_bb_initialgain_restore(dev); -} - -static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 bit_mask = 0x7f; - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); - rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask, - (u32)priv->initgain_backup.xaagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask, - (u32)priv->initgain_backup.xbagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask, - (u32)priv->initgain_backup.xcagccore1); - rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask, - (u32)priv->initgain_backup.xdagccore1); - bit_mask = bMaskByte2; - rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask, - (u32)priv->initgain_backup.cca); - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); -} - -void rtl92e_dm_backup_state(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u32 bit_mask = bMaskByte0; - - priv->bswitch_fsync = false; - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); - priv->initgain_backup.xaagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask); - priv->initgain_backup.xbagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask); - priv->initgain_backup.xcagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask); - priv->initgain_backup.xdagccore1 = rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask); - bit_mask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask); -} - static void _rtl92e_dm_dig_init(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); - dm_digtable.dig_enable_flag = true; - - dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; - - dm_digtable.dig_algorithm_switch = 0; - - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT; dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT; @@ -1029,15 +931,7 @@ static void _rtl92e_dm_dig_init(struct net_device *dev) static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev) { - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(dev); - else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - _rtl92e_dm_ctrl_initgain_byrssi_driver(dev); - else - return; + _rtl92e_dm_ctrl_initgain_byrssi_driver(dev); } /*----------------------------------------------------------------------------- @@ -1064,16 +958,10 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev) u8 i; static u8 fw_dig; - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm_switch) - fw_dig = 0; if (fw_dig <= 3) { for (i = 0; i < 3; i++) rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); fw_dig++; - dm_digtable.dig_state = DM_STA_DIG_OFF; } if (priv->rtllib->link_state == MAC80211_LINKED) @@ -1085,150 +973,14 @@ static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev) _rtl92e_dm_initial_gain(dev); _rtl92e_dm_pd_th(dev); _rtl92e_dm_cs_ratio(dev); - if (dm_digtable.dig_algorithm_switch) - dm_digtable.dig_algorithm_switch = 0; dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state; } -static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static u32 reset_cnt; - u8 i; - - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm_switch) { - dm_digtable.dig_state = DM_STA_DIG_MAX; - for (i = 0; i < 3; i++) - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); - dm_digtable.dig_algorithm_switch = 0; - } - - if (priv->rtllib->link_state != MAC80211_LINKED) - return; - - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) - return; - if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) { - if (dm_digtable.dig_state == DM_STA_DIG_OFF && - (priv->reset_count == reset_cnt)) - return; - reset_cnt = priv->reset_count; - - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.dig_state = DM_STA_DIG_OFF; - - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); - - rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17); - rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17); - rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17); - rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17); - - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x00); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42); - - rtl92e_writeb(dev, 0xa0a, 0x08); - - return; - } - - if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { - u8 reset_flag = 0; - - if (dm_digtable.dig_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt)) { - _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev); - return; - } - if (priv->reset_count != reset_cnt) - reset_flag = 1; - - reset_cnt = priv->reset_count; - - dm_digtable.dig_state = DM_STA_DIG_ON; - - if (reset_flag == 1) { - rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c); - rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c); - rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c); - rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c); - } else { - rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20); - rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20); - rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20); - rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20); - } - - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); - - rtl92e_writeb(dev, 0xa0a, 0xcd); - - rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); - } - _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev); -} - -static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static u32 reset_cnt_highpwr; - - if ((priv->undecorated_smoothed_pwdb > - dm_digtable.rssi_high_power_lowthresh) && - (priv->undecorated_smoothed_pwdb < - dm_digtable.rssi_high_power_highthresh)) - return; - - if (priv->undecorated_smoothed_pwdb >= - dm_digtable.rssi_high_power_highthresh) { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt_highpwr)) - return; - dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; - - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x10); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43); - } else { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF && - (priv->reset_count == reset_cnt_highpwr)) - return; - dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; - - if ((priv->undecorated_smoothed_pwdb < - dm_digtable.rssi_high_power_lowthresh) && - (priv->undecorated_smoothed_pwdb >= - dm_digtable.rssi_high_thresh)) { - if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) - rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20); - else - rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); - } - } - reset_cnt_highpwr = priv->reset_count; -} - static void _rtl92e_dm_initial_gain(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); u8 initial_gain = 0; static u8 initialized, force_write; - static u32 reset_cnt; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } if (rtllib_act_scanning(priv->rtllib, true)) { force_write = 1; @@ -1254,11 +1006,6 @@ static void _rtl92e_dm_initial_gain(struct net_device *dev) dm_digtable.pre_ig_value = 0; } - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1)) force_write = 1; @@ -1279,12 +1026,6 @@ static void _rtl92e_dm_pd_th(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); static u8 initialized, force_write; - static u32 reset_cnt; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { @@ -1312,11 +1053,6 @@ static void _rtl92e_dm_pd_th(struct net_device *dev) dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; } - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || (initialized <= 3) || force_write) { if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { @@ -1345,14 +1081,7 @@ static void _rtl92e_dm_pd_th(struct net_device *dev) static void _rtl92e_dm_cs_ratio(struct net_device *dev) { - struct r8192_priv *priv = rtllib_priv(dev); static u8 initialized, force_write; - static u32 reset_cnt; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) { if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) { @@ -1369,11 +1098,6 @@ static void _rtl92e_dm_cs_ratio(struct net_device *dev) dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; } - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || !initialized || force_write) { if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) @@ -1405,8 +1129,6 @@ static void _rtl92e_dm_check_edca_turbo(struct net_device *dev) unsigned long curTxOkCnt = 0; unsigned long curRxOkCnt = 0; - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) - goto dm_CheckEdcaTurbo_EXIT; if (priv->rtllib->link_state != MAC80211_LINKED) goto dm_CheckEdcaTurbo_EXIT; if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO) @@ -1525,7 +1247,7 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) tmp1byte = rtl92e_readb(dev, GPI); - rf_power_state_to_set = (tmp1byte & BIT1) ? rf_on : rf_off; + rf_power_state_to_set = (tmp1byte & BIT(1)) ? rf_on : rf_off; if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) { netdev_info(dev, "gpiochangeRF - HW Radio ON\n"); @@ -1989,7 +1711,6 @@ static void _rtl92e_dm_check_fsync(struct net_device *dev) #define RegC38_Fsync_AP_BCM 2 struct r8192_priv *priv = rtllib_priv(dev); static u8 reg_c38_State = RegC38_Default; - static u32 reset_cnt; if (priv->rtllib->link_state == MAC80211_LINKED && priv->rtllib->ht_info->IOTPeer == HT_IOT_PEER_BROADCOM) { @@ -2073,12 +1794,6 @@ static void _rtl92e_dm_check_fsync(struct net_device *dev) } } } - if (priv->reset_count != reset_cnt) { - rtl92e_writeb(dev, rOFDM0_RxDetector3, - priv->framesync); - reg_c38_State = RegC38_Default; - reset_cnt = priv->reset_count; - } } /*---------------------------Define function prototype------------------------*/ diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h index 01587e2fec65..84e673452be4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h @@ -50,18 +50,12 @@ /*------------------------------Define structure----------------------------*/ struct dig_t { - u8 dig_enable_flag; - u8 dig_algorithm; - u8 dig_algorithm_switch; - long rssi_low_thresh; long rssi_high_thresh; long rssi_high_power_lowthresh; long rssi_high_power_highthresh; - u8 dig_state; - u8 dig_highpwr_state; u8 cur_sta_connect_state; u8 pre_sta_connect_state; @@ -80,12 +74,6 @@ struct dig_t { long rssi_val; }; -enum dm_dig_sta { - DM_STA_DIG_OFF = 0, - DM_STA_DIG_ON, - DM_STA_DIG_MAX -}; - enum dm_ratr_sta { DM_RATR_STA_HIGH = 0, DM_RATR_STA_MIDDLE = 1, @@ -93,22 +81,9 @@ enum dm_ratr_sta { DM_RATR_STA_MAX }; -enum dm_dig_alg { - DIG_ALGO_BY_FALSE_ALARM = 0, - DIG_ALGO_BY_RSSI = 1, - DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2, - DIG_ALGO_BY_TOW_PORT = 3, - DIG_ALGO_MAX -}; - enum dm_dig_connect { DIG_STA_DISCONNECT = 0, DIG_STA_CONNECT = 1, - DIG_STA_BEFORE_CONNECT = 2, - DIG_AP_DISCONNECT = 3, - DIG_AP_CONNECT = 4, - DIG_AP_ADD_STATION = 5, - DIG_CONNECT_MAX }; enum dm_dig_pd_th { @@ -178,8 +153,6 @@ void rtl92e_dm_txpower_tracking_wq(void *data); void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14); -void rtl92e_dm_restore_state(struct net_device *dev); -void rtl92e_dm_backup_state(struct net_device *dev); void rtl92e_dm_init_edca_turbo(struct net_device *dev); void rtl92e_dm_rf_pathcheck_wq(void *data); void rtl92e_dm_init_txpower_tracking(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c index 0bc3e013001e..1aa73561581b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c @@ -21,7 +21,7 @@ static void _rtl92e_parse_pci_configuration(struct pci_dev *pdev, pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &link_ctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); - tmp |= BIT4; + tmp |= BIT(4); pci_write_config_byte(pdev, 0x98, tmp); tmp = 0x17; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c index 598bfc0ff3d1..44a9fe831849 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c @@ -181,11 +181,7 @@ static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode) { struct r8192_priv *priv = rtllib_priv(dev); - if (priv->rtllib->iw_mode == IW_MODE_ADHOC) - return false; - - if (!priv->ps_force) - priv->rtllib->ps = rtPsMode; + priv->rtllib->ps = rtPsMode; if (priv->rtllib->sta_sleep != LPS_IS_WAKE && rtPsMode == RTLLIB_PS_DISABLED) { unsigned long flags; @@ -208,8 +204,7 @@ void rtl92e_leisure_ps_enter(struct net_device *dev) &priv->rtllib->pwr_save_ctrl; if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && - (priv->rtllib->link_state == MAC80211_LINKED)) - || (priv->rtllib->iw_mode == IW_MODE_ADHOC)) + (priv->rtllib->link_state == MAC80211_LINKED))) return; if (psc->bLeisurePs) { diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 189798852568..4371ab1239ee 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -122,126 +122,11 @@ static int _rtl92e_wx_get_power(struct net_device *dev, return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra); } -static int _rtl92e_wx_set_rawtx(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int ret; - - if (priv->hw_radio_off) - return 0; - - mutex_lock(&priv->wx_mutex); - - ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int _rtl92e_wx_force_reset(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - mutex_lock(&priv->wx_mutex); - - priv->force_reset = *extra; - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int _rtl92e_wx_adapter_power_status(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - struct rtllib_device *ieee = priv->rtllib; - - mutex_lock(&priv->wx_mutex); - - if (*extra || priv->force_lps) { - priv->ps_force = false; - psc->bLeisurePs = true; - } else { - if (priv->rtllib->link_state == MAC80211_LINKED) - rtl92e_leisure_ps_leave(dev); - - priv->ps_force = true; - psc->bLeisurePs = false; - ieee->ps = *extra; - } - - mutex_unlock(&priv->wx_mutex); - - return 0; -} - -static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) - (&priv->rtllib->pwr_save_ctrl); - - mutex_lock(&priv->wx_mutex); - - netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n", - __func__, *extra); - - psc->reg_max_lps_awake_intvl = *extra; - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int _rtl92e_wx_set_force_lps(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - - mutex_lock(&priv->wx_mutex); - - netdev_info(dev, - "%s(): force LPS ! extra is %d (1 is open 0 is close)\n", - __func__, *extra); - priv->force_lps = *extra; - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int _rtl92e_wx_set_debug(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - u8 c = *extra; - - if (priv->hw_radio_off) - return 0; - - netdev_info(dev, "=====>%s(), *extra:%x, debugflag:%x\n", __func__, - *extra, rt_global_debug_component); - if (c > 0) - rt_global_debug_component |= (1 << c); - else - rt_global_debug_component &= BIT31; - return 0; -} - static int _rtl92e_wx_set_mode(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = netdev_priv_rsl(dev); enum rt_rf_power_state rt_state; int ret; @@ -250,8 +135,7 @@ static int _rtl92e_wx_set_mode(struct net_device *dev, return 0; rt_state = priv->rtllib->rf_power_state; mutex_lock(&priv->wx_mutex); - if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR || - ieee->net_promiscuous_md) { + if (wrqu->mode == IW_MODE_MONITOR) { if (rt_state == rf_off) { if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { @@ -724,22 +608,6 @@ end_hw_sec: return ret; } -static int _rtl92e_wx_set_scan_type(struct net_device *dev, - struct iw_request_info *aa, - union iwreq_data *wrqu, char *p) -{ - struct r8192_priv *priv = rtllib_priv(dev); - int *parms = (int *)p; - int mode = parms[0]; - - if (priv->hw_radio_off) - return 0; - - priv->rtllib->active_scan = mode; - - return 1; -} - #define R8192_MAX_RETRY 255 static int _rtl92e_wx_set_retry(struct net_device *dev, struct iw_request_info *info, @@ -844,8 +712,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev, idx--; group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; - if ((!group) || (ieee->iw_mode == IW_MODE_ADHOC) || - (alg == KEY_TYPE_WEP40)) { + if ((!group) || (alg == KEY_TYPE_WEP40)) { if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) alg = KEY_TYPE_WEP104; ieee->pairwise_key_type = alg; @@ -865,7 +732,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev, rtl92e_set_swcam(dev, idx, idx, alg, broadcast_addr, key); } else { if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && - ieee->ht_info->bCurrentHTSupport) + ieee->ht_info->current_ht_support) rtl92e_writeb(dev, 0x173, 1); rtl92e_set_key(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, 0, key); @@ -938,7 +805,7 @@ static int _rtl92e_wx_get_gen_ie(struct net_device *dev, struct r8192_priv *priv = rtllib_priv(dev); struct rtllib_device *ieee = priv->rtllib; - if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { + if (ieee->wpa_ie_len == 0 || !ieee->wpa_ie) { data->data.length = 0; return 0; } @@ -951,67 +818,6 @@ static int _rtl92e_wx_get_gen_ie(struct net_device *dev, return ret; } -#define OID_RT_INTEL_PROMISCUOUS_MODE 0xFF0101F6 - -static int _rtl92e_wx_set_promisc_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - u32 info_buf[3]; - - u32 oid; - u32 promiscuous_on; - u32 fltr_src_sta_frame; - - if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf))) - return -EFAULT; - - oid = info_buf[0]; - promiscuous_on = info_buf[1]; - fltr_src_sta_frame = info_buf[2]; - - if (oid == OID_RT_INTEL_PROMISCUOUS_MODE) { - ieee->intel_promiscuous_md_info.promiscuous_on = - (promiscuous_on) ? (true) : (false); - ieee->intel_promiscuous_md_info.fltr_src_sta_frame = - (fltr_src_sta_frame) ? (true) : (false); - (promiscuous_on) ? - (rtllib_EnableIntelPromiscuousMode(dev, false)) : - (rtllib_DisableIntelPromiscuousMode(dev, false)); - - netdev_info(dev, - "=======>%s(), on = %d, filter src sta = %d\n", - __func__, promiscuous_on, - fltr_src_sta_frame); - } else { - return -1; - } - - return 0; -} - -static int _rtl92e_wx_get_promisc_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = rtllib_priv(dev); - struct rtllib_device *ieee = priv->rtllib; - - mutex_lock(&priv->wx_mutex); - - snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d", - ieee->intel_promiscuous_md_info.promiscuous_on, - ieee->intel_promiscuous_md_info.fltr_src_sta_frame); - wrqu->data.length = strlen(extra) + 1; - - mutex_unlock(&priv->wx_mutex); - - return 0; -} - #define IW_IOCTL(x) ((x) - SIOCSIWCOMMIT) static iw_handler r8192_wx_handlers[] = { [IW_IOCTL(SIOCGIWNAME)] = _rtl92e_wx_get_name, @@ -1047,72 +853,6 @@ static iw_handler r8192_wx_handlers[] = { [IW_IOCTL(SIOCSIWENCODEEXT)] = _rtl92e_wx_set_encode_ext, }; -/* the following rule need to be following, - * Odd : get (world access), - * even : set (root access) - */ -static const struct iw_priv_args r8192_private_args[] = { - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag" - }, { - SIOCIWFIRSTPRIV + 0x1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" - }, { - SIOCIWFIRSTPRIV + 0x2, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" - }, { - SIOCIWFIRSTPRIV + 0x3, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" - }, { - SIOCIWFIRSTPRIV + 0x6, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, - "set_power" - }, { - SIOCIWFIRSTPRIV + 0xa, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, - "lps_interv" - }, { - SIOCIWFIRSTPRIV + 0xb, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, - "lps_force" - }, { - SIOCIWFIRSTPRIV + 0x16, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc" - }, { - SIOCIWFIRSTPRIV + 0x17, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc" - } - -}; - -static iw_handler r8192_private_handler[] = { - (iw_handler)_rtl92e_wx_set_debug, /*SIOCIWSECONDPRIV*/ - (iw_handler)_rtl92e_wx_set_scan_type, - (iw_handler)_rtl92e_wx_set_rawtx, - (iw_handler)_rtl92e_wx_force_reset, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)_rtl92e_wx_adapter_power_status, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)_rtl92e_wx_set_lps_awake_interval, - (iw_handler)_rtl92e_wx_set_force_lps, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)NULL, - (iw_handler)_rtl92e_wx_set_promisc_mode, - (iw_handler)_rtl92e_wx_get_promisc_mode, -}; - static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); @@ -1144,10 +884,5 @@ static struct iw_statistics *_rtl92e_get_wireless_stats(struct net_device *dev) const struct iw_handler_def r8192_wx_handlers_def = { .standard = r8192_wx_handlers, .num_standard = ARRAY_SIZE(r8192_wx_handlers), - .private = r8192_private_handler, - .num_private = ARRAY_SIZE(r8192_private_handler), - .num_private_args = sizeof(r8192_private_args) / - sizeof(struct iw_priv_args), .get_wireless_stats = _rtl92e_get_wireless_stats, - .private_args = (struct iw_priv_args *)r8192_private_args, }; diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 0e3372868f97..4af8055d2489 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -10,109 +10,109 @@ #include "rtllib.h" #include "rtl819x_BA.h" -static void activate_ba_entry(struct ba_record *pBA, u16 Time) +static void activate_ba_entry(struct ba_record *ba, u16 time) { - pBA->b_valid = true; - if (Time != 0) - mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time)); + ba->b_valid = true; + if (time != 0) + mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time)); } -static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *pBA) +static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba) { - pBA->b_valid = false; - del_timer_sync(&pBA->timer); + ba->b_valid = false; + del_timer_sync(&ba->timer); } static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *pTxTs) { - struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord; - struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord; + struct ba_record *admitted_ba = &pTxTs->TxAdmittedBARecord; + struct ba_record *pending_ba = &pTxTs->TxPendingBARecord; u8 bSendDELBA = false; - if (pPendingBa->b_valid) { - deactivate_ba_entry(ieee, pPendingBa); + if (pending_ba->b_valid) { + deactivate_ba_entry(ieee, pending_ba); bSendDELBA = true; } - if (pAdmittedBa->b_valid) { - deactivate_ba_entry(ieee, pAdmittedBa); + if (admitted_ba->b_valid) { + deactivate_ba_entry(ieee, admitted_ba); bSendDELBA = true; } return bSendDELBA; } -static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *pRxTs) +static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts) { - struct ba_record *pBa = &pRxTs->rx_admitted_ba_record; + struct ba_record *ba = &ts->rx_admitted_ba_record; u8 bSendDELBA = false; - if (pBa->b_valid) { - deactivate_ba_entry(ieee, pBa); + if (ba->b_valid) { + deactivate_ba_entry(ieee, ba); bSendDELBA = true; } return bSendDELBA; } -void rtllib_reset_ba_entry(struct ba_record *pBA) +void rtllib_reset_ba_entry(struct ba_record *ba) { - pBA->b_valid = false; - pBA->ba_param_set.short_data = 0; - pBA->ba_timeout_value = 0; - pBA->dialog_token = 0; - pBA->ba_start_seq_ctrl.short_data = 0; + ba->b_valid = false; + ba->ba_param_set.short_data = 0; + ba->ba_timeout_value = 0; + ba->dialog_token = 0; + ba->ba_start_seq_ctrl.short_data = 0; } -static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, - struct ba_record *pBA, - u16 StatusCode, u8 type) +static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst, + struct ba_record *ba, + u16 status_code, u8 type) { struct sk_buff *skb = NULL; - struct rtllib_hdr_3addr *BAReq = NULL; + struct ieee80211_hdr_3addr *BAReq = NULL; u8 *tag = NULL; u16 len = ieee->tx_headroom + 9; netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n", - __func__, type, Dst, ieee->dev); + __func__, type, dst, ieee->dev); - if (!pBA) { - netdev_warn(ieee->dev, "pBA is NULL\n"); + if (!ba) { + netdev_warn(ieee->dev, "ba is NULL\n"); return NULL; } - skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); + skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr)); if (!skb) return NULL; - memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); + memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr)); skb_reserve(skb, ieee->tx_headroom); - BAReq = skb_put(skb, sizeof(struct rtllib_hdr_3addr)); + BAReq = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); - ether_addr_copy(BAReq->addr1, Dst); + ether_addr_copy(BAReq->addr1, dst); ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr); ether_addr_copy(BAReq->addr3, ieee->current_network.bssid); - BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); + BAReq->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION); tag = skb_put(skb, 9); *tag++ = ACT_CAT_BA; *tag++ = type; - *tag++ = pBA->dialog_token; + *tag++ = ba->dialog_token; if (type == ACT_ADDBARSP) { - put_unaligned_le16(StatusCode, tag); + put_unaligned_le16(status_code, tag); tag += 2; } - put_unaligned_le16(pBA->ba_param_set.short_data, tag); + put_unaligned_le16(ba->ba_param_set.short_data, tag); tag += 2; - put_unaligned_le16(pBA->ba_timeout_value, tag); + put_unaligned_le16(ba->ba_timeout_value, tag); tag += 2; if (type == ACT_ADDBAREQ) { - memcpy(tag, (u8 *)&pBA->ba_start_seq_ctrl, 2); + memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2); tag += 2; } @@ -124,36 +124,36 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, } static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, - struct ba_record *pBA, - enum tr_select TxRxSelect, u16 ReasonCode) + struct ba_record *ba, + enum tr_select TxRxSelect, u16 reason_code) { union delba_param_set DelbaParamSet; struct sk_buff *skb = NULL; - struct rtllib_hdr_3addr *Delba = NULL; + struct ieee80211_hdr_3addr *Delba = NULL; u8 *tag = NULL; u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) - netdev_dbg(ieee->dev, "%s(): ReasonCode(%d) sentd to: %pM\n", - __func__, ReasonCode, dst); + netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n", + __func__, reason_code, dst); memset(&DelbaParamSet, 0, 2); DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0; - DelbaParamSet.field.tid = pBA->ba_param_set.field.tid; + DelbaParamSet.field.tid = ba->ba_param_set.field.tid; - skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); + skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr)); if (!skb) return NULL; skb_reserve(skb, ieee->tx_headroom); - Delba = skb_put(skb, sizeof(struct rtllib_hdr_3addr)); + Delba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); ether_addr_copy(Delba->addr1, dst); ether_addr_copy(Delba->addr2, ieee->dev->dev_addr); ether_addr_copy(Delba->addr3, ieee->current_network.bssid); - Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); + Delba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION); tag = skb_put(skb, 6); @@ -163,7 +163,7 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, put_unaligned_le16(DelbaParamSet.short_data, tag); tag += 2; - put_unaligned_le16(ReasonCode, tag); + put_unaligned_le16(reason_code, tag); tag += 2; #ifdef VERBOSE_DEBUG @@ -174,11 +174,11 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, } static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, - struct ba_record *pBA) + struct ba_record *ba) { struct sk_buff *skb; - skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); + skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ); if (skb) softmac_mgmt_xmit(skb, ieee); @@ -187,11 +187,11 @@ static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, } static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, - struct ba_record *pBA, u16 StatusCode) + struct ba_record *ba, u16 status_code) { struct sk_buff *skb; - skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); + skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP); if (skb) softmac_mgmt_xmit(skb, ieee); else @@ -199,12 +199,12 @@ static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, } static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, - struct ba_record *pBA, enum tr_select TxRxSelect, - u16 ReasonCode) + struct ba_record *ba, enum tr_select TxRxSelect, + u16 reason_code) { struct sk_buff *skb; - skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); + skb = rtllib_DELBA(ieee, dst, ba, TxRxSelect, reason_code); if (skb) softmac_mgmt_xmit(skb, ieee); else @@ -213,19 +213,19 @@ static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *req = NULL; + struct ieee80211_hdr_3addr *req = NULL; u16 rc = 0; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; - struct ba_record *pBA = NULL; + struct ba_record *ba = NULL; union ba_param_set *pBaParamSet = NULL; u16 *pBaTimeoutVal = NULL; union sequence_control *pBaStartSeqCtrl = NULL; - struct rx_ts_record *pTS = NULL; + struct rx_ts_record *ts = NULL; - if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n", (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + (int)(sizeof(struct ieee80211_hdr_3addr) + 9)); return -1; } @@ -234,32 +234,32 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) skb->data, skb->len); #endif - req = (struct rtllib_hdr_3addr *)skb->data; + req = (struct ieee80211_hdr_3addr *)skb->data; tag = (u8 *)req; dst = (u8 *)(&req->addr2[0]); - tag += sizeof(struct rtllib_hdr_3addr); + tag += sizeof(struct ieee80211_hdr_3addr); pDialogToken = tag + 2; pBaParamSet = (union ba_param_set *)(tag + 3); pBaTimeoutVal = (u16 *)(tag + 5); pBaStartSeqCtrl = (union sequence_control *)(req + 7); if (!ieee->current_network.qos_data.active || - !ieee->ht_info->bCurrentHTSupport || + !ieee->ht_info->current_ht_support || (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, - ieee->ht_info->bCurrentHTSupport); + ieee->ht_info->current_ht_support); goto OnADDBAReq_Fail; } - if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, (u8)(pBaParamSet->field.tid), RX_DIR, true)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); goto OnADDBAReq_Fail; } - pBA = &pTS->rx_admitted_ba_record; + ba = &ts->rx_admitted_ba_record; if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { rc = ADDBA_STATUS_INVALID_PARAM; @@ -268,22 +268,22 @@ int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) goto OnADDBAReq_Fail; } - rtllib_FlushRxTsPendingPkts(ieee, pTS); + rtllib_FlushRxTsPendingPkts(ieee, ts); - deactivate_ba_entry(ieee, pBA); - pBA->dialog_token = *pDialogToken; - pBA->ba_param_set = *pBaParamSet; - pBA->ba_timeout_value = *pBaTimeoutVal; - pBA->ba_start_seq_ctrl = *pBaStartSeqCtrl; + deactivate_ba_entry(ieee, ba); + ba->dialog_token = *pDialogToken; + ba->ba_param_set = *pBaParamSet; + ba->ba_timeout_value = *pBaTimeoutVal; + ba->ba_start_seq_ctrl = *pBaStartSeqCtrl; if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) - pBA->ba_param_set.field.buffer_size = 1; + ba->ba_param_set.field.buffer_size = 1; else - pBA->ba_param_set.field.buffer_size = 32; + ba->ba_param_set.field.buffer_size = 32; - activate_ba_entry(pBA, 0); - rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); + activate_ba_entry(ba, 0); + rtllib_send_ADDBARsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS); return 0; @@ -302,88 +302,88 @@ OnADDBAReq_Fail: int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *rsp = NULL; - struct ba_record *pPendingBA, *pAdmittedBA; - struct tx_ts_record *pTS = NULL; + struct ieee80211_hdr_3addr *rsp = NULL; + struct ba_record *pending_ba, *pAdmittedBA; + struct tx_ts_record *ts = NULL; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; - u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; + u16 *status_code = NULL, *pBaTimeoutVal = NULL; union ba_param_set *pBaParamSet = NULL; - u16 ReasonCode; + u16 reason_code; - if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n", (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + (int)(sizeof(struct ieee80211_hdr_3addr) + 9)); return -1; } - rsp = (struct rtllib_hdr_3addr *)skb->data; + rsp = (struct ieee80211_hdr_3addr *)skb->data; tag = (u8 *)rsp; dst = (u8 *)(&rsp->addr2[0]); - tag += sizeof(struct rtllib_hdr_3addr); + tag += sizeof(struct ieee80211_hdr_3addr); pDialogToken = tag + 2; - pStatusCode = (u16 *)(tag + 3); + status_code = (u16 *)(tag + 3); pBaParamSet = (union ba_param_set *)(tag + 5); pBaTimeoutVal = (u16 *)(tag + 7); if (!ieee->current_network.qos_data.active || - !ieee->ht_info->bCurrentHTSupport || + !ieee->ht_info->current_ht_support || !ieee->ht_info->bCurrentAMPDUEnable) { netdev_warn(ieee->dev, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", ieee->current_network.qos_data.active, - ieee->ht_info->bCurrentHTSupport, + ieee->ht_info->current_ht_support, ieee->ht_info->bCurrentAMPDUEnable); - ReasonCode = DELBA_REASON_UNKNOWN_BA; + reason_code = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } - if (!GetTs(ieee, (struct ts_common_info **)&pTS, dst, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, (u8)(pBaParamSet->field.tid), TX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); - ReasonCode = DELBA_REASON_UNKNOWN_BA; + reason_code = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } - pTS->bAddBaReqInProgress = false; - pPendingBA = &pTS->TxPendingBARecord; - pAdmittedBA = &pTS->TxAdmittedBARecord; + ts->bAddBaReqInProgress = false; + pending_ba = &ts->TxPendingBARecord; + pAdmittedBA = &ts->TxAdmittedBARecord; if (pAdmittedBA->b_valid) { netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n", __func__); return -1; - } else if (!pPendingBA->b_valid || - (*pDialogToken != pPendingBA->dialog_token)) { + } else if (!pending_ba->b_valid || + (*pDialogToken != pending_ba->dialog_token)) { netdev_warn(ieee->dev, "%s(): ADDBA Rsp. BA invalid, DELBA!\n", __func__); - ReasonCode = DELBA_REASON_UNKNOWN_BA; + reason_code = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } else { netdev_dbg(ieee->dev, "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", - __func__, *pStatusCode); - deactivate_ba_entry(ieee, pPendingBA); + __func__, *status_code); + deactivate_ba_entry(ieee, pending_ba); } - if (*pStatusCode == ADDBA_STATUS_SUCCESS) { + if (*status_code == ADDBA_STATUS_SUCCESS) { if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { - pTS->bAddBaReqDelayed = true; + ts->bAddBaReqDelayed = true; deactivate_ba_entry(ieee, pAdmittedBA); - ReasonCode = DELBA_REASON_END_BA; + reason_code = DELBA_REASON_END_BA; goto OnADDBARsp_Reject; } pAdmittedBA->dialog_token = *pDialogToken; pAdmittedBA->ba_timeout_value = *pBaTimeoutVal; - pAdmittedBA->ba_start_seq_ctrl = pPendingBA->ba_start_seq_ctrl; + pAdmittedBA->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl; pAdmittedBA->ba_param_set = *pBaParamSet; deactivate_ba_entry(ieee, pAdmittedBA); activate_ba_entry(pAdmittedBA, *pBaTimeoutVal); } else { - pTS->bAddBaReqDelayed = true; - pTS->bDisable_AddBa = true; - ReasonCode = DELBA_REASON_END_BA; + ts->bAddBaReqDelayed = true; + ts->bDisable_AddBa = true; + reason_code = DELBA_REASON_END_BA; goto OnADDBARsp_Reject; } @@ -394,30 +394,30 @@ OnADDBARsp_Reject: struct ba_record BA; BA.ba_param_set = *pBaParamSet; - rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); + rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code); return 0; } } int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *delba = NULL; + struct ieee80211_hdr_3addr *delba = NULL; union delba_param_set *pDelBaParamSet = NULL; u8 *dst = NULL; - if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) { netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n", (int)skb->len, - (int)(sizeof(struct rtllib_hdr_3addr) + 6)); + (int)(sizeof(struct ieee80211_hdr_3addr) + 6)); return -1; } if (!ieee->current_network.qos_data.active || - !ieee->ht_info->bCurrentHTSupport) { + !ieee->ht_info->current_ht_support) { netdev_warn(ieee->dev, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network. qos_data.active, - ieee->ht_info->bCurrentHTSupport); + ieee->ht_info->current_ht_support); return -1; } @@ -425,14 +425,14 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data, __func__, skb->len); #endif - delba = (struct rtllib_hdr_3addr *)skb->data; + delba = (struct ieee80211_hdr_3addr *)skb->data; dst = (u8 *)(&delba->addr2[0]); - pDelBaParamSet = (union delba_param_set *)&delba->payload[2]; + pDelBaParamSet = (union delba_param_set *)&delba->seq_ctrl + 2; if (pDelBaParamSet->field.initiator == 1) { - struct rx_ts_record *pRxTs; + struct rx_ts_record *ts; - if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst, (u8)pDelBaParamSet->field.tid, RX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", @@ -441,11 +441,11 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) return -1; } - rx_ts_delete_ba(ieee, pRxTs); + rx_ts_delete_ba(ieee, ts); } else { struct tx_ts_record *pTxTs; - if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)&pTxTs, dst, (u8)pDelBaParamSet->field.tid, TX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n", __func__); @@ -461,27 +461,27 @@ int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) return 0; } -void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *pTS, - u8 Policy, u8 bOverwritePending) +void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts, + u8 policy, u8 bOverwritePending) { - struct ba_record *pBA = &pTS->TxPendingBARecord; + struct ba_record *ba = &ts->TxPendingBARecord; - if (pBA->b_valid && !bOverwritePending) + if (ba->b_valid && !bOverwritePending) return; - deactivate_ba_entry(ieee, pBA); + deactivate_ba_entry(ieee, ba); - pBA->dialog_token++; - pBA->ba_param_set.field.amsdu_support = 0; - pBA->ba_param_set.field.ba_policy = Policy; - pBA->ba_param_set.field.tid = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; - pBA->ba_param_set.field.buffer_size = 32; - pBA->ba_timeout_value = 0; - pBA->ba_start_seq_ctrl.field.seq_num = (pTS->TxCurSeq + 3) % 4096; + ba->dialog_token++; + ba->ba_param_set.field.amsdu_support = 0; + ba->ba_param_set.field.ba_policy = policy; + ba->ba_param_set.field.tid = ts->TsCommonInfo.TSpec.ucTSID; + ba->ba_param_set.field.buffer_size = 32; + ba->ba_timeout_value = 0; + ba->ba_start_seq_ctrl.field.seq_num = (ts->TxCurSeq + 3) % 4096; - activate_ba_entry(pBA, BA_SETUP_TIMEOUT); + activate_ba_entry(ba, BA_SETUP_TIMEOUT); - rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); + rtllib_send_ADDBAReq(ieee, ts->TsCommonInfo.addr, ba); } void rtllib_ts_init_del_ba(struct rtllib_device *ieee, @@ -493,17 +493,17 @@ void rtllib_ts_init_del_ba(struct rtllib_device *ieee, (struct tx_ts_record *)pTsCommonInfo; if (tx_ts_delete_ba(ieee, pTxTs)) - rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, + rtllib_send_DELBA(ieee, pTsCommonInfo->addr, (pTxTs->TxAdmittedBARecord.b_valid) ? (&pTxTs->TxAdmittedBARecord) : (&pTxTs->TxPendingBARecord), TxRxSelect, DELBA_REASON_END_BA); } else if (TxRxSelect == RX_DIR) { - struct rx_ts_record *pRxTs = + struct rx_ts_record *ts = (struct rx_ts_record *)pTsCommonInfo; - if (rx_ts_delete_ba(ieee, pRxTs)) - rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, - &pRxTs->rx_admitted_ba_record, + if (rx_ts_delete_ba(ieee, ts)) + rtllib_send_DELBA(ieee, pTsCommonInfo->addr, + &ts->rx_admitted_ba_record, TxRxSelect, DELBA_REASON_END_BA); } } @@ -525,20 +525,20 @@ void rtllib_tx_ba_inact_timeout(struct timer_list *t) struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, TxTsRecord[pTxTs->num]); tx_ts_delete_ba(ieee, pTxTs); - rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr, + rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.addr, &pTxTs->TxAdmittedBARecord, TX_DIR, DELBA_REASON_TIMEOUT); } void rtllib_rx_ba_inact_timeout(struct timer_list *t) { - struct rx_ts_record *pRxTs = from_timer(pRxTs, t, + struct rx_ts_record *ts = from_timer(ts, t, rx_admitted_ba_record.timer); - struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, - RxTsRecord[pRxTs->num]); + struct rtllib_device *ieee = container_of(ts, struct rtllib_device, + RxTsRecord[ts->num]); - rx_ts_delete_ba(ieee, pRxTs); - rtllib_send_DELBA(ieee, pRxTs->ts_common_info.Addr, - &pRxTs->rx_admitted_ba_record, RX_DIR, + rx_ts_delete_ba(ieee, ts); + rtllib_send_DELBA(ieee, ts->ts_common_info.addr, + &ts->rx_admitted_ba_record, RX_DIR, DELBA_REASON_TIMEOUT); } diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h index 2bbd01048561..f8eb4d553fe0 100644 --- a/drivers/staging/rtl8192e/rtl819x_HT.h +++ b/drivers/staging/rtl8192e/rtl819x_HT.h @@ -93,7 +93,7 @@ enum ht_aggre_mode { struct rt_hi_throughput { u8 enable_ht; - u8 bCurrentHTSupport; + u8 current_ht_support; u8 bRegBW40MHz; u8 bCurBW40MHz; u8 bRegShortGI40MHz; diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index f19feea46158..e607bccc079a 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -67,7 +67,7 @@ static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; -void HTUpdateDefaultSetting(struct rtllib_device *ieee) +void ht_update_default_setting(struct rtllib_device *ieee) { struct rt_hi_throughput *ht_info = ieee->ht_info; @@ -207,27 +207,6 @@ static void HTIOTPeerDetermine(struct rtllib_device *ieee) netdev_dbg(ieee->dev, "IOTPEER: %x\n", ht_info->IOTPeer); } -static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) -{ - return 0; -} - -static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) -{ - return false; -} - -static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) -{ - return false; -} - -static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, - u8 *PeerMacAddr) -{ - return false; -} - static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, struct rtllib_network *network) { @@ -352,7 +331,6 @@ void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, u8 *len, u8 IsEncrypt) { - struct rt_hi_throughput *pHT = ieee->ht_info; struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; if (!posHTInfo || !pHTInfoEle) { @@ -363,32 +341,7 @@ void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, } memset(posHTInfo, 0, *len); - if (ieee->iw_mode == IW_MODE_ADHOC) { - pHTInfoEle->ControlChl = ieee->current_network.channel; - pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ? - HT_EXTCHNL_OFFSET_NO_EXT : - (ieee->current_network.channel <= 6) - ? HT_EXTCHNL_OFFSET_UPPER : - HT_EXTCHNL_OFFSET_LOWER); - pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; - pHTInfoEle->RIFS = 0; - pHTInfoEle->PSMPAccessOnly = 0; - pHTInfoEle->SrvIntGranularity = 0; - pHTInfoEle->OptMode = pHT->current_op_mode; - pHTInfoEle->NonGFDevPresent = 0; - pHTInfoEle->DualBeacon = 0; - pHTInfoEle->SecondaryBeacon = 0; - pHTInfoEle->LSigTxopProtectFull = 0; - pHTInfoEle->PcoActive = 0; - pHTInfoEle->PcoPhase = 0; - - memset(pHTInfoEle->BasicMSC, 0, 16); - - *len = 22 + 2; - - } else { - *len = 0; - } + *len = 0; } void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, @@ -515,7 +468,7 @@ void HTOnAssocRsp(struct rtllib_device *ieee) static const u8 EWC11NHTCap[] = { 0x00, 0x90, 0x4c, 0x33 }; static const u8 EWC11NHTInfo[] = { 0x00, 0x90, 0x4c, 0x34 }; - if (!ht_info->bCurrentHTSupport) { + if (!ht_info->current_ht_support) { netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); return; } @@ -620,7 +573,7 @@ void HTInitializeHTInfo(struct rtllib_device *ieee) { struct rt_hi_throughput *ht_info = ieee->ht_info; - ht_info->bCurrentHTSupport = false; + ht_info->current_ht_support = false; ht_info->bCurBW40MHz = false; ht_info->cur_tx_bw40mhz = false; @@ -691,7 +644,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, * function rtllib_softmac_new_net. WB 2008.09.10 */ if (pNetwork->bssht.bd_support_ht) { - ht_info->bCurrentHTSupport = true; + ht_info->current_ht_support = true; ht_info->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver; if (pNetwork->bssht.bd_ht_cap_len > 0 && @@ -722,22 +675,6 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, HTIOTPeerDetermine(ieee); ht_info->iot_action = 0; - bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS14; - - bIOTAction = HTIOTActIsDisableMCS15(ieee); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_DISABLE_MCS15; - - bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_DISABLE_ALL_2SS; - - bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); - if (bIOTAction) - ht_info->iot_action |= HT_IOT_ACT_DISABLE_EDCA_TURBO; - bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); if (bIOTAction) ht_info->iot_action |= HT_IOT_ACT_MGNT_USE_CCK_6M; @@ -745,7 +682,7 @@ void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, if (bIOTAction) ht_info->iot_action |= HT_IOT_ACT_CDD_FSYNC; } else { - ht_info->bCurrentHTSupport = false; + ht_info->current_ht_support = false; ht_info->current_rt2rt_aggregation = false; ht_info->current_rt2rt_long_slot_time = false; ht_info->RT2RT_HT_Mode = (enum rt_ht_capability)0; @@ -762,52 +699,16 @@ void HT_update_self_and_peer_setting(struct rtllib_device *ieee, struct ht_info_ele *pPeerHTInfo = (struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf; - if (ht_info->bCurrentHTSupport) { + if (ht_info->current_ht_support) { if (pNetwork->bssht.bd_ht_info_len != 0) ht_info->current_op_mode = pPeerHTInfo->OptMode; } } EXPORT_SYMBOL(HT_update_self_and_peer_setting); -void HTUseDefaultSetting(struct rtllib_device *ieee) -{ - struct rt_hi_throughput *ht_info = ieee->ht_info; - - if (ht_info->enable_ht) { - ht_info->bCurrentHTSupport = true; - ht_info->bCurSuppCCK = ht_info->bRegSuppCCK; - - ht_info->bCurBW40MHz = ht_info->bRegBW40MHz; - ht_info->bCurShortGI20MHz = ht_info->bRegShortGI20MHz; - - ht_info->bCurShortGI40MHz = ht_info->bRegShortGI40MHz; - - if (ieee->iw_mode == IW_MODE_ADHOC) - ieee->current_network.qos_data.active = - ieee->current_network.qos_data.supported; - ht_info->bCurrent_AMSDU_Support = ht_info->bAMSDU_Support; - ht_info->nCurrent_AMSDU_MaxSize = ht_info->nAMSDU_MaxSize; - - ht_info->bCurrentAMPDUEnable = ht_info->bAMPDUEnable; - ht_info->CurrentAMPDUFactor = ht_info->AMPDU_Factor; - - ht_info->current_mpdu_density = ht_info->current_mpdu_density; - - HTFilterMCSRate(ieee, ieee->reg_dot11tx_ht_oper_rate_set, - ieee->dot11ht_oper_rate_set); - ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, - ieee->dot11ht_oper_rate_set, - MCS_FILTER_ALL); - ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - - } else { - ht_info->bCurrentHTSupport = false; - } -} - u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) { - if (ieee->ht_info->bCurrentHTSupport) { + if (ieee->ht_info->current_ht_support) { if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); return true; diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h index 0499711ea2bf..1c00092ea3a5 100644 --- a/drivers/staging/rtl8192e/rtl819x_Qos.h +++ b/drivers/staging/rtl8192e/rtl819x_Qos.h @@ -7,76 +7,9 @@ #ifndef __INC_QOS_TYPE_H #define __INC_QOS_TYPE_H -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -union qos_tsinfo { - u8 charData[3]; - struct { - u8 ucTrafficType:1; - u8 ucTSID:4; - u8 ucDirection:2; - u8 ucAccessPolicy:2; - u8 ucAggregation:1; - u8 ucPSB:1; - u8 ucUP:3; - u8 ucTSInfoAckPolicy:2; - u8 ucSchedule:1; - u8 ucReserved:7; - } field; -}; - -union tspec_body { - u8 charData[55]; - - struct { - union qos_tsinfo TSInfo; - u16 NominalMSDUsize; - u16 MaxMSDUsize; - u32 MinServiceItv; - u32 MaxServiceItv; - u32 InactivityItv; - u32 SuspenItv; - u32 ServiceStartTime; - u32 MinDataRate; - u32 MeanDataRate; - u32 PeakDataRate; - u32 MaxBurstSize; - u32 DelayBound; - u32 MinPhyRate; - u16 SurplusBandwidthAllowance; - u16 MediumTime; - } f; +struct qos_tsinfo { + u8 ucTSID:4; + u8 ucDirection:2; }; struct octet_string { @@ -88,7 +21,6 @@ struct octet_string { #define AC1_BK 1 #define AC2_VI 2 #define AC3_VO 3 -#define AC_MAX 4 enum direction_value { DIR_UP = 0, @@ -97,62 +29,6 @@ enum direction_value { DIR_BI_DIR = 3, }; -struct acm { - u64 UsedTime; - u64 MediumTime; - u8 HwAcmCtl; -}; - -union qos_tclas { - struct _TYPE_GENERAL { - u8 Priority; - u8 ClassifierType; - u8 Mask; - } TYPE_GENERAL; - - struct _TYPE0_ETH { - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 SrcAddr[ETH_ALEN]; - u8 DstAddr[ETH_ALEN]; - u16 Type; - } TYPE0_ETH; - - struct _TYPE1_IPV4 { - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 Version; - u8 SrcIP[4]; - u8 DstIP[4]; - u16 SrcPort; - u16 DstPort; - u8 DSCP; - u8 Protocol; - u8 Reserved; - } TYPE1_IPV4; - - struct _TYPE1_IPV6 { - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 Version; - u8 SrcIP[16]; - u8 DstIP[16]; - u16 SrcPort; - u16 DstPort; - u8 FlowLabel[3]; - } TYPE1_IPV6; - - struct _TYPE2_8021Q { - u8 Priority; - u8 ClassifierType; - u8 Mask; - u16 TagType; - } TYPE2_8021Q; -}; - union aci_aifsn { u8 charData; diff --git a/drivers/staging/rtl8192e/rtl819x_TS.h b/drivers/staging/rtl8192e/rtl819x_TS.h index 0e851d4221a7..fff36315f174 100644 --- a/drivers/staging/rtl8192e/rtl819x_TS.h +++ b/drivers/staging/rtl8192e/rtl819x_TS.h @@ -10,7 +10,6 @@ #define TS_ADDBA_DELAY 60 #define TOTAL_TS_NUM 16 -#define TCLAS_NUM 4 enum tr_select { TX_DIR = 0, @@ -19,11 +18,8 @@ enum tr_select { struct ts_common_info { struct list_head List; - u8 Addr[ETH_ALEN]; - union tspec_body TSpec; - union qos_tclas TClass[TCLAS_NUM]; - u8 TClasProc; - u8 TClasNum; + u8 addr[ETH_ALEN]; + struct qos_tsinfo TSpec; }; struct tx_ts_record { diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c index 419ff72f2ba7..3206fdb3e65a 100644 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -10,10 +10,9 @@ static void RxPktPendingTimeout(struct timer_list *t) { - struct rx_ts_record *pRxTs = from_timer(pRxTs, t, - rx_pkt_pending_timer); - struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, - RxTsRecord[pRxTs->num]); + struct rx_ts_record *ts = from_timer(ts, t, rx_pkt_pending_timer); + struct rtllib_device *ieee = container_of(ts, struct rtllib_device, + RxTsRecord[ts->num]); struct rx_reorder_entry *pReorderEntry = NULL; @@ -22,24 +21,24 @@ static void RxPktPendingTimeout(struct timer_list *t) bool bPktInBuf = false; spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - if (pRxTs->rx_timeout_indicate_seq != 0xffff) { - while (!list_empty(&pRxTs->rx_pending_pkt_list)) { + if (ts->rx_timeout_indicate_seq != 0xffff) { + while (!list_empty(&ts->rx_pending_pkt_list)) { pReorderEntry = (struct rx_reorder_entry *) - list_entry(pRxTs->rx_pending_pkt_list.prev, + list_entry(ts->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); if (index == 0) - pRxTs->rx_indicate_seq = pReorderEntry->SeqNum; + ts->rx_indicate_seq = pReorderEntry->SeqNum; if (SN_LESS(pReorderEntry->SeqNum, - pRxTs->rx_indicate_seq) || + ts->rx_indicate_seq) || SN_EQUAL(pReorderEntry->SeqNum, - pRxTs->rx_indicate_seq)) { + ts->rx_indicate_seq)) { list_del_init(&pReorderEntry->List); if (SN_EQUAL(pReorderEntry->SeqNum, - pRxTs->rx_indicate_seq)) - pRxTs->rx_indicate_seq = - (pRxTs->rx_indicate_seq + 1) % 4096; + ts->rx_indicate_seq)) + ts->rx_indicate_seq = + (ts->rx_indicate_seq + 1) % 4096; netdev_dbg(ieee->dev, "%s(): Indicate SeqNum: %d\n", @@ -58,7 +57,7 @@ static void RxPktPendingTimeout(struct timer_list *t) } if (index > 0) { - pRxTs->rx_timeout_indicate_seq = 0xffff; + ts->rx_timeout_indicate_seq = 0xffff; if (index > REORDER_WIN_SIZE) { netdev_warn(ieee->dev, @@ -72,9 +71,9 @@ static void RxPktPendingTimeout(struct timer_list *t) bPktInBuf = false; } - if (bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) { - pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq; - mod_timer(&pRxTs->rx_pkt_pending_timer, jiffies + + if (bPktInBuf && (ts->rx_timeout_indicate_seq == 0xffff)) { + ts->rx_timeout_indicate_seq = ts->rx_indicate_seq; + mod_timer(&ts->rx_pkt_pending_timer, jiffies + msecs_to_jiffies(ieee->ht_info->rx_reorder_pending_time) ); } @@ -94,37 +93,34 @@ static void TsAddBaProcess(struct timer_list *t) static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) { - eth_zero_addr(pTsCommonInfo->Addr); - memset(&pTsCommonInfo->TSpec, 0, sizeof(union tspec_body)); - memset(&pTsCommonInfo->TClass, 0, sizeof(union qos_tclas) * TCLAS_NUM); - pTsCommonInfo->TClasProc = 0; - pTsCommonInfo->TClasNum = 0; + eth_zero_addr(pTsCommonInfo->addr); + memset(&pTsCommonInfo->TSpec, 0, sizeof(struct qos_tsinfo)); } -static void ResetTxTsEntry(struct tx_ts_record *pTS) +static void ResetTxTsEntry(struct tx_ts_record *ts) { - ResetTsCommonInfo(&pTS->TsCommonInfo); - pTS->TxCurSeq = 0; - pTS->bAddBaReqInProgress = false; - pTS->bAddBaReqDelayed = false; - pTS->bUsingBa = false; - pTS->bDisable_AddBa = false; - rtllib_reset_ba_entry(&pTS->TxAdmittedBARecord); - rtllib_reset_ba_entry(&pTS->TxPendingBARecord); + ResetTsCommonInfo(&ts->TsCommonInfo); + ts->TxCurSeq = 0; + ts->bAddBaReqInProgress = false; + ts->bAddBaReqDelayed = false; + ts->bUsingBa = false; + ts->bDisable_AddBa = false; + rtllib_reset_ba_entry(&ts->TxAdmittedBARecord); + rtllib_reset_ba_entry(&ts->TxPendingBARecord); } -static void ResetRxTsEntry(struct rx_ts_record *pTS) +static void ResetRxTsEntry(struct rx_ts_record *ts) { - ResetTsCommonInfo(&pTS->ts_common_info); - pTS->rx_indicate_seq = 0xffff; - pTS->rx_timeout_indicate_seq = 0xffff; - rtllib_reset_ba_entry(&pTS->rx_admitted_ba_record); + ResetTsCommonInfo(&ts->ts_common_info); + ts->rx_indicate_seq = 0xffff; + ts->rx_timeout_indicate_seq = 0xffff; + rtllib_reset_ba_entry(&ts->rx_admitted_ba_record); } -void TSInitialize(struct rtllib_device *ieee) +void rtllib_ts_init(struct rtllib_device *ieee) { struct tx_ts_record *pTxTS = ieee->TxTsRecord; - struct rx_ts_record *pRxTS = ieee->RxTsRecord; + struct rx_ts_record *rxts = ieee->RxTsRecord; struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; u8 count = 0; @@ -151,17 +147,17 @@ void TSInitialize(struct rtllib_device *ieee) INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); for (count = 0; count < TOTAL_TS_NUM; count++) { - pRxTS->num = count; - INIT_LIST_HEAD(&pRxTS->rx_pending_pkt_list); - timer_setup(&pRxTS->rx_admitted_ba_record.timer, + rxts->num = count; + INIT_LIST_HEAD(&rxts->rx_pending_pkt_list); + timer_setup(&rxts->rx_admitted_ba_record.timer, rtllib_rx_ba_inact_timeout, 0); - timer_setup(&pRxTS->rx_pkt_pending_timer, RxPktPendingTimeout, 0); + timer_setup(&rxts->rx_pkt_pending_timer, RxPktPendingTimeout, 0); - ResetRxTsEntry(pRxTS); - list_add_tail(&pRxTS->ts_common_info.List, + ResetRxTsEntry(rxts); + list_add_tail(&rxts->ts_common_info.List, &ieee->Rx_TS_Unused_List); - pRxTS++; + rxts++; } INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); for (count = 0; count < REORDER_ENTRY_NUM; count++) { @@ -174,7 +170,7 @@ void TSInitialize(struct rtllib_device *ieee) } static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, - u8 *Addr, u8 TID, + u8 *addr, u8 TID, enum tr_select TxRxSelect) { u8 dir; @@ -182,21 +178,14 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, struct list_head *psearch_list; struct ts_common_info *pRet = NULL; - if (ieee->iw_mode == IW_MODE_ADHOC) { - if (TxRxSelect == TX_DIR) - search_dir[DIR_UP] = true; - else - search_dir[DIR_DOWN] = true; + if (TxRxSelect == TX_DIR) { + search_dir[DIR_UP] = true; + search_dir[DIR_BI_DIR] = true; + search_dir[DIR_DIRECT] = true; } else { - if (TxRxSelect == TX_DIR) { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } else { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } + search_dir[DIR_DOWN] = true; + search_dir[DIR_BI_DIR] = true; + search_dir[DIR_DIRECT] = true; } if (TxRxSelect == TX_DIR) @@ -208,9 +197,9 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, if (!search_dir[dir]) continue; list_for_each_entry(pRet, psearch_list, List) { - if (memcmp(pRet->Addr, Addr, 6) == 0 && - pRet->TSpec.f.TSInfo.field.ucTSID == TID && - pRet->TSpec.f.TSInfo.field.ucDirection == dir) + if (memcmp(pRet->addr, addr, 6) == 0 && + pRet->TSpec.ucTSID == TID && + pRet->TSpec.ucDirection == dir) break; } if (&pRet->List != psearch_list) @@ -222,40 +211,30 @@ static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, return NULL; } -static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr, - union tspec_body *pTSPEC, union qos_tclas *pTCLAS, - u8 TCLAS_Num, u8 TCLAS_Proc) +static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *addr, + struct qos_tsinfo *pTSPEC) { - u8 count; - if (!pTsCommonInfo) return; - memcpy(pTsCommonInfo->Addr, Addr, 6); + memcpy(pTsCommonInfo->addr, addr, 6); if (pTSPEC) memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC, - sizeof(union tspec_body)); - - for (count = 0; count < TCLAS_Num; count++) - memcpy((u8 *)(&(pTsCommonInfo->TClass[count])), - (u8 *)pTCLAS, sizeof(union qos_tclas)); - - pTsCommonInfo->TClasProc = TCLAS_Proc; - pTsCommonInfo->TClasNum = TCLAS_Num; + sizeof(struct qos_tsinfo)); } -bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, - u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) +bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, + u8 *addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) { u8 UP = 0; - union tspec_body TSpec; - union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo; + struct qos_tsinfo TSpec; + struct qos_tsinfo *ts_info = &TSpec; struct list_head *pUnusedList; struct list_head *pAddmitList; enum direction_value Dir; - if (is_multicast_ether_addr(Addr)) { + if (is_multicast_ether_addr(addr)) { netdev_warn(ieee->dev, "Get TS for Broadcast or Multicast\n"); return false; } @@ -286,7 +265,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, } } - *ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect); + *ppTS = SearchAdmitTRStream(ieee, addr, UP, TxRxSelect); if (*ppTS) return true; @@ -316,27 +295,20 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, TsCommonInfo); ResetTxTsEntry(tmp); } else { - struct rx_ts_record *tmp = + struct rx_ts_record *ts = container_of(*ppTS, struct rx_ts_record, ts_common_info); - ResetRxTsEntry(tmp); + ResetRxTsEntry(ts); } netdev_dbg(ieee->dev, "to init current TS, UP:%d, Dir:%d, addr: %pM ppTs=%p\n", - UP, Dir, Addr, *ppTS); - pTSInfo->field.ucTrafficType = 0; - pTSInfo->field.ucTSID = UP; - pTSInfo->field.ucDirection = Dir; - pTSInfo->field.ucAccessPolicy = 1; - pTSInfo->field.ucAggregation = 0; - pTSInfo->field.ucPSB = 0; - pTSInfo->field.ucUP = UP; - pTSInfo->field.ucTSInfoAckPolicy = 0; - pTSInfo->field.ucSchedule = 0; + UP, Dir, addr, *ppTS); + ts_info->ucTSID = UP; + ts_info->ucDirection = Dir; - MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); + MakeTSEntry(*ppTS, addr, &TSpec); list_add_tail(&((*ppTS)->List), pAddmitList); return true; @@ -355,14 +327,14 @@ static void RemoveTsEntry(struct rtllib_device *ieee, if (TxRxSelect == RX_DIR) { struct rx_reorder_entry *pRxReorderEntry; - struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs; + struct rx_ts_record *ts = (struct rx_ts_record *)pTs; - if (timer_pending(&pRxTS->rx_pkt_pending_timer)) - del_timer_sync(&pRxTS->rx_pkt_pending_timer); + if (timer_pending(&ts->rx_pkt_pending_timer)) + del_timer_sync(&ts->rx_pkt_pending_timer); - while (!list_empty(&pRxTS->rx_pending_pkt_list)) { + while (!list_empty(&ts->rx_pending_pkt_list)) { pRxReorderEntry = (struct rx_reorder_entry *) - list_entry(pRxTS->rx_pending_pkt_list.prev, + list_entry(ts->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); netdev_dbg(ieee->dev, "%s(): Delete SeqNum %d!\n", __func__, pRxReorderEntry->SeqNum); @@ -388,43 +360,43 @@ static void RemoveTsEntry(struct rtllib_device *ieee, } } -void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr) +void RemovePeerTS(struct rtllib_device *ieee, u8 *addr) { - struct ts_common_info *pTS, *pTmpTS; + struct ts_common_info *ts, *pTmpTS; - netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, Addr); + netdev_info(ieee->dev, "===========>%s, %pM\n", __func__, addr); - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { - if (memcmp(pTS->Addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, List) { + if (memcmp(ts->addr, addr, 6) == 0) { + RemoveTsEntry(ieee, ts, TX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List); } } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { - if (memcmp(pTS->Addr, Addr, 6) == 0) { + list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, List) { + if (memcmp(ts->addr, addr, 6) == 0) { netdev_info(ieee->dev, "====>remove Tx_TS_admin_list\n"); - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + RemoveTsEntry(ieee, ts, TX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List); } } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { - if (memcmp(pTS->Addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, List) { + if (memcmp(ts->addr, addr, 6) == 0) { + RemoveTsEntry(ieee, ts, RX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List); } } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { - if (memcmp(pTS->Addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, List) { + if (memcmp(ts->addr, addr, 6) == 0) { + RemoveTsEntry(ieee, ts, RX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List); } } } @@ -432,30 +404,30 @@ EXPORT_SYMBOL(RemovePeerTS); void RemoveAllTS(struct rtllib_device *ieee) { - struct ts_common_info *pTS, *pTmpTS; + struct ts_common_info *ts, *pTmpTS; - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Pending_List, List) { + RemoveTsEntry(ieee, ts, TX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List); } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Tx_TS_Admit_List, List) { + RemoveTsEntry(ieee, ts, TX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Tx_TS_Unused_List); } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Pending_List, List) { + RemoveTsEntry(ieee, ts, RX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List); } - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + list_for_each_entry_safe(ts, pTmpTS, &ieee->Rx_TS_Admit_List, List) { + RemoveTsEntry(ieee, ts, RX_DIR); + list_del_init(&ts->List); + list_add_tail(&ts->List, &ieee->Rx_TS_Unused_List); } } diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index bfa4dbf94d60..d2cf3cfaaaba 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -31,7 +31,6 @@ #include #include -#include "rtllib_debug.h" #include "rtl819x_HT.h" #include "rtl819x_BA.h" #include "rtl819x_TS.h" @@ -92,7 +91,7 @@ static inline void *netdev_priv_rsl(struct net_device *dev) #define IE_CISCO_FLAG_POSITION 0x08 #define SUPPORT_CKIP_MIC 0x08 #define SUPPORT_CKIP_PK 0x10 -#define RT_RF_OFF_LEVL_HALT_NIC BIT3 +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) #define RT_IN_PS_LEVEL(psc, _PS_FLAG) \ ((psc->CurPsLevel & _PS_FLAG) ? true : false) #define RT_CLEAR_PS_LEVEL(psc, _PS_FLAG) \ @@ -172,7 +171,7 @@ struct sw_chnl_cmd { u32 Para1; u32 Para2; u32 msDelay; -} __packed; +}; /*--------------------------Define -------------------------------------------*/ #define MGN_1M 0x02 @@ -332,66 +331,23 @@ enum rt_op_mode { #define MIN_FRAG_THRESHOLD 256U #define MAX_FRAG_THRESHOLD 2346U -/* Frame control field constants */ -#define RTLLIB_FCTL_FTYPE 0x000c -#define RTLLIB_FCTL_STYPE 0x00f0 -#define RTLLIB_FCTL_FRAMETYPE 0x00fc -#define RTLLIB_FCTL_TODS 0x0100 -#define RTLLIB_FCTL_FROMDS 0x0200 -#define RTLLIB_FCTL_DSTODS 0x0300 -#define RTLLIB_FCTL_MOREFRAGS 0x0400 -#define RTLLIB_FCTL_RETRY 0x0800 -#define RTLLIB_FCTL_PM 0x1000 -#define RTLLIB_FCTL_MOREDATA 0x2000 -#define RTLLIB_FCTL_WEP 0x4000 -#define RTLLIB_FCTL_ORDER 0x8000 - #define RTLLIB_FTYPE_MGMT 0x0000 #define RTLLIB_FTYPE_CTL 0x0004 #define RTLLIB_FTYPE_DATA 0x0008 -/* management */ -#define RTLLIB_STYPE_ASSOC_REQ 0x0000 -#define RTLLIB_STYPE_ASSOC_RESP 0x0010 -#define RTLLIB_STYPE_REASSOC_REQ 0x0020 -#define RTLLIB_STYPE_REASSOC_RESP 0x0030 -#define RTLLIB_STYPE_PROBE_REQ 0x0040 -#define RTLLIB_STYPE_PROBE_RESP 0x0050 -#define RTLLIB_STYPE_BEACON 0x0080 -#define RTLLIB_STYPE_ATIM 0x0090 -#define RTLLIB_STYPE_DISASSOC 0x00A0 -#define RTLLIB_STYPE_AUTH 0x00B0 -#define RTLLIB_STYPE_DEAUTH 0x00C0 -#define RTLLIB_STYPE_MANAGE_ACT 0x00D0 - -/* control */ -#define RTLLIB_STYPE_PSPOLL 0x00A0 -#define RTLLIB_STYPE_RTS 0x00B0 -#define RTLLIB_STYPE_CTS 0x00C0 -#define RTLLIB_STYPE_ACK 0x00D0 - -/* data */ -#define RTLLIB_STYPE_DATA 0x0000 -#define RTLLIB_STYPE_DATA_CFACK 0x0010 -#define RTLLIB_STYPE_DATA_CFPOLL 0x0020 -#define RTLLIB_STYPE_DATA_CFACKPOLL 0x0030 -#define RTLLIB_STYPE_NULLFUNC 0x0040 -#define RTLLIB_STYPE_QOS_DATA 0x0080 -#define RTLLIB_STYPE_QOS_NULL 0x00C0 - #define RTLLIB_SCTL_FRAG 0x000F #define RTLLIB_SCTL_SEQ 0xFFF0 /* QOS control */ #define RTLLIB_QCTL_TID 0x000F -#define FC_QOS_BIT BIT7 +#define FC_QOS_BIT BIT(7) #define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false) #define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT))) #define IsQoSDataFrame(pframe) \ - ((*(u16 *)pframe&(RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \ - (RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16 *)pframe&RTLLIB_FCTL_ORDER) + ((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \ + (IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) +#define Frame_Order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER) #define SN_LESS(a, b) (((a-b)&0x800) != 0) #define SN_EQUAL(a, b) (a == b) #define MAX_DEV_ADDR_SIZE 8 @@ -455,11 +411,10 @@ enum _REG_PREAMBLE_MODE { #define SNAP_SIZE sizeof(struct rtllib_snap_hdr) -#define WLAN_FC_GET_TYPE(fc) ((fc) & RTLLIB_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & RTLLIB_FCTL_STYPE) -#define WLAN_FC_MORE_DATA(fc) ((fc) & RTLLIB_FCTL_MOREDATA) +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) -#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & RTLLIB_FCTL_FRAMETYPE) #define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG) #define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4) @@ -510,13 +465,6 @@ enum _REG_PREAMBLE_MODE { /* this is stolen from ipw2200 driver */ #define IEEE_IBSS_MAC_HASH_SIZE 31 -struct ieee_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num[17]; - u16 frag_num[17]; - unsigned long packet_time[17]; - struct list_head list; -}; /* NOTE: This data is for statistical purposes; not all hardware provides this * information for frames received. Not setting these will not cause @@ -673,78 +621,6 @@ enum rtllib_mfie { * information to determine what type of underlying data type is actually * stored in the data. */ -struct rtllib_pspoll_hdr { - __le16 frame_ctl; - __le16 aid; - u8 bssid[ETH_ALEN]; - u8 ta[ETH_ALEN]; -} __packed; - -struct rtllib_hdr { - __le16 frame_ctl; - __le16 duration_id; - u8 payload[]; -} __packed; - -struct rtllib_hdr_1addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtllib_hdr_2addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtllib_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[]; -} __packed; - -struct rtllib_hdr_4addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtllib_hdr_3addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - __le16 qos_ctl; - u8 payload[]; -} __packed; - -struct rtllib_hdr_4addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - __le16 qos_ctl; - u8 payload[]; -} __packed; - struct rtllib_info_element { u8 id; u8 len; @@ -752,32 +628,32 @@ struct rtllib_info_element { } __packed; struct rtllib_authentication { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; __le16 algorithm; __le16 transaction; __le16 status; /*challenge*/ struct rtllib_info_element info_element[]; -} __packed; +} __packed __aligned(2); struct rtllib_disauth { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; __le16 reason; -} __packed; +} __packed __aligned(2); struct rtllib_disassoc { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; __le16 reason; -} __packed; +} __packed __aligned(2); struct rtllib_probe_request { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; /* SSID, supported rates */ struct rtllib_info_element info_element[]; -} __packed; +} __packed __aligned(2); struct rtllib_probe_response { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; u32 time_stamp[2]; __le16 beacon_interval; __le16 capability; @@ -785,26 +661,26 @@ struct rtllib_probe_response { * CF params, IBSS params, TIM (if beacon), RSN */ struct rtllib_info_element info_element[]; -} __packed; +} __packed __aligned(2); /* Alias beacon for probe_response */ #define rtllib_beacon rtllib_probe_response struct rtllib_assoc_request_frame { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; __le16 capability; __le16 listen_interval; /* SSID, supported rates, RSN */ struct rtllib_info_element info_element[]; -} __packed; +} __packed __aligned(2); struct rtllib_assoc_response_frame { - struct rtllib_hdr_3addr header; + struct ieee80211_hdr_3addr header; __le16 capability; __le16 status; __le16 aid; struct rtllib_info_element info_element[]; /* supported rates */ -} __packed; +} __packed __aligned(2); struct rtllib_txb { u8 nr_frags; @@ -823,7 +699,7 @@ struct rtllib_rxb { struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; -} __packed; +}; union frameqos { u16 shortdata; @@ -947,13 +823,13 @@ static inline const char *eap_get_type(int type) static inline u8 Frame_QoSTID(u8 *buf) { - struct rtllib_hdr_3addr *hdr; + struct ieee80211_hdr_3addr *hdr; u16 fc; - hdr = (struct rtllib_hdr_3addr *)buf; - fc = le16_to_cpu(hdr->frame_ctl); - return (u8)((union frameqos *)(buf + (((fc & RTLLIB_FCTL_TODS) && - (fc & RTLLIB_FCTL_FROMDS)) ? 30 : 24)))->field.tid; + hdr = (struct ieee80211_hdr_3addr *)buf; + fc = le16_to_cpu(hdr->frame_control); + return (u8)((union frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) && + (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid; } struct eapol { @@ -1035,7 +911,6 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; ((up) < 6) ? WME_AC_VI : \ WME_AC_VO) -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ #define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address * plus ether type */ @@ -1183,13 +1058,6 @@ enum fsync_state { SW_Fsync }; -enum rt_ps_mode { - eActive, - eMaxPs, - eFastPs, - eAutoPs, -}; - enum ips_callback_function { IPS_CALLBACK_NONE = 0, IPS_CALLBACK_MGNT_LINK_REQUEST = 1, @@ -1209,7 +1077,6 @@ struct rt_pwr_save_ctrl { bool bLeisurePs; u8 LpsIdleCount; - u8 reg_max_lps_awake_intvl; u8 LPSAwakeIntvl; u32 CurPsLevel; @@ -1217,10 +1084,10 @@ struct rt_pwr_save_ctrl { #define RT_RF_CHANGE_SOURCE u32 -#define RF_CHANGE_BY_SW BIT31 -#define RF_CHANGE_BY_HW BIT30 -#define RF_CHANGE_BY_PS BIT29 -#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_SW BIT(31) +#define RF_CHANGE_BY_HW BIT(30) +#define RF_CHANGE_BY_PS BIT(29) +#define RF_CHANGE_BY_IPS BIT(28) #define RF_CHANGE_BY_INIT 0 enum country_code_type { @@ -1246,33 +1113,6 @@ enum scan_op_backup_opt { SCAN_OPT_MAX }; -enum fw_cmd_io_type { - FW_CMD_DIG_ENABLE = 0, - FW_CMD_DIG_DISABLE = 1, - FW_CMD_DIG_HALT = 2, - FW_CMD_DIG_RESUME = 3, - FW_CMD_HIGH_PWR_ENABLE = 4, - FW_CMD_HIGH_PWR_DISABLE = 5, - FW_CMD_RA_RESET = 6, - FW_CMD_RA_ACTIVE = 7, - FW_CMD_RA_REFRESH_N = 8, - FW_CMD_RA_REFRESH_BG = 9, - FW_CMD_RA_INIT = 10, - FW_CMD_IQK_ENABLE = 11, - FW_CMD_TXPWR_TRACK_ENABLE = 12, - FW_CMD_TXPWR_TRACK_DISABLE = 13, - FW_CMD_TXPWR_TRACK_THERMAL = 14, - FW_CMD_PAUSE_DM_BY_SCAN = 15, - FW_CMD_RESUME_DM_BY_SCAN = 16, - FW_CMD_RA_REFRESH_N_COMB = 17, - FW_CMD_RA_REFRESH_BG_COMB = 18, - FW_CMD_ANTENNA_SW_ENABLE = 19, - FW_CMD_ANTENNA_SW_DISABLE = 20, - FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21, - FW_CMD_LPS_ENTER = 22, - FW_CMD_LPS_LEAVE = 23, -}; - #define RT_MAX_LD_SLOT_NUM 10 struct rt_link_detect { u32 NumRecvBcnInPeriod; @@ -1303,7 +1143,6 @@ struct sw_cam_table { #define TOTAL_CAM_ENTRY 32 struct rate_adaptive { - u8 rate_adaptive_disabled; u8 ratr_state; u16 reserve; @@ -1321,7 +1160,6 @@ struct rate_adaptive { u8 ping_rssi_enable; u32 ping_rssi_ratr; u32 ping_rssi_thresh_for_ra; - u32 last_ratr; u8 PreRATRState; }; @@ -1334,11 +1172,6 @@ struct rt_pmkid_list { u8 bUsed; }; -struct rt_intel_promisc_mode { - bool promiscuous_on; - bool fltr_src_sta_frame; -}; - /*************** DRIVER STATUS *****/ #define STATUS_SCANNING 0 /*************** DRIVER STATUS *****/ @@ -1368,7 +1201,6 @@ struct rtllib_device { bool bForcedBgMode; u8 hwsec_active; - bool is_silent_reset; bool is_roaming; bool ieee_up; bool cannot_notify; @@ -1418,8 +1250,6 @@ struct rtllib_device { int scan_age; int iw_mode; /* operating mode (IW_MODE_*) */ - bool net_promiscuous_md; - struct rt_intel_promisc_mode intel_promiscuous_md_info; spinlock_t lock; spinlock_t wpax_suitlist_lock; @@ -1496,13 +1326,10 @@ struct rtllib_device { u8 active_channel_map[MAX_CHANNEL_NUMBER+1]; u8 bss_start_channel; - u8 ibss_maxjoin_chal; int rate; /* current rate */ int basic_rate; - short active_scan; - /* this contains flags for selectively enable softmac support */ u16 softmac_features; @@ -1525,7 +1352,6 @@ struct rtllib_device { u64 ps_time; bool polling; - short raw_tx; /* used if IEEE_SOFTMAC_TX_QUEUE is set */ short queue_stop; short scanning_continue; @@ -1602,7 +1428,6 @@ struct rtllib_device { struct delayed_work associate_procedure_wq; struct delayed_work softmac_scan_wq; struct delayed_work associate_retry_wq; - struct delayed_work start_ibss_wq; struct delayed_work hw_wakeup_wq; struct delayed_work hw_sleep_wq; struct delayed_work link_change_wq; @@ -1653,15 +1478,6 @@ struct rtllib_device { */ void (*link_change)(struct net_device *dev); - /* these two function indicates to the HW when to start - * and stop to send beacons. This is used when the - * IEEE_SOFTMAC_BEACONS is not set. For now the - * stop_send_bacons is NOT guaranteed to be called only - * after start_send_beacons. - */ - void (*start_send_beacons)(struct net_device *dev); - void (*stop_send_beacons)(struct net_device *dev); - /* power save mode related */ void (*sta_wake_up)(struct net_device *dev); void (*enter_sleep_state)(struct net_device *dev, u64 time); @@ -1761,15 +1577,15 @@ static inline int rtllib_get_hdrlen(u16 fc) switch (WLAN_FC_GET_TYPE(fc)) { case RTLLIB_FTYPE_DATA: - if ((fc & RTLLIB_FCTL_FROMDS) && (fc & RTLLIB_FCTL_TODS)) + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */ if (RTLLIB_QOS_HAS_SEQ(fc)) hdrlen += 2; /* QOS ctrl*/ break; case RTLLIB_FTYPE_CTL: switch (WLAN_FC_GET_STYPE(fc)) { - case RTLLIB_STYPE_CTS: - case RTLLIB_STYPE_ACK: + case IEEE80211_STYPE_CTS: + case IEEE80211_STYPE_ACK: hdrlen = RTLLIB_1ADDR_LEN; break; default: @@ -1782,21 +1598,6 @@ static inline int rtllib_get_hdrlen(u16 fc) return hdrlen; } -static inline u8 *rtllib_get_payload(struct rtllib_hdr *hdr) -{ - switch (rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { - case RTLLIB_1ADDR_LEN: - return ((struct rtllib_hdr_1addr *)hdr)->payload; - case RTLLIB_2ADDR_LEN: - return ((struct rtllib_hdr_2addr *)hdr)->payload; - case RTLLIB_3ADDR_LEN: - return ((struct rtllib_hdr_3addr *)hdr)->payload; - case RTLLIB_4ADDR_LEN: - return ((struct rtllib_hdr_4addr *)hdr)->payload; - } - return NULL; -} - static inline int rtllib_is_ofdm_rate(u8 rate) { switch (rate & ~RTLLIB_BASIC_RATE_MASK) { @@ -1841,8 +1642,6 @@ void rtllib_txb_free(struct rtllib_txb *txb); /* rtllib_rx.c */ int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats); -void rtllib_rx_probe_rq(struct rtllib_device *ieee, - struct sk_buff *skb); int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel); /* rtllib_wx.c */ @@ -1876,7 +1675,6 @@ void rtllib_softmac_new_net(struct rtllib_device *ieee, void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn); void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee); -void rtllib_start_ibss(struct rtllib_device *ieee); int rtllib_softmac_init(struct rtllib_device *ieee); void rtllib_softmac_free(struct rtllib_device *ieee); void rtllib_disassociate(struct rtllib_device *ieee); @@ -1887,23 +1685,18 @@ void rtllib_start_scan_syncro(struct rtllib_device *ieee); void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee); void rtllib_start_protocol(struct rtllib_device *ieee); -void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown); +void rtllib_stop_protocol(struct rtllib_device *ieee); void rtllib_EnableNetMonitorMode(struct net_device *dev, bool bInitState); void rtllib_DisableNetMonitorMode(struct net_device *dev, bool bInitState); -void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, bool bInitState); -void rtllib_DisableIntelPromiscuousMode(struct net_device *dev, - bool bInitState); -void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, - u8 mesh_flag, u8 shutdown); -void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag); + +void rtllib_softmac_stop_protocol(struct rtllib_device *ieee); +void rtllib_softmac_start_protocol(struct rtllib_device *ieee); void rtllib_reset_queue(struct rtllib_device *ieee); void rtllib_wake_all_queues(struct rtllib_device *ieee); void rtllib_stop_all_queues(struct rtllib_device *ieee); struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee); -void rtllib_start_send_beacons(struct rtllib_device *ieee); -void rtllib_stop_send_beacons(struct rtllib_device *ieee); void notify_wx_assoc_event(struct rtllib_device *ieee); void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success); @@ -1947,10 +1740,6 @@ int rtllib_wx_get_freq(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); void rtllib_wx_sync_scan_wq(void *data); -int rtllib_wx_set_rawtx(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); @@ -1972,7 +1761,7 @@ int rtllib_wx_get_rts(struct rtllib_device *ieee, struct iw_request_info *info, void HTSetConnectBwMode(struct rtllib_device *ieee, enum ht_channel_width bandwidth, enum ht_extchnl_offset Offset); -void HTUpdateDefaultSetting(struct rtllib_device *ieee); +void ht_update_default_setting(struct rtllib_device *ieee); void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, u8 *len, u8 isEncrypt, bool bAssoc); @@ -1998,21 +1787,21 @@ u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate); int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb); int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb); int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb); -void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *pTS, - u8 Policy, u8 bOverwritePending); +void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts, + u8 policy, u8 bOverwritePending); void rtllib_ts_init_del_ba(struct rtllib_device *ieee, struct ts_common_info *pTsCommonInfo, enum tr_select TxRxSelect); void rtllib_ba_setup_timeout(struct timer_list *t); void rtllib_tx_ba_inact_timeout(struct timer_list *t); void rtllib_rx_ba_inact_timeout(struct timer_list *t); -void rtllib_reset_ba_entry(struct ba_record *pBA); -bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *Addr, +void rtllib_reset_ba_entry(struct ba_record *ba); +bool rtllib_get_ts(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs); -void TSInitialize(struct rtllib_device *ieee); +void rtllib_ts_init(struct rtllib_device *ieee); void TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS); -void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr); +void RemovePeerTS(struct rtllib_device *ieee, u8 *addr); void RemoveAllTS(struct rtllib_device *ieee); static inline const char *escape_essid(const char *essid, u8 essid_len) @@ -2035,7 +1824,7 @@ bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn); * ieee handler to refer to it. */ void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, - struct rx_ts_record *pTS); + struct rx_ts_record *ts); int rtllib_parse_info_param(struct rtllib_device *ieee, struct rtllib_info_element *info_element, u16 length, @@ -2044,7 +1833,6 @@ int rtllib_parse_info_param(struct rtllib_device *ieee, void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prxbIndicateArray, u8 index); -void HTUseDefaultSetting(struct rtllib_device *ieee); #define RT_ASOC_RETRY_LIMIT 5 u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee); diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index f88096bcb181..cbb8c8dbe9b0 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -52,7 +52,7 @@ static void *rtllib_ccmp_init(int key_idx) struct rtllib_ccmp_data *priv; priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) + if (!priv) goto fail; priv->key_idx = key_idx; @@ -83,7 +83,7 @@ static void rtllib_ccmp_deinit(void *priv) kfree(priv); } -static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr, +static int ccmp_init_iv_and_aad(struct ieee80211_hdr *hdr, u8 *pn, u8 *iv, u8 *aad) { u8 *pos, qc = 0; @@ -91,9 +91,8 @@ static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr, u16 fc; int a4_included, qc_included; - fc = le16_to_cpu(hdr->frame_ctl); - a4_included = ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == - (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)); + fc = le16_to_cpu(hdr->frame_control); + a4_included = ieee80211_has_a4(hdr->frame_control); qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x80)); @@ -134,7 +133,7 @@ static int ccmp_init_iv_and_aad(struct rtllib_hdr_4addr *hdr, memcpy(&aad[2], &hdr->addr1, ETH_ALEN); memcpy(&aad[8], &hdr->addr2, ETH_ALEN); memcpy(&aad[14], &hdr->addr3, ETH_ALEN); - pos = (u8 *)&hdr->seq_ctl; + pos = (u8 *)&hdr->seq_ctrl; aad[20] = pos[0] & 0x0f; aad[21] = 0; /* all bits masked */ memset(aad + 22, 0, 8); @@ -153,7 +152,7 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) struct rtllib_ccmp_data *key = priv; int i; u8 *pos; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); if (skb_headroom(skb) < CCMP_HDR_LEN || @@ -182,7 +181,7 @@ static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = key->tx_pn[1]; *pos++ = key->tx_pn[0]; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; if (!tcb_desc->bHwSec) { struct aead_request *req; struct scatterlist sg[2]; @@ -220,7 +219,7 @@ static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_ccmp_data *key = priv; u8 keyidx, *pos; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 pn[6]; @@ -230,7 +229,7 @@ static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; } - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 9fdfcc017ee6..0244b524a7d4 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -255,7 +255,7 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) struct rtllib_tkip_data *tkey = priv; int len; u8 *pos; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); int ret = 0; @@ -266,7 +266,7 @@ static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) skb->len < hdr_len) return -1; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; if (!tcb_desc->bHwSec) { if (!tkey->tx_phase1_done) { @@ -330,7 +330,7 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u8 keyidx, *pos; u32 iv32; u16 iv16; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 rc4key[16]; @@ -341,7 +341,7 @@ static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (skb->len < hdr_len + 8 + 4) return -1; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { @@ -465,20 +465,20 @@ out: static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) { - struct rtllib_hdr_4addr *hdr11; + struct ieee80211_hdr *hdr11; - hdr11 = (struct rtllib_hdr_4addr *)skb->data; - switch (le16_to_cpu(hdr11->frame_ctl) & - (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { - case RTLLIB_FCTL_TODS: + hdr11 = (struct ieee80211_hdr *)skb->data; + switch (le16_to_cpu(hdr11->frame_control) & + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_TODS: ether_addr_copy(hdr, hdr11->addr3); /* DA */ ether_addr_copy(hdr + ETH_ALEN, hdr11->addr2); /* SA */ break; - case RTLLIB_FCTL_FROMDS: + case IEEE80211_FCTL_FROMDS: ether_addr_copy(hdr, hdr11->addr1); /* DA */ ether_addr_copy(hdr + ETH_ALEN, hdr11->addr3); /* SA */ break; - case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: ether_addr_copy(hdr, hdr11->addr3); /* DA */ ether_addr_copy(hdr + ETH_ALEN, hdr11->addr4); /* SA */ break; @@ -501,9 +501,9 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) { struct rtllib_tkip_data *tkey = priv; u8 *pos; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { netdev_dbg(skb->dev, @@ -514,7 +514,7 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) michael_mic_hdr(skb, tkey->tx_hdr); - if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) + if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control))) tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; pos = skb_put(skb, 8); if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, @@ -525,7 +525,7 @@ static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) } static void rtllib_michael_mic_failure(struct net_device *dev, - struct rtllib_hdr_4addr *hdr, + struct ieee80211_hdr *hdr, int keyidx) { union iwreq_data wrqu; @@ -550,15 +550,15 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, { struct rtllib_tkip_data *tkey = priv; u8 mic[8]; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; if (!tkey->key_set) return -1; michael_mic_hdr(skb, tkey->rx_hdr); - if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) + if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_control))) tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, @@ -566,9 +566,9 @@ static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, return -1; if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; netdev_dbg(skb->dev, "Michael MIC verification failed for MSDU from %pM keyidx=%d\n", hdr->addr2, keyidx); diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c index 062285e4d939..21c2b7666d6f 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c @@ -35,7 +35,7 @@ static void *prism2_wep_init(int keyidx) return NULL; priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) + if (!priv) return NULL; priv->key_idx = keyidx; diff --git a/drivers/staging/rtl8192e/rtllib_debug.h b/drivers/staging/rtl8192e/rtllib_debug.h deleted file mode 100644 index f6b23defe225..000000000000 --- a/drivers/staging/rtl8192e/rtllib_debug.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * - * Contact Information: wlanfae - */ -#ifndef _RTL_DEBUG_H -#define _RTL_DEBUG_H - -#include - -/* Allow files to override DRV_NAME */ -#ifndef DRV_NAME -#define DRV_NAME "rtllib_92e" -#endif - -extern u32 rt_global_debug_component; - -/* These are the defines for rt_global_debug_component */ -enum RTL_DEBUG { - COMP_TRACE = BIT(0), - COMP_DBG = BIT(1), - COMP_INIT = BIT(2), - COMP_RECV = BIT(3), - COMP_POWER = BIT(6), - COMP_SWBW = BIT(8), - COMP_SEC = BIT(9), - COMP_LPS = BIT(10), - COMP_QOS = BIT(11), - COMP_RATE = BIT(12), - COMP_RXDESC = BIT(13), - COMP_PHY = BIT(14), - COMP_DIG = BIT(15), - COMP_TXAGC = BIT(16), - COMP_HALDM = BIT(17), - COMP_POWER_TRACKING = BIT(18), - COMP_CH = BIT(19), - COMP_RF = BIT(20), - COMP_FIRMWARE = BIT(21), - COMP_RESET = BIT(23), - COMP_CMDPKT = BIT(24), - COMP_SCAN = BIT(25), - COMP_PS = BIT(26), - COMP_DOWN = BIT(27), - COMP_INTR = BIT(28), - COMP_ERR = BIT(31) -}; - -#endif diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 2416e0c60255..95b6d6b9429c 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -34,9 +34,6 @@ #include #include "rtllib.h" -u32 rt_global_debug_component = COMP_ERR; -EXPORT_SYMBOL(rt_global_debug_component); - static inline int rtllib_networks_allocate(struct rtllib_device *ieee) { if (ieee->networks) @@ -114,7 +111,6 @@ struct net_device *alloc_rtllib(int sizeof_priv) ieee->drop_unencrypted = 0; ieee->privacy_invoked = 0; ieee->ieee802_1x = 1; - ieee->raw_tx = 0; ieee->hwsec_active = 0; memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32); @@ -126,9 +122,9 @@ struct net_device *alloc_rtllib(int sizeof_priv) if (!ieee->ht_info) goto free_softmac; - HTUpdateDefaultSetting(ieee); + ht_update_default_setting(ieee); HTInitializeHTInfo(ieee); - TSInitialize(ieee); + rtllib_ts_init(ieee); for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 40e7bbb17c0d..ecaa4dec3f94 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -63,7 +63,7 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) { entry = &ieee->frag_cache[tid][i]; - if (entry->skb != NULL && + if (entry->skb && time_after(jiffies, entry->first_frag_time + 2 * HZ)) { netdev_dbg(ieee->dev, "expiring fragment cache entry seq=%u last_frag=%u\n", @@ -72,7 +72,7 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, entry->skb = NULL; } - if (entry->skb != NULL && entry->seq == seq && + if (entry->skb && entry->seq == seq && (entry->last_frag + 1 == frag || frag == -1) && memcmp(entry->src_addr, src, ETH_ALEN) == 0 && memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) @@ -85,27 +85,27 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, /* Called only as a tasklet (software IRQ) */ static struct sk_buff * rtllib_frag_cache_get(struct rtllib_device *ieee, - struct rtllib_hdr_4addr *hdr) + struct ieee80211_hdr *hdr) { struct sk_buff *skb = NULL; - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); + u16 fc = le16_to_cpu(hdr->frame_control); + u16 sc = le16_to_cpu(hdr->seq_ctrl); unsigned int frag = WLAN_GET_SEQ_FRAG(sc); unsigned int seq = WLAN_GET_SEQ_SEQ(sc); struct rtllib_frag_entry *entry; - struct rtllib_hdr_3addrqos *hdr_3addrqos; - struct rtllib_hdr_4addrqos *hdr_4addrqos; + struct ieee80211_qos_hdr *hdr_3addrqos; + struct ieee80211_qos_hdr_4addr *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + if (ieee80211_has_a4(hdr->frame_control) && RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else { @@ -115,7 +115,7 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, if (frag == 0) { /* Reserve enough space to fit maximum frame length */ skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct rtllib_hdr_4addr) + + sizeof(struct ieee80211_hdr) + 8 /* LLC */ + 2 /* alignment */ + 8 /* WEP */ + @@ -130,7 +130,7 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN) ieee->frag_next_idx[tid] = 0; - if (entry->skb != NULL) + if (entry->skb) dev_kfree_skb_any(entry->skb); entry->first_frag_time = jiffies; @@ -145,7 +145,7 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, */ entry = rtllib_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, hdr->addr1); - if (entry != NULL) { + if (entry) { entry->last_frag = frag; skb = entry->skb; } @@ -156,25 +156,25 @@ rtllib_frag_cache_get(struct rtllib_device *ieee, /* Called only as a tasklet (software IRQ) */ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, - struct rtllib_hdr_4addr *hdr) + struct ieee80211_hdr *hdr) { - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); + u16 fc = le16_to_cpu(hdr->frame_control); + u16 sc = le16_to_cpu(hdr->seq_ctrl); unsigned int seq = WLAN_GET_SEQ_SEQ(sc); struct rtllib_frag_entry *entry; - struct rtllib_hdr_3addrqos *hdr_3addrqos; - struct rtllib_hdr_4addrqos *hdr_4addrqos; + struct ieee80211_qos_hdr *hdr_3addrqos; + struct ieee80211_qos_hdr_4addr *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + if (ieee80211_has_a4(hdr->frame_control) && RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_3addrqos = (struct ieee80211_qos_hdr *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else { @@ -184,7 +184,7 @@ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, entry = rtllib_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, hdr->addr1); - if (entry == NULL) { + if (!entry) { netdev_dbg(ieee->dev, "Couldn't invalidate fragment cache entry (seq=%u)\n", seq); @@ -210,7 +210,7 @@ rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb, * this is not mandatory.... but seems that the probe * response parser uses it */ - struct rtllib_hdr_3addr *hdr = (struct rtllib_hdr_3addr *)skb->data; + struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data; rx_stats->len = skb->len; rtllib_rx_mgt(ieee, skb, rx_stats); @@ -233,23 +233,23 @@ static int rtllib_is_eapol_frame(struct rtllib_device *ieee, { struct net_device *dev = ieee->dev; u16 fc, ethertype; - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; u8 *pos; if (skb->len < 24) return 0; - hdr = (struct rtllib_hdr_4addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); + hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(hdr->frame_control); /* check that the frame is unicast frame to us */ - if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == - RTLLIB_FCTL_TODS && + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_TODS && memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == - RTLLIB_FCTL_FROMDS && + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + IEEE80211_FCTL_FROMDS && memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { /* FromDS frame with own addr as DA */ } else { @@ -273,10 +273,10 @@ static inline int rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, struct lib80211_crypt_data *crypt) { - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; int res, hdrlen; - if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) + if (!crypt || !crypt->ops->decrypt_mpdu) return 0; if (ieee->hwsec_active) { @@ -289,8 +289,8 @@ rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, tcb_desc->bHwSec = 0; } - hdr = (struct rtllib_hdr_4addr *)skb->data; - hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + hdr = (struct ieee80211_hdr *)skb->data; + hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control)); atomic_inc(&crypt->refcnt); res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); @@ -313,10 +313,10 @@ static inline int rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, int keyidx, struct lib80211_crypt_data *crypt) { - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; int res, hdrlen; - if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) + if (!crypt || !crypt->ops->decrypt_msdu) return 0; if (ieee->hwsec_active) { struct cb_desc *tcb_desc = (struct cb_desc *) @@ -328,8 +328,8 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, tcb_desc->bHwSec = 0; } - hdr = (struct rtllib_hdr_4addr *)skb->data; - hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + hdr = (struct ieee80211_hdr *)skb->data; + hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_control)); atomic_inc(&crypt->refcnt); res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); @@ -347,27 +347,27 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, /* this function is stolen from ipw2200 driver*/ #define IEEE_PACKET_RETRY_TIME (5 * HZ) static int is_duplicate_packet(struct rtllib_device *ieee, - struct rtllib_hdr_4addr *header) + struct ieee80211_hdr *header) { - u16 fc = le16_to_cpu(header->frame_ctl); - u16 sc = le16_to_cpu(header->seq_ctl); + u16 fc = le16_to_cpu(header->frame_control); + u16 sc = le16_to_cpu(header->seq_ctrl); u16 seq = WLAN_GET_SEQ_SEQ(sc); u16 frag = WLAN_GET_SEQ_FRAG(sc); u16 *last_seq, *last_frag; unsigned long *last_time; - struct rtllib_hdr_3addrqos *hdr_3addrqos; - struct rtllib_hdr_4addrqos *hdr_4addrqos; + struct ieee80211_qos_hdr *hdr_3addrqos; + struct ieee80211_qos_hdr_4addr *hdr_4addrqos; u8 tid; - if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && + if (ieee80211_has_a4(header->frame_control) && RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtllib_hdr_4addrqos *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_4addrqos = (struct ieee80211_qos_hdr_4addr *)header; + tid = le16_to_cpu(hdr_4addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else if (RTLLIB_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtllib_hdr_3addrqos *)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + hdr_3addrqos = (struct ieee80211_qos_hdr *)header; + tid = le16_to_cpu(hdr_3addrqos->qos_ctrl) & RTLLIB_QCTL_TID; tid = UP2AC(tid); tid++; } else { @@ -375,37 +375,6 @@ static int is_duplicate_packet(struct rtllib_device *ieee, } switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - { - struct list_head *p; - struct ieee_ibss_seq *entry = NULL; - u8 *mac = header->addr2; - int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; - - list_for_each(p, &ieee->ibss_mac_hash[index]) { - entry = list_entry(p, struct ieee_ibss_seq, list); - if (!memcmp(entry->mac, mac, ETH_ALEN)) - break; - } - if (p == &ieee->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(struct ieee_ibss_seq), - GFP_ATOMIC); - if (!entry) - return 0; - - ether_addr_copy(entry->mac, mac); - entry->seq_num[tid] = seq; - entry->frag_num[tid] = frag; - entry->packet_time[tid] = jiffies; - list_add(&entry->list, &ieee->ibss_mac_hash[index]); - return 0; - } - last_seq = &entry->seq_num[tid]; - last_frag = &entry->frag_num[tid]; - last_time = &entry->packet_time[tid]; - break; - } - case IW_MODE_INFRA: last_seq = &ieee->last_rxseq_num[tid]; last_frag = &ieee->last_rxfrag_num[tid]; @@ -435,12 +404,12 @@ drop: return 1; } -static bool AddReorderEntry(struct rx_ts_record *pTS, +static bool AddReorderEntry(struct rx_ts_record *ts, struct rx_reorder_entry *pReorderEntry) { - struct list_head *pList = &pTS->rx_pending_pkt_list; + struct list_head *pList = &ts->rx_pending_pkt_list; - while (pList->next != &pTS->rx_pending_pkt_list) { + while (pList->next != &ts->rx_pending_pkt_list) { if (SN_LESS(pReorderEntry->SeqNum, ((struct rx_reorder_entry *) list_entry(pList->next, struct rx_reorder_entry, List))->SeqNum)) @@ -520,13 +489,13 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, } void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, - struct rx_ts_record *pTS) + struct rx_ts_record *ts) { struct rx_reorder_entry *pRxReorderEntry; u8 RfdCnt = 0; - del_timer_sync(&pTS->rx_pkt_pending_timer); - while (!list_empty(&pTS->rx_pending_pkt_list)) { + del_timer_sync(&ts->rx_pkt_pending_timer); + while (!list_empty(&ts->rx_pending_pkt_list)) { if (RfdCnt >= REORDER_WIN_SIZE) { netdev_info(ieee->dev, "-------------->%s() error! RfdCnt >= REORDER_WIN_SIZE\n", @@ -535,7 +504,7 @@ void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, } pRxReorderEntry = (struct rx_reorder_entry *) - list_entry(pTS->rx_pending_pkt_list.prev, + list_entry(ts->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); netdev_dbg(ieee->dev, "%s(): Indicate SeqNum %d!\n", __func__, pRxReorderEntry->SeqNum); @@ -549,12 +518,12 @@ void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, } rtllib_indicate_packets(ieee, ieee->RfdArray, RfdCnt); - pTS->rx_indicate_seq = 0xffff; + ts->rx_indicate_seq = 0xffff; } static void RxReorderIndicatePacket(struct rtllib_device *ieee, struct rtllib_rxb *prxb, - struct rx_ts_record *pTS, u16 SeqNum) + struct rx_ts_record *ts, u16 SeqNum) { struct rt_hi_throughput *ht_info = ieee->ht_info; struct rx_reorder_entry *pReorderEntry = NULL; @@ -565,21 +534,21 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, unsigned long flags; netdev_dbg(ieee->dev, - "%s(): Seq is %d, pTS->rx_indicate_seq is %d, WinSize is %d\n", - __func__, SeqNum, pTS->rx_indicate_seq, WinSize); + "%s(): Seq is %d, ts->rx_indicate_seq is %d, WinSize is %d\n", + __func__, SeqNum, ts->rx_indicate_seq, WinSize); spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - WinEnd = (pTS->rx_indicate_seq + WinSize - 1) % 4096; + WinEnd = (ts->rx_indicate_seq + WinSize - 1) % 4096; /* Rx Reorder initialize condition.*/ - if (pTS->rx_indicate_seq == 0xffff) - pTS->rx_indicate_seq = SeqNum; + if (ts->rx_indicate_seq == 0xffff) + ts->rx_indicate_seq = SeqNum; /* Drop out the packet which SeqNum is smaller than WinStart */ - if (SN_LESS(SeqNum, pTS->rx_indicate_seq)) { + if (SN_LESS(SeqNum, ts->rx_indicate_seq)) { netdev_dbg(ieee->dev, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", - pTS->rx_indicate_seq, SeqNum); + ts->rx_indicate_seq, SeqNum); ht_info->rx_reorder_drop_counter++; { int i; @@ -597,18 +566,18 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ - if (SN_EQUAL(SeqNum, pTS->rx_indicate_seq)) { - pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % 4096; + if (SN_EQUAL(SeqNum, ts->rx_indicate_seq)) { + ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) % 4096; bMatchWinStart = true; } else if (SN_LESS(WinEnd, SeqNum)) { if (SeqNum >= (WinSize - 1)) - pTS->rx_indicate_seq = SeqNum + 1 - WinSize; + ts->rx_indicate_seq = SeqNum + 1 - WinSize; else - pTS->rx_indicate_seq = 4095 - + ts->rx_indicate_seq = 4095 - (WinSize - (SeqNum + 1)) + 1; netdev_dbg(ieee->dev, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", - pTS->rx_indicate_seq, SeqNum); + ts->rx_indicate_seq, SeqNum); } /* Indication process. @@ -625,7 +594,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, /* Current packet is going to be indicated.*/ netdev_dbg(ieee->dev, "Packets indication! IndicateSeq: %d, NewSeq: %d\n", - pTS->rx_indicate_seq, SeqNum); + ts->rx_indicate_seq, SeqNum); ieee->prxbIndicateArray[0] = prxb; index = 1; } else { @@ -642,12 +611,12 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, pReorderEntry->SeqNum = SeqNum; pReorderEntry->prxb = prxb; - if (!AddReorderEntry(pTS, pReorderEntry)) { + if (!AddReorderEntry(ts, pReorderEntry)) { int i; netdev_dbg(ieee->dev, "%s(): Duplicate packet is dropped. IndicateSeq: %d, NewSeq: %d\n", - __func__, pTS->rx_indicate_seq, + __func__, ts->rx_indicate_seq, SeqNum); list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); @@ -659,7 +628,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, } else { netdev_dbg(ieee->dev, "Pkt insert into struct buffer. IndicateSeq: %d, NewSeq: %d\n", - pTS->rx_indicate_seq, SeqNum); + ts->rx_indicate_seq, SeqNum); } } else { /* Packets are dropped if there are not enough reorder @@ -682,16 +651,16 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, } /* Check if there is any packet need indicate.*/ - while (!list_empty(&pTS->rx_pending_pkt_list)) { + while (!list_empty(&ts->rx_pending_pkt_list)) { netdev_dbg(ieee->dev, "%s(): start RREORDER indicate\n", __func__); pReorderEntry = (struct rx_reorder_entry *) - list_entry(pTS->rx_pending_pkt_list.prev, + list_entry(ts->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); - if (SN_LESS(pReorderEntry->SeqNum, pTS->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) { + if (SN_LESS(pReorderEntry->SeqNum, ts->rx_indicate_seq) || + SN_EQUAL(pReorderEntry->SeqNum, ts->rx_indicate_seq)) { /* This protect struct buffer from overflow. */ if (index >= REORDER_WIN_SIZE) { netdev_err(ieee->dev, @@ -703,8 +672,8 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, list_del_init(&pReorderEntry->List); - if (SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) - pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % + if (SN_EQUAL(pReorderEntry->SeqNum, ts->rx_indicate_seq)) + ts->rx_indicate_seq = (ts->rx_indicate_seq + 1) % 4096; ieee->prxbIndicateArray[index] = pReorderEntry->prxb; @@ -724,9 +693,11 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, * Rx buffering. */ if (index > 0) { - if (timer_pending(&pTS->rx_pkt_pending_timer)) - del_timer_sync(&pTS->rx_pkt_pending_timer); - pTS->rx_timeout_indicate_seq = 0xffff; + spin_unlock_irqrestore(&ieee->reorder_spinlock, flags); + if (timer_pending(&ts->rx_pkt_pending_timer)) + del_timer_sync(&ts->rx_pkt_pending_timer); + spin_lock_irqsave(&ieee->reorder_spinlock, flags); + ts->rx_timeout_indicate_seq = 0xffff; if (index > REORDER_WIN_SIZE) { netdev_err(ieee->dev, @@ -740,11 +711,13 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee, bPktInBuf = false; } - if (bPktInBuf && pTS->rx_timeout_indicate_seq == 0xffff) { + if (bPktInBuf && ts->rx_timeout_indicate_seq == 0xffff) { netdev_dbg(ieee->dev, "%s(): SET rx timeout timer\n", __func__); - pTS->rx_timeout_indicate_seq = pTS->rx_indicate_seq; - mod_timer(&pTS->rx_pkt_pending_timer, jiffies + + ts->rx_timeout_indicate_seq = ts->rx_indicate_seq; + spin_unlock_irqrestore(&ieee->reorder_spinlock, flags); + mod_timer(&ts->rx_pkt_pending_timer, jiffies + msecs_to_jiffies(ht_info->rx_reorder_pending_time)); + spin_lock_irqsave(&ieee->reorder_spinlock, flags); } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); } @@ -753,10 +726,10 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats, struct rtllib_rxb *rxb, u8 *src, u8 *dst) { - struct rtllib_hdr_3addr *hdr = (struct rtllib_hdr_3addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); + struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_control); - u16 LLCOffset = sizeof(struct rtllib_hdr_3addr); + u16 LLCOffset = sizeof(struct ieee80211_hdr_3addr); u16 ChkLength; bool bIsAggregateFrame = false; u16 nSubframe_Length; @@ -764,7 +737,7 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb, u16 SeqNum = 0; struct sk_buff *sub_skb; /* just for debug purpose */ - SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl)); + SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctrl)); if ((RTLLIB_QOS_HAS_SEQ(fc)) && (((union frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved)) bIsAggregateFrame = true; @@ -880,8 +853,8 @@ static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats) { - struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_control); size_t hdrlen; hdrlen = rtllib_get_hdrlen(fc); @@ -902,35 +875,32 @@ static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, struct sk_buff *skb, u8 multicast) { - struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; u16 fc, sc; - u8 frag, type, stype; + u8 frag; - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctl); + fc = le16_to_cpu(hdr->frame_control); + sc = le16_to_cpu(hdr->seq_ctrl); frag = WLAN_GET_SEQ_FRAG(sc); if (!ieee->ht_info->cur_rx_reorder_enable || !ieee->current_network.qos_data.active || !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { - if (!((type == RTLLIB_FTYPE_MGMT) && - (stype == RTLLIB_STYPE_BEACON))) { + if (!ieee80211_is_beacon(hdr->frame_control)) { if (is_duplicate_packet(ieee, hdr)) return -1; } } else { - struct rx_ts_record *pRxTS = NULL; + struct rx_ts_record *ts = NULL; - if (GetTs(ieee, (struct ts_common_info **)&pRxTS, hdr->addr2, + if (rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2, (u8)Frame_QoSTID((u8 *)(skb->data)), RX_DIR, true)) { - if ((fc & (1 << 11)) && (frag == pRxTS->rx_last_frag_num) && - (WLAN_GET_SEQ_SEQ(sc) == pRxTS->rx_last_seq_num)) + if ((fc & (1 << 11)) && (frag == ts->rx_last_frag_num) && + (WLAN_GET_SEQ_SEQ(sc) == ts->rx_last_seq_num)) return -1; - pRxTS->rx_last_frag_num = frag; - pRxTS->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc); + ts->rx_last_frag_num = frag; + ts->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc); } else { netdev_warn(ieee->dev, "%s(): No TS! Skip the check!\n", __func__); @@ -942,23 +912,23 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, } static void rtllib_rx_extract_addr(struct rtllib_device *ieee, - struct rtllib_hdr_4addr *hdr, u8 *dst, + struct ieee80211_hdr *hdr, u8 *dst, u8 *src, u8 *bssid) { - u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 fc = le16_to_cpu(hdr->frame_control); - switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { - case RTLLIB_FCTL_FROMDS: + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + case IEEE80211_FCTL_FROMDS: ether_addr_copy(dst, hdr->addr1); ether_addr_copy(src, hdr->addr3); ether_addr_copy(bssid, hdr->addr2); break; - case RTLLIB_FCTL_TODS: + case IEEE80211_FCTL_TODS: ether_addr_copy(dst, hdr->addr3); ether_addr_copy(src, hdr->addr2); ether_addr_copy(bssid, hdr->addr1); break; - case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: ether_addr_copy(dst, hdr->addr3); ether_addr_copy(src, hdr->addr4); ether_addr_copy(bssid, ieee->current_network.bssid); @@ -971,46 +941,34 @@ static void rtllib_rx_extract_addr(struct rtllib_device *ieee, } } -static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, +static int rtllib_rx_data_filter(struct rtllib_device *ieee, struct ieee80211_hdr *hdr, u8 *dst, u8 *src, u8 *bssid, u8 *addr2) { u8 type, stype; - + u16 fc = le16_to_cpu(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); /* Filter frames from different BSS */ - if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS) && + if (ieee80211_has_a4(hdr->frame_control) && !ether_addr_equal(ieee->current_network.bssid, bssid) && !is_zero_ether_addr(ieee->current_network.bssid)) { return -1; } - /* Filter packets sent by an STA that will be forwarded by AP */ - if (ieee->intel_promiscuous_md_info.promiscuous_on && - ieee->intel_promiscuous_md_info.fltr_src_sta_frame) { - if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) && - !ether_addr_equal(dst, ieee->current_network.bssid) && - ether_addr_equal(bssid, ieee->current_network.bssid)) { - return -1; - } - } - /* Nullfunc frames may have PS-bit set, so they must be passed to * hostap_handle_sta_rx() before being dropped here. */ - if (!ieee->intel_promiscuous_md_info.promiscuous_on) { - if (stype != RTLLIB_STYPE_DATA && - stype != RTLLIB_STYPE_DATA_CFACK && - stype != RTLLIB_STYPE_DATA_CFPOLL && - stype != RTLLIB_STYPE_DATA_CFACKPOLL && - stype != RTLLIB_STYPE_QOS_DATA) { - if (stype != RTLLIB_STYPE_NULLFUNC) - netdev_dbg(ieee->dev, - "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n", - type, stype); - return -1; - } + if (stype != IEEE80211_STYPE_DATA && + stype != IEEE80211_STYPE_DATA_CFACK && + stype != IEEE80211_STYPE_DATA_CFPOLL && + stype != IEEE80211_STYPE_DATA_CFACKPOLL && + stype != IEEE80211_STYPE_QOS_DATA) { + if (stype != IEEE80211_STYPE_NULLFUNC) + netdev_dbg(ieee->dev, + "RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n", + type, stype); + return -1; } /* packets from our adapter are dropped (echo) */ @@ -1029,8 +987,8 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb, struct lib80211_crypt_data **crypt, size_t hdrlen) { - struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_control); int idx = 0; if (skb->len >= hdrlen + 3) @@ -1040,11 +998,10 @@ static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb, /* allow NULL decrypt to indicate an station specific override * for default encryption */ - if (*crypt && ((*crypt)->ops == NULL || - (*crypt)->ops->decrypt_mpdu == NULL)) + if (*crypt && (!(*crypt)->ops || !(*crypt)->ops->decrypt_mpdu)) *crypt = NULL; - if (!*crypt && (fc & RTLLIB_FCTL_WEP)) { + if (!*crypt && (fc & IEEE80211_FCTL_PROTECTED)) { /* This seems to be triggered by some (multicast?) * frames from other than current BSS, so just drop the * frames silently instead of filling system log with @@ -1063,14 +1020,14 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats, struct lib80211_crypt_data *crypt, size_t hdrlen) { - struct rtllib_hdr_4addr *hdr; + struct ieee80211_hdr *hdr; int keyidx = 0; u16 fc, sc; u8 frag; - hdr = (struct rtllib_hdr_4addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - sc = le16_to_cpu(hdr->seq_ctl); + hdr = (struct ieee80211_hdr *)skb->data; + fc = le16_to_cpu(hdr->frame_control); + sc = le16_to_cpu(hdr->seq_ctrl); frag = WLAN_GET_SEQ_FRAG(sc); if ((!rx_stats->Decrypted)) @@ -1079,13 +1036,13 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, ieee->need_sw_enc = 0; keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt); - if ((fc & RTLLIB_FCTL_WEP) && (keyidx < 0)) { + if ((fc & IEEE80211_FCTL_PROTECTED) && (keyidx < 0)) { netdev_info(ieee->dev, "%s: decrypt frame error\n", __func__); return -1; } - hdr = (struct rtllib_hdr_4addr *)skb->data; - if ((frag != 0 || (fc & RTLLIB_FCTL_MOREFRAGS))) { + hdr = (struct ieee80211_hdr *)skb->data; + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { int flen; struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr); @@ -1094,7 +1051,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, if (!frag_skb) { netdev_dbg(ieee->dev, "Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n", - (fc & RTLLIB_FCTL_MOREFRAGS) != 0, + (fc & IEEE80211_FCTL_MOREFRAGS) != 0, WLAN_GET_SEQ_SEQ(sc), frag); return -1; } @@ -1124,7 +1081,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, dev_kfree_skb_any(skb); skb = NULL; - if (fc & RTLLIB_FCTL_MOREFRAGS) { + if (fc & IEEE80211_FCTL_MOREFRAGS) { /* more fragments expected - leave the skb in fragment * cache for now; it will be delivered to upper layers * after all fragments have been received @@ -1136,21 +1093,21 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, * delivered, so remove skb from fragment cache */ skb = frag_skb; - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; rtllib_frag_cache_invalidate(ieee, hdr); } /* skb: hdr + (possible reassembled) full MSDU payload; possibly still * encrypted/authenticated */ - if ((fc & RTLLIB_FCTL_WEP) && + if ((fc & IEEE80211_FCTL_PROTECTED) && rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) { netdev_info(ieee->dev, "%s: ==>decrypt msdu error\n", __func__); return -1; } - hdr = (struct rtllib_hdr_4addr *)skb->data; - if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep) { + hdr = (struct ieee80211_hdr *)skb->data; + if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) { if (/*ieee->ieee802_1x &&*/ rtllib_is_eapol_frame(ieee, skb, hdrlen)) { /* pass unencrypted EAPOL frames even if encryption is @@ -1169,7 +1126,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, } } - if (crypt && !(fc & RTLLIB_FCTL_WEP) && + if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && rtllib_is_eapol_frame(ieee, skb, hdrlen)) { struct eapol *eap = (struct eapol *)(skb->data + 24); @@ -1177,7 +1134,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, eap_get_type(eap->type)); } - if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep && + if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep && !rtllib_is_eapol_frame(ieee, skb, hdrlen)) { netdev_dbg(ieee->dev, "dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n", @@ -1213,7 +1170,7 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, u16 ethertype; int i = 0; - if (rxb == NULL) { + if (!rxb) { netdev_info(dev, "%s: rxb is NULL!!\n", __func__); return; } @@ -1275,10 +1232,10 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; - struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct lib80211_crypt_data *crypt = NULL; struct rtllib_rxb *rxb = NULL; - struct rx_ts_record *pTS = NULL; + struct rx_ts_record *ts = NULL; u16 fc, sc, SeqNum = 0; u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0; u8 dst[ETH_ALEN]; @@ -1286,23 +1243,18 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, u8 bssid[ETH_ALEN] = {0}; size_t hdrlen = 0; - bool bToOtherSTA = false; int ret = 0, i = 0; - fc = le16_to_cpu(hdr->frame_ctl); + fc = le16_to_cpu(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctl); + sc = le16_to_cpu(hdr->seq_ctrl); /*Filter pkt not to me*/ multicast = is_multicast_ether_addr(hdr->addr1); unicast = !multicast; - if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) { - if (ieee->net_promiscuous_md) - bToOtherSTA = true; - else - goto rx_dropped; - } + if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) + goto rx_dropped; /*Filter pkt has too small length */ hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats); @@ -1324,8 +1276,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Filter MGNT Frame */ if (type == RTLLIB_FTYPE_MGMT) { - if (bToOtherSTA) - goto rx_dropped; if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) goto rx_dropped; else @@ -1335,16 +1285,14 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Filter WAPI DATA Frame */ /* Update statstics for AP roaming */ - if (!bToOtherSTA) { - ieee->link_detect_info.NumRecvDataInPeriod++; - ieee->link_detect_info.NumRxOkInPeriod++; - } + ieee->link_detect_info.NumRecvDataInPeriod++; + ieee->link_detect_info.NumRxOkInPeriod++; /* Data frame - extract src/dst addresses */ rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid); /* Filter Data frames */ - ret = rtllib_rx_data_filter(ieee, fc, dst, src, bssid, hdr->addr2); + ret = rtllib_rx_data_filter(ieee, hdr, dst, src, bssid, hdr->addr2); if (ret < 0) goto rx_dropped; @@ -1354,7 +1302,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Send pspoll based on moredata */ if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP) && - (ieee->polling) && (!bToOtherSTA)) { + (ieee->polling)) { if (WLAN_FC_MORE_DATA(fc)) { /* more data bit is set, let's request a new frame * from the AP @@ -1378,13 +1326,12 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, goto rx_exit; /* Get TS for Rx Reorder */ - hdr = (struct rtllib_hdr_4addr *)skb->data; + hdr = (struct ieee80211_hdr *)skb->data; if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) - && (!bToOtherSTA)) { + && !is_multicast_ether_addr(hdr->addr1)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); - GetTs(ieee, (struct ts_common_info **)&pTS, hdr->addr2, TID, + rtllib_get_ts(ieee, (struct ts_common_info **)&ts, hdr->addr2, TID, RX_DIR, true); if (TID != 0 && TID != 3) ieee->bis_any_nonbepkts = true; @@ -1412,21 +1359,19 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Update WAPI PN */ /* Check if leave LPS */ - if (!bToOtherSTA) { - if (ieee->bIsAggregateFrame) - nr_subframes = rxb->nr_subframes; - else - nr_subframes = 1; - if (unicast) - ieee->link_detect_info.NumRxUnicastOkInPeriod += nr_subframes; - rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes); - } + if (ieee->bIsAggregateFrame) + nr_subframes = rxb->nr_subframes; + else + nr_subframes = 1; + if (unicast) + ieee->link_detect_info.NumRxUnicastOkInPeriod += nr_subframes; + rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes); /* Indicate packets to upper layer or Rx Reorder */ - if (!ieee->ht_info->cur_rx_reorder_enable || pTS == NULL || bToOtherSTA) + if (!ieee->ht_info->cur_rx_reorder_enable || !ts) rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src); else - RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); + RxReorderIndicatePacket(ieee, rxb, ts, SeqNum); dev_kfree_skb(skb); @@ -1446,8 +1391,8 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats) { - struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_control); size_t hdrlen = rtllib_get_hdrlen(fc); if (skb->len < hdrlen) { @@ -1490,7 +1435,6 @@ int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, } switch (ieee->iw_mode) { - case IW_MODE_ADHOC: case IW_MODE_INFRA: ret = rtllib_rx_InfraAdhoc(ieee, skb, rx_stats); break; @@ -2448,11 +2392,6 @@ static inline void update_network(struct rtllib_device *ieee, dst->BssCcxVerNumber = src->BssCcxVerNumber; } -static inline int is_beacon(u16 fc) -{ - return (WLAN_FC_GET_STYPE(fc) == RTLLIB_STYPE_BEACON); -} - static int IsPassiveChannel(struct rtllib_device *rtllib, u8 channel) { if (channel > MAX_CHANNEL_NUMBER) { @@ -2491,7 +2430,7 @@ static inline void rtllib_process_probe_response( short renew; struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), GFP_ATOMIC); - u16 frame_ctl = le16_to_cpu(beacon->header.frame_ctl); + __le16 frame_ctl = beacon->header.frame_control; if (!network) return; @@ -2521,14 +2460,14 @@ static inline void rtllib_process_probe_response( netdev_dbg(ieee->dev, "Dropped '%s' ( %pM) via %s.\n", escape_essid(info_element->data, info_element->len), beacon->header.addr3, - is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); + ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); goto free_network; } if (!rtllib_legal_channel(ieee, network->channel)) goto free_network; - if (WLAN_FC_GET_STYPE(frame_ctl) == RTLLIB_STYPE_PROBE_RESP) { + if (ieee80211_is_probe_resp(frame_ctl)) { if (IsPassiveChannel(ieee, network->channel)) { netdev_info(ieee->dev, "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", @@ -2561,7 +2500,7 @@ static inline void rtllib_process_probe_response( else ieee->current_network.buseprotection = false; } - if (is_beacon(frame_ctl)) { + if (ieee80211_is_beacon(frame_ctl)) { if (ieee->link_state >= MAC80211_LINKED) ieee->link_detect_info.NumRecvBcnInPeriod++; } @@ -2570,8 +2509,7 @@ static inline void rtllib_process_probe_response( if (is_same_network(target, network, (target->ssid_len ? 1 : 0))) break; - if ((oldest == NULL) || - (target->last_scanned < oldest->last_scanned)) + if (!oldest || (target->last_scanned < oldest->last_scanned)) oldest = target; } @@ -2597,7 +2535,7 @@ static inline void rtllib_process_probe_response( netdev_dbg(ieee->dev, "Adding '%s' ( %pM) via %s.\n", escape_essid(network->ssid, network->ssid_len), network->bssid, - is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); + ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); memcpy(target, network, sizeof(*target)); list_add_tail(&target->list, &ieee->network_list); @@ -2607,7 +2545,7 @@ static inline void rtllib_process_probe_response( netdev_dbg(ieee->dev, "Updating '%s' ( %pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), target->bssid, - is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); + ieee80211_is_beacon(frame_ctl) ? "BEACON" : "PROBE RESPONSE"); /* we have an entry and we are going to update it. But this * entry may be already expired. In this case we do the same @@ -2628,7 +2566,7 @@ static inline void rtllib_process_probe_response( } spin_unlock_irqrestore(&ieee->lock, flags); - if (is_beacon(frame_ctl) && + if (ieee80211_is_beacon(frame_ctl) && is_same_network(&ieee->current_network, network, (network->ssid_len ? 1 : 0)) && (ieee->link_state == MAC80211_LINKED)) { @@ -2642,18 +2580,14 @@ static void rtllib_rx_mgt(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *stats) { - struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data; + struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data; - if ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) != - RTLLIB_STYPE_PROBE_RESP) && - (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) != - RTLLIB_STYPE_BEACON)) + if (!ieee80211_is_probe_resp(header->frame_control) && + (!ieee80211_is_beacon(header->frame_control))) ieee->last_rx_ps_time = jiffies; - switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) { - case RTLLIB_STYPE_BEACON: - netdev_dbg(ieee->dev, "received BEACON (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); + if (ieee80211_is_beacon(header->frame_control)) { + netdev_dbg(ieee->dev, "received BEACON\n"); rtllib_process_probe_response( ieee, (struct rtllib_probe_response *)header, stats); @@ -2662,22 +2596,9 @@ static void rtllib_rx_mgt(struct rtllib_device *ieee, ieee->iw_mode == IW_MODE_INFRA && ieee->link_state == MAC80211_LINKED)) schedule_work(&ieee->ps_task); - - break; - - case RTLLIB_STYPE_PROBE_RESP: - netdev_dbg(ieee->dev, "received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); + } else if (ieee80211_is_probe_resp(header->frame_control)) { + netdev_dbg(ieee->dev, "received PROBE RESPONSE\n"); rtllib_process_probe_response(ieee, (struct rtllib_probe_response *)header, stats); - break; - case RTLLIB_STYPE_PROBE_REQ: - netdev_dbg(ieee->dev, "received PROBE REQUEST (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); - if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && - (ieee->iw_mode == IW_MODE_ADHOC && - ieee->link_state == MAC80211_LINKED)) - rtllib_rx_probe_rq(ieee, skb); - break; } } diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index de1702491191..42d652fe8601 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -187,8 +187,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) { unsigned long flags; short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct rtllib_hdr_3addr *header = - (struct rtllib_hdr_3addr *)skb->data; + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *)skb->data; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); @@ -197,7 +197,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) /* called with 2nd param 0, no mgmt lock required */ rtllib_sta_wakeup(ieee, 0); - if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON) + if (ieee80211_is_beacon(header->frame_control)) tcb_desc->queue_index = BEACON_QUEUE; else tcb_desc->queue_index = MGNT_QUEUE; @@ -213,7 +213,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) if (ieee->queue_stop) { enqueue_mgmt(ieee, skb); } else { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; @@ -230,7 +230,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) spin_unlock_irqrestore(&ieee->lock, flags); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; @@ -264,16 +264,16 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) { short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct rtllib_hdr_3addr *header = - (struct rtllib_hdr_3addr *)skb->data; + struct ieee80211_hdr_3addr *header = + (struct ieee80211_hdr_3addr *)skb->data; u16 fc, type, stype; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); - fc = le16_to_cpu(header->frame_ctl); + fc = le16_to_cpu(header->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); - if (stype != RTLLIB_STYPE_PSPOLL) + if (stype != IEEE80211_STYPE_PSPOLL) tcb_desc->queue_index = MGNT_QUEUE; else tcb_desc->queue_index = HIGH_QUEUE; @@ -287,7 +287,7 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb, tcb_desc->tx_use_drv_assinged_rate = 1; if (single) { if (type != RTLLIB_FTYPE_CTL) { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; @@ -300,7 +300,7 @@ softmac_ps_mgmt_xmit(struct sk_buff *skb, } else { if (type != RTLLIB_FTYPE_CTL) { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; @@ -331,7 +331,7 @@ static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) skb_reserve(skb, ieee->tx_headroom); req = skb_put(skb, sizeof(struct rtllib_probe_request)); - req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ); + req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); req->header.duration_id = 0; eth_broadcast_addr(req->header.addr1); @@ -406,49 +406,6 @@ void rtllib_DisableNetMonitorMode(struct net_device *dev, ieee->AllowAllDestAddrHandler(dev, false, !bInitState); } -/* Enables the specialized promiscuous mode required by Intel. - * In this mode, Intel intends to hear traffics from/to other STAs in the - * same BSS. Therefore we don't have to disable checking BSSID and we only need - * to allow all dest. BUT: if we enable checking BSSID then we can't recv - * packets from other STA. - */ -void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, - bool bInitState) -{ - bool bFilterOutNonAssociatedBSSID = false; - - struct rtllib_device *ieee = netdev_priv_rsl(dev); - - netdev_info(dev, "========>Enter Intel Promiscuous Mode\n"); - - ieee->AllowAllDestAddrHandler(dev, true, !bInitState); - ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, - (u8 *)&bFilterOutNonAssociatedBSSID); - - ieee->net_promiscuous_md = true; -} -EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode); - -/* Disables the specialized promiscuous mode required by Intel. - * See MgntEnableIntelPromiscuousMode for detail. - */ -void rtllib_DisableIntelPromiscuousMode(struct net_device *dev, - bool bInitState) -{ - bool bFilterOutNonAssociatedBSSID = true; - - struct rtllib_device *ieee = netdev_priv_rsl(dev); - - netdev_info(dev, "========>Exit Intel Promiscuous Mode\n"); - - ieee->AllowAllDestAddrHandler(dev, false, !bInitState); - ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, - (u8 *)&bFilterOutNonAssociatedBSSID); - - ieee->net_promiscuous_md = false; -} -EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode); - static void rtllib_send_probe(struct rtllib_device *ieee) { struct sk_buff *skb; @@ -462,8 +419,7 @@ static void rtllib_send_probe(struct rtllib_device *ieee) static void rtllib_send_probe_requests(struct rtllib_device *ieee) { - if (ieee->active_scan && (ieee->softmac_features & - IEEE_SOFTMAC_PROBERQ)) { + if (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ) { rtllib_send_probe(ieee); rtllib_send_probe(ieee); } @@ -607,46 +563,6 @@ out1: mutex_unlock(&ieee->scan_mutex); } -static void rtllib_beacons_start(struct rtllib_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 1; - rtllib_send_beacon(ieee); - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -static void rtllib_beacons_stop(struct rtllib_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 0; - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); - del_timer_sync(&ieee->beacon_timer); -} - -void rtllib_stop_send_beacons(struct rtllib_device *ieee) -{ - ieee->stop_send_beacons(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - rtllib_beacons_stop(ieee); -} -EXPORT_SYMBOL(rtllib_stop_send_beacons); - -void rtllib_start_send_beacons(struct rtllib_device *ieee) -{ - ieee->start_send_beacons(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - rtllib_beacons_start(ieee); -} -EXPORT_SYMBOL(rtllib_start_send_beacons); - static void rtllib_softmac_stop_scan(struct rtllib_device *ieee) { mutex_lock(&ieee->scan_mutex); @@ -739,9 +655,9 @@ rtllib_authentication_req(struct rtllib_network *beacon, auth = skb_put(skb, sizeof(struct rtllib_authentication)); - auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH); + auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH); if (challengelen) - auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP); + auth->header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); auth->header.duration_id = cpu_to_le16(0x013a); ether_addr_copy(auth->header.addr1, beacon->bssid); @@ -809,7 +725,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; encrypt = crypt && crypt->ops && ((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len)); - if (ieee->ht_info->bCurrentHTSupport) { + if (ieee->ht_info->current_ht_support) { tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap); tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap); tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo); @@ -860,7 +776,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, if (encrypt) beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP); + beacon_buf->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); beacon_buf->info_element[0].id = MFIE_TYPE_SSID; beacon_buf->info_element[0].len = ssid_len; @@ -901,8 +817,6 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, } if (wpa_ie_len) { - if (ieee->iw_mode == IW_MODE_ADHOC) - memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); tag += ieee->wpa_ie_len; } @@ -912,23 +826,23 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr) { struct sk_buff *skb; - struct rtllib_hdr_3addr *hdr; + struct ieee80211_hdr_3addr *hdr; - skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr) + ieee->tx_headroom); + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr) + ieee->tx_headroom); if (!skb) return NULL; skb_reserve(skb, ieee->tx_headroom); - hdr = skb_put(skb, sizeof(struct rtllib_hdr_3addr)); + hdr = skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); ether_addr_copy(hdr->addr1, ieee->current_network.bssid); ether_addr_copy(hdr->addr2, ieee->dev->dev_addr); ether_addr_copy(hdr->addr3, ieee->current_network.bssid); - hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA | - RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS | - (pwr ? RTLLIB_FCTL_PM : 0)); + hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_DATA | + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | + (pwr ? IEEE80211_FCTL_PM : 0)); return skb; } @@ -936,34 +850,26 @@ static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr) static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee) { struct sk_buff *skb; - struct rtllib_pspoll_hdr *hdr; + struct ieee80211_pspoll *hdr; - skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr) + ieee->tx_headroom); + skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll) + ieee->tx_headroom); if (!skb) return NULL; skb_reserve(skb, ieee->tx_headroom); - hdr = skb_put(skb, sizeof(struct rtllib_pspoll_hdr)); + hdr = skb_put(skb, sizeof(struct ieee80211_pspoll)); ether_addr_copy(hdr->bssid, ieee->current_network.bssid); ether_addr_copy(hdr->ta, ieee->dev->dev_addr); hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); - hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL | - RTLLIB_FCTL_PM); + hdr->frame_control = cpu_to_le16(RTLLIB_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | + IEEE80211_FCTL_PM); return skb; } -static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest) -{ - struct sk_buff *buf = rtllib_probe_resp(ieee, dest); - - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid) { int i = 0; @@ -1012,7 +918,7 @@ rtllib_association_req(struct rtllib_network *beacon, int len = 0; crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - if (crypt != NULL) + if (crypt) encrypt = crypt && crypt->ops && ((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len)); @@ -1026,7 +932,7 @@ rtllib_association_req(struct rtllib_network *beacon, ieee->mode = WIRELESS_MODE_G; } - if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap); ht_cap_len = sizeof(ieee->ht_info->SelfHTCap); HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, @@ -1076,7 +982,7 @@ rtllib_association_req(struct rtllib_network *beacon, hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2); - hdr->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_REQ); + hdr->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ); hdr->header.duration_id = cpu_to_le16(37); ether_addr_copy(hdr->header.addr1, beacon->bssid); ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr); @@ -1164,7 +1070,7 @@ rtllib_association_req(struct rtllib_network *beacon, memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length); tag += osCcxVerNum.Length; } - if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_HT_CAP; @@ -1198,7 +1104,7 @@ rtllib_association_req(struct rtllib_network *beacon, rtllib_TURBO_Info(ieee, &tag); } - if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) { tag = skb_put(skb, ht_cap_len); *tag++ = MFIE_TYPE_GENERIC; @@ -1311,7 +1217,7 @@ static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, "Sending authentication challenge response\n"); rtllib_encrypt_fragment(ieee, skb, - sizeof(struct rtllib_hdr_3addr)); + sizeof(struct ieee80211_hdr_3addr)); softmac_mgmt_xmit(skb, ieee); mod_timer(&ieee->associate_timer, jiffies + (HZ / 2)); @@ -1348,10 +1254,8 @@ static void rtllib_associate_complete_wq(void *data) netdev_info(ieee->dev, "Associated successfully with %pM\n", ieee->current_network.bssid); - if (!ieee->is_silent_reset) { - netdev_info(ieee->dev, "normal associate\n"); - notify_wx_assoc_event(ieee); - } + netdev_info(ieee->dev, "normal associate\n"); + notify_wx_assoc_event(ieee); netif_carrier_on(ieee->dev); ieee->is_roaming = false; @@ -1363,13 +1267,13 @@ static void rtllib_associate_complete_wq(void *data) ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B); netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate); } - if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) { + if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht) { netdev_info(ieee->dev, "Successfully associated, ht enabled\n"); HTOnAssocRsp(ieee); } else { netdev_info(ieee->dev, "Successfully associated, ht not enabled(%d, %d)\n", - ieee->ht_info->bCurrentHTSupport, + ieee->ht_info->current_ht_support, ieee->ht_info->enable_ht); memset(ieee->dot11ht_oper_rate_set, 0, 16); } @@ -1384,10 +1288,6 @@ static void rtllib_associate_complete_wq(void *data) psc->LpsIdleCount = 0; ieee->link_change(ieee->dev); - if (ieee->is_silent_reset) { - netdev_info(ieee->dev, "silent reset associate\n"); - ieee->is_silent_reset = false; - } } static void rtllib_sta_send_associnfo(struct rtllib_device *ieee) @@ -1445,14 +1345,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, WLAN_CAPABILITY_ESS)) return; - if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & - WLAN_CAPABILITY_IBSS)) - return; - - if ((ieee->iw_mode == IW_MODE_ADHOC) && - (net->channel > ieee->ibss_maxjoin_chal)) - return; - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { + if (ieee->iw_mode == IW_MODE_INFRA) { /* if the user specified the AP MAC, we need also the essid * This could be obtained by beacons or, if the network does not * broadcast it, it can be put manually. @@ -1534,8 +1427,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); else - ieee->ht_info->bCurrentHTSupport = - false; + ieee->ht_info->current_ht_support = false; ieee->link_state = RTLLIB_ASSOCIATING; schedule_delayed_work( @@ -1613,52 +1505,6 @@ static inline int auth_parse(struct net_device *dev, struct sk_buff *skb, return 0; } -static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, - u8 *src) -{ - u8 *tag; - u8 *skbend; - u8 *ssid = NULL; - u8 ssidlen = 0; - struct rtllib_hdr_3addr *header = - (struct rtllib_hdr_3addr *)skb->data; - bool bssid_match; - - if (skb->len < sizeof(struct rtllib_hdr_3addr)) - return -1; /* corrupted */ - - bssid_match = - (!ether_addr_equal(header->addr3, ieee->current_network.bssid)) && - (!is_broadcast_ether_addr(header->addr3)); - if (bssid_match) - return -1; - - ether_addr_copy(src, header->addr2); - - skbend = (u8 *)skb->data + skb->len; - - tag = skb->data + sizeof(struct rtllib_hdr_3addr); - - while (tag + 1 < skbend) { - if (*tag == 0) { - ssid = tag + 2; - ssidlen = *(tag + 1); - break; - } - tag++; /* point to the len field */ - tag = tag + *(tag); /* point to the last data byte of the tag */ - tag++; /* point to the next tag */ - } - - if (ssidlen == 0) - return 1; - - if (!ssid) - return 1; /* ssid not found in tagged param */ - - return !strncmp(ssid, ieee->current_network.ssid, ssidlen); -} - static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, int *aid) { @@ -1688,17 +1534,6 @@ static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, return le16_to_cpu(response_head->status); } -void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - - ieee->softmac_stats.rx_probe_rq++; - if (probe_rq_parse(ieee, skb, dest) > 0) { - ieee->softmac_stats.tx_probe_rs++; - rtllib_resp_to_probe(ieee, dest); - } -} - void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr) { struct sk_buff *buf = rtllib_null_func(ieee, pwr); @@ -1752,16 +1587,10 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) if (ieee->bAwakePktSent) { psc->LPSAwakeIntvl = 1; } else { - u8 MaxPeriod = 1; + u8 MaxPeriod = 5; if (psc->LPSAwakeIntvl == 0) psc->LPSAwakeIntvl = 1; - if (psc->reg_max_lps_awake_intvl == 0) - MaxPeriod = 1; - else if (psc->reg_max_lps_awake_intvl == 0xFF) - MaxPeriod = ieee->current_network.dtim_period; - else - MaxPeriod = psc->reg_max_lps_awake_intvl; psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (psc->LPSAwakeIntvl + 1); @@ -1921,16 +1750,9 @@ EXPORT_SYMBOL(rtllib_ps_tx_ack); static void rtllib_process_action(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data; - u8 *act = rtllib_get_payload((struct rtllib_hdr *)header); + u8 *act = skb->data + RTLLIB_3ADDR_LEN; u8 category = 0; - if (act == NULL) { - netdev_warn(ieee->dev, - "Error getting payload of action frame\n"); - return; - } - category = *act; act++; switch (category) { @@ -1960,8 +1782,8 @@ rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, int aid; u8 *ies; struct rtllib_assoc_response_frame *assoc_resp; - struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data; - u16 frame_ctl = le16_to_cpu(header->frame_ctl); + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; + u16 frame_ctl = le16_to_cpu(header->frame_control); netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n", WLAN_FC_GET_STYPE(frame_ctl)); @@ -2099,7 +1921,7 @@ rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb, static inline int rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb) { - struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data; + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; u16 frame_ctl; if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) @@ -2111,7 +1933,7 @@ rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb) if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && ieee->link_state == MAC80211_LINKED && (ieee->iw_mode == IW_MODE_INFRA)) { - frame_ctl = le16_to_cpu(header->frame_ctl); + frame_ctl = le16_to_cpu(header->frame_control); netdev_info(ieee->dev, "==========>received disassoc/deauth(%x) frame, reason code:%x\n", WLAN_FC_GET_STYPE(frame_ctl), @@ -2135,30 +1957,30 @@ inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, struct rtllib_rx_stats *rx_stats, u16 type, u16 stype) { - struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data; + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *)skb->data; u16 frame_ctl; if (!ieee->proto_started) return 0; - frame_ctl = le16_to_cpu(header->frame_ctl); + frame_ctl = le16_to_cpu(header->frame_control); switch (WLAN_FC_GET_STYPE(frame_ctl)) { - case RTLLIB_STYPE_ASSOC_RESP: - case RTLLIB_STYPE_REASSOC_RESP: + case IEEE80211_STYPE_ASSOC_RESP: + case IEEE80211_STYPE_REASSOC_RESP: if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1) return 1; break; - case RTLLIB_STYPE_ASSOC_REQ: - case RTLLIB_STYPE_REASSOC_REQ: + case IEEE80211_STYPE_ASSOC_REQ: + case IEEE80211_STYPE_REASSOC_REQ: break; - case RTLLIB_STYPE_AUTH: + case IEEE80211_STYPE_AUTH: rtllib_rx_auth(ieee, skb, rx_stats); break; - case RTLLIB_STYPE_DISASSOC: - case RTLLIB_STYPE_DEAUTH: + case IEEE80211_STYPE_DISASSOC: + case IEEE80211_STYPE_DEAUTH: rtllib_rx_deauth(ieee, skb); break; - case RTLLIB_STYPE_MANAGE_ACT: + case IEEE80211_STYPE_ACTION: rtllib_process_action(ieee, skb); break; default: @@ -2263,128 +2085,6 @@ void rtllib_wake_all_queues(struct rtllib_device *ieee) netif_tx_wake_all_queues(ieee->dev); } -static void rtllib_start_monitor_mode(struct rtllib_device *ieee) -{ - /* reset hardware status */ - if (ieee->raw_tx) - netif_carrier_on(ieee->dev); -} - -static void rtllib_start_ibss_wq(void *data) -{ - struct rtllib_device *ieee = container_of_dwork_rsl(data, - struct rtllib_device, start_ibss_wq); - /* iwconfig mode ad-hoc will schedule this and return - * on the other hand this will block further iwconfig SET - * operations because of the wx_mutex hold. - * Anyway some most set operations set a flag to speed-up - * (abort) this wq (when syncro scanning) before sleeping - * on the mutex - */ - if (!ieee->proto_started) { - netdev_info(ieee->dev, "==========oh driver down return\n"); - return; - } - mutex_lock(&ieee->wx_mutex); - - if (ieee->current_network.ssid_len == 0) { - strscpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID, - sizeof(ieee->current_network.ssid)); - ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - ieee->link_state = MAC80211_NOLINK; - ieee->mode = WIRELESS_MODE_G; - /* check if we have this cell in our network list */ - rtllib_softmac_check_all_nets(ieee); - - /* if not then the state is not linked. Maybe the user switched to - * ad-hoc mode just after being in monitor mode, or just after - * being very few time in managed mode (so the card have had no - * time to scan all the chans..) or we have just run up the iface - * after setting ad-hoc mode. So we have to give another try.. - * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tried to associate when - * we had just checked the ieee->link_state and we was going to start the - * scan) because in ibss mode the rtllib_new_net function, when - * finds a good net, just set the ieee->link_state to MAC80211_LINKED, - * so, at worst, we waste a bit of time to initiate an unneeded syncro - * scan, that will stop at the first round because it sees the state - * associated. - */ - if (ieee->link_state == MAC80211_NOLINK) - rtllib_start_scan_syncro(ieee); - - /* the network definitively is not here.. create a new cell */ - if (ieee->link_state == MAC80211_NOLINK) { - netdev_info(ieee->dev, "creating new IBSS cell\n"); - ieee->current_network.channel = ieee->bss_start_channel; - if (!ieee->wap_set) - eth_random_addr(ieee->current_network.bssid); - - ieee->current_network.rates_len = 4; - ieee->current_network.rates[0] = - RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB; - ieee->current_network.rates[1] = - RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB; - ieee->current_network.rates[2] = - RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB; - ieee->current_network.rates[3] = - RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB; - - ieee->current_network.rates_ex_len = 8; - ieee->current_network.rates_ex[0] = - RTLLIB_OFDM_RATE_6MB; - ieee->current_network.rates_ex[1] = - RTLLIB_OFDM_RATE_9MB; - ieee->current_network.rates_ex[2] = - RTLLIB_OFDM_RATE_12MB; - ieee->current_network.rates_ex[3] = - RTLLIB_OFDM_RATE_18MB; - ieee->current_network.rates_ex[4] = - RTLLIB_OFDM_RATE_24MB; - ieee->current_network.rates_ex[5] = - RTLLIB_OFDM_RATE_36MB; - ieee->current_network.rates_ex[6] = - RTLLIB_OFDM_RATE_48MB; - ieee->current_network.rates_ex[7] = - RTLLIB_OFDM_RATE_54MB; - ieee->rate = 108; - - ieee->current_network.qos_data.supported = 0; - ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G); - ieee->current_network.mode = ieee->mode; - ieee->current_network.atim_window = 0; - ieee->current_network.capability = WLAN_CAPABILITY_IBSS; - } - - netdev_info(ieee->dev, "%s(): ieee->mode = %d\n", __func__, ieee->mode); - if (ieee->mode == WIRELESS_MODE_N_24G) - HTUseDefaultSetting(ieee); - else - ieee->ht_info->bCurrentHTSupport = false; - - ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS, - (u8 *)(&ieee->link_state)); - - ieee->link_state = MAC80211_LINKED; - ieee->link_change(ieee->dev); - - HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - rtllib_start_send_beacons(ieee); - - notify_wx_assoc_event(ieee); - netif_carrier_on(ieee->dev); - - mutex_unlock(&ieee->wx_mutex); -} - -inline void rtllib_start_ibss(struct rtllib_device *ieee) -{ - schedule_delayed_work(&ieee->start_ibss_wq, msecs_to_jiffies(150)); -} - /* this is called only in user context, with wx_mutex held */ static void rtllib_start_bss(struct rtllib_device *ieee) { @@ -2495,7 +2195,7 @@ static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee) return NULL; b = (struct rtllib_probe_response *)skb->data; - b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON); + b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON); return skb; } @@ -2510,7 +2210,7 @@ struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee) return NULL; b = (struct rtllib_probe_response *)skb->data; - b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; @@ -2521,31 +2221,28 @@ struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee) } EXPORT_SYMBOL(rtllib_get_beacon); -void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag, - u8 shutdown) +void rtllib_softmac_stop_protocol(struct rtllib_device *ieee) { rtllib_stop_scan_syncro(ieee); mutex_lock(&ieee->wx_mutex); - rtllib_stop_protocol(ieee, shutdown); + rtllib_stop_protocol(ieee); mutex_unlock(&ieee->wx_mutex); } EXPORT_SYMBOL(rtllib_softmac_stop_protocol); -void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown) +void rtllib_stop_protocol(struct rtllib_device *ieee) { if (!ieee->proto_started) return; - if (shutdown) { - ieee->proto_started = 0; - ieee->proto_stoppping = 1; - ieee->rtllib_ips_leave(ieee->dev); - } + ieee->proto_started = 0; + ieee->proto_stoppping = 1; + ieee->rtllib_ips_leave(ieee->dev); - rtllib_stop_send_beacons(ieee); del_timer_sync(&ieee->associate_timer); + mutex_unlock(&ieee->wx_mutex); cancel_delayed_work_sync(&ieee->associate_retry_wq); - cancel_delayed_work_sync(&ieee->start_ibss_wq); + mutex_lock(&ieee->wx_mutex); cancel_delayed_work_sync(&ieee->link_change_wq); rtllib_stop_scan(ieee); @@ -2558,10 +2255,9 @@ void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown) rtllib_disassociate(ieee); } - if (shutdown) { - RemoveAllTS(ieee); - ieee->proto_stoppping = 0; - } + RemoveAllTS(ieee); + ieee->proto_stoppping = 0; + kfree(ieee->assocreq_ies); ieee->assocreq_ies = NULL; ieee->assocreq_ies_len = 0; @@ -2570,7 +2266,7 @@ void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown) ieee->assocresp_ies_len = 0; } -void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag) +void rtllib_softmac_start_protocol(struct rtllib_device *ieee) { mutex_lock(&ieee->wx_mutex); rtllib_start_protocol(ieee); @@ -2618,12 +2314,6 @@ void rtllib_start_protocol(struct rtllib_device *ieee) case IW_MODE_INFRA: rtllib_start_bss(ieee); break; - case IW_MODE_ADHOC: - rtllib_start_ibss(ieee); - break; - case IW_MODE_MONITOR: - rtllib_start_monitor_mode(ieee); - break; } } @@ -2682,7 +2372,6 @@ int rtllib_softmac_init(struct rtllib_device *ieee) timer_setup(&ieee->beacon_timer, rtllib_send_beacon_cb, 0); INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq); - INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *)rtllib_start_ibss_wq); INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq); INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq); INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq); @@ -2703,15 +2392,11 @@ int rtllib_softmac_init(struct rtllib_device *ieee) void rtllib_softmac_free(struct rtllib_device *ieee) { - mutex_lock(&ieee->wx_mutex); - kfree(ieee->dot11d_info); - ieee->dot11d_info = NULL; del_timer_sync(&ieee->associate_timer); cancel_delayed_work_sync(&ieee->associate_retry_wq); cancel_delayed_work_sync(&ieee->associate_procedure_wq); cancel_delayed_work_sync(&ieee->softmac_scan_wq); - cancel_delayed_work_sync(&ieee->start_ibss_wq); cancel_delayed_work_sync(&ieee->hw_wakeup_wq); cancel_delayed_work_sync(&ieee->hw_sleep_wq); cancel_delayed_work_sync(&ieee->link_change_wq); @@ -2719,7 +2404,9 @@ void rtllib_softmac_free(struct rtllib_device *ieee) cancel_work_sync(&ieee->ips_leave_wq); cancel_work_sync(&ieee->wx_sync_scan_wq); cancel_work_sync(&ieee->ps_task); - mutex_unlock(&ieee->wx_mutex); + + kfree(ieee->dot11d_info); + ieee->dot11d_info = NULL; } static inline struct sk_buff * @@ -2737,7 +2424,7 @@ rtllib_disauth_skb(struct rtllib_network *beacon, skb_reserve(skb, ieee->tx_headroom); disauth = skb_put(skb, sizeof(struct rtllib_disauth)); - disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH); + disauth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH); disauth->header.duration_id = 0; ether_addr_copy(disauth->header.addr1, beacon->bssid); @@ -2764,7 +2451,7 @@ rtllib_disassociate_skb(struct rtllib_network *beacon, skb_reserve(skb, ieee->tx_headroom); disass = skb_put(skb, sizeof(struct rtllib_disassoc)); - disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC); + disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC); disass->header.duration_id = 0; ether_addr_copy(disass->header.addr1, beacon->bssid); @@ -2817,30 +2504,6 @@ u8 rtllib_ap_sec_type(struct rtllib_device *ieee) } } -static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) -{ - u8 OpMode; - u8 i; - bool bFilterOutNonAssociatedBSSID = false; - - rtllib->link_state = MAC80211_NOLINK; - - for (i = 0; i < 6; i++) - rtllib->current_network.bssid[i] = 0x55; - - rtllib->OpMode = RT_OP_MODE_NO_LINK; - rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID, - rtllib->current_network.bssid); - OpMode = RT_OP_MODE_NO_LINK; - rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode); - rtllib_stop_send_beacons(rtllib); - - bFilterOutNonAssociatedBSSID = false; - rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID, - (u8 *)(&bFilterOutNonAssociatedBSSID)); - notify_wx_assoc_event(rtllib); -} - static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, u8 asRsn) { @@ -2888,8 +2551,6 @@ bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn) rtllib->sta_wake_up(rtllib->dev); if (rtllib->link_state == MAC80211_LINKED) { - if (rtllib->iw_mode == IW_MODE_ADHOC) - rtllib_MgntDisconnectIBSS(rtllib); if (rtllib->iw_mode == IW_MODE_INFRA) rtllib_MgntDisconnectAP(rtllib, asRsn); } diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 0b690f0ffeef..f32584291704 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -50,12 +50,6 @@ int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a, } ieee->current_network.channel = fwrq->m; ieee->set_chan(ieee->dev, ieee->current_network.channel); - - if (ieee->iw_mode == IW_MODE_ADHOC) - if (ieee->link_state == MAC80211_LINKED) { - rtllib_stop_send_beacons(ieee); - rtllib_start_send_beacons(ieee); - } } ret = 0; @@ -140,7 +134,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee, } if (ifup) - rtllib_stop_protocol(ieee, true); + rtllib_stop_protocol(ieee); /* just to avoid to give inconsistent infos in the * get wx method. not really needed otherwise @@ -258,7 +252,6 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, mutex_lock(&ieee->wx_mutex); switch (wrqu->mode) { case IW_MODE_MONITOR: - case IW_MODE_ADHOC: case IW_MODE_INFRA: break; case IW_MODE_AUTO: @@ -284,7 +277,7 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, if (!ieee->proto_started) { ieee->iw_mode = wrqu->mode; } else { - rtllib_stop_protocol(ieee, true); + rtllib_stop_protocol(ieee); ieee->iw_mode = wrqu->mode; rtllib_start_protocol(ieee); } @@ -317,7 +310,6 @@ void rtllib_wx_sync_scan_wq(void *data) rtllib_sta_ps_send_null_frame(ieee, 1); rtllib_stop_all_queues(ieee); - rtllib_stop_send_beacons(ieee); ieee->link_state = MAC80211_LINKED_SCANNING; ieee->link_change(ieee->dev); /* wait for ps packet to be kicked out successfully */ @@ -325,7 +317,7 @@ void rtllib_wx_sync_scan_wq(void *data) ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); - if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht && + if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht && ieee->ht_info->bCurBW40MHz) { b40M = 1; chan_offset = ieee->ht_info->CurSTAExtChnlOffset; @@ -361,9 +353,6 @@ void rtllib_wx_sync_scan_wq(void *data) ieee->link_detect_info.NumRecvBcnInPeriod = 1; ieee->link_detect_info.NumRecvDataInPeriod = 1; } - if (ieee->iw_mode == IW_MODE_ADHOC) - rtllib_start_send_beacons(ieee); - rtllib_wake_all_queues(ieee); out: @@ -412,7 +401,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee, } if (proto_started) - rtllib_stop_protocol(ieee, true); + rtllib_stop_protocol(ieee); /* this is just to be sure that the GET wx callback * has consistent infos. not needed otherwise @@ -447,38 +436,6 @@ int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a, } EXPORT_SYMBOL(rtllib_wx_get_mode); -int rtllib_wx_set_rawtx(struct rtllib_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int *parms = (int *)extra; - int enable = (parms[0] > 0); - short prev = ieee->raw_tx; - - mutex_lock(&ieee->wx_mutex); - - if (enable) - ieee->raw_tx = 1; - else - ieee->raw_tx = 0; - - netdev_info(ieee->dev, "raw TX is %s\n", - ieee->raw_tx ? "enabled" : "disabled"); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - if (prev == 0 && ieee->raw_tx) - netif_carrier_on(ieee->dev); - - if (prev && ieee->raw_tx == 1) - netif_carrier_off(ieee->dev); - } - - mutex_unlock(&ieee->wx_mutex); - - return 0; -} -EXPORT_SYMBOL(rtllib_wx_set_rawtx); - int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 4199aee930f0..9bf679438ad1 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -268,12 +268,12 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, { struct rt_hi_throughput *ht_info = ieee->ht_info; struct tx_ts_record *pTxTs = NULL; - struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; if (rtllib_act_scanning(ieee, false)) return; - if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) + if (!ht_info->current_ht_support || !ht_info->enable_ht) return; if (!IsQoSDataFrame(skb->data)) return; @@ -289,7 +289,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) return; if (ht_info->bCurrentAMPDUEnable) { - if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) { netdev_info(ieee->dev, "%s: can't get TS\n", __func__); return; @@ -354,7 +354,7 @@ static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee, tcb_desc->bUseShortGI = false; - if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) + if (!ht_info->current_ht_support || !ht_info->enable_ht) return; if (ht_info->forced_short_gi) { @@ -375,7 +375,7 @@ static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, tcb_desc->bPacketBW = false; - if (!ht_info->bCurrentHTSupport || !ht_info->enable_ht) + if (!ht_info->current_ht_support || !ht_info->enable_ht) return; if (tcb_desc->bMulticast || tcb_desc->bBroadcast) @@ -438,7 +438,7 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, tcb_desc->rts_rate = MGN_24M; break; } - if (ht_info->bCurrentHTSupport && ht_info->enable_ht) { + if (ht_info->current_ht_support && ht_info->enable_ht) { u8 HTOpMode = ht_info->current_op_mode; if ((ht_info->bCurBW40MHz && (HTOpMode == 2 || @@ -482,8 +482,7 @@ static void rtllib_txrate_selectmode(struct rtllib_device *ieee, tcb_desc->tx_use_drv_assinged_rate = true; if (!tcb_desc->tx_dis_rate_fallback || !tcb_desc->tx_use_drv_assinged_rate) { - if (ieee->iw_mode == IW_MODE_INFRA || - ieee->iw_mode == IW_MODE_ADHOC) + if (ieee->iw_mode == IW_MODE_INFRA) tcb_desc->ratr_index = 0; } } @@ -496,13 +495,13 @@ static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, if (is_multicast_ether_addr(dst)) return 0; if (IsQoSDataFrame(skb->data)) { - struct tx_ts_record *pTS = NULL; + struct tx_ts_record *ts = NULL; - if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + if (!rtllib_get_ts(ieee, (struct ts_common_info **)(&ts), dst, skb->priority, TX_DIR, true)) return 0; - seqnum = pTS->TxCurSeq; - pTS->TxCurSeq = (pTS->TxCurSeq + 1) % 4096; + seqnum = ts->TxCurSeq; + ts->TxCurSeq = (ts->TxCurSeq + 1) % 4096; return seqnum; } return 0; @@ -544,17 +543,17 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) struct rtllib_device *ieee = (struct rtllib_device *) netdev_priv_rsl(dev); struct rtllib_txb *txb = NULL; - struct rtllib_hdr_3addrqos *frag_hdr; + struct ieee80211_qos_hdr *frag_hdr; int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; unsigned long flags; struct net_device_stats *stats = &ieee->stats; int ether_type = 0, encrypt; int bytes, fc, qos_ctl = 0, hdr_len; struct sk_buff *skb_frag; - struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */ + struct ieee80211_qos_hdr header = { /* Ensure zero initialized */ .duration_id = 0, - .seq_ctl = 0, - .qos_ctl = 0 + .seq_ctrl = 0, + .qos_ctrl = 0 }; int qos_activated = ieee->current_network.qos_data.active; u8 dest[ETH_ALEN]; @@ -577,297 +576,271 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) goto success; } - if (likely(ieee->raw_tx == 0)) { - if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", - skb->len); - goto success; - } - /* Save source and destination addresses */ - ether_addr_copy(dest, skb->data); - ether_addr_copy(src, skb->data + ETH_ALEN); + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { + netdev_warn(ieee->dev, "skb too small (%d).\n", + skb->len); + goto success; + } + /* Save source and destination addresses */ + ether_addr_copy(dest, skb->data); + ether_addr_copy(src, skb->data + ETH_ALEN); - memset(skb->cb, 0, sizeof(skb->cb)); - ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, - "Could not allocate TXB\n"); - goto failed; - } - - txb->encrypted = 0; - txb->payload_size = cpu_to_le16(skb->len); - skb_put_data(txb->fragments[0], skb->data, skb->len); - - goto success; - } - - if (skb->len > 282) { - if (ether_type == ETH_P_IP) { - const struct iphdr *ip = (struct iphdr *) - ((u8 *)skb->data + 14); - if (ip->protocol == IPPROTO_UDP) { - struct udphdr *udp; - - udp = (struct udphdr *)((u8 *)ip + - (ip->ihl << 2)); - if (((((u8 *)udp)[1] == 68) && - (((u8 *)udp)[3] == 67)) || - ((((u8 *)udp)[1] == 67) && - (((u8 *)udp)[3] == 68))) { - bdhcp = true; - ieee->LPSDelayCnt = 200; - } - } - } else if (ether_type == ETH_P_ARP) { - netdev_info(ieee->dev, - "=================>DHCP Protocol start tx ARP pkt!!\n"); - bdhcp = true; - ieee->LPSDelayCnt = - ieee->current_network.tim.tim_count; - } - } - - skb->priority = rtllib_classify(skb, IsAmsdu); - crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; - encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops; - if (!encrypt && ieee->ieee802_1x && - ieee->drop_unencrypted && ether_type != ETH_P_PAE) { - stats->tx_dropped++; - goto success; - } - if (crypt && !encrypt && ether_type == ETH_P_PAE) { - struct eapol *eap = (struct eapol *)(skb->data + - sizeof(struct ethhdr) - SNAP_SIZE - - sizeof(u16)); - netdev_dbg(ieee->dev, - "TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - - /* Advance the SKB to the start of the payload */ - skb_pull(skb, sizeof(struct ethhdr)); - - /* Determine total amount of storage required for TXB packets */ - bytes = skb->len + SNAP_SIZE + sizeof(u16); - - if (encrypt) - fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP; - else - fc = RTLLIB_FTYPE_DATA; - - if (qos_activated) - fc |= RTLLIB_STYPE_QOS_DATA; - else - fc |= RTLLIB_STYPE_DATA; - - if (ieee->iw_mode == IW_MODE_INFRA) { - fc |= RTLLIB_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, - * Addr3 = DA - */ - ether_addr_copy(header.addr1, - ieee->current_network.bssid); - ether_addr_copy(header.addr2, src); - if (IsAmsdu) - ether_addr_copy(header.addr3, - ieee->current_network.bssid); - else - ether_addr_copy(header.addr3, dest); - } else if (ieee->iw_mode == IW_MODE_ADHOC) { - /* not From/To DS: Addr1 = DA, Addr2 = SA, - * Addr3 = BSSID - */ - ether_addr_copy(header.addr1, dest); - ether_addr_copy(header.addr2, src); - ether_addr_copy(header.addr3, - ieee->current_network.bssid); - } - - bIsMulticast = is_multicast_ether_addr(header.addr1); - - header.frame_ctl = cpu_to_le16(fc); - - /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) - */ - if (bIsMulticast) { - frag_size = MAX_FRAG_THRESHOLD; - qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; - } else { - frag_size = ieee->fts; - qos_ctl = 0; - } - - if (qos_activated) { - hdr_len = RTLLIB_3ADDR_LEN + 2; - - /* in case we are a client verify acm is not set for this ac */ - while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { - netdev_info(ieee->dev, "skb->priority = %x\n", - skb->priority); - if (wme_downgrade_ac(skb)) - break; - netdev_info(ieee->dev, "converted skb->priority = %x\n", - skb->priority); - } - - qos_ctl |= skb->priority; - header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); - - } else { - hdr_len = RTLLIB_3ADDR_LEN; - } - /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account - * for it when determining the amount of payload space. - */ - bytes_per_frag = frag_size - hdr_len; - if (ieee->config & - (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) - bytes_per_frag -= RTLLIB_FCS_LEN; - - /* Each fragment may need to have room for encrypting - * pre/postfix - */ - if (encrypt) { - bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + - crypt->ops->extra_mpdu_postfix_len + - crypt->ops->extra_msdu_prefix_len + - crypt->ops->extra_msdu_postfix_len; - } - /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment - */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; - - /* When we allocate the TXB we allocate enough space for the - * reserve and full fragment bytes (bytes_per_frag doesn't - * include prefix, postfix, header, FCS, etc.) - */ - txb = rtllib_alloc_txb(nr_frags, frag_size + - ieee->tx_headroom, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - txb->encrypted = encrypt; - txb->payload_size = cpu_to_le16(bytes); - - if (qos_activated) - txb->queue_index = UP2AC(skb->priority); - else - txb->queue_index = WME_AC_BE; - - for (i = 0; i < nr_frags; i++) { - skb_frag = txb->fragments[i]; - tcb_desc = (struct cb_desc *)(skb_frag->cb + - MAX_DEV_ADDR_SIZE); - if (qos_activated) { - skb_frag->priority = skb->priority; - tcb_desc->queue_index = UP2AC(skb->priority); - } else { - skb_frag->priority = WME_AC_BE; - tcb_desc->queue_index = WME_AC_BE; - } - skb_reserve(skb_frag, ieee->tx_headroom); - - if (encrypt) { - if (ieee->hwsec_active) - tcb_desc->bHwSec = 1; - else - tcb_desc->bHwSec = 0; - skb_reserve(skb_frag, - crypt->ops->extra_mpdu_prefix_len + - crypt->ops->extra_msdu_prefix_len); - } else { - tcb_desc->bHwSec = 0; - } - frag_hdr = skb_put_data(skb_frag, &header, hdr_len); - - /* If this is not the last fragment, then add the - * MOREFRAGS bit to the frame control - */ - if (i != nr_frags - 1) { - frag_hdr->frame_ctl = cpu_to_le16(fc | - RTLLIB_FCTL_MOREFRAGS); - bytes = bytes_per_frag; - - } else { - /* The last fragment has the remaining length */ - bytes = bytes_last_frag; - } - if ((qos_activated) && (!bIsMulticast)) { - frag_hdr->seq_ctl = - cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, - header.addr1)); - frag_hdr->seq_ctl = - cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl) << 4 | i); - } else { - frag_hdr->seq_ctl = - cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); - } - /* Put a SNAP header on the first fragment */ - if (i == 0) { - rtllib_put_snap(skb_put(skb_frag, - SNAP_SIZE + - sizeof(u16)), ether_type); - bytes -= SNAP_SIZE + sizeof(u16); - } - - skb_put_data(skb_frag, skb->data, bytes); - - /* Advance the SKB... */ - skb_pull(skb, bytes); - - /* Encryption routine will move the header forward in - * order to insert the IV between the header and the - * payload - */ - if (encrypt) - rtllib_encrypt_fragment(ieee, skb_frag, - hdr_len); - if (ieee->config & - (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) - skb_put(skb_frag, 4); - } - - if ((qos_activated) && (!bIsMulticast)) { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; - } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - } else { - if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", - skb->len); - goto success; - } + memset(skb->cb, 0, sizeof(skb->cb)); + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); + if (ieee->iw_mode == IW_MODE_MONITOR) { txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); - if (!txb) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); + if (unlikely(!txb)) { + netdev_warn(ieee->dev, + "Could not allocate TXB\n"); goto failed; } txb->encrypted = 0; txb->payload_size = cpu_to_le16(skb->len); skb_put_data(txb->fragments[0], skb->data, skb->len); + + goto success; + } + + if (skb->len > 282) { + if (ether_type == ETH_P_IP) { + const struct iphdr *ip = (struct iphdr *) + ((u8 *)skb->data + 14); + if (ip->protocol == IPPROTO_UDP) { + struct udphdr *udp; + + udp = (struct udphdr *)((u8 *)ip + + (ip->ihl << 2)); + if (((((u8 *)udp)[1] == 68) && + (((u8 *)udp)[3] == 67)) || + ((((u8 *)udp)[1] == 67) && + (((u8 *)udp)[3] == 68))) { + bdhcp = true; + ieee->LPSDelayCnt = 200; + } + } + } else if (ether_type == ETH_P_ARP) { + netdev_info(ieee->dev, + "=================>DHCP Protocol start tx ARP pkt!!\n"); + bdhcp = true; + ieee->LPSDelayCnt = + ieee->current_network.tim.tim_count; + } + } + + skb->priority = rtllib_classify(skb, IsAmsdu); + crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops; + if (!encrypt && ieee->ieee802_1x && + ieee->drop_unencrypted && ether_type != ETH_P_PAE) { + stats->tx_dropped++; + goto success; + } + if (crypt && !encrypt && ether_type == ETH_P_PAE) { + struct eapol *eap = (struct eapol *)(skb->data + + sizeof(struct ethhdr) - SNAP_SIZE - + sizeof(u16)); + netdev_dbg(ieee->dev, + "TX: IEEE 802.11 EAPOL frame: %s\n", + eap_get_type(eap->type)); + } + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + if (encrypt) + fc = RTLLIB_FTYPE_DATA | IEEE80211_FCTL_PROTECTED; + else + fc = RTLLIB_FTYPE_DATA; + + if (qos_activated) + fc |= IEEE80211_STYPE_QOS_DATA; + else + fc |= IEEE80211_STYPE_DATA; + + if (ieee->iw_mode == IW_MODE_INFRA) { + fc |= IEEE80211_FCTL_TODS; + /* To DS: Addr1 = BSSID, Addr2 = SA, + * Addr3 = DA + */ + ether_addr_copy(header.addr1, + ieee->current_network.bssid); + ether_addr_copy(header.addr2, src); + if (IsAmsdu) + ether_addr_copy(header.addr3, + ieee->current_network.bssid); + else + ether_addr_copy(header.addr3, dest); + } + + bIsMulticast = is_multicast_ether_addr(header.addr1); + + header.frame_control = cpu_to_le16(fc); + + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) + */ + if (bIsMulticast) { + frag_size = MAX_FRAG_THRESHOLD; + qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; + } else { + frag_size = ieee->fts; + qos_ctl = 0; + } + + if (qos_activated) { + hdr_len = RTLLIB_3ADDR_LEN + 2; + + /* in case we are a client verify acm is not set for this ac */ + while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { + netdev_info(ieee->dev, "skb->priority = %x\n", + skb->priority); + if (wme_downgrade_ac(skb)) + break; + netdev_info(ieee->dev, "converted skb->priority = %x\n", + skb->priority); + } + + qos_ctl |= skb->priority; + header.qos_ctrl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); + + } else { + hdr_len = RTLLIB_3ADDR_LEN; + } + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account + * for it when determining the amount of payload space. + */ + bytes_per_frag = frag_size - hdr_len; + if (ieee->config & + (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) + bytes_per_frag -= RTLLIB_FCS_LEN; + + /* Each fragment may need to have room for encrypting + * pre/postfix + */ + if (encrypt) { + bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + + crypt->ops->extra_mpdu_postfix_len + + crypt->ops->extra_msdu_prefix_len + + crypt->ops->extra_msdu_postfix_len; + } + /* Number of fragments is the total bytes_per_frag / + * payload_per_fragment + */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + + /* When we allocate the TXB we allocate enough space for the + * reserve and full fragment bytes (bytes_per_frag doesn't + * include prefix, postfix, header, FCS, etc.) + */ + txb = rtllib_alloc_txb(nr_frags, frag_size + + ieee->tx_headroom, GFP_ATOMIC); + if (unlikely(!txb)) { + netdev_warn(ieee->dev, "Could not allocate TXB\n"); + goto failed; + } + txb->encrypted = encrypt; + txb->payload_size = cpu_to_le16(bytes); + + if (qos_activated) + txb->queue_index = UP2AC(skb->priority); + else + txb->queue_index = WME_AC_BE; + + for (i = 0; i < nr_frags; i++) { + skb_frag = txb->fragments[i]; + tcb_desc = (struct cb_desc *)(skb_frag->cb + + MAX_DEV_ADDR_SIZE); + if (qos_activated) { + skb_frag->priority = skb->priority; + tcb_desc->queue_index = UP2AC(skb->priority); + } else { + skb_frag->priority = WME_AC_BE; + tcb_desc->queue_index = WME_AC_BE; + } + skb_reserve(skb_frag, ieee->tx_headroom); + + if (encrypt) { + if (ieee->hwsec_active) + tcb_desc->bHwSec = 1; + else + tcb_desc->bHwSec = 0; + skb_reserve(skb_frag, + crypt->ops->extra_mpdu_prefix_len + + crypt->ops->extra_msdu_prefix_len); + } else { + tcb_desc->bHwSec = 0; + } + frag_hdr = skb_put_data(skb_frag, &header, hdr_len); + + /* If this is not the last fragment, then add the + * MOREFRAGS bit to the frame control + */ + if (i != nr_frags - 1) { + frag_hdr->frame_control = cpu_to_le16(fc | + IEEE80211_FCTL_MOREFRAGS); + bytes = bytes_per_frag; + + } else { + /* The last fragment has the remaining length */ + bytes = bytes_last_frag; + } + if ((qos_activated) && (!bIsMulticast)) { + frag_hdr->seq_ctrl = + cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, + header.addr1)); + frag_hdr->seq_ctrl = + cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctrl) << 4 | i); + } else { + frag_hdr->seq_ctrl = + cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); + } + /* Put a SNAP header on the first fragment */ + if (i == 0) { + rtllib_put_snap(skb_put(skb_frag, + SNAP_SIZE + + sizeof(u16)), ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } + + skb_put_data(skb_frag, skb->data, bytes); + + /* Advance the SKB... */ + skb_pull(skb, bytes); + + /* Encryption routine will move the header forward in + * order to insert the IV between the header and the + * payload + */ + if (encrypt) + rtllib_encrypt_fragment(ieee, skb_frag, + hdr_len); + if (ieee->config & + (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) + skb_put(skb_frag, 4); + } + + if ((qos_activated) && (!bIsMulticast)) { + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; + else + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; + } else { + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; } success: diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index e9469bfef3dd..a37250de7ba3 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -29,7 +29,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, struct iw_request_info *info) { char custom[MAX_CUSTOM_LEN]; - char proto_name[IFNAMSIZ]; + char proto_name[6]; char *pname = proto_name; char *p; struct iw_event iwe; diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig deleted file mode 100644 index f3b112a058ca..000000000000 --- a/drivers/staging/rtl8192u/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config RTL8192U - tristate "RealTek RTL8192U Wireless LAN NIC driver" - depends on PCI && WLAN && USB - depends on m - select WIRELESS_EXT - select WEXT_PRIV - select CRC32 - select CRYPTO - select CRYPTO_AES - select CRYPTO_CCM - select CRYPTO_LIB_ARC4 diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile deleted file mode 100644 index d32dfd89a606..000000000000 --- a/drivers/staging/rtl8192u/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -NIC_SELECT = RTL8192U - -ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y -ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX -ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO - -r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ - r8190_rtl8256.o r819xU_phy.o r819xU_firmware.o \ - r819xU_cmdpkt.o r8192U_dm.o r819xU_firmware_img.o \ - r8192U_debugfs.o \ - ieee80211/ieee80211_crypt.o \ - ieee80211/ieee80211_crypt_tkip.o \ - ieee80211/ieee80211_crypt_ccmp.o \ - ieee80211/ieee80211_crypt_wep.o \ - ieee80211/ieee80211_rx.o \ - ieee80211/ieee80211_softmac.o \ - ieee80211/ieee80211_tx.o \ - ieee80211/ieee80211_wx.o \ - ieee80211/ieee80211_module.o \ - ieee80211/ieee80211_softmac_wx.o \ - ieee80211/rtl819x_HTProc.o \ - ieee80211/rtl819x_TSProc.o \ - ieee80211/rtl819x_BAProc.o \ - ieee80211/dot11d.o - -obj-$(CONFIG_RTL8192U) += r8192u_usb.o diff --git a/drivers/staging/rtl8192u/TODO b/drivers/staging/rtl8192u/TODO deleted file mode 100644 index ab9d5d145b3b..000000000000 --- a/drivers/staging/rtl8192u/TODO +++ /dev/null @@ -1,16 +0,0 @@ -To-do list: - -* Correct the coding style according to Linux guidelines; please read the document - at https://www.kernel.org/doc/html/latest/process/coding-style.html. -* Remove unnecessary debugging/printing macros; for those that are still needed - use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). -* Remove dead code such as unusued functions, variables, fields, etc.. -* Use in-kernel API and remove unnecessary wrappers where possible. -* Fix bugs due to code that sleeps in atomic context. -* Remove the HAL layer and migrate its functionality into the relevant parts of - the driver. -* Switch to use LIB80211. -* Switch to use MAC80211. -* Switch to use CFG80211. -* Improve the error handling of various functions, particularly those that use - existing kernel APIs. diff --git a/drivers/staging/rtl8192u/authors b/drivers/staging/rtl8192u/authors deleted file mode 100644 index 0fab11228b48..000000000000 --- a/drivers/staging/rtl8192u/authors +++ /dev/null @@ -1 +0,0 @@ -Andrea Merello diff --git a/drivers/staging/rtl8192u/changes b/drivers/staging/rtl8192u/changes deleted file mode 100644 index 0485d6eec7b5..000000000000 --- a/drivers/staging/rtl8192u/changes +++ /dev/null @@ -1,4 +0,0 @@ -v 0.1 - -First version. -This is based on the rtl8180-sa2400 pre-0.22-CVS code.. diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c deleted file mode 100644 index ddaf66fa0f93..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Implement 802.11d. */ - -#include "dot11d.h" - -void rtl8192u_dot11d_init(struct ieee80211_device *ieee) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); - - dot11d_info->dot11d_enabled = false; - - dot11d_info->state = DOT11D_STATE_NONE; - dot11d_info->country_ie_len = 0; - memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); - RESET_CIE_WATCHDOG(ieee); -} -EXPORT_SYMBOL(rtl8192u_dot11d_init); - -/* Reset to the state as we are just entering a regulatory domain. */ -void dot11d_reset(struct ieee80211_device *ieee) -{ - u32 i; - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); - /* Clear old channel map */ - memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); - /* Set new channel map */ - for (i = 1; i <= 11; i++) - (dot11d_info->channel_map)[i] = 1; - - for (i = 12; i <= 14; i++) - (dot11d_info->channel_map)[i] = 2; - - dot11d_info->state = DOT11D_STATE_NONE; - dot11d_info->country_ie_len = 0; - RESET_CIE_WATCHDOG(ieee); -} -EXPORT_SYMBOL(dot11d_reset); - -/* - * Update country IE from Beacon or Probe Resopnse and configure PHY for - * operation in the regulatory domain. - * - * TODO: Configure Tx power. - * Assumption: - * 1. IS_DOT11D_ENABLE() is TRUE. - * 2. Input IE is an valid one. - */ -void dot11d_update_country_ie(struct ieee80211_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - u8 i, j, NumTriples, MaxChnlNum; - struct chnl_txpower_triple *pTriple; - - memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); - memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER + 1); - MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */ - pTriple = (struct chnl_txpower_triple *)(pCoutryIe + 3); - for (i = 0; i < NumTriples; i++) { - if (MaxChnlNum >= pTriple->first_channel) { - /* It is not in a monotonically increasing order, so - * stop processing. - */ - netdev_err(dev->dev, "%s: Invalid country IE, skip it 1\n", __func__); - return; - } - if (MAX_CHANNEL_NUMBER < (pTriple->first_channel + pTriple->num_channels)) { - /* It is not a valid set of channel id, so stop - * processing. - */ - netdev_err(dev->dev, "%s: Invalid country IE, skip it 2\n", __func__); - return; - } - - for (j = 0; j < pTriple->num_channels; j++) { - dot11d_info->channel_map[pTriple->first_channel + j] = 1; - dot11d_info->max_tx_pwr_dbm_list[pTriple->first_channel + j] = pTriple->max_tx_pwr_dbm; - MaxChnlNum = pTriple->first_channel + j; - } - - pTriple = (struct chnl_txpower_triple *)((u8 *)pTriple + 3); - } - netdev_info(dev->dev, "Channel List:"); - for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) - if (dot11d_info->channel_map[i] > 0) - netdev_info(dev->dev, " %d", i); - netdev_info(dev->dev, "\n"); - - UPDATE_CIE_SRC(dev, pTaddr); - - dot11d_info->country_ie_len = CoutryIeLen; - memcpy(dot11d_info->country_ie_buf, pCoutryIe, CoutryIeLen); - dot11d_info->state = DOT11D_STATE_LEARNED; -} -EXPORT_SYMBOL(dot11d_update_country_ie); - -u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 Channel) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - u8 MaxTxPwrInDbm = 255; - - if (Channel > MAX_CHANNEL_NUMBER) { - netdev_err(dev->dev, "%s: Invalid Channel\n", __func__); - return MaxTxPwrInDbm; - } - if (dot11d_info->channel_map[Channel]) - MaxTxPwrInDbm = dot11d_info->max_tx_pwr_dbm_list[Channel]; - - return MaxTxPwrInDbm; -} -EXPORT_SYMBOL(dot11d_get_max_tx_pwr_in_dbm); - -void dot11d_scan_complete(struct ieee80211_device *dev) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - - switch (dot11d_info->state) { - case DOT11D_STATE_LEARNED: - dot11d_info->state = DOT11D_STATE_DONE; - break; - - case DOT11D_STATE_DONE: - if (GET_CIE_WATCHDOG(dev) == 0) { - /* Reset country IE if previous one is gone. */ - dot11d_reset(dev); - } - break; - case DOT11D_STATE_NONE: - break; - } -} -EXPORT_SYMBOL(dot11d_scan_complete); - -int is_legal_channel(struct ieee80211_device *dev, u8 channel) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - - if (channel > MAX_CHANNEL_NUMBER) { - netdev_err(dev->dev, "%s: Invalid Channel\n", __func__); - return 0; - } - if (dot11d_info->channel_map[channel] > 0) - return 1; - return 0; -} -EXPORT_SYMBOL(is_legal_channel); - -int to_legal_channel(struct ieee80211_device *dev, u8 channel) -{ - struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); - u8 default_chn = 0; - u32 i = 0; - - for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) { - if (dot11d_info->channel_map[i] > 0) { - default_chn = i; - break; - } - } - - if (channel > MAX_CHANNEL_NUMBER) { - netdev_err(dev->dev, "%s: Invalid Channel\n", __func__); - return default_chn; - } - - if (dot11d_info->channel_map[channel] > 0) - return channel; - - return default_chn; -} -EXPORT_SYMBOL(to_legal_channel); diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.h b/drivers/staging/rtl8192u/ieee80211/dot11d.h deleted file mode 100644 index 8b485fa18089..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __INC_DOT11D_H -#define __INC_DOT11D_H - -#include "ieee80211.h" - -struct chnl_txpower_triple { - u8 first_channel; - u8 num_channels; - u8 max_tx_pwr_dbm; -}; - -enum dot11d_state { - DOT11D_STATE_NONE = 0, - DOT11D_STATE_LEARNED, - DOT11D_STATE_DONE, -}; - -struct rt_dot11d_info { - u16 country_ie_len; /* > 0 if country_ie_buf[] contains valid country information element. */ - - /* country_ie_src_addr u16 aligned for comparison and copy */ - u8 country_ie_src_addr[ETH_ALEN]; /* Source AP of the country IE. */ - u8 country_ie_buf[MAX_IE_LEN]; - u8 country_ie_watchdog; - - u8 channel_map[MAX_CHANNEL_NUMBER + 1]; /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */ - u8 max_tx_pwr_dbm_list[MAX_CHANNEL_NUMBER + 1]; - - enum dot11d_state state; - u8 dot11d_enabled; /* dot11MultiDomainCapabilityEnabled */ -}; - -#define GET_DOT11D_INFO(ieee_dev) ((struct rt_dot11d_info *)((ieee_dev)->dot11d_info)) - -#define IS_DOT11D_ENABLE(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->dot11d_enabled) -#define IS_COUNTRY_IE_VALID(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_len > 0) - -#define IS_EQUAL_CIE_SRC(ieee_dev, addr) ether_addr_equal(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr) -#define UPDATE_CIE_SRC(ieee_dev, addr) ether_addr_copy(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr) - -#define GET_CIE_WATCHDOG(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_watchdog) -#define RESET_CIE_WATCHDOG(ieee_dev) (GET_CIE_WATCHDOG(ieee_dev) = 0) -#define UPDATE_CIE_WATCHDOG(ieee_dev) (++GET_CIE_WATCHDOG(ieee_dev)) - -void rtl8192u_dot11d_init(struct ieee80211_device *dev); -void dot11d_reset(struct ieee80211_device *dev); -void dot11d_update_country_ie(struct ieee80211_device *dev, - u8 *addr, - u16 coutry_ie_len, - u8 *coutry_ie); -u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 channel); -void dot11d_scan_complete(struct ieee80211_device *dev); -int is_legal_channel(struct ieee80211_device *dev, u8 channel); -int to_legal_channel(struct ieee80211_device *dev, u8 channel); - -#endif /* #ifndef __INC_DOT11D_H */ diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h deleted file mode 100644 index 694d1b18f81c..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ /dev/null @@ -1,2385 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 - * remains copyright by the original authors - * - * Portions of the merged code are based on Host AP (software wireless - * LAN access point) driver for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * Copyright (c) 2004, Intel Corporation - * - * Modified for Realtek's wi-fi cards by Andrea Merello - * - */ -#ifndef IEEE80211_H -#define IEEE80211_H -#include /* ETH_ALEN */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "rtl819x_HT.h" -#include "rtl819x_BA.h" -#include "rtl819x_TS.h" - - -#ifndef IW_MODE_MONITOR -#define IW_MODE_MONITOR 6 -#endif - -#ifndef IWEVCUSTOM -#define IWEVCUSTOM 0x8c02 -#endif - -#define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 -#define KEY_TYPE_TKIP 0x2 -#define KEY_TYPE_CCMP 0x4 -#define KEY_TYPE_WEP104 0x5 - -/* added for rtl819x tx procedure */ -#define MAX_QUEUE_SIZE 0x10 - -// -// 8190 queue mapping -// -#define BK_QUEUE 0 -#define BE_QUEUE 1 -#define VI_QUEUE 2 -#define VO_QUEUE 3 -#define HCCA_QUEUE 4 -#define TXCMD_QUEUE 5 -#define MGNT_QUEUE 6 -#define HIGH_QUEUE 7 -#define BEACON_QUEUE 8 - -#define LOW_QUEUE BE_QUEUE -#define NORMAL_QUEUE MGNT_QUEUE - -//added by amy for ps -#define SWRF_TIMEOUT 50 - -//added by amy for LEAP related -#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. -#define SUPPORT_CKIP_MIC 0x08 // bit3 -#define SUPPORT_CKIP_PK 0x10 // bit4 -/* defined for skb cb field */ -/* At most 28 byte */ -struct cb_desc { - /* Tx Desc Related flags (8-9) */ - u8 bLastIniPkt:1; - u8 bCmdOrInit:1; - u8 bFirstSeg:1; - u8 bLastSeg:1; - u8 bEncrypt:1; - u8 bTxDisableRateFallBack:1; - u8 bTxUseDriverAssingedRate:1; - u8 bHwSec:1; //indicate whether use Hw security. WB - - u8 reserved1; - - /* Tx Firmware Relaged flags (10-11)*/ - u8 bCTSEnable:1; - u8 bRTSEnable:1; - u8 bUseShortGI:1; - u8 bUseShortPreamble:1; - u8 bTxEnableFwCalcDur:1; - u8 bAMPDUEnable:1; - u8 bRTSSTBC:1; - u8 RTSSC:1; - - u8 bRTSBW:1; - u8 bPacketBW:1; - u8 bRTSUseShortPreamble:1; - u8 bRTSUseShortGI:1; - u8 bMulticast:1; - u8 bBroadcast:1; - //u8 reserved2:2; - u8 drv_agg_enable:1; - u8 reserved2:1; - - /* Tx Desc related element(12-19) */ - u8 rata_index; - u8 queue_index; - //u8 reserved3; - //u8 reserved4; - u16 txbuf_size; - //u8 reserved5; - u8 RATRIndex; - u8 reserved6; - u8 reserved7; - u8 reserved8; - - /* Tx firmware related element(20-27) */ - u8 data_rate; - u8 rts_rate; - u8 ampdu_factor; - u8 ampdu_density; - //u8 reserved9; - //u8 reserved10; - //u8 reserved11; - u8 DrvAggrNum; - u16 pkt_size; - u8 reserved12; -}; - -/*--------------------------Define -------------------------------------------*/ -#define MGN_1M 0x02 -#define MGN_2M 0x04 -#define MGN_5_5M 0x0b -#define MGN_11M 0x16 - -#define MGN_6M 0x0c -#define MGN_9M 0x12 -#define MGN_12M 0x18 -#define MGN_18M 0x24 -#define MGN_24M 0x30 -#define MGN_36M 0x48 -#define MGN_48M 0x60 -#define MGN_54M 0x6c - -#define MGN_MCS0 0x80 -#define MGN_MCS1 0x81 -#define MGN_MCS2 0x82 -#define MGN_MCS3 0x83 -#define MGN_MCS4 0x84 -#define MGN_MCS5 0x85 -#define MGN_MCS6 0x86 -#define MGN_MCS7 0x87 -#define MGN_MCS8 0x88 -#define MGN_MCS9 0x89 -#define MGN_MCS10 0x8a -#define MGN_MCS11 0x8b -#define MGN_MCS12 0x8c -#define MGN_MCS13 0x8d -#define MGN_MCS14 0x8e -#define MGN_MCS15 0x8f - -#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A || \ - priv->ieee80211->current_network.mode == IEEE_N_24G || \ - priv->ieee80211->current_network.mode == IEEE_N_5G) ? \ - 16 : 10) - -#define MGMT_QUEUE_NUM 5 - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -//It should consistent with the driver_XXX.c -// David, 2006.9.26 -#define IEEE_PARAM_WPAX_SELECT 7 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_PROTO_WPA 1 -#define IEEE_PROTO_RSN 2 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_WPAX_USEGROUP 0 -#define IEEE_WPAX_WEP40 1 -#define IEEE_WPAX_TKIP 2 -#define IEEE_WPAX_WRAP 3 -#define IEEE_WPAX_CCMP 4 -#define IEEE_WPAX_WEP104 5 - -#define IEEE_KEY_MGMT_IEEE8021X 1 -#define IEEE_KEY_MGMT_PSK 2 - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -#define MAX_IE_LEN 0xff - -// added for kernel conflict -#define ieee80211_wake_queue ieee80211_wake_queue_rsl -#define ieee80211_stop_queue ieee80211_stop_queue_rsl -#define notify_wx_assoc_event notify_wx_assoc_event_rsl -#define SendDisassociation SendDisassociation_rsl - - -struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[]; - } wpa_ie; - struct{ - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[]; - } crypt; - } u; -}; - - -// linux under 2.6.9 release may not support it, so modify it for common use -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - * 6.2.1.1.2. - * - * The figure in section 7.1.2 suggests a body size of up to 2312 - * bytes is allowed, which is a bit confusing, I suspect this - * represents the 2304 bytes of real data, plus a possible 8 bytes of - * WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) - */ -#define IEEE80211_1ADDR_LEN 10 -#define IEEE80211_2ADDR_LEN 16 -#define IEEE80211_3ADDR_LEN 24 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_FCS_LEN 4 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - - -/* Frame control field constants */ -#define IEEE80211_FCTL_VERS 0x0003 -#define IEEE80211_FCTL_FTYPE 0x000c -#define IEEE80211_FCTL_STYPE 0x00f0 -#define IEEE80211_FCTL_FRAMETYPE 0x00fc -#define IEEE80211_FCTL_TODS 0x0100 -#define IEEE80211_FCTL_FROMDS 0x0200 -#define IEEE80211_FCTL_DSTODS 0x0300 //added by david -#define IEEE80211_FCTL_MOREFRAGS 0x0400 -#define IEEE80211_FCTL_RETRY 0x0800 -#define IEEE80211_FCTL_PM 0x1000 -#define IEEE80211_FCTL_MOREDATA 0x2000 -#define IEEE80211_FCTL_WEP 0x4000 -#define IEEE80211_FCTL_ORDER 0x8000 - -#define IEEE80211_FTYPE_MGMT 0x0000 -#define IEEE80211_FTYPE_CTL 0x0004 -#define IEEE80211_FTYPE_DATA 0x0008 - -/* management */ -#define IEEE80211_STYPE_ASSOC_REQ 0x0000 -#define IEEE80211_STYPE_ASSOC_RESP 0x0010 -#define IEEE80211_STYPE_REASSOC_REQ 0x0020 -#define IEEE80211_STYPE_REASSOC_RESP 0x0030 -#define IEEE80211_STYPE_PROBE_REQ 0x0040 -#define IEEE80211_STYPE_PROBE_RESP 0x0050 -#define IEEE80211_STYPE_BEACON 0x0080 -#define IEEE80211_STYPE_ATIM 0x0090 -#define IEEE80211_STYPE_DISASSOC 0x00A0 -#define IEEE80211_STYPE_AUTH 0x00B0 -#define IEEE80211_STYPE_DEAUTH 0x00C0 -#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 - -/* control */ -#define IEEE80211_STYPE_PSPOLL 0x00A0 -#define IEEE80211_STYPE_RTS 0x00B0 -#define IEEE80211_STYPE_CTS 0x00C0 -#define IEEE80211_STYPE_ACK 0x00D0 -#define IEEE80211_STYPE_CFEND 0x00E0 -#define IEEE80211_STYPE_CFENDACK 0x00F0 -#define IEEE80211_STYPE_BLOCKACK 0x0094 - -/* data */ -#define IEEE80211_STYPE_DATA 0x0000 -#define IEEE80211_STYPE_DATA_CFACK 0x0010 -#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 -#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 -#define IEEE80211_STYPE_NULLFUNC 0x0040 -#define IEEE80211_STYPE_CFACK 0x0050 -#define IEEE80211_STYPE_CFPOLL 0x0060 -#define IEEE80211_STYPE_CFACKPOLL 0x0070 -#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 -#define IEEE80211_STYPE_QOS_NULL 0x00C0 - -#define IEEE80211_SCTL_FRAG 0x000F -#define IEEE80211_SCTL_SEQ 0xFFF0 - -/* QOS control */ -#define IEEE80211_QCTL_TID 0x000F - -#define FC_QOS_BIT BIT(7) -#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false) -#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0] & FC_QOS_BIT))) -//added by wb. Is this right? -#define IsQoSDataFrame(pframe) ((*(u16 *)pframe & (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16 *)pframe & IEEE80211_FCTL_ORDER) -#define SN_LESS(a, b) (((a - b) & 0x800) != 0) -#define SN_EQUAL(a, b) (a == b) -#define MAX_DEV_ADDR_SIZE 8 -typedef enum _ACT_CATEGORY { - ACT_CAT_QOS = 1, - ACT_CAT_DLS = 2, - ACT_CAT_BA = 3, - ACT_CAT_HT = 7, - ACT_CAT_WMM = 17, -} ACT_CATEGORY, *PACT_CATEGORY; - -typedef enum _TS_ACTION { - ACT_ADDTSREQ = 0, - ACT_ADDTSRSP = 1, - ACT_DELTS = 2, - ACT_SCHEDULE = 3, -} TS_ACTION, *PTS_ACTION; - -typedef enum _BA_ACTION { - ACT_ADDBAREQ = 0, - ACT_ADDBARSP = 1, - ACT_DELBA = 2, -} BA_ACTION, *PBA_ACTION; - -typedef enum _InitialGainOpType { - IG_Backup = 0, - IG_Restore, - IG_Max -} InitialGainOpType; - -/* debug macros */ -#define CONFIG_IEEE80211_DEBUG -#ifdef CONFIG_IEEE80211_DEBUG -extern u32 ieee80211_debug_level; -#define IEEE80211_DEBUG(level, fmt, args...) \ -do { if (ieee80211_debug_level & (level)) \ - printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) -//wb added to debug out data buf -//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA -#define IEEE80211_DEBUG_DATA(level, data, datalen) \ - do { if ((ieee80211_debug_level & (level)) == (level)) \ - { \ - int i; \ - u8 *pdata = (u8 *)data; \ - printk(KERN_DEBUG "ieee80211: %s()\n", __func__); \ - for (i = 0; i < (int)(datalen); i++) { \ - printk("%2x ", pdata[i]); \ - if ((i + 1) % 16 == 0) \ - printk("\n"); \ - } \ - printk("\n"); \ - } \ - } while (0) -#else -#define IEEE80211_DEBUG(level, fmt, args...) -#define IEEE80211_DEBUG_DATA(level, data, datalen) -#endif /* CONFIG_IEEE80211_DEBUG */ - -/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ - -/* - * To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define IEEE80211_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your - * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/ipw/debug_level - * - * you simply need to add your entry to the ipw_debug_levels array. - * - * If you do not see debug_level in /proc/net/ipw then you do not have - * CONFIG_IEEE80211_DEBUG defined in your kernel configuration - * - */ - -#define IEEE80211_DL_INFO (1<<0) -#define IEEE80211_DL_WX (1<<1) -#define IEEE80211_DL_SCAN (1<<2) -#define IEEE80211_DL_STATE (1<<3) -#define IEEE80211_DL_MGMT (1<<4) -#define IEEE80211_DL_FRAG (1<<5) -#define IEEE80211_DL_EAP (1<<6) -#define IEEE80211_DL_DROP (1<<7) - -#define IEEE80211_DL_TX (1<<8) -#define IEEE80211_DL_RX (1<<9) - -#define IEEE80211_DL_HT (1<<10) //HT -#define IEEE80211_DL_BA (1<<11) //ba -#define IEEE80211_DL_TS (1<<12) //TS -#define IEEE80211_DL_QOS (1<<13) -#define IEEE80211_DL_REORDER (1<<14) -#define IEEE80211_DL_IOT (1<<15) -#define IEEE80211_DL_IPS (1<<16) -#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen -#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. -#define IEEE80211_DL_ERR (1<<31) //always open -#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) -#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) -#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) - -#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) -#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) -#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) -#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) -#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) -#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) -#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) -#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) -#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) -#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) - -#include /* ARPHRD_ETHER */ - -#ifndef WIRELESS_SPY -#define WIRELESS_SPY // enable iwspy support -#endif -#include // new driver API - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ - -#ifndef ETH_P_80211_RAW -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) -#endif - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __packed; - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) - -#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) -#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) - -#define WLAN_CAPABILITY_BSS (1<<0) -#define WLAN_CAPABILITY_IBSS (1<<1) -#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) -#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) -#define WLAN_CAPABILITY_PRIVACY (1<<4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) -#define WLAN_CAPABILITY_PBCC (1<<6) -#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) -#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) -#define WLAN_CAPABILITY_QOS (1<<9) -#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) -#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) - -/* 802.11g ERP information element */ -#define WLAN_ERP_NON_ERP_PRESENT (1<<0) -#define WLAN_ERP_USE_PROTECTION (1<<1) -#define WLAN_ERP_BARKER_PREAMBLE (1<<2) - -#define IEEE80211_STATMASK_SIGNAL (1<<0) -#define IEEE80211_STATMASK_RSSI (1<<1) -#define IEEE80211_STATMASK_NOISE (1<<2) -#define IEEE80211_STATMASK_RATE (1<<3) -#define IEEE80211_STATMASK_WEMASK 0x7 - -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) - -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_LEN 8 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - -#define IEEE80211_NUM_OFDM_RATES 8 -#define IEEE80211_NUM_CCK_RATES 4 -#define IEEE80211_OFDM_SHIFT_MASK_A 4 - - -/* this is stolen and modified from the madwifi driver*/ -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_DATA 0x08 -#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 - -#define IEEE80211_QOS_HAS_SEQ(fc) \ - (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ - (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) - -/* this is stolen from ipw2200 driver */ -#define IEEE_IBSS_MAC_HASH_SIZE 31 -struct ieee_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num[17]; - u16 frag_num[17]; - unsigned long packet_time[17]; - struct list_head list; -}; - -/* NOTE: This data is for statistical purposes; not all hardware provides this - * information for frames received. Not setting these will not cause - * any adverse affects. - */ -struct ieee80211_rx_stats { - u32 mac_time[2]; - s8 rssi; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ - u8 received_channel; - u8 control; - u8 mask; - u8 freq; - u16 len; - u64 tsf; - u32 beacon_time; - u8 nic_type; - u16 Length; - // u8 DataRate; // In 0.5 Mbps - u8 SignalQuality; // in 0-100 index. - s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. - s8 RxPower; // in dBm Translate from PWdB - u8 SignalStrength; // in 0-100 index. - u16 bHwError:1; - u16 bCRC:1; - u16 bICV:1; - u16 bShortPreamble:1; - u16 Antenna:1; //for rtl8185 - u16 Decrypted:1; //for rtl8185, rtl8187 - u16 Wakeup:1; //for rtl8185 - u16 Reserved0:1; //for rtl8185 - u8 AGC; - u32 TimeStampLow; - u32 TimeStampHigh; - bool bShift; - bool bIsQosData; // Added by Annie, 2005-12-22. - u8 UserPriority; - - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - //1Attention Please!!!<11n or 8190 specific code should be put below this line> - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - - u8 RxDrvInfoSize; - u8 RxBufShift; - bool bIsAMPDU; - bool bFirstMPDU; - bool bContainHTC; - bool RxIs40MHzPacket; - u32 RxPWDBAll; - u8 RxMIMOSignalStrength[4]; // in 0~100 index - s8 RxMIMOSignalQuality[2]; - bool bPacketMatchBSSID; - bool bIsCCK; - bool bPacketToSelf; - //added by amy - u8 *virtual_address; - u16 packetlength; // Total packet length: Must equal to sum of all FragLength - u16 fraglength; // FragLength should equal to PacketLength in non-fragment case - u16 fragoffset; // Data offset for this fragment - u16 ntotalfrag; - bool bisrxaggrsubframe; - bool bPacketBeacon; //cosa add for rssi - bool bToSelfBA; //cosa add for rssi - s8 cck_adc_pwdb[4]; //cosa add for rx path selection - u16 Seq_Num; - -}; - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. - */ -#define IEEE80211_FRAG_CACHE_LEN 4 - -struct ieee80211_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - -struct ieee80211_stats { - unsigned int tx_unicast_frames; - unsigned int tx_multicast_frames; - unsigned int tx_fragments; - unsigned int tx_unicast_octets; - unsigned int tx_multicast_octets; - unsigned int tx_deferred_transmissions; - unsigned int tx_single_retry_frames; - unsigned int tx_multiple_retry_frames; - unsigned int tx_retry_limit_exceeded; - unsigned int tx_discards; - unsigned int rx_unicast_frames; - unsigned int rx_multicast_frames; - unsigned int rx_fragments; - unsigned int rx_unicast_octets; - unsigned int rx_multicast_octets; - unsigned int rx_fcs_errors; - unsigned int rx_discards_no_buffer; - unsigned int tx_discards_wrong_sa; - unsigned int rx_discards_undecryptable; - unsigned int rx_message_in_msg_fragments; - unsigned int rx_message_in_bad_msg_fragments; -}; - -struct ieee80211_device; - -#include "ieee80211_crypt.h" - -#define SEC_KEY_1 (1<<0) -#define SEC_KEY_2 (1<<1) -#define SEC_KEY_3 (1<<2) -#define SEC_KEY_4 (1<<3) -#define SEC_ACTIVE_KEY (1<<4) -#define SEC_AUTH_MODE (1<<5) -#define SEC_UNICAST_GROUP (1<<6) -#define SEC_LEVEL (1<<7) -#define SEC_ENABLED (1<<8) -#define SEC_ENCRYPT (1<<9) - -#define SEC_LEVEL_0 0 /* None */ -#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ -#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ -#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ -#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ - -#define SEC_ALG_NONE 0 -#define SEC_ALG_WEP 1 -#define SEC_ALG_TKIP 2 -#define SEC_ALG_CCMP 3 - -#define WEP_KEYS 4 -#define WEP_KEY_LEN 13 -#define SCM_KEY_LEN 32 -#define SCM_TEMPORAL_KEY_LENGTH 16 - -struct ieee80211_security { - u16 active_key:2, - enabled:1, - auth_algo:4, - unicast_uses_group:1, - encrypt:1; - u8 auth_mode; - u8 key_sizes[WEP_KEYS]; - u8 keys[WEP_KEYS][SCM_KEY_LEN]; - u8 level; - u16 flags; -} __packed; - - -/* - * 802.11 data frame from AP - * ,-------------------------------------------------------------------. - * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - * |------|------|---------|---------|---------|------|---------|------| - * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - * | | tion | (BSSID) | | | ence | data | | - * `-------------------------------------------------------------------' - * Total: 28-2340 bytes - */ - -/* Management Frame Information Element Types */ -enum ieee80211_mfie { - MFIE_TYPE_SSID = 0, - MFIE_TYPE_RATES = 1, - MFIE_TYPE_FH_SET = 2, - MFIE_TYPE_DS_SET = 3, - MFIE_TYPE_CF_SET = 4, - MFIE_TYPE_TIM = 5, - MFIE_TYPE_IBSS_SET = 6, - MFIE_TYPE_COUNTRY = 7, - MFIE_TYPE_HOP_PARAMS = 8, - MFIE_TYPE_HOP_TABLE = 9, - MFIE_TYPE_REQUEST = 10, - MFIE_TYPE_CHALLENGE = 16, - MFIE_TYPE_POWER_CONSTRAINT = 32, - MFIE_TYPE_POWER_CAPABILITY = 33, - MFIE_TYPE_TPC_REQUEST = 34, - MFIE_TYPE_TPC_REPORT = 35, - MFIE_TYPE_SUPP_CHANNELS = 36, - MFIE_TYPE_CSA = 37, - MFIE_TYPE_MEASURE_REQUEST = 38, - MFIE_TYPE_MEASURE_REPORT = 39, - MFIE_TYPE_QUIET = 40, - MFIE_TYPE_IBSS_DFS = 41, - MFIE_TYPE_ERP = 42, - MFIE_TYPE_RSN = 48, - MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_HT_CAP = 45, - MFIE_TYPE_HT_INFO = 61, - MFIE_TYPE_AIRONET = 133, - MFIE_TYPE_GENERIC = 221, - MFIE_TYPE_QOS_PARAMETER = 222, -}; - -/* Minimal header; can be used for passing 802.11 frames with sufficient - * information to determine what type of underlying data type is actually - * stored in the data. - */ -struct rtl_80211_hdr { - __le16 frame_ctl; - __le16 duration_id; - u8 payload[]; -} __packed; - -struct rtl_80211_hdr_1addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtl_80211_hdr_2addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtl_80211_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[]; -} __packed; - -struct rtl_80211_hdr_4addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[]; -} __packed; - -struct rtl_80211_hdr_3addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; - __le16 qos_ctl; -} __packed; - -struct rtl_80211_hdr_4addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[0]; - __le16 qos_ctl; -} __packed; - -struct ieee80211_info_element { - u8 id; - u8 len; - u8 data[]; -} __packed; - -struct ieee80211_authentication { - struct rtl_80211_hdr_3addr header; - __le16 algorithm; - __le16 transaction; - __le16 status; - /*challenge*/ - struct ieee80211_info_element info_element[]; -} __packed; - -struct ieee80211_disassoc { - struct rtl_80211_hdr_3addr header; - __le16 reason; -} __packed; - -struct ieee80211_probe_request { - struct rtl_80211_hdr_3addr header; - /* SSID, supported rates */ - struct ieee80211_info_element info_element[]; -} __packed; - -struct ieee80211_probe_response { - struct rtl_80211_hdr_3addr header; - __le32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN - */ - struct ieee80211_info_element info_element[]; -} __packed; - -/* Alias beacon for probe_response */ -#define ieee80211_beacon ieee80211_probe_response - -struct ieee80211_assoc_request_frame { - struct rtl_80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[]; -} __packed; - -struct ieee80211_reassoc_request_frame { - struct rtl_80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - u8 current_ap[ETH_ALEN]; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[]; -} __packed; - -struct ieee80211_assoc_response_frame { - struct rtl_80211_hdr_3addr header; - __le16 capability; - __le16 status; - __le16 aid; - struct ieee80211_info_element info_element[]; /* supported rates */ -} __packed; - -struct ieee80211_txb { - u8 nr_frags; - u8 encrypted; - u8 queue_index; - u8 rts_included; - u16 reserved; - __le16 frag_size; - __le16 payload_size; - struct sk_buff *fragments[]; -}; - -#define MAX_TX_AGG_COUNT 16 -struct ieee80211_drv_agg_txb { - u8 nr_drv_agg_frames; - struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; -} __packed; - -#define MAX_SUBFRAME_COUNT 64 -struct ieee80211_rxb { - u8 nr_subframes; - struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; -} __packed; - -typedef union _frameqos { - u16 shortdata; - u8 chardata[2]; - struct { - u16 tid:4; - u16 eosp:1; - u16 ack_policy:2; - u16 reserved:1; - u16 txop:8; - } field; -} frameqos, *pframeqos; - -/* SWEEP TABLE ENTRIES NUMBER*/ -#define MAX_SWEEP_TAB_ENTRIES 42 -#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... - */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) -#define MAX_NETWORK_COUNT 128 - -#define MAX_CHANNEL_NUMBER 161 -#define IEEE80211_SOFTMAC_SCAN_TIME 100 -//(HZ / 2) -#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) - -#define CRC_LENGTH 4U - -#define MAX_WPA_IE_LEN 64 - -#define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) - -/* QoS structure */ -#define NETWORK_HAS_QOS_PARAMETERS (1<<3) -#define NETWORK_HAS_QOS_INFORMATION (1<<4) -#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ - NETWORK_HAS_QOS_INFORMATION) -/* 802.11h */ -#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) -#define NETWORK_HAS_CSA (1<<6) -#define NETWORK_HAS_QUIET (1<<7) -#define NETWORK_HAS_IBSS_DFS (1<<8) -#define NETWORK_HAS_TPC_REPORT (1<<9) - -#define NETWORK_HAS_ERP_VALUE (1<<10) - -#define QOS_QUEUE_NUM 4 -#define QOS_OUI_LEN 3 -#define QOS_OUI_TYPE 2 -#define QOS_ELEMENT_ID 221 -#define QOS_OUI_INFO_SUB_TYPE 0 -#define QOS_OUI_PARAM_SUB_TYPE 1 -#define QOS_VERSION_1 1 -#define QOS_AIFSN_MIN_VALUE 2 -struct ieee80211_qos_information_element { - u8 elementID; - u8 length; - u8 qui[QOS_OUI_LEN]; - u8 qui_type; - u8 qui_subtype; - u8 version; - u8 ac_info; -} __packed; - -struct ieee80211_qos_ac_parameter { - u8 aci_aifsn; - u8 ecw_min_max; - __le16 tx_op_limit; -} __packed; - -struct ieee80211_qos_parameter_info { - struct ieee80211_qos_information_element info_element; - u8 reserved; - struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; -} __packed; - -struct ieee80211_qos_parameters { - __le16 cw_min[QOS_QUEUE_NUM]; - __le16 cw_max[QOS_QUEUE_NUM]; - u8 aifs[QOS_QUEUE_NUM]; - u8 flag[QOS_QUEUE_NUM]; - __le16 tx_op_limit[QOS_QUEUE_NUM]; -} __packed; - -struct ieee80211_qos_data { - struct ieee80211_qos_parameters parameters; - int active; - int supported; - u8 param_count; - u8 old_param_count; -}; - -struct ieee80211_tim_parameters { - u8 tim_count; - u8 tim_period; -} __packed; - -//#else -struct ieee80211_wmm_ts_info { - u8 ac_dir_tid; - u8 ac_up_psb; - u8 reserved; -} __packed; - -struct ieee80211_wmm_tspec_elem { - struct ieee80211_wmm_ts_info ts_info; - u16 norm_msdu_size; - u16 max_msdu_size; - u32 min_serv_inter; - u32 max_serv_inter; - u32 inact_inter; - u32 suspen_inter; - u32 serv_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_size; - u32 delay_bound; - u32 min_phy_rate; - u16 surp_band_allow; - u16 medium_time; -} __packed; -enum eap_type { - EAP_PACKET = 0, - EAPOL_START, - EAPOL_LOGOFF, - EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT -}; - -static const char *eap_types[] = { - [EAP_PACKET] = "EAP-Packet", - [EAPOL_START] = "EAPOL-Start", - [EAPOL_LOGOFF] = "EAPOL-Logoff", - [EAPOL_KEY] = "EAPOL-Key", - [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" -}; - -static inline const char *eap_get_type(int type) -{ - return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; -} -//added by amy for reorder -static inline u8 Frame_QoSTID(u8 *buf) -{ - struct rtl_80211_hdr_3addr *hdr; - u16 fc; - hdr = (struct rtl_80211_hdr_3addr *)buf; - fc = le16_to_cpu(hdr->frame_ctl); - return (u8)((frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) && (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid; -} - -//added by amy for reorder - -struct eapol { - u8 snap[6]; - u16 ethertype; - u8 version; - u8 type; - u16 length; -} __packed; - -struct ieee80211_softmac_stats { - unsigned int rx_ass_ok; - unsigned int rx_ass_err; - unsigned int rx_probe_rq; - unsigned int tx_probe_rs; - unsigned int tx_beacons; - unsigned int rx_auth_rq; - unsigned int rx_auth_rs_ok; - unsigned int rx_auth_rs_err; - unsigned int tx_auth_rq; - unsigned int no_auth_rs; - unsigned int no_ass_rs; - unsigned int tx_ass_rq; - unsigned int rx_ass_rq; - unsigned int tx_probe_rq; - unsigned int reassoc; - unsigned int swtxstop; - unsigned int swtxawake; - unsigned char CurrentShowTxate; - unsigned char last_packet_rate; - unsigned int txretrycount; -}; - -#define BEACON_PROBE_SSID_ID_POSITION 12 - -struct ieee80211_info_element_hdr { - u8 id; - u8 len; -} __packed; - -/* - * These are the data types that can make up management packets - * - u16 auth_algorithm; - u16 auth_sequence; - u16 beacon_interval; - u16 capability; - u8 current_ap[ETH_ALEN]; - u16 listen_interval; - struct { - u16 association_id:14, reserved:2; - } __packed; - u32 time_stamp[2]; - u16 reason; - u16 status; -*/ - -#define IEEE80211_DEFAULT_TX_ESSID "Penguin" -#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps - -enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; -#define MAX_SP_Len (WMM_all_frame << 4) -#define IEEE80211_QOS_TID 0x0f -#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) - -#define IEEE80211_DTIM_MBCAST 4 -#define IEEE80211_DTIM_UCAST 2 -#define IEEE80211_DTIM_VALID 1 -#define IEEE80211_DTIM_INVALID 0 - -#define IEEE80211_PS_DISABLED 0 -#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST -#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST - -//added by David for QoS 2006/6/30 -//#define WMM_Hang_8187 -#ifdef WMM_Hang_8187 -#undef WMM_Hang_8187 -#endif - -#define WME_AC_BK 0x00 -#define WME_AC_BE 0x01 -#define WME_AC_VI 0x02 -#define WME_AC_VO 0x03 -#define WME_ACI_MASK 0x03 -#define WME_AIFSN_MASK 0x03 -#define WME_AC_PRAM_LEN 16 - -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) -#define UP2AC(up) ( \ - ((up) < 1) ? WME_AC_BE : \ - ((up) < 3) ? WME_AC_BK : \ - ((up) < 4) ? WME_AC_BE : \ - ((up) < 6) ? WME_AC_VI : \ - WME_AC_VO) -//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue -#define AC2UP(_ac) ( \ - ((_ac) == WME_AC_VO) ? 6 : \ - ((_ac) == WME_AC_VI) ? 5 : \ - ((_ac) == WME_AC_BK) ? 1 : \ - 0) - -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ -#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address plus ether type*/ - -struct ether_header { - u8 ether_dhost[ETHER_ADDR_LEN]; - u8 ether_shost[ETHER_ADDR_LEN]; - u16 ether_type; -} __packed; - -#ifndef ETHERTYPE_PAE -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ -#endif -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#endif - -typedef enum _erp_t { - ERP_NonERPpresent = 0x01, - ERP_UseProtection = 0x02, - ERP_BarkerPreambleMode = 0x04, -} erp_t; - - -struct ieee80211_network { - /* These entries are used to identify a unique network */ - u8 bssid[ETH_ALEN]; /* u16 aligned! */ - u8 channel; - - // CCXv4 S59, MBSSID. - bool bMBssidValid; - u8 MBssid[ETH_ALEN]; /* u16 aligned! */ - u8 MBssidMask; - /* Ensure null-terminated for any debug msgs */ - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - struct ieee80211_qos_data qos_data; - - //added by amy for LEAP - bool bWithAironetIE; - bool bCkipSupported; - bool bCcxRmEnable; - u16 CcxRmState[2]; - // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. - bool bWithCcxVerNum; - u8 BssCcxVerNumber; - /* These are network statistics */ - struct ieee80211_rx_stats stats; - u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; - unsigned long last_scanned; - u8 mode; - u32 flags; - u32 last_associate; - u32 time_stamp[2]; - u16 beacon_interval; - u16 listen_interval; - u16 atim_window; - u8 erp_value; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - - struct ieee80211_tim_parameters tim; - u8 dtim_period; - u8 dtim_data; - u32 last_dtim_sta_time[2]; - - //appeded for QoS - u8 wmm_info; - struct ieee80211_wmm_ac_param wmm_param[4]; - u8 QoS_Enable; -#ifdef THOMAS_TURBO - u8 Turbo_Enable;//enable turbo mode, added by thomas -#endif - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; - // HT Related, by amy, 2008.04.29 - BSS_HT bssht; - // Add to handle broadcom AP management frame CCK rate. - bool broadcom_cap_exist; - bool ralink_cap_exist; - bool atheros_cap_exist; - bool cisco_cap_exist; - bool unknown_cap_exist; -// u8 berp_info; - bool berp_info_valid; - bool buseprotection; - //put at the end of the structure. - struct list_head list; -}; - -enum ieee80211_state { - - /* the card is not linked at all */ - IEEE80211_NOLINK = 0, - - /* IEEE80211_ASSOCIATING* are for BSS client mode - * the driver shall not perform RX filtering unless - * the state is LINKED. - * The driver shall just check for the state LINKED and - * defaults to NOLINK for ALL the other states (including - * LINKED_SCANNING) - */ - - /* the association procedure will start (wq scheduling)*/ - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATING_RETRY, - - /* the association procedure is sending AUTH request*/ - IEEE80211_ASSOCIATING_AUTHENTICATING, - - /* the association procedure has successfully authentcated - * and is sending association request - */ - IEEE80211_ASSOCIATING_AUTHENTICATED, - - /* the link is ok. the card associated to a BSS or linked - * to a ibss cell or acting as an AP and creating the bss - */ - IEEE80211_LINKED, - - /* same as LINKED, but the driver shall apply RX filter - * rules as we are in NO_LINK mode. As the card is still - * logically linked, but it is doing a syncro site survey - * then it will be back to LINKED state. - */ - IEEE80211_LINKED_SCANNING, - -}; - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) -#define DEFAULT_FTS 2346 - -#define CFG_IEEE80211_RESERVE_FCS (1<<0) -#define CFG_IEEE80211_COMPUTE_FCS (1<<1) -#define CFG_IEEE80211_RTS (1<<2) - -#define IEEE80211_24GHZ_MIN_CHANNEL 1 -#define IEEE80211_24GHZ_MAX_CHANNEL 14 -#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ - IEEE80211_24GHZ_MIN_CHANNEL + 1) - -#define IEEE80211_52GHZ_MIN_CHANNEL 34 -#define IEEE80211_52GHZ_MAX_CHANNEL 165 -#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ - IEEE80211_52GHZ_MIN_CHANNEL + 1) - - - -struct tx_pending { - int frag; - struct ieee80211_txb *txb; -}; - -struct bandwidth_autoswitch { - long threshold_20Mhzto40Mhz; - long threshold_40Mhzto20Mhz; - bool bforced_tx20Mhz; - bool bautoswitch_enable; -}; - - -//added by amy for order - -#define REORDER_WIN_SIZE 128 -#define REORDER_ENTRY_NUM 128 -struct rx_reorder_entry { - struct list_head List; - u16 SeqNum; - struct ieee80211_rxb *prxb; -}; -//added by amy for order -typedef enum _Fsync_State { - Default_Fsync, - HW_Fsync, - SW_Fsync -} Fsync_State; - -// Power save mode configured. -typedef enum _RT_PS_MODE { - eActive, // Active/Continuous access. - eMaxPs, // Max power save mode. - eFastPs // Fast power save mode. -} RT_PS_MODE; - -typedef enum _IPS_CALLBACK_FUNCION { - IPS_CALLBACK_NONE = 0, - IPS_CALLBACK_MGNT_LINK_REQUEST = 1, - IPS_CALLBACK_JOIN_REQUEST = 2, -} IPS_CALLBACK_FUNCION; - -typedef enum _RT_JOIN_ACTION { - RT_JOIN_INFRA = 1, - RT_JOIN_IBSS = 2, - RT_START_IBSS = 3, - RT_NO_ACTION = 4, -} RT_JOIN_ACTION; - -struct ibss_parms { - u16 atimWin; -}; -#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. - -// RF state. -typedef enum _RT_RF_POWER_STATE { - eRfOn, - eRfSleep, - eRfOff -} RT_RF_POWER_STATE; - -struct rt_power_save_control { - - // - // Inactive Power Save(IPS) : Disable RF when disconnected - // - bool bInactivePs; - bool bIPSModeBackup; - bool bSwRfProcessing; - RT_RF_POWER_STATE eInactivePowerState; - struct work_struct InactivePsWorkItem; - struct timer_list InactivePsTimer; - - // Return point for join action - IPS_CALLBACK_FUNCION ReturnPoint; - - // Recored Parameters for rescheduled JoinRequest - bool bTmpBssDesc; - RT_JOIN_ACTION tmpJoinAction; - struct ieee80211_network tmpBssDesc; - - // Recored Parameters for rescheduled MgntLinkRequest - bool bTmpScanOnly; - bool bTmpActiveScan; - bool bTmpFilterHiddenAP; - bool bTmpUpdateParms; - u8 tmpSsidBuf[33]; - struct octet_string tmpSsid2Scan; - bool bTmpSsid2Scan; - u8 tmpNetworkType; - u8 tmpChannelNumber; - u16 tmpBcnPeriod; - u8 tmpDtimPeriod; - u16 tmpmCap; - struct octet_string tmpSuppRateSet; - u8 tmpSuppRateBuf[MAX_NUM_RATES]; - bool bTmpSuppRate; - struct ibss_parms tmpIbpm; - bool bTmpIbpm; - - // - // Leisre Poswer Save : Disable RF if connected but traffic is not busy - // - bool bLeisurePs; - -}; - -typedef u32 RT_RF_CHANGE_SOURCE; -#define RF_CHANGE_BY_SW BIT(31) -#define RF_CHANGE_BY_HW BIT(30) -#define RF_CHANGE_BY_PS BIT(29) -#define RF_CHANGE_BY_IPS BIT(28) -#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. - -typedef enum { - COUNTRY_CODE_FCC = 0, - COUNTRY_CODE_IC = 1, - COUNTRY_CODE_ETSI = 2, - COUNTRY_CODE_SPAIN = 3, - COUNTRY_CODE_FRANCE = 4, - COUNTRY_CODE_MKK = 5, - COUNTRY_CODE_MKK1 = 6, - COUNTRY_CODE_ISRAEL = 7, - COUNTRY_CODE_TELEC, - COUNTRY_CODE_MIC, - COUNTRY_CODE_GLOBAL_DOMAIN -} country_code_type_t; - -#define RT_MAX_LD_SLOT_NUM 10 -struct rt_link_detect { - - u32 NumRecvBcnInPeriod; - u32 NumRecvDataInPeriod; - - u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status - u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status - u16 SlotNum; // number of CheckForHang period to determine link status - u16 SlotIndex; - - u32 NumTxOkInPeriod; - u32 NumRxOkInPeriod; - bool bBusyTraffic; -}; - - -struct ieee80211_device { - struct net_device *dev; - struct ieee80211_security sec; - - //hw security related -// u8 hwsec_support; //support? - u8 hwsec_active; //hw security active. - bool is_silent_reset; - bool ieee_up; - //added by amy - bool bSupportRemoteWakeUp; - RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. - bool actscanning; - bool beinretry; - RT_RF_POWER_STATE eRFPowerState; - RT_RF_CHANGE_SOURCE RfOffReason; - bool is_set_key; - //11n spec related I wonder if These info structure need to be moved out of ieee80211_device - - //11n HT below - PRT_HIGH_THROUGHPUT pHTInfo; - //struct timer_list SwBwTimer; -// spinlock_t chnlop_spinlock; - spinlock_t bw_spinlock; - - spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to separate different descriptors - //the way fill this is the same as in the IE - u8 Regdot11HTOperationalRateSet[16]; //use RATR format - u8 dot11HTOperationalRateSet[16]; //use RATR format - u8 RegHTSuppRateSet[16]; - u8 HTCurrentOperaRate; - u8 HTHighestOperaRate; - //wb added for rate operation mode to firmware - u8 bTxDisableRateFallBack; - u8 bTxUseDriverAssingedRate; - atomic_t atm_chnlop; - atomic_t atm_swbw; -// u8 HTHighestOperaRate; -// u8 HTCurrentOperaRate; - - // 802.11e and WMM Traffic Stream Info (TX) - struct list_head Tx_TS_Admit_List; - struct list_head Tx_TS_Pending_List; - struct list_head Tx_TS_Unused_List; - struct tx_ts_record TxTsRecord[TOTAL_TS_NUM]; - // 802.11e and WMM Traffic Stream Info (RX) - struct list_head Rx_TS_Admit_List; - struct list_head Rx_TS_Pending_List; - struct list_head Rx_TS_Unused_List; - struct rx_ts_record RxTsRecord[TOTAL_TS_NUM]; - struct rx_reorder_entry RxReorderEntry[128]; - struct list_head RxReorder_Unused_List; - // Qos related. Added by Annie, 2005-11-01. -// PSTA_QOS pStaQos; - u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) - - - /* Bookkeeping structures */ - struct net_device_stats stats; - struct ieee80211_stats ieee_stats; - struct ieee80211_softmac_stats softmac_stats; - - /* Probe / Beacon management */ - struct list_head network_free_list; - struct list_head network_list; - struct ieee80211_network *networks; - int scans; - int scan_age; - - int iw_mode; /* operating mode (IW_MODE_*) */ - struct iw_spy_data spy_data; - - spinlock_t lock; - spinlock_t wpax_suitlist_lock; - - int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs - */ - u32 config; - - /* WEP and other encryption related settings at the device level */ - int open_wep; /* Set to 1 to allow unencrypted frames */ - int auth_mode; - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes - */ - - /* If the host performs {en,de}cryption, then set to 1 */ - int host_encrypt; - int host_encrypt_msdu; - int host_decrypt; - /* host performs multicast decryption */ - int host_mc_decrypt; - - /* host should strip IV and ICV from protected frames */ - /* meaningful only when hardware decryption is being used */ - int host_strip_iv_icv; - - int host_open_frag; - int host_build_iv; - int ieee802_1x; /* is IEEE 802.1X used */ - - /* WPA data */ - bool bHalfWirelessN24GMode; - int wpa_enabled; - int drop_unencrypted; - int tkip_countermeasures; - int privacy_invoked; - size_t wpa_ie_len; - u8 *wpa_ie; - u8 ap_mac_addr[6]; - u16 pairwise_key_type; - u16 group_key_type; - struct list_head crypt_deinit_list; - struct ieee80211_crypt_data *crypt[WEP_KEYS]; - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ - struct timer_list crypt_deinit_timer; - int crypt_quiesced; - - int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames - */ - - /* Fragmentation structures */ - // each streaming contain a entry - struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; - unsigned int frag_next_idx[17]; - u16 fts; /* Fragmentation Threshold */ -#define DEFAULT_RTS_THRESHOLD 2346U -#define MIN_RTS_THRESHOLD 1 -#define MAX_RTS_THRESHOLD 2346U - u16 rts; /* RTS threshold */ - - /* Association info */ - u8 bssid[ETH_ALEN]; - - /* This stores infos for the current network. - * Either the network we are associated in INFRASTRUCTURE - * or the network that we are creating in MASTER mode. - * ad-hoc is a mixture ;-). - * Note that in infrastructure mode, even when not associated, - * fields bssid and essid may be valid (if wpa_set and essid_set - * are true) as thy carry the value set by the user via iwconfig - */ - struct ieee80211_network current_network; - - enum ieee80211_state state; - - int short_slot; - int reg_mode; - int mode; /* A, B, G */ - int modulation; /* CCK, OFDM */ - int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ - int abg_true; /* ABG flag */ - - /* used for forcing the ibss workqueue to terminate - * without wait for the syncro scan to terminate - */ - short sync_scan_hurryup; - - int perfect_rssi; - int worst_rssi; - - u16 prev_seq_ctl; /* used to drop duplicate frames */ - - /* map of allowed channels. 0 is dummy */ - // FIXME: remember to default to a basic channel plan depending of the PHY type - void *dot11d_info; - bool bGlobalDomain; - int rate; /* current rate */ - int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features - short active_scan; - - /* this contains flags for selectively enable softmac support */ - u16 softmac_features; - - /* if the sequence control field is not filled by HW */ - u16 seq_ctrl[5]; - - /* association procedure transaction sequence number */ - u16 associate_seq; - - /* AID for RTXed association responses */ - u16 assoc_id; - - /* power save mode related*/ - short ps; - short sta_sleep; - int ps_timeout; - int ps_period; - struct work_struct ps_task; - u32 ps_th; - u32 ps_tl; - - short raw_tx; - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - short queue_stop; - short scanning; - short proto_started; - - struct mutex wx_mutex; - struct mutex scan_mutex; - - spinlock_t mgmt_tx_lock; - spinlock_t beacon_lock; - - short beacon_txing; - - short wap_set; - short ssid_set; - - u8 wpax_type_set; //{added by David, 2006.9.28} - u32 wpax_type_notify; //{added by David, 2006.9.26} - - /* QoS related flag */ - s8 init_wmmparam_flag; - /* set on initialization */ - u8 qos_support; - - /* for discarding duplicated packets in IBSS */ - struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; - - /* for discarding duplicated packets in BSS */ - u16 last_rxseq_num[17]; /* rx seq previous per-tid */ - u16 last_rxfrag_num[17];/* tx frag previous per-tid */ - unsigned long last_packet_time[17]; - - /* for PS mode */ - unsigned long last_rx_ps_time; - - /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ - struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; - int mgmt_queue_head; - int mgmt_queue_tail; -//{ added for rtl819x -#define IEEE80211_QUEUE_LIMIT 128 - u8 AsocRetryCount; - unsigned int hw_header; - struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; - u32 sta_edca_param[4]; - bool aggregation; - // Enable/Disable Rx immediate BA capability. - bool enable_rx_imm_BA; - bool bibsscoordinator; - - //+by amy for DM ,080515 - //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 - bool bdynamic_txpower_enable; - - bool bCTSToSelfEnable; - u8 CTSToSelfTH; - - u32 fsync_time_interval; - u32 fsync_rate_bitmap; - u8 fsync_rssi_threshold; - bool bfsync_enable; - - u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval - u32 fsync_firstdiff_ratethreshold; // low threshold - u32 fsync_seconddiff_ratethreshold; // decrease threshold - Fsync_State fsync_state; - bool bis_any_nonbepkts; - //20Mhz 40Mhz AutoSwitch Threshold - struct bandwidth_autoswitch bandwidth_auto_switch; - //for txpower tracking - bool FwRWRF; - - //added by amy for AP roaming - struct rt_link_detect LinkDetectInfo; - //added by amy for ps - struct rt_power_save_control PowerSaveControl; -//} - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - struct tx_pending tx_pending; - - /* used if IEEE_SOFTMAC_ASSOCIATE is set */ - struct timer_list associate_timer; - - /* used if IEEE_SOFTMAC_BEACONS is set */ - struct timer_list beacon_timer; - struct work_struct associate_complete_wq; - struct work_struct associate_procedure_wq; - struct delayed_work softmac_scan_wq; - struct delayed_work associate_retry_wq; - struct delayed_work start_ibss_wq; - struct work_struct wx_sync_scan_wq; - struct workqueue_struct *wq; - // Qos related. Added by Annie, 2005-11-01. - //STA_QOS StaQos; - - //u32 STA_EDCA_PARAM[4]; - //CHANNEL_ACCESS_SETTING ChannelAccessSetting; - - struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; - - /* Callback functions */ - void (*set_security)(struct net_device *dev, - struct ieee80211_security *sec); - - /* Used to TX data frame by using txb structs. - * this is not used if in the softmac_features - * is set the flag IEEE_SOFTMAC_TX_QUEUE - */ - int (*hard_start_xmit)(struct ieee80211_txb *txb, - struct net_device *dev); - - int (*reset_port)(struct net_device *dev); - int (*is_queue_full)(struct net_device *dev, int pri); - - int (*handle_management)(struct net_device *dev, - struct ieee80211_network *network, u16 type); - int (*is_qos_active)(struct net_device *dev, struct sk_buff *skb); - - /* Softmac-generated frames (management) are TXed via this - * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is - * not set. As some cards may have different HW queues that - * one might want to use for data and management frames - * the option to have two callbacks might be useful. - * This function can't sleep. - */ - int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev); - - /* used instead of hard_start_xmit (not softmac_hard_start_xmit) - * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set - * then also management frames are sent via this callback. - * This function can't sleep. - */ - void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev, int rate); - - /* stops the HW queue for DATA frames. Useful to avoid - * waste time to TX data frame when we are reassociating - * This function can sleep. - */ - void (*data_hard_stop)(struct net_device *dev); - - /* OK this is complementar to data_poll_hard_stop */ - void (*data_hard_resume)(struct net_device *dev); - - /* ask to the driver to retune the radio . - * This function can sleep. the driver should ensure - * the radio has been switched before return. - */ - void (*set_chan)(struct net_device *dev, short ch); - - /* These are not used if the ieee stack takes care of - * scanning (IEEE_SOFTMAC_SCAN feature set). - * In this case only the set_chan is used. - * - * The syncro version is similar to the start_scan but - * does not return until all channels has been scanned. - * this is called in user context and should sleep, - * it is called in a work_queue when switching to ad-hoc mode - * or in behalf of iwlist scan when the card is associated - * and root user ask for a scan. - * the function stop_scan should stop both the syncro and - * background scanning and can sleep. - * The function start_scan should initiate the background - * scanning and can't sleep. - */ - void (*scan_syncro)(struct net_device *dev); - void (*start_scan)(struct net_device *dev); - void (*stop_scan)(struct net_device *dev); - - /* indicate the driver that the link state is changed - * for example it may indicate the card is associated now. - * Driver might be interested in this to apply RX filter - * rules or simply light the LINK led - */ - void (*link_change)(struct net_device *dev); - - /* these two function indicates to the HW when to start - * and stop to send beacons. This is used when the - * IEEE_SOFTMAC_BEACONS is not set. For now the - * stop_send_bacons is NOT guaranteed to be called only - * after start_send_beacons. - */ - void (*start_send_beacons)(struct net_device *dev, u16 tx_rate); - void (*stop_send_beacons)(struct net_device *dev); - - /* power save mode related */ - void (*sta_wake_up)(struct net_device *dev); - void (*ps_request_tx_ack)(struct net_device *dev); - void (*enter_sleep_state)(struct net_device *dev, u32 th, u32 tl); - short (*ps_is_queue_empty)(struct net_device *dev); - int (*handle_beacon)(struct net_device *dev, struct ieee80211_beacon *beacon, struct ieee80211_network *network); - int (*handle_assoc_response)(struct net_device *dev, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network); - - - /* check whether Tx hw resource available */ - short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); - //added by wb for HT related -// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); - void (*SetBWModeHandler)(struct net_device *dev, enum ht_channel_width Bandwidth, enum ht_extension_chan_offset Offset); -// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); - bool (*GetNmodeSupportBySecCfg)(struct net_device *dev); - void (*SetWirelessMode)(struct net_device *dev, u8 wireless_mode); - bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device *dev); - void (*InitialGainHandler)(struct net_device *dev, u8 Operation); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 - */ - u8 priv[]; -}; - -#define IEEE_A (1<<0) -#define IEEE_B (1<<1) -#define IEEE_G (1<<2) -#define IEEE_N_24G (1<<4) -#define IEEE_N_5G (1<<5) -#define IEEE_MODE_MASK (IEEE_A | IEEE_B | IEEE_G) - -/* Generate a 802.11 header */ - -/* Uses the channel change callback directly - * instead of [start/stop] scan callbacks - */ -#define IEEE_SOFTMAC_SCAN (1<<2) - -/* Perform authentication and association handshake */ -#define IEEE_SOFTMAC_ASSOCIATE (1<<3) - -/* Generate probe requests */ -#define IEEE_SOFTMAC_PROBERQ (1<<4) - -/* Generate respones to probe requests */ -#define IEEE_SOFTMAC_PROBERS (1<<5) - -/* The ieee802.11 stack will manages the netif queue - * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. - */ -#define IEEE_SOFTMAC_TX_QUEUE (1<<7) - -/* Uses only the softmac_data_hard_start_xmit - * even for TX management frames. - */ -#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) - -/* Generate beacons. The stack will enqueue beacons - * to the card - */ -#define IEEE_SOFTMAC_BEACONS (1<<6) - -static inline void *ieee80211_priv(struct net_device *dev) -{ - return ((struct ieee80211_device *)netdev_priv(dev))->priv; -} - -static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - -static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) -{ - /* - * It is possible for both access points and our device to support - * combinations of modes, so as long as there is one valid combination - * of ap/device supported modes, then return success - * - */ - if ((mode & IEEE_A) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_52GHZ_BAND)) - return 1; - - if ((mode & IEEE_G) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - if ((mode & IEEE_B) && - (ieee->modulation & IEEE80211_CCK_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - return 0; -} - -static inline int ieee80211_get_hdrlen(u16 fc) -{ - int hdrlen = IEEE80211_3ADDR_LEN; - - switch (WLAN_FC_GET_TYPE(fc)) { - case IEEE80211_FTYPE_DATA: - if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ - if (IEEE80211_QOS_HAS_SEQ(fc)) - hdrlen += 2; /* QOS ctrl*/ - break; - case IEEE80211_FTYPE_CTL: - switch (WLAN_FC_GET_STYPE(fc)) { - case IEEE80211_STYPE_CTS: - case IEEE80211_STYPE_ACK: - hdrlen = IEEE80211_1ADDR_LEN; - break; - default: - hdrlen = IEEE80211_2ADDR_LEN; - break; - } - break; - } - - return hdrlen; -} - -static inline u8 *ieee80211_get_payload(struct rtl_80211_hdr *hdr) -{ - switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { - case IEEE80211_1ADDR_LEN: - return ((struct rtl_80211_hdr_1addr *)hdr)->payload; - case IEEE80211_2ADDR_LEN: - return ((struct rtl_80211_hdr_2addr *)hdr)->payload; - case IEEE80211_3ADDR_LEN: - return ((struct rtl_80211_hdr_3addr *)hdr)->payload; - case IEEE80211_4ADDR_LEN: - return ((struct rtl_80211_hdr_4addr *)hdr)->payload; - } - return NULL; -} - -static inline int ieee80211_is_ofdm_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_OFDM_RATE_6MB: - case IEEE80211_OFDM_RATE_9MB: - case IEEE80211_OFDM_RATE_12MB: - case IEEE80211_OFDM_RATE_18MB: - case IEEE80211_OFDM_RATE_24MB: - case IEEE80211_OFDM_RATE_36MB: - case IEEE80211_OFDM_RATE_48MB: - case IEEE80211_OFDM_RATE_54MB: - return 1; - } - return 0; -} - -static inline int ieee80211_is_cck_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_CCK_RATE_1MB: - case IEEE80211_CCK_RATE_2MB: - case IEEE80211_CCK_RATE_5MB: - case IEEE80211_CCK_RATE_11MB: - return 1; - } - return 0; -} - - -/* ieee80211.c */ -void free_ieee80211(struct net_device *dev); -struct net_device *alloc_ieee80211(int sizeof_priv); - -int ieee80211_set_encryption(struct ieee80211_device *ieee); - -/* ieee80211_tx.c */ - -int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, - struct sk_buff *frag, int hdr_len); - -netdev_tx_t ieee80211_xmit(struct sk_buff *skb, struct net_device *dev); -void ieee80211_txb_free(struct ieee80211_txb *txb); - - -/* ieee80211_rx.c */ -int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats); -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct rtl_80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats); - -/* ieee80211_wx.c */ -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); - -/* ieee80211_softmac.c */ -short ieee80211_is_54g(const struct ieee80211_network *net); -short ieee80211_is_shortslot(const struct ieee80211_network *net); -int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, - u16 type, u16 stype); -void ieee80211_softmac_new_net(struct ieee80211_device *ieee, - struct ieee80211_network *net); - -void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn); -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, - struct ieee80211_device *ieee); - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -void notify_wx_assoc_event(struct ieee80211_device *ieee); -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_bss(struct ieee80211_device *ieee); -void ieee80211_start_master_bss(struct ieee80211_device *ieee); -void ieee80211_start_ibss(struct ieee80211_device *ieee); -void ieee80211_softmac_init(struct ieee80211_device *ieee); -void ieee80211_softmac_free(struct ieee80211_device *ieee); -void ieee80211_associate_abort(struct ieee80211_device *ieee); -void ieee80211_disassociate(struct ieee80211_device *ieee); -void ieee80211_stop_scan(struct ieee80211_device *ieee); -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); -void ieee80211_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_protocol(struct ieee80211_device *ieee); -void ieee80211_stop_protocol(struct ieee80211_device *ieee); -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); -void ieee80211_reset_queue(struct ieee80211_device *ieee); -void ieee80211_wake_queue(struct ieee80211_device *ieee); -void ieee80211_stop_queue(struct ieee80211_device *ieee); -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); -void ieee80211_start_send_beacons(struct ieee80211_device *ieee); -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, - struct iw_point *p); -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); - -void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); - -/* ieee80211_crypt_ccmp&tkip&wep.c */ - -int ieee80211_crypto_init(void); -void ieee80211_crypto_deinit(void); -int ieee80211_crypto_tkip_init(void); -void ieee80211_crypto_tkip_exit(void); -int ieee80211_crypto_ccmp_init(void); -void ieee80211_crypto_ccmp_exit(void); -int ieee80211_crypto_wep_init(void); -void ieee80211_crypto_wep_exit(void); - -/* ieee80211_softmac_wx.c */ - -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); - -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra); - -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -/* ieee80211_module.c */ -#ifdef CONFIG_IEEE80211_DEBUG -int ieee80211_debug_init(void); -void ieee80211_debug_exit(void); -#else -static inline int ieee80211_debug_init(void) { return 0; } -static inline void ieee80211_debug_exit(void) { } -#endif - -//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); -void ieee80211_wx_sync_scan_wq(struct work_struct *work); - - -int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -//HT -#define MAX_RECEIVE_BUFFER_SIZE 9100 // -void HTDebugHTCapability(u8 *CapIE, u8 *TitleString); -void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString); - -void HTSetConnectBwMode(struct ieee80211_device *ieee, - enum ht_channel_width Bandwidth, enum ht_extension_chan_offset Offset); -void HTUpdateDefaultSetting(struct ieee80211_device *ieee); -void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, - u8 *len, u8 isEncrypt); -void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, - u8 *len, u8 isEncrypt); -void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, - u8 *len); -void HTOnAssocRsp(struct ieee80211_device *ieee); -void HTInitializeHTInfo(struct ieee80211_device *ieee); -void HTInitializeBssDesc(PBSS_HT pBssHT); -void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, - struct ieee80211_network *pNetwork); -void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, - struct ieee80211_network *pNetwork); -u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, - u8 *pMCSRateSet, u8 *pMCSFilter); -extern u8 MCS_FILTER_ALL[]; -extern u16 MCS_DATA_RATE[2][2][77]; -u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame); -void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); -bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee); -u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate); -//function in BAPROC.c -int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb); -int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb); -int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb); -void TsInitAddBA(struct ieee80211_device *ieee, struct tx_ts_record *pTS, - u8 Policy, u8 bOverwritePending); -void TsInitDelBA(struct ieee80211_device *ieee, - struct ts_common_info *pTsCommonInfo, enum tr_select TxRxSelect); -void BaSetupTimeOut(struct timer_list *t); -void TxBaInactTimeout(struct timer_list *t); -void RxBaInactTimeout(struct timer_list *t); -void ResetBaEntry(struct ba_record *pBA); -//function in TS.c -bool GetTs( - struct ieee80211_device *ieee, - struct ts_common_info **ppTS, - u8 *Addr, - u8 TID, - enum tr_select TxRxSelect, //Rx:1, Tx:0 - bool bAddNewTs - ); -void TSInitialize(struct ieee80211_device *ieee); -void TsStartAddBaProcess(struct ieee80211_device *ieee, struct tx_ts_record *pTxTS); -void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr); -void RemoveAllTS(struct ieee80211_device *ieee); -void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); - -extern const long ieee80211_wlan_frequencies[]; - -static inline void ieee80211_increment_scans(struct ieee80211_device *ieee) -{ - ieee->scans++; -} - -static inline int ieee80211_get_scans(struct ieee80211_device *ieee) -{ - return ieee->scans; -} - -static inline const char *escape_essid(const char *essid, u8 essid_len) -{ - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - - if (ieee80211_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "", sizeof("")); - return escaped; - } - - snprintf(escaped, sizeof(escaped), "%*pE", essid_len, essid); - return escaped; -} - -/* For the function is more related to hardware setting, it's better to use the - * ieee handler to refer to it. - */ -short check_nic_enough_desc(struct net_device *dev, int queue_index); -int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); -int ieee80211_parse_info_param(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - u16 length, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats); - -void ieee80211_indicate_packets(struct ieee80211_device *ieee, - struct ieee80211_rxb **prxbIndicateArray, - u8 index); -#define RT_ASOC_RETRY_LIMIT 5 -#endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c deleted file mode 100644 index 840db6250b87..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen - * Portions Copyright (C) 2004, Intel Corporation - */ - -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("HostAP crypto"); -MODULE_LICENSE("GPL"); - -struct ieee80211_crypto_alg { - struct list_head list; - struct ieee80211_crypto_ops *ops; -}; - - -struct ieee80211_crypto { - struct list_head algs; - spinlock_t lock; -}; - -static struct ieee80211_crypto *hcrypt; - -void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, - int force) -{ - struct list_head *ptr, *n; - struct ieee80211_crypt_data *entry; - - for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; - ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct ieee80211_crypt_data, list); - - if (atomic_read(&entry->refcnt) != 0 && !force) - continue; - - list_del(ptr); - - if (entry->ops) - entry->ops->deinit(entry->priv); - kfree(entry); - } -} - -void ieee80211_crypt_deinit_handler(struct timer_list *t) -{ - struct ieee80211_device *ieee = from_timer(ieee, t, crypt_deinit_timer); - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - ieee80211_crypt_deinit_entries(ieee, 0); - if (!list_empty(&ieee->crypt_deinit_list)) { - netdev_dbg(ieee->dev, "%s: entries remaining in delayed crypt deletion list\n", - ieee->dev->name); - ieee->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&ieee->crypt_deinit_timer); - } - spin_unlock_irqrestore(&ieee->lock, flags); - -} - -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt) -{ - struct ieee80211_crypt_data *tmp; - unsigned long flags; - - if (!(*crypt)) - return; - - tmp = *crypt; - *crypt = NULL; - - /* must not run ops->deinit() while there may be pending encrypt or - * decrypt operations. Use a list of delayed deinits to avoid needing - * locking. - */ - - spin_lock_irqsave(&ieee->lock, flags); - list_add(&tmp->list, &ieee->crypt_deinit_list); - if (!timer_pending(&ieee->crypt_deinit_timer)) { - ieee->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&ieee->crypt_deinit_timer); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) -{ - unsigned long flags; - struct ieee80211_crypto_alg *alg; - - if (!hcrypt) - return -1; - - alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (!alg) - return -ENOMEM; - - alg->ops = ops; - - spin_lock_irqsave(&hcrypt->lock, flags); - list_add(&alg->list, &hcrypt->algs); - spin_unlock_irqrestore(&hcrypt->lock, flags); - - pr_debug("ieee80211_crypt: registered algorithm '%s'\n", - ops->name); - - return 0; -} - -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) -{ - unsigned long flags; - struct list_head *ptr; - struct ieee80211_crypto_alg *del_alg = NULL; - - if (!hcrypt) - return -1; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *)ptr; - if (alg->ops == ops) { - list_del(&alg->list); - del_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (del_alg) { - pr_debug("ieee80211_crypt: unregistered algorithm '%s'\n", - ops->name); - kfree(del_alg); - } - - return del_alg ? 0 : -1; -} - - -struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) -{ - unsigned long flags; - struct list_head *ptr; - struct ieee80211_crypto_alg *found_alg = NULL; - - if (!hcrypt) - return NULL; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *)ptr; - if (strcmp(alg->ops->name, name) == 0) { - found_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (found_alg) - return found_alg->ops; - return NULL; -} - - -static void *ieee80211_crypt_null_init(int keyidx) { return (void *)1; } -static void ieee80211_crypt_null_deinit(void *priv) {} - -static struct ieee80211_crypto_ops ieee80211_crypt_null = { - .name = "NULL", - .init = ieee80211_crypt_null_init, - .deinit = ieee80211_crypt_null_deinit, - .encrypt_mpdu = NULL, - .decrypt_mpdu = NULL, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = NULL, - .get_key = NULL, - .extra_prefix_len = 0, - .extra_postfix_len = 0, - .owner = THIS_MODULE, -}; - -int __init ieee80211_crypto_init(void) -{ - int ret = -ENOMEM; - - hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); - if (!hcrypt) - goto out; - - INIT_LIST_HEAD(&hcrypt->algs); - spin_lock_init(&hcrypt->lock); - - ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); - if (ret < 0) { - kfree(hcrypt); - hcrypt = NULL; - } -out: - return ret; -} - -void ieee80211_crypto_deinit(void) -{ - struct list_head *ptr, *n; - - if (!hcrypt) - return; - - for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; - ptr = n, n = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *)ptr; - list_del(ptr); - pr_debug("ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", - alg->ops->name); - kfree(alg); - } - - kfree(hcrypt); -} diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h deleted file mode 100644 index d3bd5598b25b..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Original code based on Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * - * Copyright (c) 2004, Intel Corporation - */ - -/* - * This file defines the interface to the ieee80211 crypto module. - */ -#ifndef IEEE80211_CRYPT_H -#define IEEE80211_CRYPT_H - -#include - -struct ieee80211_crypto_ops { - const char *name; - - /* init new crypto context (e.g., allocate private data space, - * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success - */ - void * (*init)(int keyidx); - - /* deinitialize crypto context and free allocated private data */ - void (*deinit)(void *priv); - - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return - * value from decrypt_mpdu is passed as the keyidx value for - * decrypt_msdu. skb must have enough head and tail room for the - * encryption; if not, error will be returned; these functions are - * called for all MPDUs (i.e., fragments). - */ - int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - - /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. - */ - int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); - - int (*set_key)(void *key, int len, u8 *seq, void *priv); - int (*get_key)(void *key, int len, u8 *seq, void *priv); - - /* procfs handler for printing out key information and possible - * statistics - */ - char * (*print_stats)(char *p, void *priv); - - /* maximum number of bytes added by encryption; encrypt buf is - * allocated with extra_prefix_len bytes, copy of in_buf, and - * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned - */ - int extra_prefix_len, extra_postfix_len; - - struct module *owner; -}; - -struct ieee80211_crypt_data { - struct list_head list; /* delayed deletion list */ - struct ieee80211_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); -void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force); -void ieee80211_crypt_deinit_handler(struct timer_list *t); -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt); - -#endif diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c deleted file mode 100644 index f17d07dad56d..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ /dev/null @@ -1,421 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include - #include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: CCMP"); -MODULE_LICENSE("GPL"); - -#define AES_BLOCK_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - -struct ieee80211_ccmp_data { - u8 key[CCMP_TK_LEN]; - int key_set; - - u8 tx_pn[CCMP_PN_LEN]; - u8 rx_pn[CCMP_PN_LEN]; - - u32 dot11RSNAStatsCCMPFormatErrors; - u32 dot11RSNAStatsCCMPReplays; - u32 dot11RSNAStatsCCMPDecryptErrors; - - int key_idx; - - struct crypto_aead *tfm; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_aad[2 * AES_BLOCK_LEN]; - u8 rx_aad[2 * AES_BLOCK_LEN]; -}; - -static void *ieee80211_ccmp_init(int key_idx) -{ - struct ieee80211_ccmp_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - goto fail; - priv->key_idx = key_idx; - - priv->tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tfm)) { - pr_debug("ieee80211_crypt_ccmp: could not allocate crypto API aes\n"); - priv->tfm = NULL; - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_aead(priv->tfm); - kfree(priv); - } - - return NULL; -} - -static void ieee80211_ccmp_deinit(void *priv) -{ - struct ieee80211_ccmp_data *_priv = priv; - - if (_priv && _priv->tfm) - crypto_free_aead(_priv->tfm); - kfree(priv); -} - -static int ccmp_init_iv_and_aad(struct rtl_80211_hdr_4addr *hdr, - u8 *pn, u8 *iv, u8 *aad) -{ - u8 *pos, qc = 0; - size_t aad_len; - u16 fc; - int a4_included, qc_included; - - fc = le16_to_cpu(hdr->frame_ctl); - a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); - /* qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && - * (WLAN_FC_GET_STYPE(fc) & 0x08)); - */ - /* fixed by David :2006.9.6 */ - qc_included = (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && - (WLAN_FC_GET_STYPE(fc) & 0x80); - aad_len = 22; - if (a4_included) - aad_len += 6; - if (qc_included) { - pos = (u8 *)&hdr->addr4; - if (a4_included) - pos += 6; - qc = *pos & 0x0f; - aad_len += 2; - } - - /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC - * mode authentication are not allowed to collide, yet both are derived - * from the same vector. We only set L := 1 here to indicate that the - * data size can be represented in (L+1) bytes. The CCM layer will take - * care of storing the data length in the top (L+1) bytes and setting - * and clearing the other bits as is required to derive the two IVs. - */ - iv[0] = 0x1; - - /* Nonce: QC | A2 | PN */ - iv[1] = qc; - memcpy(iv + 2, hdr->addr2, ETH_ALEN); - memcpy(iv + 8, pn, CCMP_PN_LEN); - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - pos = (u8 *)hdr; - aad[0] = pos[0] & 0x8f; - aad[1] = pos[1] & 0xc7; - memcpy(&aad[2], &hdr->addr1, ETH_ALEN); - memcpy(&aad[8], &hdr->addr2, ETH_ALEN); - memcpy(&aad[14], &hdr->addr3, ETH_ALEN); - pos = (u8 *)&hdr->seq_ctl; - aad[20] = pos[0] & 0x0f; - aad[21] = 0; /* all bits masked */ - memset(aad + 22, 0, 8); - if (a4_included) - memcpy(aad + 22, hdr->addr4, ETH_ALEN); - if (qc_included) { - aad[a4_included ? 28 : 22] = qc; - /* rest of QC masked */ - } - - return aad_len; -} - -static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_ccmp_data *key = priv; - int i; - u8 *pos; - struct rtl_80211_hdr_4addr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - - if (skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < CCMP_MIC_LEN || - skb->len < hdr_len) - return -1; - - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdr_len); - pos += hdr_len; - /* mic = skb_put(skb, CCMP_MIC_LEN); */ - - i = CCMP_PN_LEN - 1; - while (i >= 0) { - key->tx_pn[i]++; - if (key->tx_pn[i] != 0) - break; - i--; - } - - *pos++ = key->tx_pn[5]; - *pos++ = key->tx_pn[4]; - *pos++ = 0; - *pos++ = (key->key_idx << 6) | BIT(5) /* Ext IV included */; - *pos++ = key->tx_pn[3]; - *pos++ = key->tx_pn[2]; - *pos++ = key->tx_pn[1]; - *pos++ = key->tx_pn[0]; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - if (!tcb_desc->bHwSec) { - struct aead_request *req; - struct scatterlist sg[2]; - u8 *aad = key->tx_aad; - u8 iv[AES_BLOCK_LEN]; - int aad_len, ret; - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; - - req = aead_request_alloc(key->tfm, GFP_ATOMIC); - if (!req) - return -ENOMEM; - - aad_len = ccmp_init_iv_and_aad(hdr, key->tx_pn, iv, aad); - - skb_put(skb, CCMP_MIC_LEN); - - sg_init_table(sg, 2); - sg_set_buf(&sg[0], aad, aad_len); - sg_set_buf(&sg[1], skb->data + hdr_len + CCMP_HDR_LEN, - data_len + CCMP_MIC_LEN); - - aead_request_set_callback(req, 0, NULL, NULL); - aead_request_set_ad(req, aad_len); - aead_request_set_crypt(req, sg, sg, data_len, iv); - - ret = crypto_aead_encrypt(req); - aead_request_free(req); - - return ret; - } - return 0; -} - -static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_ccmp_data *key = priv; - u8 keyidx, *pos; - struct rtl_80211_hdr_4addr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 pn[6]; - - if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { - key->dot11RSNAStatsCCMPFormatErrors++; - return -1; - } - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & BIT(5))) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "CCMP: received packet without ExtIV flag from %pM\n", - hdr->addr2); - } - key->dot11RSNAStatsCCMPFormatErrors++; - return -2; - } - keyidx >>= 6; - if (key->key_idx != keyidx) { - netdev_dbg(skb->dev, "CCMP: RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", - key->key_idx, keyidx, priv); - return -6; - } - if (!key->key_set) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "CCMP: received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); - } - return -3; - } - - pn[0] = pos[7]; - pn[1] = pos[6]; - pn[2] = pos[5]; - pn[3] = pos[4]; - pn[4] = pos[1]; - pn[5] = pos[0]; - pos += 8; - - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "CCMP: replay detected: STA=%pM previous PN %pm received PN %pm\n", - hdr->addr2, key->rx_pn, pn); - } - key->dot11RSNAStatsCCMPReplays++; - return -4; - } - if (!tcb_desc->bHwSec) { - struct aead_request *req; - struct scatterlist sg[2]; - u8 *aad = key->rx_aad; - u8 iv[AES_BLOCK_LEN]; - int aad_len, ret; - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN; - - req = aead_request_alloc(key->tfm, GFP_ATOMIC); - if (!req) - return -ENOMEM; - - aad_len = ccmp_init_iv_and_aad(hdr, pn, iv, aad); - - sg_init_table(sg, 2); - sg_set_buf(&sg[0], aad, aad_len); - sg_set_buf(&sg[1], pos, data_len); - - aead_request_set_callback(req, 0, NULL, NULL); - aead_request_set_ad(req, aad_len); - aead_request_set_crypt(req, sg, sg, data_len, iv); - - ret = crypto_aead_decrypt(req); - aead_request_free(req); - - if (ret) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "CCMP: decrypt failed: STA=%pM\n", - hdr->addr2); - } - key->dot11RSNAStatsCCMPDecryptErrors++; - return -5; - } - - memcpy(key->rx_pn, pn, CCMP_PN_LEN); - } - /* Remove hdr and MIC */ - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); - skb_pull(skb, CCMP_HDR_LEN); - skb_trim(skb, skb->len - CCMP_MIC_LEN); - - return keyidx; -} - -static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_ccmp_data *data = priv; - int keyidx; - struct crypto_aead *tfm = data->tfm; - - keyidx = data->key_idx; - memset(data, 0, sizeof(*data)); - data->key_idx = keyidx; - if (len == CCMP_TK_LEN) { - memcpy(data->key, key, CCMP_TK_LEN); - data->key_set = 1; - if (seq) { - data->rx_pn[0] = seq[5]; - data->rx_pn[1] = seq[4]; - data->rx_pn[2] = seq[3]; - data->rx_pn[3] = seq[2]; - data->rx_pn[4] = seq[1]; - data->rx_pn[5] = seq[0]; - } - if (crypto_aead_setauthsize(tfm, CCMP_MIC_LEN) || - crypto_aead_setkey(tfm, data->key, CCMP_TK_LEN)) - return -1; - } else if (len == 0) { - data->key_set = 0; - } else { - return -1; - } - - return 0; -} - -static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_ccmp_data *data = priv; - - if (len < CCMP_TK_LEN) - return 0; - - if (!data->key_set) - return 0; - memcpy(key, data->key, CCMP_TK_LEN); - - if (seq) { - seq[0] = data->tx_pn[5]; - seq[1] = data->tx_pn[4]; - seq[2] = data->tx_pn[3]; - seq[3] = data->tx_pn[2]; - seq[4] = data->tx_pn[1]; - seq[5] = data->tx_pn[0]; - } - - return CCMP_TK_LEN; -} - -static char *ieee80211_ccmp_print_stats(char *p, void *priv) -{ - struct ieee80211_ccmp_data *ccmp = priv; - - p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - ccmp->tx_pn, ccmp->rx_pn, - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; -} - -static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { - .name = "CCMP", - .init = ieee80211_ccmp_init, - .deinit = ieee80211_ccmp_deinit, - .encrypt_mpdu = ieee80211_ccmp_encrypt, - .decrypt_mpdu = ieee80211_ccmp_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = ieee80211_ccmp_set_key, - .get_key = ieee80211_ccmp_get_key, - .print_stats = ieee80211_ccmp_print_stats, - .extra_prefix_len = CCMP_HDR_LEN, - .extra_postfix_len = CCMP_MIC_LEN, - .owner = THIS_MODULE, -}; - -int __init ieee80211_crypto_ccmp_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); -} - -void ieee80211_crypto_ccmp_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); -} diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c deleted file mode 100644 index 9bfd24ad46b6..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: TKIP"); -MODULE_LICENSE("GPL"); - -struct ieee80211_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct arc4_ctx rx_ctx_arc4; - struct arc4_ctx tx_ctx_arc4; - struct crypto_shash *rx_tfm_michael; - struct crypto_shash *tx_tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - -static void *ieee80211_tkip_init(int key_idx) -{ - struct ieee80211_tkip_data *priv; - - if (fips_enabled) - return NULL; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - goto fail; - priv->key_idx = key_idx; - - priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); - if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - priv->tx_tfm_michael = NULL; - goto fail; - } - - priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); - if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - priv->rx_tfm_michael = NULL; - goto fail; - } - - return priv; - -fail: - if (priv) { - crypto_free_shash(priv->tx_tfm_michael); - crypto_free_shash(priv->rx_tfm_michael); - kfree(priv); - } - - return NULL; -} - - -static void ieee80211_tkip_deinit(void *priv) -{ - struct ieee80211_tkip_data *_priv = priv; - - if (_priv) { - crypto_free_shash(_priv->tx_tfm_michael); - crypto_free_shash(_priv->rx_tfm_michael); - } - kfree_sensitive(priv); -} - - -static inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - - -static inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - - -static inline u8 Hi8(u16 val) -{ - return val >> 8; -} - - -static inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - - -static inline u16 Hi16(u32 val) -{ - return val >> 16; -} - - -static inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (((u16)hi) << 8); -} - -static const u16 Sbox[256] = { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - - -static inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - - -#define PHASE1_LOOP_COUNT 8 - - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* - * Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. - */ - u16 *PPK = (u16 *)&WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[0]))); - PPK[1] += _S_(PPK[0] ^ le16_to_cpu(*(__le16 *)(&TK[2]))); - PPK[2] += _S_(PPK[1] ^ le16_to_cpu(*(__le16 *)(&TK[4]))); - PPK[3] += _S_(PPK[2] ^ le16_to_cpu(*(__le16 *)(&TK[6]))); - PPK[4] += _S_(PPK[3] ^ le16_to_cpu(*(__le16 *)(&TK[8]))); - PPK[5] += _S_(PPK[4] ^ le16_to_cpu(*(__le16 *)(&TK[10]))); - - PPK[0] += RotR1(PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[12]))); - PPK[1] += RotR1(PPK[0] ^ le16_to_cpu(*(__le16 *)(&TK[14]))); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* - * Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV - */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[0]))) >> 1); - -#ifdef __BIG_ENDIAN - { - int i; - - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - - -static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - int len; - u8 *pos; - struct rtl_80211_hdr_4addr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 rc4key[16], *icv; - u32 crc; - - if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - - if (!tcb_desc->bHwSec) { - if (!tkey->tx_phase1_done) { - tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); - tkey->tx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - } else - tkey->tx_phase1_done = 1; - - - len = skb->len - hdr_len; - pos = skb_push(skb, 8); - memmove(pos, pos + 8, hdr_len); - pos += hdr_len; - - if (tcb_desc->bHwSec) { - *pos++ = Hi8(tkey->tx_iv16); - *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F; - *pos++ = Lo8(tkey->tx_iv16); - } else { - *pos++ = rc4key[0]; - *pos++ = rc4key[1]; - *pos++ = rc4key[2]; - } - - *pos++ = (tkey->key_idx << 6) | BIT(5) /* Ext IV included */; - *pos++ = tkey->tx_iv32 & 0xff; - *pos++ = (tkey->tx_iv32 >> 8) & 0xff; - *pos++ = (tkey->tx_iv32 >> 16) & 0xff; - *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - - if (!tcb_desc->bHwSec) { - icv = skb_put(skb, 4); - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16); - arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4); - } - - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - - return 0; -} - -static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - u8 keyidx, *pos; - u32 iv32; - u16 iv16; - struct rtl_80211_hdr_4addr *hdr; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 rc4key[16]; - u8 icv[4]; - u32 crc; - int plen; - - if (skb->len < hdr_len + 8 + 4) - return -1; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & BIT(5))) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "TKIP: received packet without ExtIV" - " flag from %pM\n", hdr->addr2); - } - return -2; - } - keyidx >>= 6; - if (tkey->key_idx != keyidx) { - netdev_dbg(skb->dev, "TKIP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); - return -6; - } - if (!tkey->key_set) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "TKIP: received packet from %pM" - " with keyid=%d that does not have a configured" - " key\n", hdr->addr2, keyidx); - } - return -3; - } - iv16 = (pos[0] << 8) | pos[2]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; - - if (!tcb_desc->bHwSec) { - if (iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { - if (net_ratelimit()) { - netdev_dbg(skb->dev, "TKIP: replay detected: STA=%pM" - " previous TSC %08x%04x received TSC " - "%08x%04x\n", hdr->addr2, - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); - } - tkey->dot11RSNAStatsTKIPReplays++; - return -4; - } - - if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); - tkey->rx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); - - plen = skb->len - hdr_len - 12; - - arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16); - arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - if (memcmp(icv, pos + plen, 4) != 0) { - if (iv32 != tkey->rx_iv32) { - /* - * Previously cached Phase1 result was already - * lost, so it needs to be recalculated for the - * next packet. - */ - tkey->rx_phase1_done = 0; - } - if (net_ratelimit()) { - netdev_dbg(skb->dev, "TKIP: ICV error detected: STA=" - "%pM\n", hdr->addr2); - } - tkey->dot11RSNAStatsTKIPICVErrors++; - return -5; - } - - } - - /* - * Update real counters only after Michael MIC verification has - * completed. - */ - tkey->rx_iv32_new = iv32; - tkey->rx_iv16_new = iv16; - - /* Remove IV and ICV */ - memmove(skb->data + 8, skb->data, hdr_len); - skb_pull(skb, 8); - skb_trim(skb, skb->len - 4); - - return keyidx; -} - -static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr, - u8 *data, size_t data_len, u8 *mic) -{ - SHASH_DESC_ON_STACK(desc, tfm_michael); - int err; - - desc->tfm = tfm_michael; - - if (crypto_shash_setkey(tfm_michael, key, 8)) - return -1; - - err = crypto_shash_init(desc); - if (err) - goto out; - err = crypto_shash_update(desc, hdr, 16); - if (err) - goto out; - err = crypto_shash_update(desc, data, data_len); - if (err) - goto out; - err = crypto_shash_final(desc, mic); - -out: - shash_desc_zero(desc); - return err; -} - -static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) -{ - struct rtl_80211_hdr_4addr *hdr11; - - hdr11 = (struct rtl_80211_hdr_4addr *)skb->data; - switch (le16_to_cpu(hdr11->frame_ctl) & - (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - case IEEE80211_FCTL_FROMDS: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ - break; - default: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - } - - hdr[12] = 0; /* priority */ - - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ -} - - -static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - u8 *pos; - struct rtl_80211_hdr_4addr *hdr; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - - if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - netdev_dbg(skb->dev, "Invalid packet for Michael MIC add " - "(tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); - return -1; - } - - michael_mic_hdr(skb, tkey->tx_hdr); - - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. - if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) - tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - // } - pos = skb_put(skb, 8); - - if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) - return -1; - - return 0; -} - -static void ieee80211_michael_mic_failure(struct net_device *dev, - struct rtl_80211_hdr_4addr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - - /* TODO: needed parameters: count, keyid, key type, TSC */ - memset(&ev, 0, sizeof(ev)); - ev.flags = keyidx & IW_MICFAILURE_KEY_ID; - if (hdr->addr1[0] & 0x01) - ev.flags |= IW_MICFAILURE_GROUP; - else - ev.flags |= IW_MICFAILURE_PAIRWISE; - ev.src_addr.sa_family = ARPHRD_ETHER; - memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); -} - -static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - u8 mic[8]; - struct rtl_80211_hdr_4addr *hdr; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - - if (!tkey->key_set) - return -1; - - michael_mic_hdr(skb, tkey->rx_hdr); - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. - if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) - tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - // } - - if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct rtl_80211_hdr_4addr *hdr; - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - - netdev_dbg(skb->dev, "Michael MIC verification failed for " - "MSDU from %pM keyidx=%d\n", - hdr->addr2, keyidx); - if (skb->dev) - ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); - tkey->dot11RSNAStatsTKIPLocalMICFailures++; - return -1; - } - - /* - * Update TSC counters for RX now that the packet verification has - * completed. - */ - tkey->rx_iv32 = tkey->rx_iv32_new; - tkey->rx_iv16 = tkey->rx_iv16_new; - - skb_trim(skb, skb->len - 8); - - return 0; -} - - -static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - int keyidx; - struct crypto_shash *tfm = tkey->tx_tfm_michael; - struct crypto_shash *tfm3 = tkey->rx_tfm_michael; - - keyidx = tkey->key_idx; - memset(tkey, 0, sizeof(*tkey)); - tkey->key_idx = keyidx; - tkey->tx_tfm_michael = tfm; - tkey->rx_tfm_michael = tfm3; - - if (len == TKIP_KEY_LEN) { - memcpy(tkey->key, key, TKIP_KEY_LEN); - tkey->key_set = 1; - tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ - if (seq) { - tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | - (seq[3] << 8) | seq[2]; - tkey->rx_iv16 = (seq[1] << 8) | seq[0]; - } - } else if (len == 0) - tkey->key_set = 0; - else - return -1; - - return 0; -} - - -static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - - if (len < TKIP_KEY_LEN) - return 0; - - if (!tkey->key_set) - return 0; - memcpy(key, tkey->key, TKIP_KEY_LEN); - - if (seq) { - /* Return the sequence number of the last transmitted frame. */ - u16 iv16 = tkey->tx_iv16; - u32 iv32 = tkey->tx_iv32; - - if (iv16 == 0) - iv32--; - iv16--; - seq[0] = tkey->tx_iv16; - seq[1] = tkey->tx_iv16 >> 8; - seq[2] = tkey->tx_iv32; - seq[3] = tkey->tx_iv32 >> 8; - seq[4] = tkey->tx_iv32 >> 16; - seq[5] = tkey->tx_iv32 >> 24; - } - - return TKIP_KEY_LEN; -} - - -static char *ieee80211_tkip_print_stats(char *p, void *priv) -{ - struct ieee80211_tkip_data *tkip = priv; - - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; -} - - -static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { - .name = "TKIP", - .init = ieee80211_tkip_init, - .deinit = ieee80211_tkip_deinit, - .encrypt_mpdu = ieee80211_tkip_encrypt, - .decrypt_mpdu = ieee80211_tkip_decrypt, - .encrypt_msdu = ieee80211_michael_mic_add, - .decrypt_msdu = ieee80211_michael_mic_verify, - .set_key = ieee80211_tkip_set_key, - .get_key = ieee80211_tkip_get_key, - .print_stats = ieee80211_tkip_print_stats, - .extra_prefix_len = 4 + 4, /* IV + ExtIV */ - .extra_postfix_len = 8 + 4, /* MIC + ICV */ - .owner = THIS_MODULE, -}; - -int __init ieee80211_crypto_tkip_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); -} - -void ieee80211_crypto_tkip_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); -} diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c deleted file mode 100644 index a2cdf3bfd1a4..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Host AP crypt: host-based WEP encryption implementation for Host AP driver - * - * Copyright (c) 2002-2004, Jouni Malinen - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: WEP"); -MODULE_LICENSE("GPL"); - -struct prism2_wep_data { - u32 iv; -#define WEP_KEY_LEN 13 - u8 key[WEP_KEY_LEN + 1]; - u8 key_len; - u8 key_idx; - struct arc4_ctx rx_ctx_arc4; - struct arc4_ctx tx_ctx_arc4; -}; - - -static void *prism2_wep_init(int keyidx) -{ - struct prism2_wep_data *priv; - - if (fips_enabled) - return NULL; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return NULL; - priv->key_idx = keyidx; - - /* start WEP IV from a random value */ - get_random_bytes(&priv->iv, 4); - - return priv; -} - - -static void prism2_wep_deinit(void *priv) -{ - kfree_sensitive(priv); -} - -/* Perform WEP encryption on given skb that has at least 4 bytes of headroom - * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, - * so the payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 klen, len; - u8 key[WEP_KEY_LEN + 3]; - u8 *pos; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u32 crc; - u8 *icv; - - if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - len = skb->len - hdr_len; - pos = skb_push(skb, 4); - memmove(pos, pos + 4, hdr_len); - pos += hdr_len; - - klen = 3 + wep->key_len; - - wep->iv++; - - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key - * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. - */ - if ((wep->iv & 0xff00) == 0xff00) { - u8 B = (wep->iv >> 16) & 0xff; - - if (B >= 3 && B < klen) - wep->iv += 0x0100; - } - - /* Prepend 24-bit IV to RC4 key and TX frame */ - *pos++ = key[0] = (wep->iv >> 16) & 0xff; - *pos++ = key[1] = (wep->iv >> 8) & 0xff; - *pos++ = key[2] = wep->iv & 0xff; - *pos++ = wep->key_idx << 6; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - if (!tcb_desc->bHwSec) { - /* Append little-endian CRC32 and encrypt it to produce ICV */ - crc = ~crc32_le(~0, pos, len); - icv = skb_put(skb, 4); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - arc4_setkey(&wep->tx_ctx_arc4, key, klen); - arc4_crypt(&wep->tx_ctx_arc4, pos, pos, len + 4); - } - - return 0; -} - - -/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). len includes both IV and ICV. - * - * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on - * failure. If frame is OK, IV and ICV will be removed. - */ -static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 klen, plen; - u8 key[WEP_KEY_LEN + 3]; - u8 keyidx, *pos; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u32 crc; - u8 icv[4]; - - if (skb->len < hdr_len + 8) - return -1; - - pos = skb->data + hdr_len; - key[0] = *pos++; - key[1] = *pos++; - key[2] = *pos++; - keyidx = *pos++ >> 6; - if (keyidx != wep->key_idx) - return -1; - - klen = 3 + wep->key_len; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - plen = skb->len - hdr_len - 8; - - if (!tcb_desc->bHwSec) { - arc4_setkey(&wep->rx_ctx_arc4, key, klen); - arc4_crypt(&wep->rx_ctx_arc4, pos, pos, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - /* ICV mismatch - drop frame */ - return -2; - } - } - /* Remove IV and ICV */ - memmove(skb->data + 4, skb->data, hdr_len); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - - return 0; -} - - -static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < 0 || len > WEP_KEY_LEN) - return -1; - - memcpy(wep->key, key, len); - wep->key_len = len; - - return 0; -} - - -static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < wep->key_len) - return 0; - - memcpy(key, wep->key, wep->key_len); - - return wep->key_len; -} - - -static char *prism2_wep_print_stats(char *p, void *priv) -{ - struct prism2_wep_data *wep = priv; - - p += sprintf(p, "key[%d] alg=WEP len=%d\n", - wep->key_idx, wep->key_len); - return p; -} - - -static struct ieee80211_crypto_ops ieee80211_crypt_wep = { - .name = "WEP", - .init = prism2_wep_init, - .deinit = prism2_wep_deinit, - .encrypt_mpdu = prism2_wep_encrypt, - .decrypt_mpdu = prism2_wep_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = prism2_wep_set_key, - .get_key = prism2_wep_get_key, - .print_stats = prism2_wep_print_stats, - .extra_prefix_len = 4, /* IV */ - .extra_postfix_len = 4, /* ICV */ - .owner = THIS_MODULE, -}; - -int __init ieee80211_crypto_wep_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); -} - -void ieee80211_crypto_wep_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); -} - diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c deleted file mode 100644 index 3f93939bc4ee..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ /dev/null @@ -1,287 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/******************************************************************************* - * - * Copyright(c) 2004 Intel Corporation. All rights reserved. - * - * Portions of this file are based on the WEP enablement code provided by the - * Host AP project hostap-drivers v0.1.3 - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - ******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -MODULE_DESCRIPTION("802.11 data/management/control stack"); -MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation "); -MODULE_LICENSE("GPL"); - -#define DRV_NAME "ieee80211" - -static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) -{ - if (ieee->networks) - return 0; - - ieee->networks = kcalloc(MAX_NETWORK_COUNT, - sizeof(struct ieee80211_network), - GFP_KERNEL); - if (!ieee->networks) { - netdev_warn(ieee->dev, "Out of memory allocating beacons\n"); - return -ENOMEM; - } - - return 0; -} - -static inline void ieee80211_networks_free(struct ieee80211_device *ieee) -{ - if (!ieee->networks) - return; - kfree(ieee->networks); - ieee->networks = NULL; -} - -static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) -{ - int i; - - INIT_LIST_HEAD(&ieee->network_free_list); - INIT_LIST_HEAD(&ieee->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); -} - -struct net_device *alloc_ieee80211(int sizeof_priv) -{ - struct ieee80211_device *ieee; - struct net_device *dev; - int i, err; - - IEEE80211_DEBUG_INFO("Initializing...\n"); - - dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); - if (!dev) { - IEEE80211_ERROR("Unable to network device.\n"); - goto failed; - } - - ieee = netdev_priv(dev); - ieee->dev = dev; - - err = ieee80211_networks_allocate(ieee); - if (err) { - IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", - err); - goto failed; - } - ieee80211_networks_initialize(ieee); - - /* Default fragmentation threshold is maximum payload size */ - ieee->fts = DEFAULT_FTS; - ieee->scan_age = DEFAULT_MAX_SCAN_AGE; - ieee->open_wep = 1; - - /* Default to enabling full open WEP with host based encrypt/decrypt */ - ieee->host_encrypt = 1; - ieee->host_decrypt = 1; - ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ - - INIT_LIST_HEAD(&ieee->crypt_deinit_list); - timer_setup(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler, - 0); - - spin_lock_init(&ieee->lock); - spin_lock_init(&ieee->wpax_suitlist_lock); - spin_lock_init(&ieee->bw_spinlock); - spin_lock_init(&ieee->reorder_spinlock); - /* added by WB */ - atomic_set(&ieee->atm_chnlop, 0); - atomic_set(&ieee->atm_swbw, 0); - - ieee->wpax_type_set = 0; - ieee->wpa_enabled = 0; - ieee->tkip_countermeasures = 0; - ieee->drop_unencrypted = 0; - ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; - ieee->raw_tx = 0; - //ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead. - ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary. */ - - ieee80211_softmac_init(ieee); - - ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); - if (!ieee->pHTInfo) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); - - /* By this point in code ieee80211_networks_allocate() has been - * successfully called so the memory allocated should be freed - */ - ieee80211_networks_free(ieee); - goto failed; - } - HTUpdateDefaultSetting(ieee); - HTInitializeHTInfo(ieee); /* may move to other place. */ - TSInitialize(ieee); - - for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) - INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - return dev; - - failed: - if (dev) - free_netdev(dev); - - return NULL; -} - -void free_ieee80211(struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - int i; - /* struct list_head *p, *q; */ -// del_timer_sync(&ieee->SwBwTimer); - kfree(ieee->pHTInfo); - ieee->pHTInfo = NULL; - RemoveAllTS(ieee); - ieee80211_softmac_free(ieee); - del_timer_sync(&ieee->crypt_deinit_timer); - ieee80211_crypt_deinit_entries(ieee, 1); - - for (i = 0; i < WEP_KEYS; i++) { - struct ieee80211_crypt_data *crypt = ieee->crypt[i]; - - if (crypt) { - if (crypt->ops) - crypt->ops->deinit(crypt->priv); - kfree(crypt); - ieee->crypt[i] = NULL; - } - } - - ieee80211_networks_free(ieee); - free_netdev(dev); -} - -#ifdef CONFIG_IEEE80211_DEBUG - -u32 ieee80211_debug_level; -static int debug = // IEEE80211_DL_INFO | - // IEEE80211_DL_WX | - // IEEE80211_DL_SCAN | - // IEEE80211_DL_STATE | - // IEEE80211_DL_MGMT | - // IEEE80211_DL_FRAG | - // IEEE80211_DL_EAP | - // IEEE80211_DL_DROP | - // IEEE80211_DL_TX | - // IEEE80211_DL_RX | - //IEEE80211_DL_QOS | - // IEEE80211_DL_HT | - // IEEE80211_DL_TS | -// IEEE80211_DL_BA | - // IEEE80211_DL_REORDER| -// IEEE80211_DL_TRACE | - //IEEE80211_DL_DATA | - IEEE80211_DL_ERR /* awayls open this flags to show error out */ - ; -static struct proc_dir_entry *ieee80211_proc; - -static int show_debug_level(struct seq_file *m, void *v) -{ - seq_printf(m, "0x%08X\n", ieee80211_debug_level); - - return 0; -} - -static ssize_t write_debug_level(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - unsigned long val; - int err = kstrtoul_from_user(buffer, count, 0, &val); - - if (err) - return err; - ieee80211_debug_level = val; - return count; -} - -static int open_debug_level(struct inode *inode, struct file *file) -{ - return single_open(file, show_debug_level, NULL); -} - -static const struct proc_ops debug_level_proc_ops = { - .proc_open = open_debug_level, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = write_debug_level, - .proc_release = single_release, -}; - -int __init ieee80211_debug_init(void) -{ - struct proc_dir_entry *e; - - ieee80211_debug_level = debug; - - ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); - if (!ieee80211_proc) { - IEEE80211_ERROR("Unable to create " DRV_NAME - " proc directory\n"); - return -EIO; - } - e = proc_create("debug_level", 0644, ieee80211_proc, &debug_level_proc_ops); - if (!e) { - remove_proc_entry(DRV_NAME, init_net.proc_net); - ieee80211_proc = NULL; - return -EIO; - } - return 0; -} - -void ieee80211_debug_exit(void) -{ - if (ieee80211_proc) { - remove_proc_entry("debug_level", ieee80211_proc); - remove_proc_entry(DRV_NAME, init_net.proc_net); - ieee80211_proc = NULL; - } -} - -module_param(debug, int, 0444); -MODULE_PARM_DESC(debug, "debug output mask"); -#endif diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c deleted file mode 100644 index 5da8ac401df0..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ /dev/null @@ -1,2430 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Original code based Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3 - hostap.o module, common routines - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * Copyright (c) 2004, Intel Corporation - ****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" -#include "dot11d.h" -static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct rtl_80211_hdr_4addr *hdr = (struct rtl_80211_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - skb->dev = ieee->dev; - skb_reset_mac_header(skb); - - skb_pull(skb, ieee80211_get_hdrlen(fc)); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_80211_RAW); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static struct ieee80211_frag_entry * -ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq, - unsigned int frag, u8 tid, u8 *src, u8 *dst) -{ - struct ieee80211_frag_entry *entry; - int i; - - for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) { - entry = &ieee->frag_cache[tid][i]; - if (entry->skb && - time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - IEEE80211_DEBUG_FRAG( - "expiring fragment cache entry " - "seq=%u last_frag=%u\n", - entry->seq, entry->last_frag); - dev_kfree_skb_any(entry->skb); - entry->skb = NULL; - } - - if (entry->skb && entry->seq == seq && - (entry->last_frag + 1 == frag || frag == -1) && - memcmp(entry->src_addr, src, ETH_ALEN) == 0 && - memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) - return entry; - } - - return NULL; -} - -/* Called only as a tasklet (software IRQ) */ -static struct sk_buff * -ieee80211_frag_cache_get(struct ieee80211_device *ieee, - struct rtl_80211_hdr_4addr *hdr) -{ - struct sk_buff *skb = NULL; - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int frag = WLAN_GET_SEQ_FRAG(sc); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct rtl_80211_hdr_3addrqos *hdr_3addrqos; - struct rtl_80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - if (frag == 0) { - /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct rtl_80211_hdr_4addr) + - 8 /* LLC */ + - 2 /* alignment */ + - 8 /* WEP */ + - ETH_ALEN /* WDS */ + - (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */); - if (!skb) - return NULL; - - entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; - ieee->frag_next_idx[tid]++; - if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN) - ieee->frag_next_idx[tid] = 0; - - if (entry->skb) - dev_kfree_skb_any(entry->skb); - - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->last_frag = frag; - entry->skb = skb; - memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); - memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); - } else { - /* received a fragment of a frame for which the head fragment - * should have already been received */ - entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, - hdr->addr1); - if (entry) { - entry->last_frag = frag; - skb = entry->skb; - } - } - - return skb; -} - - -/* Called only as a tasklet (software IRQ) */ -static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, - struct rtl_80211_hdr_4addr *hdr) -{ - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct rtl_80211_hdr_3addrqos *hdr_3addrqos; - struct rtl_80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, - hdr->addr1); - - if (!entry) { - IEEE80211_DEBUG_FRAG( - "could not invalidate fragment cache " - "entry (seq=%u)\n", seq); - return -1; - } - - entry->skb = NULL; - return 0; -} - - - -/* ieee80211_rx_frame_mgtmt - * - * Responsible for handling management control frames - * - * Called by ieee80211_rx */ -static inline int -ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) -{ - /* On the struct stats definition there is written that - * this is not mandatory.... but seems that the probe - * response parser uses it - */ - struct rtl_80211_hdr_3addr *hdr = (struct rtl_80211_hdr_3addr *)skb->data; - - rx_stats->len = skb->len; - ieee80211_rx_mgt(ieee, (struct rtl_80211_hdr_4addr *)skb->data, rx_stats); - /* if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) */ - if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) { - /* use ADDR1 to perform address matching for Management frames */ - dev_kfree_skb_any(skb); - return 0; - } - - ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype); - - dev_kfree_skb_any(skb); - - return 0; - - #ifdef NOT_YET - if (ieee->iw_mode == IW_MODE_MASTER) { - netdev_dbg(ieee->dev, "Master mode not yet supported.\n"); - return 0; -/* - hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *) - skb->data);*/ - } - - if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) { - if (stype == WLAN_FC_STYPE_BEACON && - ieee->iw_mode == IW_MODE_MASTER) { - struct sk_buff *skb2; - /* Process beacon frames also in kernel driver to - * update STA(AP) table statistics */ - skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2) - hostap_rx(skb2->dev, skb2, rx_stats); - } - - /* send management frames to the user space daemon for - * processing */ - ieee->apdevstats.rx_packets++; - ieee->apdevstats.rx_bytes += skb->len; - prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT); - return 0; - } - - if (ieee->iw_mode == IW_MODE_MASTER) { - if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { - netdev_dbg(skb->dev, "unknown management frame " - "(type=0x%02x, stype=0x%02x) dropped\n", - type, stype); - return -1; - } - - hostap_rx(skb->dev, skb, rx_stats); - return 0; - } - - netdev_dbg(skb->dev, "hostap_rx_frame_mgmt: management frame " - "received in non-Host AP mode\n"); - return -1; - #endif -} - - - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = { - 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = { - 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - -/* Called by ieee80211_rx_frame_decrypt */ -static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, - struct sk_buff *skb, size_t hdrlen) -{ - struct net_device *dev = ieee->dev; - u16 fc, ethertype; - struct rtl_80211_hdr_4addr *hdr; - u8 *pos; - - if (skb->len < 24) - return 0; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - - /* check that the frame is unicast frame to us */ - if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_TODS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - /* FromDS frame with own addr as DA */ - } else - return 0; - - if (skb->len < 24 + 8) - return 0; - - /* check for port access entity Ethernet type */ -// pos = skb->data + 24; - pos = skb->data + hdrlen; - ethertype = (pos[6] << 8) | pos[7]; - if (ethertype == ETH_P_PAE) - return 1; - - return 0; -} - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) -{ - struct rtl_80211_hdr_4addr *hdr; - int res, hdrlen; - - if (!crypt || !crypt->ops->decrypt_mpdu) - return 0; - if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->bHwSec = 1; - } - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - - if (ieee->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { - if (net_ratelimit()) { - netdev_dbg(ieee->dev, "TKIP countermeasures: dropped " - "received packet from %pM\n", - hdr->addr2); - } - return -1; - } - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - IEEE80211_DEBUG_DROP( - "decryption failed (SA=%pM" - ") res=%d\n", hdr->addr2, res); - if (res == -2) - IEEE80211_DEBUG_DROP("Decryption failed ICV " - "mismatch (key %d)\n", - skb->data[hdrlen + 3] >> 6); - ieee->ieee_stats.rx_discards_undecryptable++; - return -1; - } - - return res; -} - - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *skb, - int keyidx, struct ieee80211_crypt_data *crypt) -{ - struct rtl_80211_hdr_4addr *hdr; - int res, hdrlen; - - if (!crypt || !crypt->ops->decrypt_msdu) - return 0; - if (ieee->hwsec_active) { - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->bHwSec = 1; - } - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_dbg(ieee->dev, "MSDU decryption/MIC verification failed" - " (SA=%pM keyidx=%d)\n", - hdr->addr2, keyidx); - return -1; - } - - return 0; -} - - -/* this function is stolen from ipw2200 driver*/ -#define IEEE_PACKET_RETRY_TIME (5 * HZ) -static int is_duplicate_packet(struct ieee80211_device *ieee, - struct rtl_80211_hdr_4addr *header) -{ - u16 fc = le16_to_cpu(header->frame_ctl); - u16 sc = le16_to_cpu(header->seq_ctl); - u16 seq = WLAN_GET_SEQ_SEQ(sc); - u16 frag = WLAN_GET_SEQ_FRAG(sc); - u16 *last_seq, *last_frag; - unsigned long *last_time; - struct rtl_80211_hdr_3addrqos *hdr_3addrqos; - struct rtl_80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - - //TO2DS and QoS - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS - hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid++; - } else { // no QoS - tid = 0; - } - - switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - { - struct list_head *p; - struct ieee_ibss_seq *entry = NULL; - u8 *mac = header->addr2; - int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; - - list_for_each(p, &ieee->ibss_mac_hash[index]) { - entry = list_entry(p, struct ieee_ibss_seq, list); - if (!memcmp(entry->mac, mac, ETH_ALEN)) - break; - } - // if (memcmp(entry->mac, mac, ETH_ALEN)){ - if (p == &ieee->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); - if (!entry) - return 0; - memcpy(entry->mac, mac, ETH_ALEN); - entry->seq_num[tid] = seq; - entry->frag_num[tid] = frag; - entry->packet_time[tid] = jiffies; - list_add(&entry->list, &ieee->ibss_mac_hash[index]); - return 0; - } - last_seq = &entry->seq_num[tid]; - last_frag = &entry->frag_num[tid]; - last_time = &entry->packet_time[tid]; - break; - } - - case IW_MODE_INFRA: - last_seq = &ieee->last_rxseq_num[tid]; - last_frag = &ieee->last_rxfrag_num[tid]; - last_time = &ieee->last_packet_time[tid]; - - break; - default: - return 0; - } - -// if(tid != 0) { -// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl); -// } - if ((*last_seq == seq) && - time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { - if (*last_frag == frag) - goto drop; - if (*last_frag + 1 != frag) - /* out-of-order fragment */ - goto drop; - } else - *last_seq = seq; - - *last_frag = frag; - *last_time = jiffies; - return 0; - -drop: -// BUG_ON(!(fc & IEEE80211_FCTL_RETRY)); - - return 1; -} - -static bool AddReorderEntry(struct rx_ts_record *pTS, struct rx_reorder_entry *pReorderEntry) -{ - struct list_head *pList = &pTS->rx_pending_pkt_list; - while (pList->next != &pTS->rx_pending_pkt_list) { - if (SN_LESS(pReorderEntry->SeqNum, list_entry(pList->next, struct rx_reorder_entry, List)->SeqNum)) - pList = pList->next; - else if (SN_EQUAL(pReorderEntry->SeqNum, list_entry(pList->next, struct rx_reorder_entry, List)->SeqNum)) - return false; - else - break; - } - pReorderEntry->List.next = pList->next; - pReorderEntry->List.next->prev = &pReorderEntry->List; - pReorderEntry->List.prev = pList; - pList->next = &pReorderEntry->List; - - return true; -} - -static void indicate_packets(struct ieee80211_device *ieee, - struct ieee80211_rxb *rxb) -{ - struct net_device_stats *stats = &ieee->stats; - struct net_device *dev = ieee->dev; - u16 ethertype; - u8 i; - - for (i = 0; i < rxb->nr_subframes; i++) { - struct sk_buff *sub_skb = rxb->subframes[i]; - - if (!sub_skb) - continue; - - /* convert hdr + possible LLC headers into Ethernet header */ - ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) && - ethertype != ETH_P_AARP && - ethertype != ETH_P_IPX) || - !memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(sub_skb, SNAP_SIZE); - } else { - /* Leave Ethernet header part of hdr and full payload */ - put_unaligned_be16(sub_skb->len, skb_push(sub_skb, 2)); - } - memcpy(skb_push(sub_skb, ETH_ALEN), rxb->src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), rxb->dst, ETH_ALEN); - - stats->rx_packets++; - stats->rx_bytes += sub_skb->len; - if (is_multicast_ether_addr(rxb->dst)) - stats->multicast++; - - /* Indicate the packets to upper layer */ - sub_skb->protocol = eth_type_trans(sub_skb, dev); - memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->dev = dev; - /* 802.11 crc not sufficient */ - sub_skb->ip_summed = CHECKSUM_NONE; - ieee->last_rx_ps_time = jiffies; - netif_rx(sub_skb); - } -} - -void ieee80211_indicate_packets(struct ieee80211_device *ieee, - struct ieee80211_rxb **prxbIndicateArray, - u8 index) -{ - u8 i; - - for (i = 0; i < index; i++) { - struct ieee80211_rxb *prxb = prxbIndicateArray[i]; - - indicate_packets(ieee, prxb); - kfree(prxb); - prxb = NULL; - } -} - -static void RxReorderIndicatePacket(struct ieee80211_device *ieee, - struct ieee80211_rxb *prxb, - struct rx_ts_record *pTS, u16 SeqNum) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - struct rx_reorder_entry *pReorderEntry = NULL; - struct ieee80211_rxb **prxbIndicateArray; - u8 WinSize = pHTInfo->RxReorderWinSize; - u16 WinEnd = (pTS->rx_indicate_seq + WinSize - 1) % 4096; - u8 index = 0; - bool bMatchWinStart = false, bPktInBuf = false; - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Seq is %d,pTS->rx_indicate_seq is %d, WinSize is %d\n", __func__, SeqNum, pTS->rx_indicate_seq, WinSize); - - prxbIndicateArray = kmalloc_array(REORDER_WIN_SIZE, - sizeof(struct ieee80211_rxb *), - GFP_ATOMIC); - if (!prxbIndicateArray) - return; - - /* Rx Reorder initialize condition.*/ - if (pTS->rx_indicate_seq == 0xffff) - pTS->rx_indicate_seq = SeqNum; - - /* Drop out the packet which SeqNum is smaller than WinStart */ - if (SN_LESS(SeqNum, pTS->rx_indicate_seq)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", - pTS->rx_indicate_seq, SeqNum); - pHTInfo->RxReorderDropCounter++; - { - int i; - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - - kfree(prxb); - prxb = NULL; - } - - kfree(prxbIndicateArray); - return; - } - - /* - * Sliding window manipulation. Conditions includes: - * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 - * 2. Incoming SeqNum is larger than the WinEnd => Window shift N - */ - if (SN_EQUAL(SeqNum, pTS->rx_indicate_seq)) { - pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % 4096; - bMatchWinStart = true; - } else if (SN_LESS(WinEnd, SeqNum)) { - if (SeqNum >= (WinSize - 1)) - pTS->rx_indicate_seq = SeqNum + 1 - WinSize; - else - pTS->rx_indicate_seq = 4095 - (WinSize - (SeqNum + 1)) + 1; - - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); - } - - /* - * Indication process. - * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets - * with the SeqNum smaller than latest WinStart and buffer other packets. - */ - /* For Rx Reorder condition: - * 1. All packets with SeqNum smaller than WinStart => Indicate - * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. - */ - if (bMatchWinStart) { - /* Current packet is going to be indicated.*/ - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\ - pTS->rx_indicate_seq, SeqNum); - prxbIndicateArray[0] = prxb; -// printk("========================>%s(): SeqNum is %d\n",__func__,SeqNum); - index = 1; - } else { - /* Current packet is going to be inserted into pending list.*/ - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to ordered list\n",__func__); - if (!list_empty(&ieee->RxReorder_Unused_List)) { - pReorderEntry = list_entry(ieee->RxReorder_Unused_List.next, struct rx_reorder_entry, List); - list_del_init(&pReorderEntry->List); - - /* Make a reorder entry and insert into a the packet list.*/ - pReorderEntry->SeqNum = SeqNum; - pReorderEntry->prxb = prxb; - // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__func__,pReorderEntry->SeqNum); - - if (!AddReorderEntry(pTS, pReorderEntry)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", - __func__, pTS->rx_indicate_seq, SeqNum); - list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); - { - int i; - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - - kfree(prxb); - prxb = NULL; - } - } else { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, - "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); - } - } else { - /* - * Packets are dropped if there is not enough reorder entries. - * This part shall be modified!! We can just indicate all the - * packets in buffer and get reorder entries. - */ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n"); - { - int i; - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - - kfree(prxb); - prxb = NULL; - } - } - } - - /* Check if there is any packet need indicate.*/ - while (!list_empty(&pTS->rx_pending_pkt_list)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): start RREORDER indicate\n", __func__); - pReorderEntry = list_entry(pTS->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); - if (SN_LESS(pReorderEntry->SeqNum, pTS->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) { - /* This protect buffer from overflow. */ - if (index >= REORDER_WIN_SIZE) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n"); - bPktInBuf = true; - break; - } - - list_del_init(&pReorderEntry->List); - - if (SN_EQUAL(pReorderEntry->SeqNum, pTS->rx_indicate_seq)) - pTS->rx_indicate_seq = (pTS->rx_indicate_seq + 1) % 4096; - - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n", pTS->rx_indicate_seq, SeqNum); - prxbIndicateArray[index] = pReorderEntry->prxb; - // printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__func__,pReorderEntry->SeqNum); - index++; - - list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); - } else { - bPktInBuf = true; - break; - } - } - - /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/ - if (index > 0) { - // Cancel previous pending timer. - // del_timer_sync(&pTS->rx_pkt_pending_timer); - pTS->rx_timeout_indicate_seq = 0xffff; - - // Indicate packets - if (index > REORDER_WIN_SIZE) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"); - kfree(prxbIndicateArray); - return; - } - ieee80211_indicate_packets(ieee, prxbIndicateArray, index); - } - - if (bPktInBuf && pTS->rx_timeout_indicate_seq == 0xffff) { - // Set new pending timer. - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): SET rx timeout timer\n", __func__); - pTS->rx_timeout_indicate_seq = pTS->rx_indicate_seq; - if (timer_pending(&pTS->rx_pkt_pending_timer)) - del_timer_sync(&pTS->rx_pkt_pending_timer); - pTS->rx_pkt_pending_timer.expires = jiffies + - msecs_to_jiffies(pHTInfo->RxReorderPendingTime); - add_timer(&pTS->rx_pkt_pending_timer); - } - - kfree(prxbIndicateArray); -} - -static u8 parse_subframe(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, - struct ieee80211_rxb *rxb, u8 *src, u8 *dst) -{ - struct rtl_80211_hdr_3addr *hdr = (struct rtl_80211_hdr_3addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - u16 LLCOffset = sizeof(struct rtl_80211_hdr_3addr); - u16 ChkLength; - bool bIsAggregateFrame = false; - u16 nSubframe_Length; - u8 nPadding_Length = 0; - u16 SeqNum = 0; - - struct sk_buff *sub_skb; - /* just for debug purpose */ - SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl)); - - if ((IEEE80211_QOS_HAS_SEQ(fc)) && \ - (((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) { - bIsAggregateFrame = true; - } - - if (IEEE80211_QOS_HAS_SEQ(fc)) - LLCOffset += 2; - - if (rx_stats->bContainHTC) - LLCOffset += HTCLNG; - - // Null packet, don't indicate it to upper layer - ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ - - if (skb->len <= ChkLength) - return 0; - - skb_pull(skb, LLCOffset); - - if (!bIsAggregateFrame) { - rxb->nr_subframes = 1; -#ifdef JOHN_NOCPY - rxb->subframes[0] = skb; -#else - rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC); -#endif - - memcpy(rxb->src, src, ETH_ALEN); - memcpy(rxb->dst, dst, ETH_ALEN); - //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len); - return 1; - } else { - rxb->nr_subframes = 0; - memcpy(rxb->src, src, ETH_ALEN); - memcpy(rxb->dst, dst, ETH_ALEN); - while (skb->len > ETHERNET_HEADER_SIZE) { - /* Offset 12 denote 2 mac address */ - nSubframe_Length = *((u16 *)(skb->data + 12)); - //==m==>change the length order - nSubframe_Length = (nSubframe_Length >> 8) + (nSubframe_Length << 8); - - if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { - netdev_dbg(ieee->dev, "A-MSDU parse error!! pRfd->nTotalSubframe : %d\n", - rxb->nr_subframes); - netdev_dbg(ieee->dev, "A-MSDU parse error!! Subframe Length: %d\n", nSubframe_Length); - netdev_dbg(ieee->dev, "nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len, nSubframe_Length); - netdev_dbg(ieee->dev, "The Packet SeqNum is %d\n", SeqNum); - return 0; - } - - /* move the data point to data content */ - skb_pull(skb, ETHERNET_HEADER_SIZE); - -#ifdef JOHN_NOCPY - sub_skb = skb_clone(skb, GFP_ATOMIC); - sub_skb->len = nSubframe_Length; - sub_skb->tail = sub_skb->data + nSubframe_Length; -#else - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(nSubframe_Length + 12); - if (!sub_skb) - return 0; - skb_reserve(sub_skb, 12); - skb_put_data(sub_skb, skb->data, nSubframe_Length); -#endif - rxb->subframes[rxb->nr_subframes++] = sub_skb; - if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { - IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n"); - break; - } - skb_pull(skb, nSubframe_Length); - - if (skb->len != 0) { - nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4); - if (nPadding_Length == 4) - nPadding_Length = 0; - - if (skb->len < nPadding_Length) - return 0; - - skb_pull(skb, nPadding_Length); - } - } -#ifdef JOHN_NOCPY - dev_kfree_skb(skb); -#endif - //{just for debug added by david - //printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes); - //} - return rxb->nr_subframes; - } -} - -/* All received frames are sent to this function. @skb contains the frame in - * IEEE 802.11 format, i.e., in the format it was sent over air. - * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct net_device *dev = ieee->dev; - struct rtl_80211_hdr_4addr *hdr; - //struct rtl_80211_hdr_3addrqos *hdr; - - size_t hdrlen; - u16 fc, type, stype, sc; - struct net_device_stats *stats; - unsigned int frag; - //added by amy for reorder - u8 TID = 0; - u16 SeqNum = 0; - struct rx_ts_record *pTS = NULL; - //bool bIsAggregateFrame = false; - //added by amy for reorder -#ifdef NOT_YET - struct net_device *wds = NULL; - struct net_device *wds = NULL; - int from_assoc_ap = 0; - void *sta = NULL; -#endif -// u16 qos_ctl = 0; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - struct ieee80211_crypt_data *crypt = NULL; - int keyidx = 0; - - int i; - struct ieee80211_rxb *rxb = NULL; - // cheat the hdr type - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - stats = &ieee->stats; - - if (skb->len < 10) { - netdev_info(dev, "SKB length < 10\n"); - goto rx_dropped; - } - - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctl); - - frag = WLAN_GET_SEQ_FRAG(sc); - hdrlen = ieee80211_get_hdrlen(fc); - - if (HTCCheck(ieee, skb->data)) { - if (net_ratelimit()) - netdev_warn(dev, "find HTCControl\n"); - hdrlen += 4; - rx_stats->bContainHTC = true; - } - - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); -#ifdef NOT_YET - /* Put this code here so that we avoid duplicating it in all - * Rx paths. - Jean II */ -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ - /* If spy monitoring on */ - if (iface->spy_data.spy_number > 0) { - struct iw_quality wstats; - wstats.level = rx_stats->rssi; - wstats.noise = rx_stats->noise; - wstats.updated = 6; /* No qual value */ - /* Update spy records */ - wireless_spy_update(dev, hdr->addr2, &wstats); - } -#endif /* IW_WIRELESS_SPY */ - hostap_update_rx_stats(local->ap, hdr, rx_stats); -#endif - - if (ieee->iw_mode == IW_MODE_MONITOR) { - unsigned int len = skb->len; - - ieee80211_monitor_rx(ieee, skb, rx_stats); - stats->rx_packets++; - stats->rx_bytes += len; - return 1; - } - - if (ieee->host_decrypt) { - int idx = 0; - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - crypt = ieee->crypt[idx]; -#ifdef NOT_YET - sta = NULL; - - /* Use station specific key to override default keys if the - * receiver address is a unicast address ("individual RA"). If - * bcrx_sta_key parameter is set, station specific key is used - * even with broad/multicast targets (this is against IEEE - * 802.11, but makes it easier to use different keys with - * stations that do not support WEP key mapping). */ - - if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) - (void)hostap_handle_sta_crypto(local, hdr, &crypt, - &sta); -#endif - - /* allow NULL decrypt to indicate an station specific override - * for default encryption */ - if (crypt && (!crypt->ops || !crypt->ops->decrypt_mpdu)) - crypt = NULL; - - if (!crypt && (fc & IEEE80211_FCTL_WEP)) { - /* This seems to be triggered by some (multicast?) - * frames from other than current BSS, so just drop the - * frames silently instead of filling system log with - * these reports. */ - IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=%pM)\n", - hdr->addr2); - ieee->ieee_stats.rx_discards_undecryptable++; - goto rx_dropped; - } - } - - if (skb->len < IEEE80211_DATA_HDR3_LEN) - goto rx_dropped; - - // if QoS enabled, should check the sequence for each of the AC - if ((!ieee->pHTInfo->bCurRxReorderEnable) || !ieee->current_network.qos_data.active || !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)) { - if (is_duplicate_packet(ieee, hdr)) - goto rx_dropped; - - } else { - struct rx_ts_record *pRxTS = NULL; - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__func__, tid); - if (GetTs( - ieee, - (struct ts_common_info **)&pRxTS, - hdr->addr2, - Frame_QoSTID((u8 *)(skb->data)), - RX_DIR, - true)) { - - // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->rx_last_frag_num is %d,frag is %d,pRxTS->rx_last_seq_num is %d,seq is %d\n",__func__,pRxTS->rx_last_frag_num,frag,pRxTS->rx_last_seq_num,WLAN_GET_SEQ_SEQ(sc)); - if ((fc & (1 << 11)) && - (frag == pRxTS->rx_last_frag_num) && - (WLAN_GET_SEQ_SEQ(sc) == pRxTS->rx_last_seq_num)) { - goto rx_dropped; - } else { - pRxTS->rx_last_frag_num = frag; - pRxTS->rx_last_seq_num = WLAN_GET_SEQ_SEQ(sc); - } - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n", __func__); - goto rx_dropped; - } - } - if (type == IEEE80211_FTYPE_MGMT) { - - - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); - if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) - goto rx_dropped; - else - goto rx_exit; - } - - /* Data frame - extract src/dst addresses */ - switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_FROMDS: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - memcpy(bssid, hdr->addr2, ETH_ALEN); - break; - case IEEE80211_FCTL_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr1, ETH_ALEN); - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - if (skb->len < IEEE80211_DATA_HDR4_LEN) - goto rx_dropped; - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); - break; - default: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr3, ETH_ALEN); - break; - } - -#ifdef NOT_YET - if (hostap_rx_frame_wds(ieee, hdr, fc, &wds)) - goto rx_dropped; - if (wds) { - skb->dev = dev = wds; - stats = hostap_get_stats(dev); - } - - if (ieee->iw_mode == IW_MODE_MASTER && !wds && - (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && - ieee->stadev && - memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) { - /* Frame from BSSID of the AP for which we are a client */ - skb->dev = dev = ieee->stadev; - stats = hostap_get_stats(dev); - from_assoc_ap = 1; - } - - if ((ieee->iw_mode == IW_MODE_MASTER || - ieee->iw_mode == IW_MODE_REPEAT) && - !from_assoc_ap) { - switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats, - wds)) { - case AP_RX_CONTINUE_NOT_AUTHORIZED: - case AP_RX_CONTINUE: - break; - case AP_RX_DROP: - goto rx_dropped; - case AP_RX_EXIT: - goto rx_exit; - } - } -#endif - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); - /* Nullfunc frames may have PS-bit set, so they must be passed to - * hostap_handle_sta_rx() before being dropped here. */ - if (stype != IEEE80211_STYPE_DATA && - stype != IEEE80211_STYPE_DATA_CFACK && - stype != IEEE80211_STYPE_DATA_CFPOLL && - stype != IEEE80211_STYPE_DATA_CFACKPOLL && - stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4 - ) { - if (stype != IEEE80211_STYPE_NULLFUNC) - IEEE80211_DEBUG_DROP( - "RX: dropped data frame " - "with no data (type=0x%02x, " - "subtype=0x%02x, len=%d)\n", - type, stype, skb->len); - goto rx_dropped; - } - if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) - goto rx_dropped; - - /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ - - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP)) { - keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt); - if (keyidx < 0) { - netdev_dbg(ieee->dev, "decrypt frame error\n"); - goto rx_dropped; - } - } - - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - - /* skb: hdr + (possibly fragmented) plaintext payload */ - // PR: FIXME: hostap has additional conditions in the "if" below: - // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { - int flen; - struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); - IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); - - if (!frag_skb) { - IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG, - "Rx cannot get skb from fragment " - "cache (morefrag=%d seq=%u frag=%u)\n", - (fc & IEEE80211_FCTL_MOREFRAGS) != 0, - WLAN_GET_SEQ_SEQ(sc), frag); - goto rx_dropped; - } - flen = skb->len; - if (frag != 0) - flen -= hdrlen; - - if (frag_skb->tail + flen > frag_skb->end) { - netdev_warn(dev, "host decrypted and " - "reassembled frame did not fit skb\n"); - ieee80211_frag_cache_invalidate(ieee, hdr); - goto rx_dropped; - } - - if (frag == 0) { - /* copy first fragment (including full headers) into - * beginning of the fragment cache skb */ - skb_put_data(frag_skb, skb->data, flen); - } else { - /* append frame payload to the end of the fragment - * cache skb */ - skb_put_data(frag_skb, skb->data + hdrlen, flen); - } - dev_kfree_skb_any(skb); - skb = NULL; - - if (fc & IEEE80211_FCTL_MOREFRAGS) { - /* more fragments expected - leave the skb in fragment - * cache for now; it will be delivered to upper layers - * after all fragments have been received */ - goto rx_exit; - } - - /* this was the last fragment and the frame will be - * delivered, so remove skb from fragment cache */ - skb = frag_skb; - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - ieee80211_frag_cache_invalidate(ieee, hdr); - } - - /* skb: hdr + (possible reassembled) full MSDU payload; possibly still - * encrypted/authenticated */ - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) { - netdev_dbg(ieee->dev, "==>decrypt msdu error\n"); - goto rx_dropped; - } - - //added by amy for AP roaming - ieee->LinkDetectInfo.NumRecvDataInPeriod++; - ieee->LinkDetectInfo.NumRxOkInPeriod++; - - hdr = (struct rtl_80211_hdr_4addr *)skb->data; - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { - if (/*ieee->ieee802_1x &&*/ - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - -#ifdef CONFIG_IEEE80211_DEBUG - /* pass unencrypted EAPOL frames even if encryption is - * configured */ - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); -#endif - } else { - IEEE80211_DEBUG_DROP( - "encryption configured, but RX " - "frame not encrypted (SA=%pM)\n", - hdr->addr2); - goto rx_dropped; - } - } - -#ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !(fc & IEEE80211_FCTL_WEP) && - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); - } -#endif - - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep && - !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - IEEE80211_DEBUG_DROP( - "dropped unencrypted RX data " - "frame from %pM" - " (drop_unencrypted=1)\n", - hdr->addr2); - goto rx_dropped; - } -/* - if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n"); - } -*/ -//added by amy for reorder - if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1)) { - TID = Frame_QoSTID(skb->data); - SeqNum = WLAN_GET_SEQ_SEQ(sc); - GetTs(ieee, (struct ts_common_info **)&pTS, hdr->addr2, TID, RX_DIR, true); - if (TID != 0 && TID != 3) - ieee->bis_any_nonbepkts = true; - } -//added by amy for reorder - /* skb: hdr + (possible reassembled) full plaintext payload */ - //ethertype = (payload[6] << 8) | payload[7]; - rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); - if (!rxb) - goto rx_dropped; - /* to parse amsdu packets */ - /* qos data packets & reserved bit is 1 */ - if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) { - /* only to free rxb, and not submit the packets to upper layer */ - for (i = 0; i < rxb->nr_subframes; i++) - dev_kfree_skb(rxb->subframes[i]); - - kfree(rxb); - rxb = NULL; - goto rx_dropped; - } - -//added by amy for reorder - if (!ieee->pHTInfo->bCurRxReorderEnable || !pTS) { - indicate_packets(ieee, rxb); - kfree(rxb); - rxb = NULL; - - } else { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n", __func__); - RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); - } -#ifndef JOHN_NOCPY - dev_kfree_skb(skb); -#endif - - rx_exit: -#ifdef NOT_YET - if (sta) - hostap_handle_sta_release(sta); -#endif - return 1; - - rx_dropped: - kfree(rxb); - rxb = NULL; - stats->rx_dropped++; - - /* Returning 0 indicates to caller that we have not handled the SKB-- - * so it is still allocated and can be used again by underlying - * hardware as a DMA target */ - return 0; -} -EXPORT_SYMBOL(ieee80211_rx); - -#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 - -static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; - -/* -* Make the structure we read from the beacon packet to have -* the right values -*/ -static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element - *info_element, int sub_type) -{ - if (info_element->elementID != QOS_ELEMENT_ID) - return -1; - if (info_element->qui_subtype != sub_type) - return -1; - if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) - return -1; - if (info_element->qui_type != QOS_OUI_TYPE) - return -1; - if (info_element->version != QOS_VERSION_1) - return -1; - - return 0; -} - - -/* - * Parse a QoS parameter element - */ -static int ieee80211_read_qos_param_element( - struct ieee80211_qos_parameter_info *element_param, - struct ieee80211_info_element *info_element) -{ - size_t size = sizeof(*element_param); - - if (!element_param || !info_element || info_element->len != size - 2) - return -1; - - memcpy(element_param, info_element, size); - return ieee80211_verify_qos_info(&element_param->info_element, - QOS_OUI_PARAM_SUB_TYPE); -} - -/* - * Parse a QoS information element - */ -static int ieee80211_read_qos_info_element( - struct ieee80211_qos_information_element *element_info, - struct ieee80211_info_element *info_element) -{ - size_t size = sizeof(*element_info); - - if (!element_info || !info_element || info_element->len != size - 2) - return -1; - - memcpy(element_info, info_element, size); - return ieee80211_verify_qos_info(element_info, QOS_OUI_INFO_SUB_TYPE); -} - - -/* - * Write QoS parameters from the ac parameters. - */ -static int ieee80211_qos_convert_ac_to_parameters( - struct ieee80211_qos_parameter_info *param_elm, - struct ieee80211_qos_parameters *qos_param) -{ - int i; - struct ieee80211_qos_ac_parameter *ac_params; - u8 aci; - //u8 cw_min; - //u8 cw_max; - - for (i = 0; i < QOS_QUEUE_NUM; i++) { - ac_params = &(param_elm->ac_params_record[i]); - - aci = (ac_params->aci_aifsn & 0x60) >> 5; - - if (aci >= QOS_QUEUE_NUM) - continue; - qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; - - /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ - qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci]; - - qos_param->cw_min[aci] = - cpu_to_le16(ac_params->ecw_min_max & 0x0F); - - qos_param->cw_max[aci] = - cpu_to_le16((ac_params->ecw_min_max & 0xF0) >> 4); - - qos_param->flag[aci] = - (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; - qos_param->tx_op_limit[aci] = ac_params->tx_op_limit; - } - return 0; -} - -/* - * we have a generic data element which it may contain QoS information or - * parameters element. check the information element length to decide - * which type to read - */ -static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element - *info_element, - struct ieee80211_network *network) -{ - int rc = 0; - struct ieee80211_qos_parameters *qos_param = NULL; - struct ieee80211_qos_information_element qos_info_element; - - rc = ieee80211_read_qos_info_element(&qos_info_element, info_element); - - if (rc == 0) { - network->qos_data.param_count = qos_info_element.ac_info & 0x0F; - network->flags |= NETWORK_HAS_QOS_INFORMATION; - } else { - struct ieee80211_qos_parameter_info param_element; - - rc = ieee80211_read_qos_param_element(¶m_element, - info_element); - if (rc == 0) { - qos_param = &(network->qos_data.parameters); - ieee80211_qos_convert_ac_to_parameters(¶m_element, - qos_param); - network->flags |= NETWORK_HAS_QOS_PARAMETERS; - network->qos_data.param_count = - param_element.info_element.ac_info & 0x0F; - } - } - - if (rc == 0) { - IEEE80211_DEBUG_QOS("QoS is supported\n"); - network->qos_data.supported = 1; - } - return rc; -} - -#ifdef CONFIG_IEEE80211_DEBUG -#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x - -static const char *get_info_element_string(u16 id) -{ - switch (id) { - MFIE_STRING(SSID); - MFIE_STRING(RATES); - MFIE_STRING(FH_SET); - MFIE_STRING(DS_SET); - MFIE_STRING(CF_SET); - MFIE_STRING(TIM); - MFIE_STRING(IBSS_SET); - MFIE_STRING(COUNTRY); - MFIE_STRING(HOP_PARAMS); - MFIE_STRING(HOP_TABLE); - MFIE_STRING(REQUEST); - MFIE_STRING(CHALLENGE); - MFIE_STRING(POWER_CONSTRAINT); - MFIE_STRING(POWER_CAPABILITY); - MFIE_STRING(TPC_REQUEST); - MFIE_STRING(TPC_REPORT); - MFIE_STRING(SUPP_CHANNELS); - MFIE_STRING(CSA); - MFIE_STRING(MEASURE_REQUEST); - MFIE_STRING(MEASURE_REPORT); - MFIE_STRING(QUIET); - MFIE_STRING(IBSS_DFS); - // MFIE_STRING(ERP_INFO); - MFIE_STRING(RSN); - MFIE_STRING(RATES_EX); - MFIE_STRING(GENERIC); - MFIE_STRING(QOS_PARAMETER); - default: - return "UNKNOWN"; - } -} -#endif - -static inline void ieee80211_extract_country_ie( - struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - struct ieee80211_network *network, - u8 *addr2 -) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (info_element->len != 0) { - memcpy(network->CountryIeBuf, info_element->data, info_element->len); - network->CountryIeLen = info_element->len; - - if (!IS_COUNTRY_IE_VALID(ieee)) { - dot11d_update_country_ie(ieee, addr2, info_element->len, info_element->data); - } - } - - // - // 070305, rcnjko: I update country IE watch dog here because - // some AP (e.g. Cisco 1242) don't include country IE in their - // probe response frame. - // - if (IS_EQUAL_CIE_SRC(ieee, addr2)) - UPDATE_CIE_WATCHDOG(ieee); - } -} - -int ieee80211_parse_info_param(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - u16 length, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats) -{ - u8 i; - short offset; - u16 tmp_htcap_len = 0; - u16 tmp_htinfo_len = 0; - u16 ht_realtek_agg_len = 0; - u8 ht_realtek_agg_buf[MAX_IE_LEN]; -// u16 broadcom_len = 0; -#ifdef CONFIG_IEEE80211_DEBUG - char rates_str[64]; - char *p; -#endif - - while (length >= sizeof(*info_element)) { - if (sizeof(*info_element) + info_element->len > length) { - IEEE80211_DEBUG_MGMT("Info elem: parse failed: " - "info_element->len + 2 > left : " - "info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + - sizeof(*info_element), - length, info_element->id); - /* We stop processing but don't return an error here - * because some misbehaviour APs break this rule. ie. - * Orinoco AP1000. */ - break; - } - - switch (info_element->id) { - case MFIE_TYPE_SSID: - if (ieee80211_is_empty_essid(info_element->data, - info_element->len)) { - network->flags |= NETWORK_EMPTY_ESSID; - break; - } - - network->ssid_len = min(info_element->len, - (u8)IW_ESSID_MAX_SIZE); - memcpy(network->ssid, info_element->data, network->ssid_len); - if (network->ssid_len < IW_ESSID_MAX_SIZE) - memset(network->ssid + network->ssid_len, 0, - IW_ESSID_MAX_SIZE - network->ssid_len); - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n", - network->ssid, network->ssid_len); - break; - - case MFIE_TYPE_RATES: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_len = min(info_element->len, - MAX_RATES_LENGTH); - for (i = 0; i < network->rates_len; i++) { - network->rates[i] = info_element->data[i]; -#ifdef CONFIG_IEEE80211_DEBUG - p += scnprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); - break; - - case MFIE_TYPE_RATES_EX: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_ex_len = min(info_element->len, - MAX_RATES_EX_LENGTH); - for (i = 0; i < network->rates_ex_len; i++) { - network->rates_ex[i] = info_element->data[i]; -#ifdef CONFIG_IEEE80211_DEBUG - p += scnprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates_ex[i]); -#endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); - break; - - case MFIE_TYPE_DS_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n", - info_element->data[0]); - network->channel = info_element->data[0]; - break; - - case MFIE_TYPE_FH_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n"); - break; - - case MFIE_TYPE_CF_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n"); - break; - - case MFIE_TYPE_TIM: - if (info_element->len < 4) - break; - - network->tim.tim_count = info_element->data[0]; - network->tim.tim_period = info_element->data[1]; - - network->dtim_period = info_element->data[1]; - if (ieee->state != IEEE80211_LINKED) - break; - - network->last_dtim_sta_time[0] = stats->mac_time[0]; - network->last_dtim_sta_time[1] = stats->mac_time[1]; - - network->dtim_data = IEEE80211_DTIM_VALID; - - if (info_element->data[0] != 0) - break; - - if (info_element->data[2] & 1) - network->dtim_data |= IEEE80211_DTIM_MBCAST; - - offset = (info_element->data[2] >> 1) * 2; - - if (ieee->assoc_id < 8 * offset || - ieee->assoc_id > 8 * (offset + info_element->len - 3)) - - break; - - offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ; - - if (info_element->data[3 + offset] & (1 << (ieee->assoc_id % 8))) - network->dtim_data |= IEEE80211_DTIM_UCAST; - - //IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n"); - break; - - case MFIE_TYPE_ERP: - network->erp_value = info_element->data[0]; - network->flags |= NETWORK_HAS_ERP_VALUE; - IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", - network->erp_value); - break; - case MFIE_TYPE_IBSS_SET: - network->atim_window = info_element->data[0]; - IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n", - network->atim_window); - break; - - case MFIE_TYPE_CHALLENGE: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n"); - break; - - case MFIE_TYPE_GENERIC: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n", - info_element->len); - if (!ieee80211_parse_qos_info_param_IE(info_element, - network)) - break; - - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - network->wpa_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->wpa_ie, info_element, - network->wpa_ie_len); - break; - } - -#ifdef THOMAS_TURBO - if (info_element->len == 7 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x01 && - info_element->data[4] == 0x02) { - network->Turbo_Enable = 1; - } -#endif - - //for HTcap and HTinfo parameters - if (tmp_htcap_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x033){ - - tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); - if (tmp_htcap_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? \ - sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); - } - } - if (tmp_htcap_len != 0) - network->bssht.bdSupportHT = true; - else - network->bssht.bdSupportHT = false; - } - - - if (tmp_htinfo_len == 0) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x034){ - - tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); - if (tmp_htinfo_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - if (tmp_htinfo_len) { - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ? \ - sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); - } - - } - - } - } - - if (ieee->aggregation) { - if (network->bssht.bdSupportHT) { - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x02){ - - ht_realtek_agg_len = min(info_element->len, (u8)MAX_IE_LEN); - memcpy(ht_realtek_agg_buf, info_element->data, info_element->len); - - } - if (ht_realtek_agg_len >= 5) { - network->bssht.bdRT2RTAggregation = true; - - if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) - network->bssht.bdRT2RTLongSlotTime = true; - } - } - - } - - //if(tmp_htcap_len !=0 || tmp_htinfo_len != 0) - { - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x05 && - info_element->data[2] == 0xb5) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf7) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x10 && - info_element->data[2] == 0x18)){ - - network->broadcom_cap_exist = true; - - } - } - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0c && - info_element->data[2] == 0x43) { - network->ralink_cap_exist = true; - } else - network->ralink_cap_exist = false; - //added by amy for atheros AP - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x03 && - info_element->data[2] == 0x7f) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x13 && - info_element->data[2] == 0x74)) { - netdev_dbg(ieee->dev, "========> Atheros AP exists\n"); - network->atheros_cap_exist = true; - } else - network->atheros_cap_exist = false; - - if (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96) { - network->cisco_cap_exist = true; - } else - network->cisco_cap_exist = false; - //added by amy for LEAP of cisco - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x01) { - if (info_element->len == 6) { - memcpy(network->CcxRmState, &info_element[4], 2); - if (network->CcxRmState[0] != 0) - network->bCcxRmEnable = true; - else - network->bCcxRmEnable = false; - // - // CCXv4 Table 59-1 MBSSID Masks. - // - network->MBssidMask = network->CcxRmState[1] & 0x07; - if (network->MBssidMask != 0) { - network->bMBssidValid = true; - network->MBssidMask = 0xff << (network->MBssidMask); - ether_addr_copy(network->MBssid, network->bssid); - network->MBssid[5] &= network->MBssidMask; - } else { - network->bMBssidValid = false; - } - } else { - network->bCcxRmEnable = false; - } - } - if (info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x03) { - if (info_element->len == 5) { - network->bWithCcxVerNum = true; - network->BssCcxVerNumber = info_element->data[4]; - } else { - network->bWithCcxVerNum = false; - network->BssCcxVerNumber = 0; - } - } - break; - - case MFIE_TYPE_RSN: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n", - info_element->len); - network->rsn_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->rsn_ie, info_element, - network->rsn_ie_len); - break; - - //HT related element. - case MFIE_TYPE_HT_CAP: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", - info_element->len); - tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); - if (tmp_htcap_len != 0) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? \ - sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); - - //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() - // windows driver will update WMM parameters each beacon received once connected - // Linux driver is a bit different. - network->bssht.bdSupportHT = true; - } else - network->bssht.bdSupportHT = false; - break; - - - case MFIE_TYPE_HT_INFO: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", - info_element->len); - tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); - if (tmp_htinfo_len) { - network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ? \ - sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); - } - break; - - case MFIE_TYPE_AIRONET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", - info_element->len); - if (info_element->len > IE_CISCO_FLAG_POSITION) { - network->bWithAironetIE = true; - - // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23): - // "A Cisco access point advertises support for CKIP in beacon and probe response packets, - // by adding an Aironet element and setting one or both of the CKIP negotiation bits." - if ((info_element->data[IE_CISCO_FLAG_POSITION] & SUPPORT_CKIP_MIC) || - (info_element->data[IE_CISCO_FLAG_POSITION] & SUPPORT_CKIP_PK)) { - network->bCkipSupported = true; - } else { - network->bCkipSupported = false; - } - } else { - network->bWithAironetIE = false; - network->bCkipSupported = false; - } - break; - case MFIE_TYPE_QOS_PARAMETER: - netdev_err(ieee->dev, - "QoS Error need to parse QOS_PARAMETER IE\n"); - break; - - case MFIE_TYPE_COUNTRY: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", - info_element->len); - ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP - break; -/* TODO */ - default: - IEEE80211_DEBUG_MGMT - ("Unsupported info element: %s (%d)\n", - get_info_element_string(info_element->id), - info_element->id); - break; - } - - length -= sizeof(*info_element) + info_element->len; - info_element = - (struct ieee80211_info_element *)&info_element-> - data[info_element->len]; - } - - if (!network->atheros_cap_exist && !network->broadcom_cap_exist && - !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) { - network->unknown_cap_exist = true; - } else { - network->unknown_cap_exist = false; - } - return 0; -} - -/* 0-100 index */ -static long ieee80211_translate_todbm(u8 signal_strength_index) -{ - long signal_power; // in dBm. - - // Translate to dBm (x=0.5y-95). - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -static inline int ieee80211_network_init( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats) -{ -#ifdef CONFIG_IEEE80211_DEBUG - //char rates_str[64]; - //char *p; -#endif - - network->qos_data.active = 0; - network->qos_data.supported = 0; - network->qos_data.param_count = 0; - network->qos_data.old_param_count = 0; - - /* Pull out fixed field data */ - memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); - network->capability = le16_to_cpu(beacon->capability); - network->last_scanned = jiffies; - network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); - network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); - network->beacon_interval = le16_to_cpu(beacon->beacon_interval); - /* Where to pull this? beacon->listen_interval;*/ - network->listen_interval = 0x0A; - network->rates_len = network->rates_ex_len = 0; - network->last_associate = 0; - network->ssid_len = 0; - network->flags = 0; - network->atim_window = 0; - network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? - 0x3 : 0x0; - network->berp_info_valid = false; - network->broadcom_cap_exist = false; - network->ralink_cap_exist = false; - network->atheros_cap_exist = false; - network->cisco_cap_exist = false; - network->unknown_cap_exist = false; -#ifdef THOMAS_TURBO - network->Turbo_Enable = 0; -#endif - network->CountryIeLen = 0; - memset(network->CountryIeBuf, 0, MAX_IE_LEN); -//Initialize HT parameters - //ieee80211_ht_initialize(&network->bssht); - HTInitializeBssDesc(&network->bssht); - if (stats->freq == IEEE80211_52GHZ_BAND) { - /* for A band (No DS info) */ - network->channel = stats->received_channel; - } else - network->flags |= NETWORK_HAS_CCK; - - network->wpa_ie_len = 0; - network->rsn_ie_len = 0; - - if (ieee80211_parse_info_param - (ieee, beacon->info_element, stats->len - sizeof(*beacon), network, stats)) - return 1; - - network->mode = 0; - if (stats->freq == IEEE80211_52GHZ_BAND) - network->mode = IEEE_A; - else { - if (network->flags & NETWORK_HAS_OFDM) - network->mode |= IEEE_G; - if (network->flags & NETWORK_HAS_CCK) - network->mode |= IEEE_B; - } - - if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " - "network.\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid); - return 1; - } - - if (network->bssht.bdSupportHT) { - if (network->mode == IEEE_A) - network->mode = IEEE_N_5G; - else if (network->mode & (IEEE_G | IEEE_B)) - network->mode = IEEE_N_24G; - } - if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) - network->flags |= NETWORK_EMPTY_ESSID; - - stats->signal = 30 + (stats->SignalStrength * 70) / 100; - stats->noise = ieee80211_translate_todbm((u8)(100 - stats->signal)) - 25; - - memcpy(&network->stats, stats, sizeof(network->stats)); - - return 0; -} - -static inline int is_same_network(struct ieee80211_network *src, - struct ieee80211_network *dst, struct ieee80211_device *ieee) -{ - /* A network is only a duplicate if the channel, BSSID, ESSID - * and the capability field (in particular IBSS and BSS) all match. - * We treat all with the same BSSID and channel - * as one network */ - return //((src->ssid_len == dst->ssid_len) && - (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && - (src->channel == dst->channel) && - !memcmp(src->bssid, dst->bssid, ETH_ALEN) && - //!memcmp(src->ssid, dst->ssid, src->ssid_len) && - (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && - ((src->capability & WLAN_CAPABILITY_IBSS) == - (dst->capability & WLAN_CAPABILITY_IBSS)) && - ((src->capability & WLAN_CAPABILITY_BSS) == - (dst->capability & WLAN_CAPABILITY_BSS))); -} - -static inline void update_network(struct ieee80211_network *dst, - struct ieee80211_network *src) -{ - int qos_active; - u8 old_param; - - memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); - dst->capability = src->capability; - memcpy(dst->rates, src->rates, src->rates_len); - dst->rates_len = src->rates_len; - memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); - dst->rates_ex_len = src->rates_ex_len; - if (src->ssid_len > 0) { - memset(dst->ssid, 0, dst->ssid_len); - dst->ssid_len = src->ssid_len; - memcpy(dst->ssid, src->ssid, src->ssid_len); - } - dst->mode = src->mode; - dst->flags = src->flags; - dst->time_stamp[0] = src->time_stamp[0]; - dst->time_stamp[1] = src->time_stamp[1]; - if (src->flags & NETWORK_HAS_ERP_VALUE) { - dst->erp_value = src->erp_value; - dst->berp_info_valid = src->berp_info_valid = true; - } - dst->beacon_interval = src->beacon_interval; - dst->listen_interval = src->listen_interval; - dst->atim_window = src->atim_window; - dst->dtim_period = src->dtim_period; - dst->dtim_data = src->dtim_data; - dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0]; - dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1]; - memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters)); - - dst->bssht.bdSupportHT = src->bssht.bdSupportHT; - dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation; - dst->bssht.bdHTCapLen = src->bssht.bdHTCapLen; - memcpy(dst->bssht.bdHTCapBuf, src->bssht.bdHTCapBuf, src->bssht.bdHTCapLen); - dst->bssht.bdHTInfoLen = src->bssht.bdHTInfoLen; - memcpy(dst->bssht.bdHTInfoBuf, src->bssht.bdHTInfoBuf, src->bssht.bdHTInfoLen); - dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer; - dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime; - dst->broadcom_cap_exist = src->broadcom_cap_exist; - dst->ralink_cap_exist = src->ralink_cap_exist; - dst->atheros_cap_exist = src->atheros_cap_exist; - dst->cisco_cap_exist = src->cisco_cap_exist; - dst->unknown_cap_exist = src->unknown_cap_exist; - memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); - dst->wpa_ie_len = src->wpa_ie_len; - memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); - dst->rsn_ie_len = src->rsn_ie_len; - - dst->last_scanned = jiffies; - /* qos related parameters */ - //qos_active = src->qos_data.active; - qos_active = dst->qos_data.active; - //old_param = dst->qos_data.old_param_count; - old_param = dst->qos_data.param_count; - if (dst->flags & NETWORK_HAS_QOS_MASK) - memcpy(&dst->qos_data, &src->qos_data, - sizeof(struct ieee80211_qos_data)); - else { - dst->qos_data.supported = src->qos_data.supported; - dst->qos_data.param_count = src->qos_data.param_count; - } - - if (dst->qos_data.supported == 1) { - dst->QoS_Enable = 1; - if (dst->ssid_len) - IEEE80211_DEBUG_QOS - ("QoS the network %s is QoS supported\n", - dst->ssid); - else - IEEE80211_DEBUG_QOS - ("QoS the network is QoS supported\n"); - } - dst->qos_data.active = qos_active; - dst->qos_data.old_param_count = old_param; - - /* dst->last_associate is not overwritten */ - dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. - if (src->wmm_param[0].aci_aifsn || \ - src->wmm_param[1].aci_aifsn || \ - src->wmm_param[2].aci_aifsn || \ - src->wmm_param[3].aci_aifsn) { - memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); - } - //dst->QoS_Enable = src->QoS_Enable; -#ifdef THOMAS_TURBO - dst->Turbo_Enable = src->Turbo_Enable; -#endif - - dst->CountryIeLen = src->CountryIeLen; - memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); - - //added by amy for LEAP - dst->bWithAironetIE = src->bWithAironetIE; - dst->bCkipSupported = src->bCkipSupported; - memcpy(dst->CcxRmState, src->CcxRmState, 2); - dst->bCcxRmEnable = src->bCcxRmEnable; - dst->MBssidMask = src->MBssidMask; - dst->bMBssidValid = src->bMBssidValid; - memcpy(dst->MBssid, src->MBssid, 6); - dst->bWithCcxVerNum = src->bWithCcxVerNum; - dst->BssCcxVerNumber = src->BssCcxVerNumber; - -} - -static inline int is_beacon(__le16 fc) -{ - return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON); -} - -static inline void ieee80211_process_probe_response( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_rx_stats *stats) -{ - struct ieee80211_network *network; - struct ieee80211_network *target; - struct ieee80211_network *oldest = NULL; -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_info_element *info_element = &beacon->info_element[0]; -#endif - int fc = WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)); - unsigned long flags; - short renew; - u16 capability; - //u8 wmm_info; - - network = kzalloc(sizeof(*network), GFP_ATOMIC); - if (!network) - goto out; - - capability = le16_to_cpu(beacon->capability); - IEEE80211_DEBUG_SCAN( - "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - (capability & BIT(0xf)) ? '1' : '0', - (capability & BIT(0xe)) ? '1' : '0', - (capability & BIT(0xd)) ? '1' : '0', - (capability & BIT(0xc)) ? '1' : '0', - (capability & BIT(0xb)) ? '1' : '0', - (capability & BIT(0xa)) ? '1' : '0', - (capability & BIT(0x9)) ? '1' : '0', - (capability & BIT(0x8)) ? '1' : '0', - (capability & BIT(0x7)) ? '1' : '0', - (capability & BIT(0x6)) ? '1' : '0', - (capability & BIT(0x5)) ? '1' : '0', - (capability & BIT(0x4)) ? '1' : '0', - (capability & BIT(0x3)) ? '1' : '0', - (capability & BIT(0x2)) ? '1' : '0', - (capability & BIT(0x1)) ? '1' : '0', - (capability & BIT(0x0)) ? '1' : '0'); - - if (ieee80211_network_init(ieee, beacon, network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", - escape_essid(info_element->data, - info_element->len), - beacon->header.addr3, - fc == IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - goto out; - } - - // For Asus EeePc request, - // (1) if wireless adapter receive get any 802.11d country code in AP beacon, - // wireless adapter should follow the country code. - // (2) If there is no any country code in beacon, - // then wireless adapter should do active scan from ch1~11 and - // passive scan from ch12~14 - - if (!is_legal_channel(ieee, network->channel)) - goto out; - if (ieee->bGlobalDomain) { - if (fc == IEEE80211_STYPE_PROBE_RESP) { - if (IS_COUNTRY_IE_VALID(ieee)) { - // Case 1: Country code - if (!is_legal_channel(ieee, network->channel)) { - netdev_warn(ieee->dev, "GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel); - goto out; - } - } else { - // Case 2: No any country code. - // Filter over channel ch12~14 - if (network->channel > 11) { - netdev_warn(ieee->dev, "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network->channel); - goto out; - } - } - } else { - if (IS_COUNTRY_IE_VALID(ieee)) { - // Case 1: Country code - if (!is_legal_channel(ieee, network->channel)) { - netdev_warn(ieee->dev, "GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network->channel); - goto out; - } - } else { - // Case 2: No any country code. - // Filter over channel ch12~14 - if (network->channel > 14) { - netdev_warn(ieee->dev, "GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network->channel); - goto out; - } - } - } - } - - /* The network parsed correctly -- so now we scan our known networks - * to see if we can find it in our list. - * - * NOTE: This search is definitely not optimized. Once its doing - * the "right thing" we'll optimize it for efficiency if - * necessary */ - - /* Search for this entry in the list and update it if it is - * already there. */ - - spin_lock_irqsave(&ieee->lock, flags); - - if (is_same_network(&ieee->current_network, network, ieee)) { - update_network(&ieee->current_network, network); - if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G) - && ieee->current_network.berp_info_valid){ - if (ieee->current_network.erp_value & ERP_UseProtection) - ieee->current_network.buseprotection = true; - else - ieee->current_network.buseprotection = false; - } - if (is_beacon(beacon->header.frame_ctl)) { - if (ieee->state == IEEE80211_LINKED) - ieee->LinkDetectInfo.NumRecvBcnInPeriod++; - } else //hidden AP - network->flags = (~NETWORK_EMPTY_ESSID & network->flags) | (NETWORK_EMPTY_ESSID & ieee->current_network.flags); - } - - list_for_each_entry(target, &ieee->network_list, list) { - if (is_same_network(target, network, ieee)) - break; - if (!oldest || - (target->last_scanned < oldest->last_scanned)) - oldest = target; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information */ - if (&target->list == &ieee->network_list) { - if (list_empty(&ieee->network_free_list)) { - /* If there are no more slots, expire the oldest */ - list_del(&oldest->list); - target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " - "network list.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid); - } else { - /* Otherwise just pull from the free list */ - target = list_entry(ieee->network_free_list.next, - struct ieee80211_network, list); - list_del(ieee->network_free_list.next); - } - - -#ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - fc == IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); -#endif - memcpy(target, network, sizeof(*target)); - list_add_tail(&target->list, &ieee->network_list); - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) - ieee80211_softmac_new_net(ieee, network); - } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid, - fc == IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - - /* we have an entry and we are going to update it. But this entry may - * be already expired. In this case we do the same as we found a new - * net and call the new_net handler - */ - renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); - //YJ,add,080819,for hidden ap - if (is_beacon(beacon->header.frame_ctl) == 0) - network->flags = (~NETWORK_EMPTY_ESSID & network->flags) | (NETWORK_EMPTY_ESSID & target->flags); - //if(strncmp(network->ssid, "linksys-c",9) == 0) - // printk("====>2 network->ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network->ssid, network->flags, target->ssid, target->flags); - if (((network->flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ - && (((network->ssid_len > 0) && (strncmp(target->ssid, network->ssid, network->ssid_len)))\ - || ((ieee->current_network.ssid_len == network->ssid_len) && (strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK)))) - renew = 1; - //YJ,add,080819,for hidden ap,end - - update_network(target, network); - if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) - ieee80211_softmac_new_net(ieee, network); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - if (is_beacon(beacon->header.frame_ctl) && is_same_network(&ieee->current_network, network, ieee) && \ - (ieee->state == IEEE80211_LINKED)) { - if (ieee->handle_beacon) - ieee->handle_beacon(ieee->dev, beacon, &ieee->current_network); - } - -out: - kfree(network); -} - -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct rtl_80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats) -{ - switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) { - - case IEEE80211_STYPE_BEACON: - IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); - IEEE80211_DEBUG_SCAN("Beacon\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - break; - - case IEEE80211_STYPE_PROBE_RESP: - IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); - IEEE80211_DEBUG_SCAN("Probe response\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - break; - - } -} -EXPORT_SYMBOL(ieee80211_rx_mgt); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c deleted file mode 100644 index 92001cb36730..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ /dev/null @@ -1,3056 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Few lines might be stolen from other part of the ieee80211 - * stack. Copyright who own it's copyright - * - * WPA code stolen from the ipw2200 driver. - * Copyright who own it's copyright. - */ -#include "ieee80211.h" - -#include -#include -#include -#include -#include - -#include "dot11d.h" - -short ieee80211_is_54g(const struct ieee80211_network *net) -{ - return (net->rates_ex_len > 0) || (net->rates_len > 4); -} -EXPORT_SYMBOL(ieee80211_is_54g); - -short ieee80211_is_shortslot(const struct ieee80211_network *net) -{ - return net->capability & WLAN_CAPABILITY_SHORT_SLOT; -} -EXPORT_SYMBOL(ieee80211_is_shortslot); - -/* returns the total length needed for placing the RATE MFIE - * tag and the EXTENDED RATE MFIE tag if needed. - * It includes two bytes per tag for the tag itself and its len - */ -static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) -{ - unsigned int rate_len = 0; - - if (ieee->modulation & IEEE80211_CCK_MODULATION) - rate_len = IEEE80211_CCK_RATE_LEN + 2; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - rate_len += IEEE80211_OFDM_RATE_LEN + 2; - - return rate_len; -} - -/* place the MFIE rate, tag to the memory (double) pointer. - * Then it updates the pointer so that - * it points after the new MFIE tag added. - */ -static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - *tag++ = MFIE_TYPE_RATES; - *tag++ = 4; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - } - - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - -static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) { - *tag++ = MFIE_TYPE_RATES_EX; - *tag++ = 8; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - } - - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - -static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; /* 0 */ - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0x50; - *tag++ = 0xf2; - *tag++ = 0x02; /* 5 */ - *tag++ = 0x00; - *tag++ = 0x01; -#ifdef SUPPORT_USPD - if (ieee->current_network.wmm_info & 0x80) - *tag++ = 0x0f | MAX_SP_Len; - else - *tag++ = MAX_SP_Len; -#else - *tag++ = MAX_SP_Len; -#endif - *tag_p = tag; -} - -#ifdef THOMAS_TURBO -static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; /* 0 */ - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0xe0; - *tag++ = 0x4c; - *tag++ = 0x01; /* 5 */ - *tag++ = 0x02; - *tag++ = 0x11; - *tag++ = 0x00; - - *tag_p = tag; - netdev_alert(ieee->dev, "This is enable turbo mode IE process\n"); -} -#endif - -static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - int nh; - - nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM; - -/* - * if the queue is full but we have newer frames then - * just overwrites the oldest. - * - * if (nh == ieee->mgmt_queue_tail) - * return -1; - */ - ieee->mgmt_queue_head = nh; - ieee->mgmt_queue_ring[nh] = skb; - - //return 0; -} - -static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) -{ - struct sk_buff *ret; - - if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head) - return NULL; - - ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; - - ieee->mgmt_queue_tail = - (ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM; - - return ret; -} - -static void init_mgmt_queue(struct ieee80211_device *ieee) -{ - ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; -} - -static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u8 rate; - - /* 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. */ - if (pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M) - rate = 0x0c; - else - rate = ieee->basic_rate & 0x7f; - - if (rate == 0) { - /* 2005.01.26, by rcnjko. */ - if (ieee->mode == IEEE_A || - ieee->mode == IEEE_N_5G || - (ieee->mode == IEEE_N_24G && !pHTInfo->bCurSuppCCK)) - rate = 0x0c; - else - rate = 0x02; - } - - /* - // Data rate of ProbeReq is already decided. Annie, 2005-03-31 - if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) ) { - if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A) - rate = 0x0c; - else - rate = 0x02; - } - */ - return rate; -} - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); - -inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) -{ - unsigned long flags; - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct rtl_80211_hdr_3addr *header = - (struct rtl_80211_hdr_3addr *)skb->data; - - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd param 0, no mgmt lock required */ - ieee80211_sta_wakeup(ieee, 0); - - tcb_desc->queue_index = MGNT_QUEUE; - tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); - tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; - - if (single) { - if (ieee->queue_stop) { - enqueue_mgmt(ieee, skb); - } else { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - netif_trans_update(ieee->dev); - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - //dev_kfree_skb_any(skb);//edit by thomas - } - - spin_unlock_irqrestore(&ieee->lock, flags); - } else { - spin_unlock_irqrestore(&ieee->lock, flags); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* check whether the managed packet queued greater than 5 */ - if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) || \ - (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) || \ - (ieee->queue_stop)) { - /* insert the skb packet to the management queue */ - /* as for the completion function, it does not need - * to check it any more. - * */ - printk("%s():insert to waitqueue!\n", __func__); - skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); - } else { - ieee->softmac_hard_start_xmit(skb, ieee->dev); - //dev_kfree_skb_any(skb);//edit by thomas - } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); - } -} - -static inline void -softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) -{ - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct rtl_80211_hdr_3addr *header = - (struct rtl_80211_hdr_3addr *)skb->data; - - if (single) { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - netif_trans_update(ieee->dev); - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - } else { - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - ieee->softmac_hard_start_xmit(skb, ieee->dev); - } - //dev_kfree_skb_any(skb);//edit by thomas -} - -static inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) -{ - unsigned int len, rate_len; - u8 *tag; - struct sk_buff *skb; - struct ieee80211_probe_request *req; - - len = ieee->current_network.ssid_len; - - rate_len = ieee80211_MFIE_rate_len(ieee); - - skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + - 2 + len + rate_len + ieee->tx_headroom); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - req = skb_put(skb, sizeof(struct ieee80211_probe_request)); - req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - req->header.duration_id = 0; /* FIXME: is this OK? */ - - eth_broadcast_addr(req->header.addr1); - memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - eth_broadcast_addr(req->header.addr3); - - tag = skb_put(skb, len + 2 + rate_len); - - *tag++ = MFIE_TYPE_SSID; - *tag++ = len; - memcpy(tag, ieee->current_network.ssid, len); - tag += len; - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - return skb; -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); - -static void ieee80211_send_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - if (!ieee->ieee_up) - return; - //unsigned long flags; - skb = ieee80211_get_beacon_(ieee); - - if (skb) { - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_beacons++; - //dev_kfree_skb_any(skb);//edit by thomas - } -// ieee->beacon_timer.expires = jiffies + -// (MSECS( ieee->current_network.beacon_interval -5)); - - //spin_lock_irqsave(&ieee->beacon_lock,flags); - if (ieee->beacon_txing && ieee->ieee_up) { -// if(!timer_pending(&ieee->beacon_timer)) -// add_timer(&ieee->beacon_timer); - mod_timer(&ieee->beacon_timer, - jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval - 5)); - } - //spin_unlock_irqrestore(&ieee->beacon_lock,flags); -} - -static void ieee80211_send_beacon_cb(struct timer_list *t) -{ - struct ieee80211_device *ieee = - from_timer(ieee, t, beacon_timer); - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - ieee80211_send_beacon(ieee); - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -static void ieee80211_send_probe(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - skb = ieee80211_probe_req(ieee); - if (skb) { - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_probe_rq++; - //dev_kfree_skb_any(skb);//edit by thomas - } -} - -static void ieee80211_send_probe_requests(struct ieee80211_device *ieee) -{ - if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) { - ieee80211_send_probe(ieee); - ieee80211_send_probe(ieee); - } -} - -/* this performs syncro scan blocking the caller until all channels - * in the allowed channel map has been checked. - */ -void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) -{ - short ch = 0; - u8 channel_map[MAX_CHANNEL_NUMBER + 1]; - - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER + 1); - mutex_lock(&ieee->scan_mutex); - - while (1) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - goto out; /* scan completed */ - } while (!channel_map[ch]); - - /* this function can be called in two situations - * 1- We have switched to ad-hoc mode and we are - * performing a complete syncro scan before conclude - * there are no interesting cell and to create a - * new one. In this case the link state is - * IEEE80211_NOLINK until we found an interesting cell. - * If so the ieee8021_new_net, called by the RX path - * will set the state to IEEE80211_LINKED, so we stop - * scanning - * 2- We are linked and the root uses run iwlist scan. - * So we switch to IEEE80211_LINKED_SCANNING to remember - * that we are still logically linked (not interested in - * new network events, despite for updating the net list, - * but we are temporarily 'unlinked' as the driver shall - * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check - * if the state become LINKED because of the #1 situation - */ - - if (ieee->state == IEEE80211_LINKED) - goto out; - ieee->set_chan(ieee->dev, ch); - if (channel_map[ch] == 1) - ieee80211_send_probe_requests(ieee); - - /* this prevent excessive time wait when we - * need to wait for a syncro scan to end.. - */ - if (ieee->state >= IEEE80211_LINKED && ieee->sync_scan_hurryup) - goto out; - - msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME); - } -out: - if (ieee->state < IEEE80211_LINKED) { - ieee->actscanning = false; - mutex_unlock(&ieee->scan_mutex); - } else { - ieee->sync_scan_hurryup = 0; - if (IS_DOT11D_ENABLE(ieee)) - dot11d_scan_complete(ieee); - mutex_unlock(&ieee->scan_mutex); - } -} -EXPORT_SYMBOL(ieee80211_softmac_scan_syncro); - -static void ieee80211_softmac_scan_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); - static short watchdog; - u8 channel_map[MAX_CHANNEL_NUMBER + 1]; - - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER + 1); - if (!ieee->ieee_up) - return; - mutex_lock(&ieee->scan_mutex); - do { - ieee->current_network.channel = - (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; - if (watchdog++ > MAX_CHANNEL_NUMBER) { - //if current channel is not in channel map, set to default channel. - if (!channel_map[ieee->current_network.channel]) { - ieee->current_network.channel = 6; - goto out; /* no good chans */ - } - } - } while (!channel_map[ieee->current_network.channel]); - if (ieee->scanning == 0) - goto out; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - if (channel_map[ieee->current_network.channel] == 1) - ieee80211_send_probe_requests(ieee); - - schedule_delayed_work(&ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); - - mutex_unlock(&ieee->scan_mutex); - return; -out: - if (IS_DOT11D_ENABLE(ieee)) - dot11d_scan_complete(ieee); - ieee->actscanning = false; - watchdog = 0; - ieee->scanning = 0; - mutex_unlock(&ieee->scan_mutex); -} - -static void ieee80211_beacons_start(struct ieee80211_device *ieee) -{ - unsigned long flags; - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 1; - ieee80211_send_beacon(ieee); - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -static void ieee80211_beacons_stop(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 0; - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); - del_timer_sync(&ieee->beacon_timer); -} - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) -{ - if (ieee->stop_send_beacons) - ieee->stop_send_beacons(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_stop(ieee); -} -EXPORT_SYMBOL(ieee80211_stop_send_beacons); - -void ieee80211_start_send_beacons(struct ieee80211_device *ieee) -{ - if (ieee->start_send_beacons) - ieee->start_send_beacons(ieee->dev, ieee->basic_rate); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_start(ieee); -} -EXPORT_SYMBOL(ieee80211_start_send_beacons); - -static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) -{ -// unsigned long flags; - - //ieee->sync_scan_hurryup = 1; - - mutex_lock(&ieee->scan_mutex); -// spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->scanning == 1) { - ieee->scanning = 0; - - cancel_delayed_work(&ieee->softmac_scan_wq); - } - -// spin_unlock_irqrestore(&ieee->lock, flags); - mutex_unlock(&ieee->scan_mutex); -} - -void ieee80211_stop_scan(struct ieee80211_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_stop_scan(ieee); - else - ieee->stop_scan(ieee->dev); -} -EXPORT_SYMBOL(ieee80211_stop_scan); - -/* called with ieee->lock held */ -static void ieee80211_start_scan(struct ieee80211_device *ieee) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (IS_COUNTRY_IE_VALID(ieee)) - RESET_CIE_WATCHDOG(ieee); - } - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { - if (ieee->scanning == 0) { - ieee->scanning = 1; - schedule_delayed_work(&ieee->softmac_scan_wq, 0); - } - } else { - ieee->start_scan(ieee->dev); - } -} - -/* called with wx_mutex held */ -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (IS_COUNTRY_IE_VALID(ieee)) - RESET_CIE_WATCHDOG(ieee); - } - ieee->sync_scan_hurryup = 0; - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_scan_syncro(ieee); - else - ieee->scan_syncro(ieee->dev); -} -EXPORT_SYMBOL(ieee80211_start_scan_syncro); - -static inline struct sk_buff * -ieee80211_authentication_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, int challengelen) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - auth = skb_put(skb, sizeof(struct ieee80211_authentication)); - - if (challengelen) - auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH - | IEEE80211_FCTL_WEP); - else - auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); - - auth->header.duration_id = cpu_to_le16(0x013a); - - memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); - - //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - if (ieee->auth_mode == 0) - auth->algorithm = WLAN_AUTH_OPEN; - else if (ieee->auth_mode == 1) - auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY); - else if (ieee->auth_mode == 2) - auth->algorithm = WLAN_AUTH_OPEN; /* 0x80; */ - printk("=================>%s():auth->algorithm is %d\n", __func__, auth->algorithm); - auth->transaction = cpu_to_le16(ieee->associate_seq); - ieee->associate_seq++; - - auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); - - return skb; -} - -static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) -{ - u8 *tag; - int beacon_size; - struct ieee80211_probe_response *beacon_buf; - struct sk_buff *skb = NULL; - int encrypt; - int atim_len, erp_len; - struct ieee80211_crypt_data *crypt; - - char *ssid = ieee->current_network.ssid; - int ssid_len = ieee->current_network.ssid_len; - int rate_len = ieee->current_network.rates_len + 2; - int rate_ex_len = ieee->current_network.rates_ex_len; - int wpa_ie_len = ieee->wpa_ie_len; - u8 erpinfo_content = 0; - - u8 *tmp_ht_cap_buf; - u8 tmp_ht_cap_len = 0; - u8 *tmp_ht_info_buf; - u8 tmp_ht_info_len = 0; - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u8 *tmp_generic_ie_buf = NULL; - u8 tmp_generic_ie_len = 0; - - if (rate_ex_len > 0) - rate_ex_len += 2; - - if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS) - atim_len = 4; - else - atim_len = 0; - - if (ieee80211_is_54g(&ieee->current_network)) - erp_len = 3; - else - erp_len = 0; - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = ieee->host_encrypt && crypt && crypt->ops && - ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); - /* HT ralated element */ - tmp_ht_cap_buf = (u8 *)&ieee->pHTInfo->SelfHTCap; - tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); - tmp_ht_info_buf = (u8 *)&ieee->pHTInfo->SelfHTInfo; - tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); - HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len, encrypt); - HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len, encrypt); - - if (pHTInfo->bRegRT2RTAggregation) { - tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; - tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); - HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); - } -// printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len); - beacon_size = sizeof(struct ieee80211_probe_response) + 2 - + ssid_len - + 3 //channel - + rate_len - + rate_ex_len - + atim_len - + erp_len - + wpa_ie_len - // + tmp_ht_cap_len - // + tmp_ht_info_len - // + tmp_generic_ie_len -// + wmm_len+2 - + ieee->tx_headroom; - skb = dev_alloc_skb(beacon_size); - if (!skb) - return NULL; - skb_reserve(skb, ieee->tx_headroom); - beacon_buf = skb_put(skb, (beacon_size - ieee->tx_headroom)); - memcpy(beacon_buf->header.addr1, dest, ETH_ALEN); - memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); - - beacon_buf->header.duration_id = 0; /* FIXME */ - beacon_buf->beacon_interval = - cpu_to_le16(ieee->current_network.beacon_interval); - beacon_buf->capability = - cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); - beacon_buf->capability |= - cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); /* add short preamble here */ - - if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - if (encrypt) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); - beacon_buf->info_element[0].id = MFIE_TYPE_SSID; - beacon_buf->info_element[0].len = ssid_len; - - tag = (u8 *)beacon_buf->info_element[0].data; - - memcpy(tag, ssid, ssid_len); - - tag += ssid_len; - - *(tag++) = MFIE_TYPE_RATES; - *(tag++) = rate_len - 2; - memcpy(tag, ieee->current_network.rates, rate_len - 2); - tag += rate_len - 2; - - *(tag++) = MFIE_TYPE_DS_SET; - *(tag++) = 1; - *(tag++) = ieee->current_network.channel; - - if (atim_len) { - *(tag++) = MFIE_TYPE_IBSS_SET; - *(tag++) = 2; - - put_unaligned_le16(ieee->current_network.atim_window, - tag); - tag += 2; - } - - if (erp_len) { - *(tag++) = MFIE_TYPE_ERP; - *(tag++) = 1; - *(tag++) = erpinfo_content; - } - if (rate_ex_len) { - *(tag++) = MFIE_TYPE_RATES_EX; - *(tag++) = rate_ex_len - 2; - memcpy(tag, ieee->current_network.rates_ex, rate_ex_len - 2); - tag += rate_ex_len - 2; - } - - if (wpa_ie_len) { - if (ieee->iw_mode == IW_MODE_ADHOC) { - //as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07 - memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); - } - memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); - tag += wpa_ie_len; - } - - //skb->dev = ieee->dev; - return skb; -} - -static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee, - u8 *dest) -{ - struct sk_buff *skb; - u8 *tag; - - struct ieee80211_crypt_data *crypt; - struct ieee80211_assoc_response_frame *assoc; - short encrypt; - - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - assoc = skb_put(skb, sizeof(struct ieee80211_assoc_response_frame)); - - assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); - memcpy(assoc->header.addr1, dest, ETH_ALEN); - memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? - WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); - - if (ieee->short_slot) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - if (ieee->host_encrypt) - crypt = ieee->crypt[ieee->tx_keyidx]; - else - crypt = NULL; - - encrypt = crypt && crypt->ops; - - if (encrypt) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - assoc->status = 0; - assoc->aid = cpu_to_le16(ieee->assoc_id); - if (ieee->assoc_id == 0x2007) - ieee->assoc_id = 0; - else - ieee->assoc_id++; - - tag = skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - - return skb; -} - -static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee, - int status, u8 *dest) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication) + 1; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb->len = sizeof(struct ieee80211_authentication); - - auth = (struct ieee80211_authentication *)skb->data; - - auth->status = cpu_to_le16(status); - auth->transaction = cpu_to_le16(2); - auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); - - memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr1, dest, ETH_ALEN); - auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); - return skb; -} - -static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, - short pwr) -{ - struct sk_buff *skb; - struct rtl_80211_hdr_3addr *hdr; - - skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr)); - - if (!skb) - return NULL; - - hdr = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr)); - - memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); - - hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | - (pwr ? IEEE80211_FCTL_PM : 0)); - - return skb; -} - -static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest) -{ - struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); - - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - -static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, - u8 *dest) -{ - struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); - - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - -static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) -{ - struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - -static inline struct sk_buff * -ieee80211_association_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - //unsigned long flags; - - struct ieee80211_assoc_request_frame *hdr; - u8 *tag;//,*rsn_ie; - //short info_addr = 0; - //int i; - //u16 suite_count = 0; - //u8 suit_select = 0; - //unsigned int wpa_len = beacon->wpa_ie_len; - //for HT - u8 *ht_cap_buf = NULL; - u8 ht_cap_len = 0; - u8 *realtek_ie_buf = NULL; - u8 realtek_ie_len = 0; - int wpa_ie_len = ieee->wpa_ie_len; - unsigned int ckip_ie_len = 0; - unsigned int ccxrm_ie_len = 0; - unsigned int cxvernum_ie_len = 0; - struct ieee80211_crypt_data *crypt; - int encrypt; - - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0; -#ifdef THOMAS_TURBO - unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0; -#endif - - int len = 0; - - crypt = ieee->crypt[ieee->tx_keyidx]; - encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); - - /* Include High Throuput capability && Realtek proprietary */ - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { - ht_cap_buf = (u8 *)&ieee->pHTInfo->SelfHTCap; - ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); - HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt); - if (ieee->pHTInfo->bCurrentRT2RTAggregation) { - realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; - realtek_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); - HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len); - } - } - if (ieee->qos_support) - wmm_info_len = beacon->qos_data.supported ? 9 : 0; - - if (beacon->bCkipSupported) - ckip_ie_len = 30 + 2; - - if (beacon->bCcxRmEnable) - ccxrm_ie_len = 6 + 2; - - if (beacon->BssCcxVerNumber >= 2) - cxvernum_ie_len = 5 + 2; - -#ifdef THOMAS_TURBO - len = sizeof(struct ieee80211_assoc_request_frame) + 2 - + beacon->ssid_len /* essid tagged val */ - + rate_len /* rates tagged val */ - + wpa_ie_len - + wmm_info_len - + turbo_info_len - + ht_cap_len - + realtek_ie_len - + ckip_ie_len - + ccxrm_ie_len - + cxvernum_ie_len - + ieee->tx_headroom; -#else - len = sizeof(struct ieee80211_assoc_request_frame) + 2 - + beacon->ssid_len /* essid tagged val */ - + rate_len /* rates tagged val */ - + wpa_ie_len - + wmm_info_len - + ht_cap_len - + realtek_ie_len - + ckip_ie_len - + ccxrm_ie_len - + cxvernum_ie_len - + ieee->tx_headroom; -#endif - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - hdr = skb_put(skb, sizeof(struct ieee80211_assoc_request_frame) + 2); - - hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; - hdr->header.duration_id = cpu_to_le16(37); - memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); - - memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John - - hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); - if (beacon->capability & WLAN_CAPABILITY_PRIVACY) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here - - if (ieee->short_slot) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - if (wmm_info_len) //QOS - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); - - hdr->listen_interval = cpu_to_le16(0xa); - - hdr->info_element[0].id = MFIE_TYPE_SSID; - - hdr->info_element[0].len = beacon->ssid_len; - skb_put_data(skb, beacon->ssid, beacon->ssid_len); - - tag = skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. - if (beacon->bCkipSupported) { - static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" - u8 CcxAironetBuf[30]; - struct octet_string osCcxAironetIE; - - memset(CcxAironetBuf, 0, 30); - osCcxAironetIE.octet = CcxAironetBuf; - osCcxAironetIE.length = sizeof(CcxAironetBuf); - // - // Ref. CCX test plan v3.61, 3.2.3.1 step 13. - // We want to make the device type as "4500-client". 060926, by CCW. - // - memcpy(osCcxAironetIE.octet, AironetIeOui, sizeof(AironetIeOui)); - - // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23): - // "The CKIP negotiation is started with the associate request from the client to the access point, - // containing an Aironet element with both the MIC and KP bits set." - osCcxAironetIE.octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK | SUPPORT_CKIP_MIC); - tag = skb_put(skb, ckip_ie_len); - *tag++ = MFIE_TYPE_AIRONET; - *tag++ = osCcxAironetIE.length; - memcpy(tag, osCcxAironetIE.octet, osCcxAironetIE.length); - tag += osCcxAironetIE.length; - } - - if (beacon->bCcxRmEnable) { - static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; - struct octet_string osCcxRmCap; - - osCcxRmCap.octet = CcxRmCapBuf; - osCcxRmCap.length = sizeof(CcxRmCapBuf); - tag = skb_put(skb, ccxrm_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = osCcxRmCap.length; - memcpy(tag, osCcxRmCap.octet, osCcxRmCap.length); - tag += osCcxRmCap.length; - } - - if (beacon->BssCcxVerNumber >= 2) { - u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; - struct octet_string osCcxVerNum; - CcxVerNumBuf[4] = beacon->BssCcxVerNumber; - osCcxVerNum.octet = CcxVerNumBuf; - osCcxVerNum.length = sizeof(CcxVerNumBuf); - tag = skb_put(skb, cxvernum_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = osCcxVerNum.length; - memcpy(tag, osCcxVerNum.octet, osCcxVerNum.length); - tag += osCcxVerNum.length; - } - //HT cap element - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { - if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_HT_CAP; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf, ht_cap_len - 2); - tag += ht_cap_len - 2; - } - } - - //choose what wpa_supplicant gives to associate. - if (wpa_ie_len) - skb_put_data(skb, ieee->wpa_ie, wpa_ie_len); - - if (wmm_info_len) { - tag = skb_put(skb, wmm_info_len); - ieee80211_WMM_Info(ieee, &tag); - } -#ifdef THOMAS_TURBO - if (turbo_info_len) { - tag = skb_put(skb, turbo_info_len); - ieee80211_TURBO_Info(ieee, &tag); - } -#endif - - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { - if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf, ht_cap_len - 2); - tag += ht_cap_len - 2; - } - - if (ieee->pHTInfo->bCurrentRT2RTAggregation) { - tag = skb_put(skb, realtek_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = realtek_ie_len - 2; - memcpy(tag, realtek_ie_buf, realtek_ie_len - 2); - } - } -// printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); - return skb; -} - -void ieee80211_associate_abort(struct ieee80211_device *ieee) -{ - unsigned long flags; - spin_lock_irqsave(&ieee->lock, flags); - - ieee->associate_seq++; - - /* don't scan, and avoid having the RX path possibly - * try again to associate. Even do not react to AUTH or - * ASSOC response. Just wait for the retry wq to be scheduled. - * Here we will check if there are good nets to associate - * with, so we retry or just get back to NO_LINK and scanning - */ - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) { - IEEE80211_DEBUG_MGMT("Authentication failed\n"); - ieee->softmac_stats.no_auth_rs++; - } else { - IEEE80211_DEBUG_MGMT("Association failed\n"); - ieee->softmac_stats.no_ass_rs++; - } - - ieee->state = IEEE80211_ASSOCIATING_RETRY; - - schedule_delayed_work(&ieee->associate_retry_wq, \ - IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static void ieee80211_associate_abort_cb(struct timer_list *t) -{ - struct ieee80211_device *dev = from_timer(dev, t, associate_timer); - - ieee80211_associate_abort(dev); -} - -static void ieee80211_associate_step1(struct ieee80211_device *ieee) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - IEEE80211_DEBUG_MGMT("Stopping scan\n"); - - ieee->softmac_stats.tx_auth_rq++; - skb = ieee80211_authentication_req(beacon, ieee, 0); - - if (!skb) { - ieee80211_associate_abort(ieee); - } else { - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING; - IEEE80211_DEBUG_MGMT("Sending authentication request\n"); - softmac_mgmt_xmit(skb, ieee); - //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 - if (!timer_pending(&ieee->associate_timer)) { - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - //dev_kfree_skb_any(skb);//edit by thomas - } -} - -static void ieee80211_auth_challenge(struct ieee80211_device *ieee, - u8 *challenge, - int chlen) -{ - u8 *c; - struct sk_buff *skb; - struct ieee80211_network *beacon = &ieee->current_network; -// int hlen = sizeof(struct ieee80211_authentication); - - ieee->associate_seq++; - ieee->softmac_stats.tx_auth_rq++; - - skb = ieee80211_authentication_req(beacon, ieee, chlen + 2); - if (!skb) { - ieee80211_associate_abort(ieee); - } else { - c = skb_put(skb, chlen + 2); - *(c++) = MFIE_TYPE_CHALLENGE; - *(c++) = chlen; - memcpy(c, challenge, chlen); - - IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); - - ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr)); - - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ / 2)); - //dev_kfree_skb_any(skb);//edit by thomas - } - kfree(challenge); -} - -static void ieee80211_associate_step2(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_network *beacon = &ieee->current_network; - - del_timer_sync(&ieee->associate_timer); - - IEEE80211_DEBUG_MGMT("Sending association request\n"); - - ieee->softmac_stats.tx_ass_rq++; - skb = ieee80211_association_req(beacon, ieee); - if (!skb) { - ieee80211_associate_abort(ieee); - } else { - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ / 2)); - //dev_kfree_skb_any(skb);//edit by thomas - } -} -static void ieee80211_associate_complete_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); - - netdev_info(ieee->dev, "Associated successfully\n"); - if (ieee80211_is_54g(&ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)) { - ieee->rate = 108; - netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate); - } else { - ieee->rate = 22; - netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate); - } - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { - printk("Successfully associated, ht enabled\n"); - HTOnAssocRsp(ieee); - } else { - printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); - memset(ieee->dot11HTOperationalRateSet, 0, 16); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } - ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500); - // To prevent the immediately calling watch_dog after association. - if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; - } - ieee->link_change(ieee->dev); - if (!ieee->is_silent_reset) { - printk("============>normal associate\n"); - notify_wx_assoc_event(ieee); - } else { - printk("==================>silent reset associate\n"); - ieee->is_silent_reset = false; - } - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - netif_carrier_on(ieee->dev); -} - -static void ieee80211_associate_complete(struct ieee80211_device *ieee) -{ -// int i; -// struct net_device* dev = ieee->dev; - del_timer_sync(&ieee->associate_timer); - - ieee->state = IEEE80211_LINKED; - //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet); - schedule_work(&ieee->associate_complete_wq); -} - -static void ieee80211_associate_procedure_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); - ieee->sync_scan_hurryup = 1; - mutex_lock(&ieee->wx_mutex); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - - ieee80211_stop_scan(ieee); - printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel); - //ieee->set_chan(ieee->dev, ieee->current_network.channel); - HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - - ieee->associate_seq = 1; - ieee80211_associate_step1(ieee); - - mutex_unlock(&ieee->wx_mutex); -} - -inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) -{ - u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1]; - int tmp_ssid_len = 0; - - short apset, ssidset, ssidbroad, apmatch, ssidmatch; - - /* we are interested in new only if we are not associated - * and we are not associating / authenticating - */ - if (ieee->state != IEEE80211_NOLINK) - return; - - if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) - return; - - if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) - return; - - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { - /* if the user specified the AP MAC, we need also the essid - * This could be obtained by beacons or, if the network does not - * broadcast it, it can be put manually. - */ - apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 ); - ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0'; - ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0'); - apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0); - ssidmatch = (ieee->current_network.ssid_len == net->ssid_len) && - (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); - - /* if the user set the AP check if match. - * if the network does not broadcast essid we check the user supplyed ANY essid - * if the network does broadcast and the user does not set essid it is OK - * if the network does broadcast and the user did set essid check if essid match - */ - if ((apset && apmatch && - ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) || - /* if the ap is not set, check that the user set the bssid - * and the network does broadcast and that those two bssid matches - */ - (!apset && ssidset && ssidbroad && ssidmatch)) { - /* if the essid is hidden replace it with the - * essid provided by the user. - */ - if (!ssidbroad) { - strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); - tmp_ssid_len = ieee->current_network.ssid_len; - } - memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); - - strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); - ieee->current_network.ssid_len = tmp_ssid_len; - netdev_info(ieee->dev, - "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n", - ieee->current_network.ssid, - ieee->current_network.channel, - ieee->current_network.qos_data.supported, - ieee->pHTInfo->bEnableHT, - ieee->current_network.bssht.bdSupportHT); - - //ieee->pHTInfo->IOTAction = 0; - HTResetIOTSetting(ieee->pHTInfo); - if (ieee->iw_mode == IW_MODE_INFRA) { - /* Join the network for the first time */ - ieee->AsocRetryCount = 0; - //for HT by amy 080514 - if ((ieee->current_network.qos_data.supported == 1) && - // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT)) - ieee->current_network.bssht.bdSupportHT) { -/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/ - // ieee->pHTInfo->bCurrentHTSupport = true; - HTResetSelfAndSavePeerSetting(ieee, &ieee->current_network); - } else { - ieee->pHTInfo->bCurrentHTSupport = false; - } - - ieee->state = IEEE80211_ASSOCIATING; - schedule_work(&ieee->associate_procedure_wq); - } else { - if (ieee80211_is_54g(&ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)) { - ieee->rate = 108; - ieee->SetWirelessMode(ieee->dev, IEEE_G); - netdev_info(ieee->dev, - "Using G rates\n"); - } else { - ieee->rate = 22; - ieee->SetWirelessMode(ieee->dev, IEEE_B); - netdev_info(ieee->dev, - "Using B rates\n"); - } - memset(ieee->dot11HTOperationalRateSet, 0, 16); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - ieee->state = IEEE80211_LINKED; - } - } - } -} - -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) -{ - unsigned long flags; - struct ieee80211_network *target; - - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(target, &ieee->network_list, list) { - /* if the state become different that NOLINK means - * we had found what we are searching for - */ - - if (ieee->state != IEEE80211_NOLINK) - break; - - if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) - ieee80211_softmac_new_net(ieee, target); - } - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static inline int auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) -{ - struct ieee80211_authentication *a; - u8 *t; - if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) { - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); - return -EINVAL; - } - *challenge = NULL; - a = (struct ieee80211_authentication *)skb->data; - if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) { - t = skb->data + sizeof(struct ieee80211_authentication); - - if (*(t++) == MFIE_TYPE_CHALLENGE) { - *chlen = *(t++); - *challenge = kmemdup(t, *chlen, GFP_ATOMIC); - if (!*challenge) - return -ENOMEM; - } - } - - if (a->status) { - IEEE80211_DEBUG_MGMT("auth_parse() failed\n"); - return -EINVAL; - } - - return 0; -} - -static int auth_rq_parse(struct sk_buff *skb, u8 *dest) -{ - struct ieee80211_authentication *a; - - if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) { - IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len); - return -1; - } - a = (struct ieee80211_authentication *)skb->data; - - memcpy(dest, a->header.addr2, ETH_ALEN); - - if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) - return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; - - return WLAN_STATUS_SUCCESS; -} - -static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) -{ - u8 *tag; - u8 *skbend; - u8 *ssid = NULL; - u8 ssidlen = 0; - - struct rtl_80211_hdr_3addr *header = - (struct rtl_80211_hdr_3addr *)skb->data; - - if (skb->len < sizeof(struct rtl_80211_hdr_3addr)) - return -1; /* corrupted */ - - memcpy(src, header->addr2, ETH_ALEN); - - skbend = (u8 *)skb->data + skb->len; - - tag = skb->data + sizeof(struct rtl_80211_hdr_3addr); - - while (tag + 1 < skbend) { - if (*tag == 0) { - ssid = tag + 2; - ssidlen = *(tag + 1); - break; - } - tag++; /* point to the len field */ - tag = tag + *(tag); /* point to the last data byte of the tag */ - tag++; /* point to the next tag */ - } - - //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src)); - if (ssidlen == 0) - return 1; - - if (!ssid) - return 1; /* ssid not found in tagged param */ - - return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); -} - -static int assoc_rq_parse(struct sk_buff *skb, u8 *dest) -{ - struct ieee80211_assoc_request_frame *a; - - if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - - sizeof(struct ieee80211_info_element))) { - IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len); - return -1; - } - - a = (struct ieee80211_assoc_request_frame *)skb->data; - - memcpy(dest, a->header.addr2, ETH_ALEN); - - return 0; -} - -static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid) -{ - struct ieee80211_assoc_response_frame *response_head; - u16 status_code; - - if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) { - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); - return 0xcafe; - } - - response_head = (struct ieee80211_assoc_response_frame *)skb->data; - *aid = le16_to_cpu(response_head->aid) & 0x3fff; - - status_code = le16_to_cpu(response_head->status); - if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES || - status_code == WLAN_STATUS_CAPS_UNSUPPORTED) && - ((ieee->mode == IEEE_G) && - (ieee->current_network.mode == IEEE_N_24G) && - (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT - 1)))) { - ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE; - } else { - ieee->AsocRetryCount = 0; - } - - return le16_to_cpu(response_head->status); -} - -static inline void -ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - - //IEEE80211DMESG("Rx probe"); - ieee->softmac_stats.rx_probe_rq++; - //DMESG("Dest is "MACSTR, MAC2STR(dest)); - if (probe_rq_parse(ieee, skb, dest)) { - //IEEE80211DMESG("Was for me!"); - ieee->softmac_stats.tx_probe_rs++; - ieee80211_resp_to_probe(ieee, dest); - } -} - -static inline void -ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - int status; - //IEEE80211DMESG("Rx probe"); - ieee->softmac_stats.rx_auth_rq++; - - status = auth_rq_parse(skb, dest); - if (status != -1) - ieee80211_resp_to_auth(ieee, status, dest); - //DMESG("Dest is "MACSTR, MAC2STR(dest)); -} - -static inline void -ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - //unsigned long flags; - - ieee->softmac_stats.rx_ass_rq++; - if (assoc_rq_parse(skb, dest) != -1) - ieee80211_resp_to_assoc_rq(ieee, dest); - - netdev_info(ieee->dev, "New client associated: %pM\n", dest); - //FIXME -} - -static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, - short pwr) -{ - struct sk_buff *buf = ieee80211_null_func(ieee, pwr); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); -} -/* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */ - -static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, - u32 *time_l) -{ - int timeout; - u8 dtim; - /*if(ieee->ps == IEEE80211_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->state != IEEE80211_LINKED) - - return 0; - */ - dtim = ieee->current_network.dtim_data; - if (!(dtim & IEEE80211_DTIM_VALID)) - return 0; - timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval - ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; - - if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps)) - return 2; - - if (!time_after(jiffies, - dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout))) - return 0; - - if (!time_after(jiffies, - ieee->last_rx_ps_time + msecs_to_jiffies(timeout))) - return 0; - - if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) && - (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) - return 0; - - if (time_l) { - *time_l = ieee->current_network.last_dtim_sta_time[0] - + (ieee->current_network.beacon_interval - * ieee->current_network.dtim_period) * 1000; - } - - if (time_h) { - *time_h = ieee->current_network.last_dtim_sta_time[1]; - if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) - *time_h += 1; - } - - return 1; -} - -static inline void ieee80211_sta_ps(struct work_struct *work) -{ - struct ieee80211_device *ieee; - u32 th, tl; - short sleep; - unsigned long flags, flags2; - - ieee = container_of(work, struct ieee80211_device, ps_task); - - spin_lock_irqsave(&ieee->lock, flags); - - if ((ieee->ps == IEEE80211_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->state != IEEE80211_LINKED)) { - // #warning CHECK_LOCK_HERE - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - ieee80211_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - - sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl); - /* 2 wake, 1 sleep, 0 do nothing */ - if (sleep == 0) - goto out; - - if (sleep == 1) { - if (ieee->sta_sleep == 1) { - ieee->enter_sleep_state(ieee->dev, th, tl); - } else if (ieee->sta_sleep == 0) { - // printk("send null 1\n"); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - if (ieee->ps_is_queue_empty(ieee->dev)) { - ieee->sta_sleep = 2; - - ieee->ps_request_tx_ack(ieee->dev); - - ieee80211_sta_ps_send_null_frame(ieee, 1); - - ieee->ps_th = th; - ieee->ps_tl = tl; - } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - } else if (sleep == 2) { -//#warning CHECK_LOCK_HERE - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - ieee80211_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } -out: - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) -{ - if (ieee->sta_sleep == 0) { - if (nl) { - printk("Warning: driver is probably failing to report TX ps error\n"); - ieee->ps_request_tx_ack(ieee->dev); - ieee80211_sta_ps_send_null_frame(ieee, 0); - } - return; - } - - if (ieee->sta_sleep == 1) - ieee->sta_wake_up(ieee->dev); - - ieee->sta_sleep = 0; - - if (nl) { - ieee->ps_request_tx_ack(ieee->dev); - ieee80211_sta_ps_send_null_frame(ieee, 0); - } -} - -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) -{ - unsigned long flags, flags2; - - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->sta_sleep == 2) { - /* Null frame with PS bit set */ - if (success) { - ieee->sta_sleep = 1; - ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl); - } - /* if the card report not success we can't be sure the AP - * has not RXed so we can't assume the AP believe us awake - */ - } else { - /* 21112005 - tx again null without PS bit if lost */ - if ((ieee->sta_sleep == 0) && !success) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - ieee80211_sta_ps_send_null_frame(ieee, 0); - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(ieee80211_ps_tx_ack); - -static void ieee80211_process_action(struct ieee80211_device *ieee, - struct sk_buff *skb) -{ - struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data; - u8 *act = ieee80211_get_payload(header); - u8 tmp = 0; -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); - if (!act) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n"); - return; - } - tmp = *act; - act++; - switch (tmp) { - case ACT_CAT_BA: - if (*act == ACT_ADDBAREQ) - ieee80211_rx_ADDBAReq(ieee, skb); - else if (*act == ACT_ADDBARSP) - ieee80211_rx_ADDBARsp(ieee, skb); - else if (*act == ACT_DELBA) - ieee80211_rx_DELBA(ieee, skb); - break; - default: - break; - } - return; -} - -static void ieee80211_check_auth_response(struct ieee80211_device *ieee, - struct sk_buff *skb) -{ - /* default support N mode, disable halfNmode */ - bool bSupportNmode = true, bHalfSupportNmode = false; - int errcode; - u8 *challenge; - int chlen = 0; - u32 iotAction; - - errcode = auth_parse(skb, &challenge, &chlen); - if (!errcode) { - if (ieee->open_wep || !challenge) { - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; - ieee->softmac_stats.rx_auth_rs_ok++; - iotAction = ieee->pHTInfo->IOTAction; - if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) { - if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { - /* WEP or TKIP encryption */ - if (IsHTHalfNmodeAPs(ieee)) { - bSupportNmode = true; - bHalfSupportNmode = true; - } else { - bSupportNmode = false; - bHalfSupportNmode = false; - } - netdev_dbg(ieee->dev, "SEC(%d, %d)\n", - bSupportNmode, - bHalfSupportNmode); - } - } - /* Dummy wirless mode setting- avoid encryption issue */ - if (bSupportNmode) { - /* N mode setting */ - ieee->SetWirelessMode(ieee->dev, - ieee->current_network.mode); - } else { - /* b/g mode setting - TODO */ - ieee->SetWirelessMode(ieee->dev, IEEE_G); - } - - if (ieee->current_network.mode == IEEE_N_24G && - bHalfSupportNmode) { - netdev_dbg(ieee->dev, "enter half N mode\n"); - ieee->bHalfWirelessN24GMode = true; - } else { - ieee->bHalfWirelessN24GMode = false; - } - ieee80211_associate_step2(ieee); - } else { - ieee80211_auth_challenge(ieee, challenge, chlen); - } - } else { - ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Auth response status code %d\n", errcode); - ieee80211_associate_abort(ieee); - } -} - -inline int -ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) -{ - struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *)skb->data; - u16 errcode; - int aid; - struct ieee80211_assoc_response_frame *assoc_resp; -// struct ieee80211_info_element *info_element; - - if (!ieee->proto_started) - return 0; - - if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->state == IEEE80211_LINKED)) - schedule_work(&ieee->ps_task); - - if (WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && - WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) - ieee->last_rx_ps_time = jiffies; - - switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { - case IEEE80211_STYPE_ASSOC_RESP: - case IEEE80211_STYPE_REASSOC_RESP: - IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && - ieee->iw_mode == IW_MODE_INFRA) { - struct ieee80211_network *network; - - network = kzalloc(sizeof(*network), GFP_KERNEL); - if (!network) - return -ENOMEM; - - errcode = assoc_parse(ieee, skb, &aid); - if (!errcode) { - ieee->state = IEEE80211_LINKED; - ieee->assoc_id = aid; - ieee->softmac_stats.rx_ass_ok++; - /* station support qos */ - /* Let the register setting defaultly with Legacy station */ - if (ieee->qos_support) { - assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data; - if (ieee80211_parse_info_param(ieee, assoc_resp->info_element,\ - rx_stats->len - sizeof(*assoc_resp), \ - network, rx_stats)) { - return 1; - } else { - //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network. - memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); - memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); - } - if (ieee->handle_assoc_response) - ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network); - } - ieee80211_associate_complete(ieee); - } else { - /* aid could not been allocated */ - ieee->softmac_stats.rx_ass_err++; - printk("Association response status code 0x%x\n", - errcode); - IEEE80211_DEBUG_MGMT("Association response status code 0x%x\n", - errcode); - if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) - schedule_work(&ieee->associate_procedure_wq); - else - ieee80211_associate_abort(ieee); - } - kfree(network); - } - break; - - case IEEE80211_STYPE_ASSOC_REQ: - case IEEE80211_STYPE_REASSOC_REQ: - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->iw_mode == IW_MODE_MASTER) - ieee80211_rx_assoc_rq(ieee, skb); - break; - - case IEEE80211_STYPE_AUTH: - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) { - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING - && ieee->iw_mode == IW_MODE_INFRA) { - IEEE80211_DEBUG_MGMT("Received auth response"); - ieee80211_check_auth_response(ieee, skb); - } else if (ieee->iw_mode == IW_MODE_MASTER) { - ieee80211_rx_auth_rq(ieee, skb); - } - } - break; - - case IEEE80211_STYPE_PROBE_REQ: - if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && - ((ieee->iw_mode == IW_MODE_ADHOC || - ieee->iw_mode == IW_MODE_MASTER) && - ieee->state == IEEE80211_LINKED)) { - ieee80211_rx_probe_rq(ieee, skb); - } - break; - - case IEEE80211_STYPE_DISASSOC: - case IEEE80211_STYPE_DEAUTH: - /* FIXME for now repeat all the association procedure - * both for disassociation and deauthentication - */ - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->state == IEEE80211_LINKED && - ieee->iw_mode == IW_MODE_INFRA) { - ieee->state = IEEE80211_ASSOCIATING; - ieee->softmac_stats.reassoc++; - - notify_wx_assoc_event(ieee); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - RemovePeerTS(ieee, header->addr2); - schedule_work(&ieee->associate_procedure_wq); - } - break; - case IEEE80211_STYPE_MANAGE_ACT: - ieee80211_process_action(ieee, skb); - break; - default: - return -1; - } - - //dev_kfree_skb_any(skb); - return 0; -} - -/* The following are for a simpler TX queue management. - * Instead of using netif_[stop/wake]_queue, the driver - * will use these two functions (plus a reset one) that - * will internally call the kernel netif_* and take care - * of the ieee802.11 fragmentation. - * So, the driver receives a fragment at a time and might - * call the stop function when it wants, without taking - * care to have enough room to TX an entire packet. - * This might be useful if each fragment needs its own - * descriptor. Thus, just keeping a total free memory > than - * the max fragmentation threshold is not enough. If the - * ieee802.11 stack passed a TXB struct, then you would need - * to keep N free descriptors where - * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD. - * In this way you need just one and the 802.11 stack - * will take care of buffering fragments and pass them to - * the driver later, when it wakes the queue. - */ -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) -{ - unsigned int queue_index = txb->queue_index; - unsigned long flags; - int i; - struct cb_desc *tcb_desc = NULL; - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd parm 0, no tx mgmt lock required */ - ieee80211_sta_wakeup(ieee, 0); - - /* update the tx status */ - ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size); - ieee->stats.tx_packets++; - tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); - if (tcb_desc->bMulticast) - ieee->stats.multicast++; - - /* if xmit available, just xmit it immediately, else just insert it to the wait queue */ - for (i = 0; i < txb->nr_frags; i++) { -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) || -#else - if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) || -#endif - (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) || - (ieee->queue_stop)) { - /* insert the skb packet to the wait queue */ - /* as for the completion function, it does not need - * to check it any more. - * */ - //printk("error:no descriptor left@queue_index %d\n", queue_index); - //ieee80211_stop_queue(ieee); -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); -#else - skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); -#endif - } else { - ieee->softmac_data_hard_start_xmit(txb->fragments[i], - ieee->dev, ieee->rate); - //ieee->stats.tx_packets++; - //ieee->stats.tx_bytes += txb->fragments[i]->len; - //ieee->dev->trans_start = jiffies; - } - } - ieee80211_txb_free(txb); - -//exit: - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(ieee80211_softmac_xmit); - -/* called with ieee->lock acquired */ -static void ieee80211_resume_tx(struct ieee80211_device *ieee) -{ - int i; - for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { - if (ieee->queue_stop) { - ieee->tx_pending.frag = i; - return; - } else { - ieee->softmac_data_hard_start_xmit(ieee->tx_pending.txb->fragments[i], - ieee->dev, ieee->rate); - //(i+1)tx_pending.txb->nr_frags); - ieee->stats.tx_packets++; - netif_trans_update(ieee->dev); - } - } - - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; -} - -void ieee80211_reset_queue(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - init_mgmt_queue(ieee); - if (ieee->tx_pending.txb) { - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; - } - ieee->queue_stop = 0; - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(ieee80211_reset_queue); - -void ieee80211_wake_queue(struct ieee80211_device *ieee) -{ - unsigned long flags; - struct sk_buff *skb; - struct rtl_80211_hdr_3addr *header; - - spin_lock_irqsave(&ieee->lock, flags); - if (!ieee->queue_stop) - goto exit; - - ieee->queue_stop = 0; - - if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) { - while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) { - header = (struct rtl_80211_hdr_3addr *)skb->data; - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - //dev_kfree_skb_any(skb);//edit by thomas - } - } - if (!ieee->queue_stop && ieee->tx_pending.txb) - ieee80211_resume_tx(ieee); - - if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) { - ieee->softmac_stats.swtxawake++; - netif_wake_queue(ieee->dev); - } -exit: - spin_unlock_irqrestore(&ieee->lock, flags); -} -EXPORT_SYMBOL(ieee80211_wake_queue); - -void ieee80211_stop_queue(struct ieee80211_device *ieee) -{ - //unsigned long flags; - //spin_lock_irqsave(&ieee->lock,flags); - - if (!netif_queue_stopped(ieee->dev)) { - netif_stop_queue(ieee->dev); - ieee->softmac_stats.swtxstop++; - } - ieee->queue_stop = 1; - //spin_unlock_irqrestore(&ieee->lock,flags); -} -EXPORT_SYMBOL(ieee80211_stop_queue); - -/* called in user context only */ -void ieee80211_start_master_bss(struct ieee80211_device *ieee) -{ - ieee->assoc_id = 1; - - if (ieee->current_network.ssid_len == 0) { - strncpy(ieee->current_network.ssid, - IEEE80211_DEFAULT_TX_ESSID, - IW_ESSID_MAX_SIZE); - - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); - - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); - notify_wx_assoc_event(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); -} - -static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) -{ - if (ieee->raw_tx) { - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); - } -} -static void ieee80211_start_ibss_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); - /* iwconfig mode ad-hoc will schedule this and return - * on the other hand this will block further iwconfig SET - * operations because of the wx_mutex hold. - * Anyway some most set operations set a flag to speed-up - * (abort) this wq (when syncro scanning) before sleeping - * on the semaphore - */ - if (!ieee->proto_started) { - printk("==========oh driver down return\n"); - return; - } - mutex_lock(&ieee->wx_mutex); - - if (ieee->current_network.ssid_len == 0) { - strscpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID, - sizeof(ieee->current_network.ssid)); - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - /* check if we have this cell in our network list */ - ieee80211_softmac_check_all_nets(ieee); - -// if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) - if (ieee->state == IEEE80211_NOLINK) - ieee->current_network.channel = 6; - /* if not then the state is not linked. Maybe the user switched to - * ad-hoc mode just after being in monitor mode, or just after - * being very few time in managed mode (so the card have had no - * time to scan all the chans..) or we have just run up the iface - * after setting ad-hoc mode. So we have to give another try.. - * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tried to associate when - * we had just checked the ieee->state and we was going to start the - * scan) because in ibss mode the ieee80211_new_net function, when - * finds a good net, just set the ieee->state to IEEE80211_LINKED, - * so, at worst, we waste a bit of time to initiate an unneeded syncro - * scan, that will stop at the first round because it sees the state - * associated. - */ - if (ieee->state == IEEE80211_NOLINK) - ieee80211_start_scan_syncro(ieee); - - /* the network definitively is not here.. create a new cell */ - if (ieee->state == IEEE80211_NOLINK) { - printk("creating new IBSS cell\n"); - if (!ieee->wap_set) - eth_random_addr(ieee->current_network.bssid); - - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - ieee->current_network.rates_len = 4; - - ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - } else { - ieee->current_network.rates_len = 0; - } - if (ieee->modulation & IEEE80211_OFDM_MODULATION) { - ieee->current_network.rates_ex_len = 8; - - ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - - ieee->rate = 108; - } else { - ieee->current_network.rates_ex_len = 0; - ieee->rate = 22; - } - - // By default, WMM function will be disabled in IBSS mode - ieee->current_network.QoS_Enable = 0; - ieee->SetWirelessMode(ieee->dev, IEEE_G); - ieee->current_network.atim_window = 0; - ieee->current_network.capability = WLAN_CAPABILITY_IBSS; - if (ieee->short_slot) - ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; - } - - ieee->state = IEEE80211_LINKED; - - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->link_change(ieee->dev); - - notify_wx_assoc_event(ieee); - - ieee80211_start_send_beacons(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - netif_carrier_on(ieee->dev); - - mutex_unlock(&ieee->wx_mutex); -} - -inline void ieee80211_start_ibss(struct ieee80211_device *ieee) -{ - schedule_delayed_work(&ieee->start_ibss_wq, 150); -} - -/* this is called only in user context, with wx_mutex held */ -void ieee80211_start_bss(struct ieee80211_device *ieee) -{ - unsigned long flags; - // - // Ref: 802.11d 11.1.3.3 - // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. - // - if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) { - if (!ieee->bGlobalDomain) - return; - } - /* check if we have already found the net we - * are interested in (if any). - * if not (we are disassociated and we are not - * in associating / authenticating phase) start the background scanning. - */ - ieee80211_softmac_check_all_nets(ieee); - - /* ensure no-one start an associating process (thus setting - * the ieee->state to ieee80211_ASSOCIATING) while we - * have just checked it and we are going to enable scan. - * The ieee80211_new_net function is always called with - * lock held (from both ieee80211_softmac_check_all_nets and - * the rx path), so we cannot be in the middle of such function - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state == IEEE80211_NOLINK) { - ieee->actscanning = true; - ieee80211_start_scan(ieee); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -/* called only in userspace context */ -void ieee80211_disassociate(struct ieee80211_device *ieee) -{ - netif_carrier_off(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) - ieee80211_reset_queue(ieee); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - if (IS_DOT11D_ENABLE(ieee)) - dot11d_reset(ieee); - ieee->state = IEEE80211_NOLINK; - ieee->is_set_key = false; - ieee->link_change(ieee->dev); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - notify_wx_assoc_event(ieee); -} -EXPORT_SYMBOL(ieee80211_disassociate); - -static void ieee80211_associate_retry_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); - unsigned long flags; - - mutex_lock(&ieee->wx_mutex); - if (!ieee->proto_started) - goto exit; - - if (ieee->state != IEEE80211_ASSOCIATING_RETRY) - goto exit; - - /* until we do not set the state to IEEE80211_NOLINK - * there are no possibility to have someone else trying - * to start an association procedure (we get here with - * ieee->state = IEEE80211_ASSOCIATING). - * When we set the state to IEEE80211_NOLINK it is possible - * that the RX path run an attempt to associate, but - * both ieee80211_softmac_check_all_nets and the - * RX path works with ieee->lock held so there are no - * problems. If we are still disassociated then start a scan. - * the lock here is necessary to ensure no one try to start - * an association procedure when we have just checked the - * state and we are going to start the scan. - */ - ieee->state = IEEE80211_NOLINK; - - ieee80211_softmac_check_all_nets(ieee); - - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state == IEEE80211_NOLINK) - ieee80211_start_scan(ieee); - - spin_unlock_irqrestore(&ieee->lock, flags); - -exit: - mutex_unlock(&ieee->wx_mutex); -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) -{ - u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - struct sk_buff *skb; - struct ieee80211_probe_response *b; - - skb = ieee80211_probe_resp(ieee, broadcast_addr); - - if (!skb) - return NULL; - - b = (struct ieee80211_probe_response *)skb->data; - b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); - - return skb; -} - -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_probe_response *b; - - skb = ieee80211_get_beacon_(ieee); - if (!skb) - return NULL; - - b = (struct ieee80211_probe_response *)skb->data; - b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - return skb; -} -EXPORT_SYMBOL(ieee80211_get_beacon); - -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) -{ - ieee->sync_scan_hurryup = 1; - mutex_lock(&ieee->wx_mutex); - ieee80211_stop_protocol(ieee); - mutex_unlock(&ieee->wx_mutex); -} -EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); - -void ieee80211_stop_protocol(struct ieee80211_device *ieee) -{ - if (!ieee->proto_started) - return; - - ieee->proto_started = 0; - - ieee80211_stop_send_beacons(ieee); - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - cancel_delayed_work(&ieee->start_ibss_wq); - ieee80211_stop_scan(ieee); - - ieee80211_disassociate(ieee); - RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS -} - -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) -{ - ieee->sync_scan_hurryup = 0; - mutex_lock(&ieee->wx_mutex); - ieee80211_start_protocol(ieee); - mutex_unlock(&ieee->wx_mutex); -} -EXPORT_SYMBOL(ieee80211_softmac_start_protocol); - -void ieee80211_start_protocol(struct ieee80211_device *ieee) -{ - short ch = 0; - int i = 0; - - if (ieee->proto_started) - return; - - ieee->proto_started = 1; - - if (ieee->current_network.channel == 0) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - return; /* no channel found */ - } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]); - ieee->current_network.channel = ch; - } - - if (ieee->current_network.beacon_interval == 0) - ieee->current_network.beacon_interval = 100; -// printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel); -// ieee->set_chan(ieee->dev,ieee->current_network.channel); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. - - /* if the user set the MAC of the ad-hoc cell and then - * switch to managed mode, shall we make sure that association - * attempts does not fail just because the user provide the essid - * and the nic is still checking for the AP MAC ?? - */ - if (ieee->iw_mode == IW_MODE_INFRA) - ieee80211_start_bss(ieee); - - else if (ieee->iw_mode == IW_MODE_ADHOC) - ieee80211_start_ibss(ieee); - - else if (ieee->iw_mode == IW_MODE_MASTER) - ieee80211_start_master_bss(ieee); - - else if (ieee->iw_mode == IW_MODE_MONITOR) - ieee80211_start_monitor_mode(ieee); -} - -#define DRV_NAME "Ieee80211" -void ieee80211_softmac_init(struct ieee80211_device *ieee) -{ - int i; - memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); - - ieee->state = IEEE80211_NOLINK; - ieee->sync_scan_hurryup = 0; - for (i = 0; i < 5; i++) - ieee->seq_ctrl[i] = 0; - - ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL); - if (!ieee->dot11d_info) - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); - //added for AP roaming - ieee->LinkDetectInfo.SlotNum = 2; - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; - - ieee->assoc_id = 0; - ieee->queue_stop = 0; - ieee->scanning = 0; - ieee->softmac_features = 0; //so IEEE2100-like driver are happy - ieee->wap_set = 0; - ieee->ssid_set = 0; - ieee->proto_started = 0; - ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; - ieee->rate = 22; - ieee->ps = IEEE80211_PS_DISABLED; - ieee->sta_sleep = 0; - ieee->Regdot11HTOperationalRateSet[0] = 0xff;//support MCS 0~7 - ieee->Regdot11HTOperationalRateSet[1] = 0xff;//support MCS 8~15 - ieee->Regdot11HTOperationalRateSet[4] = 0x01; - //added by amy - ieee->actscanning = false; - ieee->beinretry = false; - ieee->is_set_key = false; - init_mgmt_queue(ieee); - - ieee->sta_edca_param[0] = 0x0000A403; - ieee->sta_edca_param[1] = 0x0000A427; - ieee->sta_edca_param[2] = 0x005E4342; - ieee->sta_edca_param[3] = 0x002F3262; - ieee->aggregation = true; - ieee->enable_rx_imm_BA = true; - ieee->tx_pending.txb = NULL; - - timer_setup(&ieee->associate_timer, ieee80211_associate_abort_cb, 0); - - timer_setup(&ieee->beacon_timer, ieee80211_send_beacon_cb, 0); - - INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq); - INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); - INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq); - INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq); - INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq); - INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq); - - mutex_init(&ieee->wx_mutex); - mutex_init(&ieee->scan_mutex); - - spin_lock_init(&ieee->mgmt_tx_lock); - spin_lock_init(&ieee->beacon_lock); - - INIT_WORK(&ieee->ps_task, ieee80211_sta_ps); -} - -void ieee80211_softmac_free(struct ieee80211_device *ieee) -{ - mutex_lock(&ieee->wx_mutex); - kfree(ieee->dot11d_info); - ieee->dot11d_info = NULL; - del_timer_sync(&ieee->associate_timer); - - cancel_delayed_work(&ieee->associate_retry_wq); - cancel_work_sync(&ieee->ps_task); - mutex_unlock(&ieee->wx_mutex); -} - -/******************************************************** - * Start of WPA code. * - * this is stolen from the ipw2200 driver * - ********************************************************/ -static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) -{ - /* This is called when wpa_supplicant loads and closes the driver - * interface. */ - printk("%s WPA\n", value ? "enabling" : "disabling"); - ieee->wpa_enabled = value; - return 0; -} - -static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, - char *wpa_ie, int wpa_ie_len) -{ - /* make sure WPA is enabled */ - ieee80211_wpa_enable(ieee, 1); - - ieee80211_disassociate(ieee); -} - -static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) -{ - int ret = 0; - - switch (command) { - case IEEE_MLME_STA_DEAUTH: - // silently ignore - break; - - case IEEE_MLME_STA_DISASSOC: - ieee80211_disassociate(ieee); - break; - - default: - printk("Unknown MLME request: %d\n", command); - ret = -EOPNOTSUPP; - } - - return ret; -} - -static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, - struct ieee_param *param, int plen) -{ - u8 *buf; - - if (param->u.wpa_ie.len > MAX_WPA_IE_LEN) - return -EINVAL; - - if (param->u.wpa_ie.len) { - buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, - GFP_KERNEL); - if (!buf) - return -ENOMEM; - - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = param->u.wpa_ie.len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - - ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); - return 0; -} - -#define AUTH_ALG_OPEN_SYSTEM 0x1 -#define AUTH_ALG_SHARED_KEY 0x2 - -static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) -{ - struct ieee80211_security sec = { - .flags = SEC_AUTH_MODE, - }; - - if (value & AUTH_ALG_SHARED_KEY) { - sec.auth_mode = WLAN_AUTH_SHARED_KEY; - ieee->open_wep = 0; - ieee->auth_mode = 1; - } else if (value & AUTH_ALG_OPEN_SYSTEM) { - sec.auth_mode = WLAN_AUTH_OPEN; - ieee->open_wep = 1; - ieee->auth_mode = 0; - } else if (value & IW_AUTH_ALG_LEAP) { - sec.auth_mode = WLAN_AUTH_LEAP; - ieee->open_wep = 1; - ieee->auth_mode = 2; - } - - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - //else - // ret = -EOPNOTSUPP; - - return 0; -} - -static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) -{ - int ret = 0; - unsigned long flags; - - switch (name) { - case IEEE_PARAM_WPA_ENABLED: - ret = ieee80211_wpa_enable(ieee, value); - break; - - case IEEE_PARAM_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = value; - break; - - case IEEE_PARAM_DROP_UNENCRYPTED: { - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - struct ieee80211_security sec = { - .flags = SEC_ENABLED, - .enabled = value, - }; - ieee->drop_unencrypted = value; - /* We only change SEC_LEVEL for open mode. Others - * are set by ipw_wpa_set_encryption. - */ - if (!value) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_0; - } else { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - break; - } - - case IEEE_PARAM_PRIVACY_INVOKED: - ieee->privacy_invoked = value; - break; - - case IEEE_PARAM_AUTH_ALGS: - ret = ieee80211_wpa_set_auth_algs(ieee, value); - break; - - case IEEE_PARAM_IEEE_802_1X: - ieee->ieee802_1x = value; - break; - case IEEE_PARAM_WPAX_SELECT: - // added for WPA2 mixed mode - spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags); - ieee->wpax_type_set = 1; - ieee->wpax_type_notify = value; - spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags); - break; - - default: - printk("Unknown WPA param: %d\n", name); - ret = -EOPNOTSUPP; - } - - return ret; -} - -/* implementation borrowed from hostap driver */ -static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, - struct ieee_param *param, int param_len) -{ - int ret = 0; - const char *module = NULL; - - struct ieee80211_crypto_ops *ops = NULL; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - - param->u.crypt.err = 0; - param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len != - (int)((char *)param->u.crypt.key - (char *)param) + - param->u.crypt.key_len) { - printk("Len mismatch %d, %d\n", param_len, - param->u.crypt.key_len); - return -EINVAL; - } - if (is_broadcast_ether_addr(param->sta_addr)) { - if (param->u.crypt.idx >= WEP_KEYS) - return -EINVAL; - crypt = &ieee->crypt[param->u.crypt.idx]; - } else { - return -EINVAL; - } - - if (strcmp(param->u.crypt.alg, "none") == 0) { - if (crypt) { - sec.enabled = 0; - // FIXME FIXME - //sec.encrypt = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - goto done; - } - sec.enabled = 1; -// FIXME FIXME -// sec.encrypt = 1; - sec.flags |= SEC_ENABLED; - - /* IPW HW cannot build TKIP MIC, host decryption still needed. */ - if (!(ieee->host_encrypt || ieee->host_decrypt) && - strcmp(param->u.crypt.alg, "TKIP")) - goto skip_host_crypt; - - //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place - if (!strcmp(param->u.crypt.alg, "WEP")) - module = "ieee80211_crypt_wep"; - else if (!strcmp(param->u.crypt.alg, "TKIP")) - module = "ieee80211_crypt_tkip"; - else if (!strcmp(param->u.crypt.alg, "CCMP")) - module = "ieee80211_crypt_ccmp"; - if (module) - ops = try_then_request_module(ieee80211_get_crypto_ops(param->u.crypt.alg), - module); - if (!ops) { - printk("unknown crypto alg '%s'\n", param->u.crypt.alg); - param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; - ret = -EINVAL; - goto done; - } - - if (!*crypt || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); - if (!new_crypt) { - ret = -ENOMEM; - goto done; - } - new_crypt->ops = ops; - if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) - new_crypt->priv = - new_crypt->ops->init(param->u.crypt.idx); - - if (!new_crypt->priv) { - kfree(new_crypt); - param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(param->u.crypt.key, - param->u.crypt.key_len, param->u.crypt.seq, - (*crypt)->priv) < 0) { - printk("key setting failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - - skip_host_crypt: - if (param->u.crypt.set_tx) { - ieee->tx_keyidx = param->u.crypt.idx; - sec.active_key = param->u.crypt.idx; - sec.flags |= SEC_ACTIVE_KEY; - } else { - sec.flags &= ~SEC_ACTIVE_KEY; - } - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, - param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - done: - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && - ieee->reset_port(ieee->dev)) { - printk("reset_port failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; - return -EINVAL; - } - - return ret; -} - -static inline struct sk_buff *ieee80211_disassociate_skb(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, - u8 asRsn) -{ - struct sk_buff *skb; - struct ieee80211_disassoc *disass; - - skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc)); - if (!skb) - return NULL; - - disass = skb_put(skb, sizeof(struct ieee80211_disassoc)); - disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); - disass->header.duration_id = 0; - - memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); - - disass->reason = cpu_to_le16(asRsn); - return skb; -} - -void -SendDisassociation(struct ieee80211_device *ieee, - u8 *asSta, - u8 asRsn -) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - skb = ieee80211_disassociate_skb(beacon, ieee, asRsn); - if (skb) { - softmac_mgmt_xmit(skb, ieee); - //dev_kfree_skb_any(skb);//edit by thomas - } -} -EXPORT_SYMBOL(SendDisassociation); - -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) -{ - struct ieee_param *param; - int ret = 0; - - mutex_lock(&ieee->wx_mutex); - //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); - - if (p->length < sizeof(struct ieee_param) || !p->pointer) { - ret = -EINVAL; - goto out; - } - - param = memdup_user(p->pointer, p->length); - if (IS_ERR(param)) { - ret = PTR_ERR(param); - goto out; - } - - switch (param->cmd) { - case IEEE_CMD_SET_WPA_PARAM: - ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - - case IEEE_CMD_SET_WPA_IE: - ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); - break; - - case IEEE_CMD_SET_ENCRYPTION: - ret = ieee80211_wpa_set_encryption(ieee, param, p->length); - break; - - case IEEE_CMD_MLME: - ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, - param->u.mlme.reason_code); - break; - - default: - printk("Unknown WPA supplicant request: %d\n", param->cmd); - ret = -EOPNOTSUPP; - break; - } - - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - - kfree(param); -out: - mutex_unlock(&ieee->wx_mutex); - - return ret; -} -EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl); - -void notify_wx_assoc_event(struct ieee80211_device *ieee) -{ - union iwreq_data wrqu; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - if (ieee->state == IEEE80211_LINKED) - memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); - else - eth_zero_addr(wrqu.ap_addr.sa_data); - wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); -} -EXPORT_SYMBOL(notify_wx_assoc_event); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c deleted file mode 100644 index afa92ddfa005..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ /dev/null @@ -1,598 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Some pieces of code might be stolen from ipw2100 driver - * copyright of who own it's copyright ;-) - * - * PS wx handler mostly stolen from hostap, copyright who - * own it's copyright ;-) - */ - - -#include - -#include "ieee80211.h" -#include "dot11d.h" -/* FIXME: add A freqs */ - -const long ieee80211_wlan_frequencies[] = { - 2412, 2417, 2422, 2427, - 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, - 2472, 2484 -}; -EXPORT_SYMBOL(ieee80211_wlan_frequencies); - -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct iw_freq *fwrq = &wrqu->freq; - - mutex_lock(&ieee->wx_mutex); - - if (ieee->iw_mode == IW_MODE_INFRA) { - ret = -EOPNOTSUPP; - goto out; - } - - /* if setting by freq convert to channel */ - if (fwrq->e == 1) { - if ((fwrq->m >= (int)2.412e8 && - fwrq->m <= (int)2.487e8)) { - int f = fwrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) - c++; - - /* hack to fall through */ - fwrq->e = 0; - fwrq->m = c + 1; - } - } - - if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) { - ret = -EOPNOTSUPP; - goto out; - - } else { /* Set the channel */ - - if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) { - ret = -EINVAL; - goto out; - } - ieee->current_network.channel = fwrq->m; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - if (ieee->state == IEEE80211_LINKED) { - ieee80211_stop_send_beacons(ieee); - ieee80211_start_send_beacons(ieee); - } - } - - ret = 0; -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(ieee80211_wx_set_freq); - -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct iw_freq *fwrq = &wrqu->freq; - - if (ieee->current_network.channel == 0) - return -1; - /* NM 0.7.0 will not accept channel any more. */ - fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel - 1] * 100000; - fwrq->e = 1; - /* fwrq->m = ieee->current_network.channel; */ - /* fwrq->e = 0; */ - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_freq); - -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - unsigned long flags; - - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && - ieee->wap_set == 0) - - eth_zero_addr(wrqu->ap_addr.sa_data); - else - memcpy(wrqu->ap_addr.sa_data, - ieee->current_network.bssid, ETH_ALEN); - - spin_unlock_irqrestore(&ieee->lock, flags); - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_wap); - -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - - int ret = 0; - unsigned long flags; - - short ifup = ieee->proto_started; /* dev->flags & IFF_UP; */ - struct sockaddr *temp = (struct sockaddr *)awrq; - - ieee->sync_scan_hurryup = 1; - - mutex_lock(&ieee->wx_mutex); - /* use ifconfig hw ether */ - if (ieee->iw_mode == IW_MODE_MASTER) { - ret = -1; - goto out; - } - - if (temp->sa_family != ARPHRD_ETHER) { - ret = -EINVAL; - goto out; - } - - if (ifup) - ieee80211_stop_protocol(ieee); - - /* just to avoid to give inconsistent infos in the - * get wx method. not really needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = !is_zero_ether_addr(temp->sa_data); - - spin_unlock_irqrestore(&ieee->lock, flags); - - if (ifup) - ieee80211_start_protocol(ieee); -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(ieee80211_wx_set_wap); - -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) -{ - int len, ret = 0; - unsigned long flags; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->current_network.ssid[0] == '\0' || - ieee->current_network.ssid_len == 0) { - ret = -1; - goto out; - } - - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && - ieee->ssid_set == 0) { - ret = -1; - goto out; - } - len = ieee->current_network.ssid_len; - wrqu->essid.length = len; - strncpy(b, ieee->current_network.ssid, len); - wrqu->essid.flags = 1; - -out: - spin_unlock_irqrestore(&ieee->lock, flags); - - return ret; - -} -EXPORT_SYMBOL(ieee80211_wx_get_essid); - -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - - u32 target_rate = wrqu->bitrate.value; - - ieee->rate = target_rate / 100000; - /* FIXME: we might want to limit rate also in management protocols. */ - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_rate); - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - u32 tmp_rate; - - tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); - - wrqu->bitrate.value = tmp_rate * 500000; - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_rate); - -int ieee80211_wx_set_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - if (wrqu->rts.disabled || !wrqu->rts.fixed) { - ieee->rts = DEFAULT_RTS_THRESHOLD; - } else { - if (wrqu->rts.value < MIN_RTS_THRESHOLD || - wrqu->rts.value > MAX_RTS_THRESHOLD) - return -EINVAL; - ieee->rts = wrqu->rts.value; - } - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_rts); - -int ieee80211_wx_get_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->rts.value = ieee->rts; - wrqu->rts.fixed = 0; /* no auto select */ - wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_rts); - -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - - ieee->sync_scan_hurryup = 1; - - mutex_lock(&ieee->wx_mutex); - - if (wrqu->mode == ieee->iw_mode) - goto out; - - if (wrqu->mode == IW_MODE_MONITOR) - ieee->dev->type = ARPHRD_IEEE80211; - else - ieee->dev->type = ARPHRD_ETHER; - - if (!ieee->proto_started) { - ieee->iw_mode = wrqu->mode; - } else { - ieee80211_stop_protocol(ieee); - ieee->iw_mode = wrqu->mode; - ieee80211_start_protocol(ieee); - } - -out: - mutex_unlock(&ieee->wx_mutex); - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_mode); - -void ieee80211_wx_sync_scan_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); - short chan; - enum ht_extension_chan_offset chan_offset = 0; - enum ht_channel_width bandwidth = 0; - int b40M = 0; - - chan = ieee->current_network.channel; - netif_carrier_off(ieee->dev); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - - ieee80211_stop_send_beacons(ieee); - - ieee->state = IEEE80211_LINKED_SCANNING; - ieee->link_change(ieee->dev); - ieee->InitialGainHandler(ieee->dev, IG_Backup); - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { - b40M = 1; - chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; - bandwidth = (enum ht_channel_width)ieee->pHTInfo->bCurBW40MHz; - printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } - ieee80211_start_scan_syncro(ieee); - if (b40M) { - printk("Scan in 20M, back to 40M\n"); - if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, chan + 2); - else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, chan - 2); - else - ieee->set_chan(ieee->dev, chan); - ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); - } else { - ieee->set_chan(ieee->dev, chan); - } - - ieee->InitialGainHandler(ieee->dev, IG_Restore); - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); - /* To prevent the immediately calling watch_dog after scan. */ - if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; - } - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - ieee80211_start_send_beacons(ieee); - - netif_carrier_on(ieee->dev); - mutex_unlock(&ieee->wx_mutex); - -} - -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret = 0; - - mutex_lock(&ieee->wx_mutex); - - if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) { - ret = -1; - goto out; - } - - if (ieee->state == IEEE80211_LINKED) { - queue_work(ieee->wq, &ieee->wx_sync_scan_wq); - /* intentionally forget to up sem */ - return 0; - } - -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(ieee80211_wx_set_scan); - -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - - int ret = 0, len; - short proto_started; - unsigned long flags; - - ieee->sync_scan_hurryup = 1; - mutex_lock(&ieee->wx_mutex); - - proto_started = ieee->proto_started; - - if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { - ret = -E2BIG; - goto out; - } - - if (ieee->iw_mode == IW_MODE_MONITOR) { - ret = -1; - goto out; - } - - if (proto_started) - ieee80211_stop_protocol(ieee); - - - /* this is just to be sure that the GET wx callback - * has consisten infos. not needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (wrqu->essid.flags && wrqu->essid.length) { - /* first flush current network.ssid */ - len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE; - strncpy(ieee->current_network.ssid, extra, len + 1); - ieee->current_network.ssid_len = len + 1; - ieee->ssid_set = 1; - } else { - ieee->ssid_set = 0; - ieee->current_network.ssid[0] = '\0'; - ieee->current_network.ssid_len = 0; - } - spin_unlock_irqrestore(&ieee->lock, flags); - - if (proto_started) - ieee80211_start_protocol(ieee); -out: - mutex_unlock(&ieee->wx_mutex); - return ret; -} -EXPORT_SYMBOL(ieee80211_wx_set_essid); - -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - - wrqu->mode = ieee->iw_mode; - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_mode); - -int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - - int *parms = (int *)extra; - int enable = (parms[0] > 0); - short prev = ieee->raw_tx; - - mutex_lock(&ieee->wx_mutex); - - if (enable) - ieee->raw_tx = 1; - else - ieee->raw_tx = 0; - - netdev_info(ieee->dev, "raw TX is %s\n", - ieee->raw_tx ? "enabled" : "disabled"); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - if (prev == 0 && ieee->raw_tx) { - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); - } - - if (prev && ieee->raw_tx == 1) - netif_carrier_off(ieee->dev); - } - - mutex_unlock(&ieee->wx_mutex); - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_rawtx); - -int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - strscpy(wrqu->name, "802.11", IFNAMSIZ); - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - strlcat(wrqu->name, "b", IFNAMSIZ); - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "/g", IFNAMSIZ); - } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) { - strlcat(wrqu->name, "g", IFNAMSIZ); - } - - if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) - strlcat(wrqu->name, "/n", IFNAMSIZ); - - if ((ieee->state == IEEE80211_LINKED) || - (ieee->state == IEEE80211_LINKED_SCANNING)) - strlcat(wrqu->name, " linked", IFNAMSIZ); - else if (ieee->state != IEEE80211_NOLINK) - strlcat(wrqu->name, " link..", IFNAMSIZ); - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_name); - -/* this is mostly stolen from hostap */ -int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - - mutex_lock(&ieee->wx_mutex); - - if (wrqu->power.disabled) { - ieee->ps = IEEE80211_PS_DISABLED; - goto exit; - } - if (wrqu->power.flags & IW_POWER_TIMEOUT) { - /* ieee->ps_period = wrqu->power.value / 1000; */ - ieee->ps_timeout = wrqu->power.value / 1000; - } - - if (wrqu->power.flags & IW_POWER_PERIOD) { - - /* ieee->ps_timeout = wrqu->power.value / 1000; */ - ieee->ps_period = wrqu->power.value / 1000; - /* wrq->value / 1024; */ - - } - switch (wrqu->power.flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - ieee->ps = IEEE80211_PS_UNICAST; - break; - case IW_POWER_MULTICAST_R: - ieee->ps = IEEE80211_PS_MBCAST; - break; - case IW_POWER_ALL_R: - ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; - break; - - case IW_POWER_ON: - /* ieee->ps = IEEE80211_PS_DISABLED; */ - break; - - default: - ret = -EINVAL; - goto exit; - - } -exit: - mutex_unlock(&ieee->wx_mutex); - return ret; - -} -EXPORT_SYMBOL(ieee80211_wx_set_power); - -/* this is stolen from hostap */ -int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - mutex_lock(&ieee->wx_mutex); - - if (ieee->ps == IEEE80211_PS_DISABLED) { - wrqu->power.disabled = 1; - goto exit; - } - - wrqu->power.disabled = 0; - - if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - wrqu->power.flags = IW_POWER_TIMEOUT; - wrqu->power.value = ieee->ps_timeout * 1000; - } else { - /* ret = -EOPNOTSUPP; */ - /* goto exit; */ - wrqu->power.flags = IW_POWER_PERIOD; - wrqu->power.value = ieee->ps_period * 1000; - /* ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; */ - } - - if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) - wrqu->power.flags |= IW_POWER_ALL_R; - else if (ieee->ps & IEEE80211_PS_MBCAST) - wrqu->power.flags |= IW_POWER_MULTICAST_R; - else - wrqu->power.flags |= IW_POWER_UNICAST_R; - -exit: - mutex_unlock(&ieee->wx_mutex); - return 0; - -} -EXPORT_SYMBOL(ieee80211_wx_get_power); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c deleted file mode 100644 index e4b6454809a0..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ /dev/null @@ -1,839 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * - * Few modifications for Realtek's Wi-Fi drivers by - * Andrea Merello - * - * A special thanks goes to Realtek for their support ! - * - ******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - - -/* - * - * - * 802.11 Data Frame - * - * - * 802.11 frame_contorl for data frames - 2 bytes - * ,-----------------------------------------------------------------------------------------. - * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| - * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| - * desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | - * | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | - * '-----------------------------------------------------------------------------------------' - * /\ - * | - * 802.11 Data Frame | - * ,--------- 'ctrl' expands to >-----------' - * | - * ,--'---,-------------------------------------------------------------. - * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - * |------|------|---------|---------|---------|------|---------|------| - * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - * | | tion | (BSSID) | | | ence | data | | - * `--------------------------------------------------| |------' - * Total: 28 non-data bytes `----.----' - * | - * .- 'Frame data' expands to <---------------------------' - * | - * V - * ,---------------------------------------------------. - * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - * |------|------|---------|----------|------|---------| - * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - * | DSAP | SSAP | | | | Packet | - * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - * `-----------------------------------------| | - * Total: 8 non-data bytes `----.----' - * | - * .- 'IP Packet' expands, if WEP enabled, to <--' - * | - * V - * ,-----------------------. - * Bytes | 4 | 0-2296 | 4 | - * |-----|-----------|-----| - * Desc. | IV | Encrypted | ICV | - * | | IP Packet | | - * `-----------------------' - * Total: 8 non-data bytes - * - * - * 802.3 Ethernet Data Frame - * - * ,-----------------------------------------. - * Bytes | 6 | 6 | 2 | Variable | 4 | - * |-------|-------|------|-----------|------| - * Desc. | Dest. | Source| Type | IP Packet | fcs | - * | MAC | MAC | | | | - * `-----------------------------------------' - * Total: 18 non-data bytes - * - * In the event that fragmentation is required, the incoming payload is split into - * N parts of size ieee->fts. The first fragment contains the SNAP header and the - * remaining packets are just data. - * - * If encryption is enabled, each fragment payload size is reduced by enough space - * to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) - * So if you have 1500 bytes of payload with ieee->fts set to 500 without - * encryption it will take 3 frames. With WEP it will take 4 frames as the - * payload of each frame is reduced to 492 bytes. - * - * SKB visualization - * - * ,- skb->data - * | - * | ETHERNET HEADER ,-<-- PAYLOAD - * | | 14 bytes from skb->data - * | 2 bytes for Type --> ,T. | (sizeof ethhdr) - * | | | | - * |,-Dest.--. ,--Src.---. | | | - * | 6 bytes| | 6 bytes | | | | - * v | | | | | | - * 0 | v 1 | v | v 2 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * ^ | ^ | ^ | - * | | | | | | - * | | | | `T' <---- 2 bytes for Type - * | | | | - * | | '---SNAP--' <-------- 6 bytes for SNAP - * | | - * `-IV--' <-------------------- 4 bytes for IV (WEP) - * - * SNAP HEADER - * - */ - -static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; -static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; - -static inline int ieee80211_put_snap(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - - *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); - - return SNAP_SIZE + sizeof(u16); -} - -int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len) -{ - struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; - int res; - - if (!(crypt && crypt->ops)) { - printk("=========>%s(), crypt is null\n", __func__); - return -1; - } - - if (ieee->tkip_countermeasures && - crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - if (net_ratelimit()) { - struct rtl_80211_hdr_3addrqos *header; - - header = (struct rtl_80211_hdr_3addrqos *)frag->data; - netdev_dbg(ieee->dev, "TKIP countermeasures: dropped " - "TX packet to %pM\n", header->addr1); - } - return -1; - } - - /* To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) - */ - - // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. - /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. - */ - atomic_inc(&crypt->refcnt); - res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) - res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); - - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_info(ieee->dev, "Encryption failed: len=%d.\n", - frag->len); - ieee->ieee_stats.tx_discards++; - return -1; - } - - return 0; -} - - -void ieee80211_txb_free(struct ieee80211_txb *txb) -{ - //int i; - if (unlikely(!txb)) - return; - kfree(txb); -} -EXPORT_SYMBOL(ieee80211_txb_free); - -static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, - gfp_t gfp_mask) -{ - struct ieee80211_txb *txb; - int i; - txb = kmalloc( - sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags), - gfp_mask); - if (!txb) - return NULL; - - memset(txb, 0, sizeof(struct ieee80211_txb)); - txb->nr_frags = nr_frags; - txb->frag_size = __cpu_to_le16(txb_size); - - for (i = 0; i < nr_frags; i++) { - txb->fragments[i] = dev_alloc_skb(txb_size); - if (unlikely(!txb->fragments[i])) { - i--; - break; - } - memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); - } - if (unlikely(i != nr_frags)) { - while (i >= 0) - dev_kfree_skb_any(txb->fragments[i--]); - kfree(txb); - return NULL; - } - return txb; -} - -// Classify the to-be send data packet -// Need to acquire the sent queue index. -static int -ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) -{ - struct ethhdr *eth; - struct iphdr *ip; - eth = (struct ethhdr *)skb->data; - if (eth->h_proto != htons(ETH_P_IP)) - return 0; - - ip = ip_hdr(skb); - switch (ip->tos & 0xfc) { - case 0x20: - return 2; - case 0x40: - return 1; - case 0x60: - return 3; - case 0x80: - return 4; - case 0xa0: - return 5; - case 0xc0: - return 6; - case 0xe0: - return 7; - default: - return 0; - } -} - -static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, - struct sk_buff *skb, struct cb_desc *tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - struct tx_ts_record *pTxTs = NULL; - struct rtl_80211_hdr_1addr *hdr = (struct rtl_80211_hdr_1addr *)skb->data; - - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) - return; - if (!IsQoSDataFrame(skb->data)) - return; - - if (is_multicast_ether_addr(hdr->addr1)) - return; - //check packet and mode later - if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) - return; - - if (pHTInfo->bCurrentAMPDUEnable) { - if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) { - printk("===>can't get TS\n"); - return; - } - if (!pTxTs->tx_admitted_ba_record.valid) { - TsStartAddBaProcess(ieee, pTxTs); - goto FORCED_AGG_SETTING; - } else if (!pTxTs->using_ba) { - if (SN_LESS(pTxTs->tx_admitted_ba_record.start_seq_ctrl.field.seq_num, (pTxTs->tx_cur_seq + 1) % 4096)) - pTxTs->using_ba = true; - else - goto FORCED_AGG_SETTING; - } - - if (ieee->iw_mode == IW_MODE_INFRA) { - tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor; - tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity; - } - } -FORCED_AGG_SETTING: - switch (pHTInfo->ForcedAMPDUMode) { - case HT_AGG_AUTO: - break; - - case HT_AGG_FORCE_ENABLE: - tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity; - tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor; - break; - - case HT_AGG_FORCE_DISABLE: - tcb_desc->bAMPDUEnable = false; - tcb_desc->ampdu_density = 0; - tcb_desc->ampdu_factor = 0; - break; - - } - return; -} - -static void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee, - struct cb_desc *tcb_desc) -{ - tcb_desc->bUseShortPreamble = false; - if (tcb_desc->data_rate == 2) {//// 1M can only use Long Preamble. 11B spec - return; - } else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { - tcb_desc->bUseShortPreamble = true; - } - return; -} -static void -ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, struct cb_desc *tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - tcb_desc->bUseShortGI = false; - - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) - return; - - if (pHTInfo->bForcedShortGI) { - tcb_desc->bUseShortGI = true; - return; - } - - if (pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI40MHz) - tcb_desc->bUseShortGI = true; - else if (!pHTInfo->bCurBW40MHz && pHTInfo->bCurShortGI20MHz) - tcb_desc->bUseShortGI = true; -} - -static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, - struct cb_desc *tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - tcb_desc->bPacketBW = false; - - if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) - return; - - if (tcb_desc->bMulticast || tcb_desc->bBroadcast) - return; - - if ((tcb_desc->data_rate & 0x80) == 0) // If using legacy rate, it shall use 20MHz channel. - return; - //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance - if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) - tcb_desc->bPacketBW = true; - return; -} - -static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, - struct cb_desc *tcb_desc, - struct sk_buff *skb) -{ - // Common Settings - tcb_desc->bRTSSTBC = false; - tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used. - tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS - tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate. - tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz - - if (tcb_desc->bBroadcast || tcb_desc->bMulticast) //only unicast frame will use rts/cts - return; - - if (is_broadcast_ether_addr(skb->data + 16)) //check addr3 as infrastructure add3 is DA. - return; - - if (ieee->mode < IEEE_N_24G) /* b, g mode */ { - // (1) RTS_Threshold is compared to the MPDU, not MSDU. - // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. - // Other fragments are protected by previous fragment. - // So we only need to check the length of first fragment. - if (skb->len > ieee->rts) { - tcb_desc->bRTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - } else if (ieee->current_network.buseprotection) { - // Use CTS-to-SELF in protection mode. - tcb_desc->bRTSEnable = true; - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - } - //otherwise return; - return; - } else { // 11n High throughput case. - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - while (true) { - //check ERP protection - if (ieee->current_network.buseprotection) {// CTS-to-SELF - tcb_desc->bRTSEnable = true; - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - //check HT op mode - if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { - u8 HTOpMode = pHTInfo->CurrentOpMode; - if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || - (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - tcb_desc->bRTSEnable = true; - break; - } - } - //check rts - if (skb->len > ieee->rts) { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - tcb_desc->bRTSEnable = true; - break; - } - //to do list: check MIMO power save condition. - //check AMPDU aggregation for TXOP - if (tcb_desc->bAMPDUEnable) { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads - // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily - tcb_desc->bRTSEnable = false; - break; - } - //check IOT action - if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) { - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - break; - } - // Totally no protection case!! - goto NO_PROTECTION; - } - } - // For test , CTS replace with RTS - if (0) { - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - } - if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - tcb_desc->bUseShortPreamble = true; - if (ieee->mode == IW_MODE_MASTER) - goto NO_PROTECTION; - return; -NO_PROTECTION: - tcb_desc->bRTSEnable = false; - tcb_desc->bCTSEnable = false; - tcb_desc->rts_rate = 0; - tcb_desc->RTSSC = 0; - tcb_desc->bRTSBW = false; -} - - -static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, - struct cb_desc *tcb_desc) -{ - if (ieee->bTxDisableRateFallBack) - tcb_desc->bTxDisableRateFallBack = true; - - if (ieee->bTxUseDriverAssingedRate) - tcb_desc->bTxUseDriverAssingedRate = true; - if (!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) { - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) - tcb_desc->RATRIndex = 0; - } -} - -static void ieee80211_query_seqnum(struct ieee80211_device *ieee, - struct sk_buff *skb, u8 *dst) -{ - if (is_multicast_ether_addr(dst)) - return; - if (IsQoSDataFrame(skb->data)) /* we deal qos data only */ { - struct tx_ts_record *pTS = NULL; - if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, skb->priority, TX_DIR, true)) { - return; - } - pTS->tx_cur_seq = (pTS->tx_cur_seq + 1) % 4096; - } -} - -netdev_tx_t ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - struct ieee80211_txb *txb = NULL; - struct rtl_80211_hdr_3addrqos *frag_hdr; - int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; - unsigned long flags; - struct net_device_stats *stats = &ieee->stats; - int ether_type = 0, encrypt; - int bytes, fc, qos_ctl = 0, hdr_len; - struct sk_buff *skb_frag; - struct rtl_80211_hdr_3addrqos header = { /* Ensure zero initialized */ - .duration_id = 0, - .seq_ctl = 0, - .qos_ctl = 0 - }; - u8 dest[ETH_ALEN], src[ETH_ALEN]; - int qos_actived = ieee->current_network.qos_data.active; - - struct ieee80211_crypt_data *crypt; - - struct cb_desc *tcb_desc; - - spin_lock_irqsave(&ieee->lock, flags); - - /* If there is no driver handler to take the TXB, dont' bother - * creating it... - */ - if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || - ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { - netdev_warn(ieee->dev, "No xmit handler.\n"); - goto success; - } - - - if (likely(ieee->raw_tx == 0)) { - if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", - skb->len); - goto success; - } - - memset(skb->cb, 0, sizeof(skb->cb)); - ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && - ieee->host_encrypt && crypt && crypt->ops; - - if (!encrypt && ieee->ieee802_1x && - ieee->drop_unencrypted && ether_type != ETH_P_PAE) { - stats->tx_dropped++; - goto success; - } - #ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !encrypt && ether_type == ETH_P_PAE) { - struct eapol *eap = (struct eapol *)(skb->data + - sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); - IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - #endif - - /* Save source and destination addresses */ - memcpy(&dest, skb->data, ETH_ALEN); - memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN); - - /* Advance the SKB to the start of the payload */ - skb_pull(skb, sizeof(struct ethhdr)); - - /* Determine total amount of storage required for TXB packets */ - bytes = skb->len + SNAP_SIZE + sizeof(u16); - - if (encrypt) - fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP; - else - - fc = IEEE80211_FTYPE_DATA; - - //if(ieee->current_network.QoS_Enable) - if (qos_actived) - fc |= IEEE80211_STYPE_QOS_DATA; - else - fc |= IEEE80211_STYPE_DATA; - - if (ieee->iw_mode == IW_MODE_INFRA) { - fc |= IEEE80211_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, - * Addr3 = DA - */ - memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(&header.addr2, &src, ETH_ALEN); - memcpy(&header.addr3, &dest, ETH_ALEN); - } else if (ieee->iw_mode == IW_MODE_ADHOC) { - /* not From/To DS: Addr1 = DA, Addr2 = SA, - * Addr3 = BSSID - */ - memcpy(&header.addr1, dest, ETH_ALEN); - memcpy(&header.addr2, src, ETH_ALEN); - memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); - } - - header.frame_ctl = cpu_to_le16(fc); - - /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) - */ - if (is_multicast_ether_addr(header.addr1)) { - frag_size = MAX_FRAG_THRESHOLD; - qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; - } else { - frag_size = ieee->fts;//default:392 - qos_ctl = 0; - } - - //if (ieee->current_network.QoS_Enable) - if (qos_actived) { - hdr_len = IEEE80211_3ADDR_LEN + 2; - - skb->priority = ieee80211_classify(skb, &ieee->current_network); - qos_ctl |= skb->priority; //set in the ieee80211_classify - header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID); - } else { - hdr_len = IEEE80211_3ADDR_LEN; - } - /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account for - * it when determining the amount of payload space. - */ - bytes_per_frag = frag_size - hdr_len; - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - bytes_per_frag -= IEEE80211_FCS_LEN; - - /* Each fragment may need to have room for encryption pre/postfix */ - if (encrypt) - bytes_per_frag -= crypt->ops->extra_prefix_len + - crypt->ops->extra_postfix_len; - - /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment - */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; - - /* When we allocate the TXB we allocate enough space for the reserve - * and full fragment bytes (bytes_per_frag doesn't include prefix, - * postfix, header, FCS, etc.) - */ - txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - txb->encrypted = encrypt; - txb->payload_size = __cpu_to_le16(bytes); - - //if (ieee->current_network.QoS_Enable) - if (qos_actived) - txb->queue_index = UP2AC(skb->priority); - else - txb->queue_index = WME_AC_BK; - - - - for (i = 0; i < nr_frags; i++) { - skb_frag = txb->fragments[i]; - tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); - if (qos_actived) { - skb_frag->priority = skb->priority;//UP2AC(skb->priority); - tcb_desc->queue_index = UP2AC(skb->priority); - } else { - skb_frag->priority = WME_AC_BK; - tcb_desc->queue_index = WME_AC_BK; - } - skb_reserve(skb_frag, ieee->tx_headroom); - - if (encrypt) { - if (ieee->hwsec_active) - tcb_desc->bHwSec = 1; - else - tcb_desc->bHwSec = 0; - skb_reserve(skb_frag, crypt->ops->extra_prefix_len); - } else { - tcb_desc->bHwSec = 0; - } - frag_hdr = skb_put_data(skb_frag, &header, hdr_len); - - /* If this is not the last fragment, then add the MOREFRAGS - * bit to the frame control - */ - if (i != nr_frags - 1) { - frag_hdr->frame_ctl = cpu_to_le16( - fc | IEEE80211_FCTL_MOREFRAGS); - bytes = bytes_per_frag; - - } else { - /* The last fragment takes the remaining length */ - bytes = bytes_last_frag; - } - //if(ieee->current_network.QoS_Enable) - if (qos_actived) { - // add 1 only indicate to corresponding seq number control 2006/7/12 - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority) + 1] << 4 | i); - } else { - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); - } - - /* Put a SNAP header on the first fragment */ - if (i == 0) { - ieee80211_put_snap( - skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), - ether_type); - bytes -= SNAP_SIZE + sizeof(u16); - } - - skb_put_data(skb_frag, skb->data, bytes); - - /* Advance the SKB... */ - skb_pull(skb, bytes); - - /* Encryption routine will move the header forward in order - * to insert the IV between the header and the payload - */ - if (encrypt) - ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - skb_put(skb_frag, 4); - } - - if (qos_actived) { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; - } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - } else { - if (unlikely(skb->len < sizeof(struct rtl_80211_hdr_3addr))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", - skb->len); - goto success; - } - - txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); - if (!txb) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - - txb->encrypted = 0; - txb->payload_size = __cpu_to_le16(skb->len); - skb_put_data(txb->fragments[0], skb->data, skb->len); - } - - success: -//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. - if (txb) { - tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->bTxEnableFwCalcDur = 1; - if (is_multicast_ether_addr(header.addr1)) - tcb_desc->bMulticast = 1; - if (is_broadcast_ether_addr(header.addr1)) - tcb_desc->bBroadcast = 1; - ieee80211_txrate_selectmode(ieee, tcb_desc); - if (tcb_desc->bMulticast || tcb_desc->bBroadcast) - tcb_desc->data_rate = ieee->basic_rate; - else - tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); - ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc); - ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); - ieee80211_query_HTCapShortGI(ieee, tcb_desc); - ieee80211_query_BandwidthMode(ieee, tcb_desc); - ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]); - ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1); - } - spin_unlock_irqrestore(&ieee->lock, flags); - dev_kfree_skb_any(skb); - if (txb) { - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { - ieee80211_softmac_xmit(txb, ieee); - } else { - if ((*ieee->hard_start_xmit)(txb, dev) == 0) { - stats->tx_packets++; - stats->tx_bytes += __le16_to_cpu(txb->payload_size); - return NETDEV_TX_OK; - } - ieee80211_txb_free(txb); - } - } - - return NETDEV_TX_OK; - - failed: - spin_unlock_irqrestore(&ieee->lock, flags); - netif_stop_queue(dev); - stats->tx_errors++; - return 1; - -} diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c deleted file mode 100644 index d6829cf6f7e3..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ /dev/null @@ -1,810 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - - Copyright(c) 2004 Intel Corporation. All rights reserved. - - Portions of this file are based on the WEP enablement code provided by the - Host AP project hostap-drivers v0.1.3 - Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - - Copyright (c) 2002-2003, Jouni Malinen - - Contact Information: - James P. Ketrenos - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -******************************************************************************/ -#include -#include -#include -#include - -#include "ieee80211.h" -struct modes_unit { - char *mode_string; - int mode_size; -}; -static struct modes_unit ieee80211_modes[] = { - {"a", 1}, - {"b", 1}, - {"g", 1}, - {"?", 1}, - {"N-24G", 5}, - {"N-5G", 4}, -}; - -#define iwe_stream_add_event_rsl iwe_stream_add_event - -#define MAX_CUSTOM_LEN 64 -static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, - char *start, char *stop, - struct ieee80211_network *network, - struct iw_request_info *info) -{ - char custom[MAX_CUSTOM_LEN]; - char proto_name[IFNAMSIZ]; - char *pname = proto_name; - char *p; - struct iw_event iwe; - int i, j; - u16 max_rate, rate; - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN); - /* Remaining entries will be displayed in the order we provide them */ - - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; -// if (network->flags & NETWORK_EMPTY_ESSID) { - if (network->ssid_len == 0) { - iwe.u.data.length = sizeof(""); - start = iwe_stream_add_point(info, start, stop, &iwe, ""); - } else { - iwe.u.data.length = min(network->ssid_len, (u8)32); - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - } - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - for (i = 0; i < ARRAY_SIZE(ieee80211_modes); i++) { - if (network->mode & BIT(i)) { - sprintf(pname, ieee80211_modes[i].mode_string, ieee80211_modes[i].mode_size); - pname += ieee80211_modes[i].mode_size; - } - } - *pname = '\0'; - snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name); - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN); - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - if (network->capability & - (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) { - if (network->capability & WLAN_CAPABILITY_BSS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN); - } - - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; -/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode); - iwe.u.freq.e = 3; */ - iwe.u.freq.m = network->channel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN); - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (network->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - /* Add basic and extended rates */ - max_rate = 0; - p = custom; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); - for (i = 0, j = 0; i < network->rates_len; ) { - if (j < network->rates_ex_len && - ((network->rates_ex[j] & 0x7F) < - (network->rates[i] & 0x7F))) - rate = network->rates_ex[j++] & 0x7F; - else - rate = network->rates[i++] & 0x7F; - if (rate > max_rate) - max_rate = rate; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - } - for (; j < network->rates_ex_len; j++) { - rate = network->rates_ex[j] & 0x7F; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - if (rate > max_rate) - max_rate = rate; - } - - if (network->mode >= IEEE_N_24G) /* add N rate here */ { - struct ht_capability_ele *ht_cap = NULL; - bool is40M = false, isShortGI = false; - u8 max_mcs = 0; - if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4)) - ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[4]; - else - ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[0]; - is40M = (ht_cap->ChlWidth) ? 1 : 0; - isShortGI = (ht_cap->ChlWidth) ? - ((ht_cap->ShortGI40Mhz) ? 1 : 0) : - ((ht_cap->ShortGI20Mhz) ? 1 : 0); - - max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL); - rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f]; - if (rate > max_rate) - max_rate = rate; - } - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = max_rate * 500000; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, - IW_EV_PARAM_LEN); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - /* Add quality statistics */ - /* TODO: Fix these values... */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = network->stats.signal; - iwe.u.qual.level = network->stats.rssi; - iwe.u.qual.noise = network->stats.noise; - iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; - if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) - iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) - iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) - iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; - iwe.u.qual.updated = 7; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN); - iwe.cmd = IWEVCUSTOM; - p = custom; - - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - if (ieee->wpa_enabled && network->wpa_ie_len) { - char buf[MAX_WPA_IE_LEN * 2 + 30]; - // printk("WPA IE\n"); - u8 *p = buf; - p += sprintf(p, "wpa_ie="); - for (i = 0; i < network->wpa_ie_len; i++) - p += sprintf(p, "%02x", network->wpa_ie[i]); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - if (ieee->wpa_enabled && network->rsn_ie_len) { - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - u8 *p = buf; - p += sprintf(p, "rsn_ie="); - for (i = 0; i < network->rsn_ie_len; i++) - p += sprintf(p, "%02x", network->rsn_ie[i]); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - - /* Add EXTRA: Age to display seconds since last beacon/probe response - * for given network. */ - iwe.cmd = IWEVCUSTOM; - p = custom; - p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), - " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - return start; -} - -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ieee80211_network *network; - unsigned long flags; - - char *ev = extra; -// char *stop = ev + IW_SCAN_MAX_DATA; - char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA; - //char *stop = ev + IW_SCAN_MAX_DATA; - int i = 0; - int err = 0; - IEEE80211_DEBUG_WX("Getting scan\n"); - mutex_lock(&ieee->wx_mutex); - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(network, &ieee->network_list, list) { - i++; - if ((stop - ev) < 200) { - err = -E2BIG; - break; - } - if (ieee->scan_age == 0 || - time_after(network->last_scanned + ieee->scan_age, jiffies)) - ev = rtl819x_translate_scan(ieee, ev, stop, network, info); - else - IEEE80211_DEBUG_SCAN( - "Not showing network '%s (" - "%pM)' due to age (%lums).\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - (jiffies - network->last_scanned) / (HZ / 100)); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - mutex_unlock(&ieee->wx_mutex); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - - IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i); - - return err; -} -EXPORT_SYMBOL(ieee80211_wx_get_scan); - -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - struct net_device *dev = ieee->dev; - struct ieee80211_security sec = { - .flags = 0 - }; - int i, key, key_provided, len; - struct ieee80211_crypt_data **crypt; - - IEEE80211_DEBUG_WX("SET_ENCODE\n"); - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - key_provided = 1; - } else { - key_provided = 0; - key = ieee->tx_keyidx; - } - - IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? - "provided" : "default"); - crypt = &ieee->crypt[key]; - - if (erq->flags & IW_ENCODE_DISABLED) { - if (key_provided && *crypt) { - IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", - key); - ieee80211_crypt_delayed_deinit(ieee, crypt); - } else - IEEE80211_DEBUG_WX("Disabling encryption.\n"); - - /* Check all the keys to see if any are still configured, - * and if no key index was provided, de-init them all */ - for (i = 0; i < WEP_KEYS; i++) { - if (ieee->crypt[i]) { - if (key_provided) - break; - ieee80211_crypt_delayed_deinit( - ieee, &ieee->crypt[i]); - } - } - - if (i == WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - } - - goto done; - } - - - - sec.enabled = 1; - sec.flags |= SEC_ENABLED; - - if (*crypt && (*crypt)->ops && - strcmp((*crypt)->ops->name, "WEP") != 0) { - /* changing to use WEP; deinit previously used algorithm - * on this key */ - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - - if (!*crypt) { - struct ieee80211_crypt_data *new_crypt; - - /* take WEP into use */ - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (!new_crypt) - return -ENOMEM; - new_crypt->ops = try_then_request_module(ieee80211_get_crypto_ops("WEP"), - "ieee80211_crypt_wep"); - if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) - new_crypt->priv = new_crypt->ops->init(key); - - if (!new_crypt->ops || !new_crypt->priv) { - kfree(new_crypt); - new_crypt = NULL; - - netdev_warn(dev, "could not initialize WEP: " - "load module ieee80211_crypt_wep\n"); - return -EOPNOTSUPP; - } - *crypt = new_crypt; - } - - /* If a new key was provided, set it up */ - if (erq->length > 0) { - len = erq->length <= 5 ? 5 : 13; - memcpy(sec.keys[key], keybuf, erq->length); - if (len > erq->length) - memset(sec.keys[key] + erq->length, 0, - len - erq->length); - IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", - key, escape_essid(sec.keys[key], len), - erq->length, len); - sec.key_sizes[key] = len; - (*crypt)->ops->set_key(sec.keys[key], len, NULL, - (*crypt)->priv); - sec.flags |= BIT(key); - /* This ensures a key will be activated if no key is - * explicitly set - */ - if (key == sec.active_key) - sec.flags |= SEC_ACTIVE_KEY; - ieee->tx_keyidx = key; - - } else { - len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, - NULL, (*crypt)->priv); - if (len == 0) { - /* Set a default key of all 0 */ - printk("Setting key %d to all zero.\n", - key); - - IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", - key); - memset(sec.keys[key], 0, 13); - (*crypt)->ops->set_key(sec.keys[key], 13, NULL, - (*crypt)->priv); - sec.key_sizes[key] = 13; - sec.flags |= BIT(key); - } - - /* No key data - just set the default TX key index */ - if (key_provided) { - IEEE80211_DEBUG_WX( - "Setting key %d to default Tx key.\n", key); - ieee->tx_keyidx = key; - sec.active_key = key; - sec.flags |= SEC_ACTIVE_KEY; - } - } - - done: - ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); - ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.flags |= SEC_AUTH_MODE; - IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? - "OPEN" : "SHARED KEY"); - - /* For now we just support WEP, so only set that security level... - * TODO: When WPA is added this is one place that needs to change */ - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ - - if (ieee->set_security) - ieee->set_security(dev, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - netdev_dbg(ieee->dev, "reset_port failed\n"); - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_encode); - -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - int len, key; - struct ieee80211_crypt_data *crypt; - - IEEE80211_DEBUG_WX("GET_ENCODE\n"); - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - } else - key = ieee->tx_keyidx; - - crypt = ieee->crypt[key]; - erq->flags = key + 1; - - if (!crypt || !crypt->ops) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); - if (len < 0) - len = 0; - erq->length = len; - - erq->flags |= IW_ENCODE_ENABLED; - - if (ieee->open_wep) - erq->flags |= IW_ENCODE_OPEN; - else - erq->flags |= IW_ENCODE_RESTRICTED; - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_encode); - -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct net_device *dev = ieee->dev; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int i, idx; - int group_key = 0; - const char *alg, *module; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > WEP_KEYS) - return -EINVAL; - idx--; - } else - idx = ieee->tx_keyidx; - - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - - crypt = &ieee->crypt[idx]; - - group_key = 1; - } else { - /* some Cisco APs use idx>0 for unicast in dynamic WEP */ - if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) - return -EINVAL; - if (ieee->iw_mode == IW_MODE_INFRA) - - crypt = &ieee->crypt[idx]; - - else - return -EINVAL; - } - - sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT; - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - if (*crypt) - ieee80211_crypt_delayed_deinit(ieee, crypt); - - for (i = 0; i < WEP_KEYS; i++) - - if (ieee->crypt[i]) - - break; - - if (i == WEP_KEYS) { - sec.enabled = 0; - // sec.encrypt = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_LEVEL; - } - goto done; - } - - sec.enabled = 1; - // sec.encrypt = 1; - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - alg = "WEP"; - module = "ieee80211_crypt_wep"; - break; - case IW_ENCODE_ALG_TKIP: - alg = "TKIP"; - module = "ieee80211_crypt_tkip"; - break; - case IW_ENCODE_ALG_CCMP: - alg = "CCMP"; - module = "ieee80211_crypt_ccmp"; - break; - default: - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - ret = -EINVAL; - goto done; - } - printk("alg name:%s\n", alg); - - ops = try_then_request_module(ieee80211_get_crypto_ops(alg), module); - if (!ops) { - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - printk("========>unknown crypto alg %d\n", ext->alg); - ret = -EINVAL; - goto done; - } - - if (!*crypt || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); - if (!new_crypt) { - ret = -ENOMEM; - goto done; - } - new_crypt->ops = ops; - if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) - new_crypt->priv = new_crypt->ops->init(idx); - if (!new_crypt->priv) { - kfree(new_crypt); - ret = -EINVAL; - goto done; - } - *crypt = new_crypt; - } - - if (ext->key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, - (*crypt)->priv) < 0) { - IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name); - printk("key setting failed\n"); - ret = -EINVAL; - goto done; - } - //skip_host_crypt: - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - ieee->tx_keyidx = idx; - sec.active_key = idx; - sec.flags |= SEC_ACTIVE_KEY; - } - - if (ext->alg != IW_ENCODE_ALG_NONE) { - //memcpy(sec.keys[idx], ext->key, ext->key_len); - sec.key_sizes[idx] = ext->key_len; - sec.flags |= BIT(idx); - if (ext->alg == IW_ENCODE_ALG_WEP) { - // sec.encode_alg[idx] = SEC_ALG_WEP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (ext->alg == IW_ENCODE_ALG_TKIP) { - // sec.encode_alg[idx] = SEC_ALG_TKIP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (ext->alg == IW_ENCODE_ALG_CCMP) { - // sec.encode_alg[idx] = SEC_ALG_CCMP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - /* Don't set sec level for group keys. */ - if (group_key) - sec.flags &= ~SEC_LEVEL; - } -done: - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); - return -EINVAL; - } - return ret; -} -EXPORT_SYMBOL(ieee80211_wx_set_encode_ext); - -int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct ieee80211_crypt_data *crypt; - int idx, max_key_len; - - max_key_len = encoding->length - sizeof(*ext); - if (max_key_len < 0) - return -EINVAL; - - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > WEP_KEYS) - return -EINVAL; - idx--; - } else - idx = ieee->tx_keyidx; - - if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && - ext->alg != IW_ENCODE_ALG_WEP) - if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) - return -EINVAL; - - crypt = ieee->crypt[idx]; - encoding->flags = idx + 1; - memset(ext, 0, sizeof(*ext)); - - if (!crypt || !crypt->ops) { - ext->alg = IW_ENCODE_ALG_NONE; - ext->key_len = 0; - encoding->flags |= IW_ENCODE_DISABLED; - } else { - if (strcmp(crypt->ops->name, "WEP") == 0) - ext->alg = IW_ENCODE_ALG_WEP; - else if (strcmp(crypt->ops->name, "TKIP") == 0) - ext->alg = IW_ENCODE_ALG_TKIP; - else if (strcmp(crypt->ops->name, "CCMP") == 0) - ext->alg = IW_ENCODE_ALG_CCMP; - else - return -EINVAL; - ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv); - encoding->flags |= IW_ENCODE_ENABLED; - if (ext->key_len && - (ext->alg == IW_ENCODE_ALG_TKIP || - ext->alg == IW_ENCODE_ALG_CCMP)) - ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; - } - - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_get_encode_ext); - -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_mlme *mlme = (struct iw_mlme *)extra; - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - case IW_MLME_DISASSOC: - ieee80211_disassociate(ieee); - break; - default: - return -EOPNOTSUPP; - } - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_mlme); - -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - /*need to support wpa2 here*/ - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* - * * Host AP driver does not use these parameters and allows - * * wpa_supplicant to control them internally. - * */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = data->value; - break; - case IW_AUTH_DROP_UNENCRYPTED: - ieee->drop_unencrypted = data->value; - break; - - case IW_AUTH_80211_AUTH_ALG: - //printk("======>%s():data->value is %d\n",__func__,data->value); - // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0; - if (data->value & IW_AUTH_ALG_SHARED_KEY) { - ieee->open_wep = 0; - ieee->auth_mode = 1; - } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) { - ieee->open_wep = 1; - ieee->auth_mode = 0; - } else if (data->value & IW_AUTH_ALG_LEAP) { - ieee->open_wep = 1; - ieee->auth_mode = 2; - } else - return -EINVAL; - break; - - case IW_AUTH_WPA_ENABLED: - ieee->wpa_enabled = (data->value) ? 1 : 0; - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - ieee->ieee802_1x = data->value; - break; - case IW_AUTH_PRIVACY_INVOKED: - ieee->privacy_invoked = data->value; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_auth); - -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) -{ - u8 *buf; - - if (len > MAX_WPA_IE_LEN || (len && !ie)) { - //printk("return error out, len:%d\n", len); - return -EINVAL; - } - - - if (len) { - if (len != ie[1] + 2) { - printk("len:%zu, ie:%d\n", len, ie[1]); - return -EINVAL; - } - buf = kmemdup(ie, len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - return 0; -} -EXPORT_SYMBOL(ieee80211_wx_set_gen_ie); diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h deleted file mode 100644 index 1a727856ba53..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _BATYPE_H_ -#define _BATYPE_H_ - -#define BA_SETUP_TIMEOUT 200 - -#define BA_POLICY_DELAYED 0 -#define BA_POLICY_IMMEDIATE 1 - -#define ADDBA_STATUS_SUCCESS 0 -#define ADDBA_STATUS_REFUSED 37 -#define ADDBA_STATUS_INVALID_PARAM 38 - -#define DELBA_REASON_END_BA 37 -#define DELBA_REASON_UNKNOWN_BA 38 -#define DELBA_REASON_TIMEOUT 39 - -union sequence_control { - u16 short_data; - struct { - u16 frag_num:4; - u16 seq_num:12; - } field; -}; - -union ba_param_set { - u16 short_data; - struct { - u16 amsdu_support:1; - u16 ba_policy:1; - u16 tid:4; - u16 buffer_size:10; - } field; -}; - -union delba_param_set { - u16 short_data; - struct { - u16 reserved:11; - u16 initiator:1; - u16 tid:4; - } field; -}; - -struct ba_record { - struct timer_list timer; - u8 valid; - u8 dialog_token; - union ba_param_set param_set; - u16 timeout_value; - union sequence_control start_seq_ctrl; -}; - -#endif //end _BATYPE_H_ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c deleted file mode 100644 index 6823e405eeb8..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ /dev/null @@ -1,700 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/******************************************************************************************************************************** - * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is - * related to TS, this part need some structure defined in QOS side code. Also TX RX is going to be resturctured, so how to send - * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. - * WB 2008-05-27 - * *****************************************************************************************************************************/ -#include -#include -#include "ieee80211.h" -#include "rtl819x_BA.h" - -/******************************************************************************************************************** - *function: Activate BA entry. And if Time is nozero, start timer. - * input: struct ba_record *pBA //BA entry to be enabled - * u16 Time //indicate time delay. - * output: none - ********************************************************************************************************************/ -static void ActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA, u16 Time) -{ - pBA->valid = true; - if (Time != 0) - mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time)); -} - -/******************************************************************************************************************** - *function: deactivate BA entry, including its timer. - * input: struct ba_record *pBA //BA entry to be disabled - * output: none - ********************************************************************************************************************/ -static void DeActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA) -{ - pBA->valid = false; - del_timer_sync(&pBA->timer); -} -/******************************************************************************************************************** - *function: deactivete BA entry in Tx Ts, and send DELBA. - * input: - * struct tx_ts_record *pTxTs //Tx Ts which is to deactivate BA entry. - * output: none - * notice: As struct tx_ts_record * structure will be defined in QOS, so wait to be merged. //FIXME - ********************************************************************************************************************/ -static u8 TxTsDeleteBA(struct ieee80211_device *ieee, struct tx_ts_record *pTxTs) -{ - struct ba_record *pAdmittedBa = &pTxTs->tx_admitted_ba_record; //These two BA entries must exist in TS structure - struct ba_record *pPendingBa = &pTxTs->tx_pending_ba_record; - u8 bSendDELBA = false; - - // Delete pending BA - if (pPendingBa->valid) { - DeActivateBAEntry(ieee, pPendingBa); - bSendDELBA = true; - } - - // Delete admitted BA - if (pAdmittedBa->valid) { - DeActivateBAEntry(ieee, pAdmittedBa); - bSendDELBA = true; - } - - return bSendDELBA; -} - -/******************************************************************************************************************** - *function: deactivete BA entry in Tx Ts, and send DELBA. - * input: - * struct rx_ts_record *pRxTs //Rx Ts which is to deactivate BA entry. - * output: none - * notice: As struct rx_ts_record * structure will be defined in QOS, so wait to be merged. //FIXME, same with above - ********************************************************************************************************************/ -static u8 RxTsDeleteBA(struct ieee80211_device *ieee, struct rx_ts_record *pRxTs) -{ - struct ba_record *pBa = &pRxTs->rx_admitted_ba_record; - u8 bSendDELBA = false; - - if (pBa->valid) { - DeActivateBAEntry(ieee, pBa); - bSendDELBA = true; - } - - return bSendDELBA; -} - -/******************************************************************************************************************** - *function: reset BA entry - * input: - * struct ba_record *pBA //entry to be reset - * output: none - ********************************************************************************************************************/ -void ResetBaEntry(struct ba_record *pBA) -{ - pBA->valid = false; - pBA->param_set.short_data = 0; - pBA->timeout_value = 0; - pBA->dialog_token = 0; - pBA->start_seq_ctrl.short_data = 0; -} -//These functions need porting here or not? -/******************************************************************************************************************************* - *function: construct ADDBAREQ and ADDBARSP frame here together. - * input: u8* Dst //ADDBA frame's destination - * struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA. - * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?) - * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ) - * output: none - * return: sk_buff* skb //return constructed skb to xmit - *******************************************************************************************************************************/ -static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, struct ba_record *pBA, u16 StatusCode, u8 type) -{ - struct sk_buff *skb = NULL; - struct rtl_80211_hdr_3addr *BAReq = NULL; - u8 *tag = NULL; - u16 len = ieee->tx_headroom + 9; - //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); - if (pBA == NULL) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA is NULL\n"); - return NULL; - } - skb = dev_alloc_skb(len + sizeof(struct rtl_80211_hdr_3addr)); //need to add something others? FIXME - if (!skb) - return NULL; - - memset(skb->data, 0, sizeof(struct rtl_80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb. - skb_reserve(skb, ieee->tx_headroom); - - BAReq = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr)); - - memcpy(BAReq->addr1, Dst, ETH_ALEN); - memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); - - memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); - - BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame - - //tag += sizeof( struct rtl_80211_hdr_3addr); //move to action field - tag = skb_put(skb, 9); - *tag++ = ACT_CAT_BA; - *tag++ = type; - // Dialog Token - *tag++ = pBA->dialog_token; - - if (type == ACT_ADDBARSP) { - // Status Code - netdev_info(ieee->dev, "=====>to send ADDBARSP\n"); - - put_unaligned_le16(StatusCode, tag); - tag += 2; - } - // BA Parameter Set - - put_unaligned_le16(pBA->param_set.short_data, tag); - tag += 2; - // BA Timeout Value - - put_unaligned_le16(pBA->timeout_value, tag); - tag += 2; - - if (type == ACT_ADDBAREQ) { - // BA Start SeqCtrl - memcpy(tag, (u8 *)&(pBA->start_seq_ctrl), 2); - tag += 2; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); - return skb; - //return NULL; -} - - -/******************************************************************************************************************** - *function: construct DELBA frame - * input: u8* dst //DELBA frame's destination - * struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA - * enum tr_select TxRxSelect //TX RX direction - * u16 ReasonCode //status code. - * output: none - * return: sk_buff* skb //return constructed skb to xmit - ********************************************************************************************************************/ -static struct sk_buff *ieee80211_DELBA( - struct ieee80211_device *ieee, - u8 *dst, - struct ba_record *pBA, - enum tr_select TxRxSelect, - u16 ReasonCode - ) -{ - union delba_param_set DelbaParamSet; - struct sk_buff *skb = NULL; - struct rtl_80211_hdr_3addr *Delba = NULL; - u8 *tag = NULL; - //len = head len + DELBA Parameter Set(2) + Reason Code(2) - u16 len = 6 + ieee->tx_headroom; - - if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, - "========>%s(), ReasonCode(%d) sentd to:%pM\n", - __func__, ReasonCode, dst); - - memset(&DelbaParamSet, 0, 2); - - DelbaParamSet.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0; - DelbaParamSet.field.tid = pBA->param_set.field.tid; - - skb = dev_alloc_skb(len + sizeof(struct rtl_80211_hdr_3addr)); //need to add something others? FIXME - if (!skb) - return NULL; -// memset(skb->data, 0, len+sizeof( struct rtl_80211_hdr_3addr)); - skb_reserve(skb, ieee->tx_headroom); - - Delba = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr)); - - memcpy(Delba->addr1, dst, ETH_ALEN); - memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); - Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame - - tag = skb_put(skb, 6); - - *tag++ = ACT_CAT_BA; - *tag++ = ACT_DELBA; - - // DELBA Parameter Set - - put_unaligned_le16(DelbaParamSet.short_data, tag); - tag += 2; - // Reason Code - - put_unaligned_le16(ReasonCode, tag); - tag += 2; - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); - if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, - "<=====%s()\n", __func__); - return skb; -} - -/******************************************************************************************************************** - *function: send ADDBAReq frame out - * input: u8* dst //ADDBAReq frame's destination - * struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - ********************************************************************************************************************/ -static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, - u8 *dst, struct ba_record *pBA) -{ - struct sk_buff *skb; - skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero. - - if (skb) { - softmac_mgmt_xmit(skb, ieee); - //add statistic needed here. - //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit() - //WB - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); - } -} - -/******************************************************************************************************************** - *function: send ADDBARSP frame out - * input: u8* dst //DELBA frame's destination - * struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA - * u16 StatusCode //RSP StatusCode - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - ********************************************************************************************************************/ -static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst, - struct ba_record *pBA, u16 StatusCode) -{ - struct sk_buff *skb; - skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames - if (skb) { - softmac_mgmt_xmit(skb, ieee); - //same above - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); - } - - return; - -} -/******************************************************************************************************************** - *function: send ADDBARSP frame out - * input: u8* dst //DELBA frame's destination - * struct ba_record *pBA //BA_RECORD entry which stores the necessary information for BA - * enum tr_select TxRxSelect //TX or RX - * u16 ReasonCode //DEL ReasonCode - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - ********************************************************************************************************************/ - -static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst, - struct ba_record *pBA, enum tr_select TxRxSelect, - u16 ReasonCode) -{ - struct sk_buff *skb; - skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames - if (skb) { - softmac_mgmt_xmit(skb, ieee); - //same above - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __func__); - } -} - -/******************************************************************************************************************** - *function: RX ADDBAReq - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. - ********************************************************************************************************************/ -int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - struct rtl_80211_hdr_3addr *req = NULL; - u16 rc = 0; - u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; - struct ba_record *pBA = NULL; - union ba_param_set *pBaParamSet = NULL; - u16 *pBaTimeoutVal = NULL; - union sequence_control *pBaStartSeqCtrl = NULL; - struct rx_ts_record *pTS = NULL; - - if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - " Invalid skb len in BAREQ(%d / %zu)\n", - skb->len, - (sizeof(struct rtl_80211_hdr_3addr) + 9)); - return -1; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); - - req = (struct rtl_80211_hdr_3addr *)skb->data; - tag = (u8 *)req; - dst = &req->addr2[0]; - tag += sizeof(struct rtl_80211_hdr_3addr); - pDialogToken = tag + 2; //category+action - pBaParamSet = (union ba_param_set *)(tag + 3); //+DialogToken - pBaTimeoutVal = (u16 *)(tag + 5); - pBaStartSeqCtrl = (union sequence_control *)(req + 7); - - netdev_info(ieee->dev, "====================>rx ADDBAREQ from :%pM\n", dst); -//some other capability is not ready now. - if ((ieee->current_network.qos_data.active == 0) || - (!ieee->pHTInfo->bCurrentHTSupport)) //|| - // (!ieee->pStaQos->bEnableRxImmBA) ) - { - rc = ADDBA_STATUS_REFUSED; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); - goto OnADDBAReq_Fail; - } - // Search for related traffic stream. - // If there is no matched TS, reject the ADDBA request. - if (!GetTs( - ieee, - (struct ts_common_info **)(&pTS), - dst, - (u8)(pBaParamSet->field.tid), - RX_DIR, - true)) { - rc = ADDBA_STATUS_REFUSED; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__); - goto OnADDBAReq_Fail; - } - pBA = &pTS->rx_admitted_ba_record; - // To Determine the ADDBA Req content - // We can do much more check here, including buffer_size, AMSDU_Support, Policy, StartSeqCtrl... - // I want to check StartSeqCtrl to make sure when we start aggregation!!! - // - if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { - rc = ADDBA_STATUS_INVALID_PARAM; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __func__); - goto OnADDBAReq_Fail; - } - // Admit the ADDBA Request - // - DeActivateBAEntry(ieee, pBA); - pBA->dialog_token = *pDialogToken; - pBA->param_set = *pBaParamSet; - pBA->timeout_value = *pBaTimeoutVal; - pBA->start_seq_ctrl = *pBaStartSeqCtrl; - //for half N mode we only aggregate 1 frame - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) - pBA->param_set.field.buffer_size = 1; - else - pBA->param_set.field.buffer_size = 32; - ActivateBAEntry(ieee, pBA, pBA->timeout_value); - ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); - - // End of procedure. - return 0; - -OnADDBAReq_Fail: - { - struct ba_record BA; - BA.param_set = *pBaParamSet; - BA.timeout_value = *pBaTimeoutVal; - BA.dialog_token = *pDialogToken; - BA.param_set.field.ba_policy = BA_POLICY_IMMEDIATE; - ieee80211_send_ADDBARsp(ieee, dst, &BA, rc); - return 0; //we send RSP out. - } - -} - -/******************************************************************************************************************** - *function: RX ADDBARSP - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. - ********************************************************************************************************************/ -int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - struct rtl_80211_hdr_3addr *rsp = NULL; - struct ba_record *pPendingBA, *pAdmittedBA; - struct tx_ts_record *pTS = NULL; - u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; - u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; - union ba_param_set *pBaParamSet = NULL; - u16 ReasonCode; - - if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - " Invalid skb len in BARSP(%d / %zu)\n", - skb->len, - (sizeof(struct rtl_80211_hdr_3addr) + 9)); - return -1; - } - rsp = (struct rtl_80211_hdr_3addr *)skb->data; - tag = (u8 *)rsp; - dst = &rsp->addr2[0]; - tag += sizeof(struct rtl_80211_hdr_3addr); - pDialogToken = tag + 2; - pStatusCode = (u16 *)(tag + 3); - pBaParamSet = (union ba_param_set *)(tag + 5); - pBaTimeoutVal = (u16 *)(tag + 7); - - // Check the capability - // Since we can always receive A-MPDU, we just check if it is under HT mode. - if (ieee->current_network.qos_data.active == 0 || - !ieee->pHTInfo->bCurrentHTSupport || - !ieee->pHTInfo->bCurrentAMPDUEnable) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } - - - // - // Search for related TS. - // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame. - // - if (!GetTs( - ieee, - (struct ts_common_info **)(&pTS), - dst, - (u8)(pBaParamSet->field.tid), - TX_DIR, - false)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } - - pTS->add_ba_req_in_progress = false; - pPendingBA = &pTS->tx_pending_ba_record; - pAdmittedBA = &pTS->tx_admitted_ba_record; - - - // - // Check if related BA is waiting for setup. - // If not, reject by sending DELBA frame. - // - if (pAdmittedBA->valid) { - // Since BA is already setup, we ignore all other ADDBA Response. - IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n"); - return -1; - } else if ((!pPendingBA->valid) || (*pDialogToken != pPendingBA->dialog_token)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n"); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } else { - IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode); - DeActivateBAEntry(ieee, pPendingBA); - } - - - if (*pStatusCode == ADDBA_STATUS_SUCCESS) { - // - // Determine ADDBA Rsp content here. - // We can compare the value of BA parameter set that Peer returned and Self sent. - // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism. - // - if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) { - // Since this is a kind of ADDBA failed, we delay next ADDBA process. - pTS->add_ba_req_delayed = true; - DeActivateBAEntry(ieee, pAdmittedBA); - ReasonCode = DELBA_REASON_END_BA; - goto OnADDBARsp_Reject; - } - - - // - // Admitted condition - // - pAdmittedBA->dialog_token = *pDialogToken; - pAdmittedBA->timeout_value = *pBaTimeoutVal; - pAdmittedBA->start_seq_ctrl = pPendingBA->start_seq_ctrl; - pAdmittedBA->param_set = *pBaParamSet; - DeActivateBAEntry(ieee, pAdmittedBA); - ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); - } else { - // Delay next ADDBA process. - pTS->add_ba_req_delayed = true; - } - - // End of procedure - return 0; - -OnADDBARsp_Reject: - { - struct ba_record BA; - BA.param_set = *pBaParamSet; - ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); - return 0; - } - -} - -/******************************************************************************************************************** - *function: RX DELBA - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. - ********************************************************************************************************************/ -int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - struct rtl_80211_hdr_3addr *delba = NULL; - union delba_param_set *pDelBaParamSet = NULL; - u8 *dst = NULL; - - if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 6) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - " Invalid skb len in DELBA(%d / %zu)\n", - skb->len, - (sizeof(struct rtl_80211_hdr_3addr) + 6)); - return -1; - } - - if (ieee->current_network.qos_data.active == 0 || - !ieee->pHTInfo->bCurrentHTSupport) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); - return -1; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_BA, skb->data, skb->len); - delba = (struct rtl_80211_hdr_3addr *)skb->data; - dst = &delba->addr2[0]; - pDelBaParamSet = (union delba_param_set *)&delba->payload[2]; - - if (pDelBaParamSet->field.initiator == 1) { - struct rx_ts_record *pRxTs; - - if (!GetTs( - ieee, - (struct ts_common_info **)&pRxTs, - dst, - (u8)pDelBaParamSet->field.tid, - RX_DIR, - false)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __func__); - return -1; - } - - RxTsDeleteBA(ieee, pRxTs); - } else { - struct tx_ts_record *pTxTs; - - if (!GetTs( - ieee, - (struct ts_common_info **)&pTxTs, - dst, - (u8)pDelBaParamSet->field.tid, - TX_DIR, - false)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __func__); - return -1; - } - - pTxTs->using_ba = false; - pTxTs->add_ba_req_in_progress = false; - pTxTs->add_ba_req_delayed = false; - del_timer_sync(&pTxTs->ts_add_ba_timer); - //PlatformCancelTimer(Adapter, &pTxTs->ts_add_ba_timer); - TxTsDeleteBA(ieee, pTxTs); - } - return 0; -} - -// -// ADDBA initiate. This can only be called by TX side. -// -void -TsInitAddBA( - struct ieee80211_device *ieee, - struct tx_ts_record *pTS, - u8 Policy, - u8 bOverwritePending - ) -{ - struct ba_record *pBA = &pTS->tx_pending_ba_record; - - if (pBA->valid && !bOverwritePending) - return; - - // Set parameters to "Pending" variable set - DeActivateBAEntry(ieee, pBA); - - pBA->dialog_token++; // DialogToken: Only keep the latest dialog token - pBA->param_set.field.amsdu_support = 0; // Do not support A-MSDU with A-MPDU now!! - pBA->param_set.field.ba_policy = Policy; // Policy: Delayed or Immediate - pBA->param_set.field.tid = pTS->ts_common_info.t_spec.ts_info.uc_tsid; // TID - // buffer_size: This need to be set according to A-MPDU vector - pBA->param_set.field.buffer_size = 32; // buffer_size: This need to be set according to A-MPDU vector - pBA->timeout_value = 0; // Timeout value: Set 0 to disable Timer - pBA->start_seq_ctrl.field.seq_num = (pTS->tx_cur_seq + 3) % 4096; // Block Ack will start after 3 packets later. - - ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); - - ieee80211_send_ADDBAReq(ieee, pTS->ts_common_info.addr, pBA); -} - -void -TsInitDelBA(struct ieee80211_device *ieee, struct ts_common_info *pTsCommonInfo, enum tr_select TxRxSelect) -{ - if (TxRxSelect == TX_DIR) { - struct tx_ts_record *pTxTs = (struct tx_ts_record *)pTsCommonInfo; - - if (TxTsDeleteBA(ieee, pTxTs)) - ieee80211_send_DELBA( - ieee, - pTsCommonInfo->addr, - (pTxTs->tx_admitted_ba_record.valid) ? (&pTxTs->tx_admitted_ba_record) : (&pTxTs->tx_pending_ba_record), - TxRxSelect, - DELBA_REASON_END_BA); - } else if (TxRxSelect == RX_DIR) { - struct rx_ts_record *pRxTs = (struct rx_ts_record *)pTsCommonInfo; - if (RxTsDeleteBA(ieee, pRxTs)) - ieee80211_send_DELBA( - ieee, - pTsCommonInfo->addr, - &pRxTs->rx_admitted_ba_record, - TxRxSelect, - DELBA_REASON_END_BA); - } -} -/******************************************************************************************************************** - *function: BA setup timer - * input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer - * return: NULL - * notice: - ********************************************************************************************************************/ -void BaSetupTimeOut(struct timer_list *t) -{ - struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_pending_ba_record.timer); - - pTxTs->add_ba_req_in_progress = false; - pTxTs->add_ba_req_delayed = true; - pTxTs->tx_pending_ba_record.valid = false; -} - -void TxBaInactTimeout(struct timer_list *t) -{ - struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_admitted_ba_record.timer); - struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]); - TxTsDeleteBA(ieee, pTxTs); - ieee80211_send_DELBA( - ieee, - pTxTs->ts_common_info.addr, - &pTxTs->tx_admitted_ba_record, - TX_DIR, - DELBA_REASON_TIMEOUT); -} - -void RxBaInactTimeout(struct timer_list *t) -{ - struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_admitted_ba_record.timer); - struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); - - RxTsDeleteBA(ieee, pRxTs); - ieee80211_send_DELBA( - ieee, - pRxTs->ts_common_info.addr, - &pRxTs->rx_admitted_ba_record, - RX_DIR, - DELBA_REASON_TIMEOUT); -} diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h deleted file mode 100644 index 79346a00af09..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +++ /dev/null @@ -1,302 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _RTL819XU_HTTYPE_H_ -#define _RTL819XU_HTTYPE_H_ - -/* - * The HT Capability element is present in beacons, association request, - * reassociation request and probe response frames - */ - -/* - * MIMO Power Save Settings - */ -#define MIMO_PS_STATIC 0 - -/* - * There should be 128 bits to cover all of the MCS rates. However, since - * 8190 does not support too much rates, one integer is quite enough. - */ -#define HTCLNG 4 - -/* - * Represent Channel Width in HT Capabilities - */ -enum ht_channel_width { - HT_CHANNEL_WIDTH_20 = 0, - HT_CHANNEL_WIDTH_20_40 = 1, -}; - -/* - * Represent Extension Channel Offset in HT Capabilities - * This is available only in 40Mhz mode. - */ -enum ht_extension_chan_offset { - HT_EXTCHNL_OFFSET_NO_EXT = 0, - HT_EXTCHNL_OFFSET_UPPER = 1, - HT_EXTCHNL_OFFSET_NO_DEF = 2, - HT_EXTCHNL_OFFSET_LOWER = 3, -}; - -struct ht_capability_ele { - //HT capability info - u8 AdvCoding:1; - u8 ChlWidth:1; - u8 MimoPwrSave:2; - u8 GreenField:1; - u8 ShortGI20Mhz:1; - u8 ShortGI40Mhz:1; - u8 TxSTBC:1; - u8 RxSTBC:2; - u8 DelayBA:1; - u8 MaxAMSDUSize:1; - u8 DssCCk:1; - u8 PSMP:1; - u8 Rsvd1:1; - u8 LSigTxopProtect:1; - - //MAC HT parameters info - u8 MaxRxAMPDUFactor:2; - u8 MPDUDensity:3; - u8 Rsvd2:3; - - //Supported MCS set - u8 MCS[16]; - - //Extended HT Capability Info - u16 ExtHTCapInfo; - - //TXBF Capabilities - u8 TxBFCap[4]; - - //Antenna Selection Capabilities - u8 ASCap; - -} __packed; - -/* - * The HT Information element is present in beacons - * Only AP is required to include this element - */ -typedef struct _HT_INFORMATION_ELE { - u8 ControlChl; - - u8 ExtChlOffset:2; - u8 RecommemdedTxWidth:1; - u8 RIFS:1; - u8 PSMPAccessOnly:1; - u8 SrvIntGranularity:3; - - u8 OptMode:2; - u8 NonGFDevPresent:1; - u8 Revd1:5; - u8 Revd2:8; - - u8 Rsvd3:6; - u8 DualBeacon:1; - u8 DualCTSProtect:1; - - u8 SecondaryBeacon:1; - u8 LSigTxopProtectFull:1; - u8 PcoActive:1; - u8 PcoPhase:1; - u8 Rsvd4:4; - - u8 BasicMSC[16]; -} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE; - -typedef enum _HT_SPEC_VER { - HT_SPEC_VER_IEEE = 0, - HT_SPEC_VER_EWC = 1, -} HT_SPEC_VER, *PHT_SPEC_VER; - -typedef enum _HT_AGGRE_MODE_E { - HT_AGG_AUTO = 0, - HT_AGG_FORCE_ENABLE = 1, - HT_AGG_FORCE_DISABLE = 2, -} HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E; - -/* - * The Data structure is used to keep HT related variables when card is - * configured as non-AP STA mode. **Note** Current_xxx should be set - * to default value in HTInitializeHTInfo() - */ -typedef struct _RT_HIGH_THROUGHPUT { - u8 bEnableHT; - u8 bCurrentHTSupport; - - u8 bRegBW40MHz; // Tx 40MHz channel capability - u8 bCurBW40MHz; // Tx 40MHz channel capability - - u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz - u8 bCurShortGI40MHz; // Tx Short GI for 40MHz - - u8 bRegShortGI20MHz; // Tx Short GI for 20MHz - u8 bCurShortGI20MHz; // Tx Short GI for 20MHz - - u8 bRegSuppCCK; // Tx CCK rate capability - u8 bCurSuppCCK; // Tx CCK rate capability - - // 802.11n spec version for "peer" - HT_SPEC_VER ePeerHTSpecVer; - - // HT related information for "Self" - struct ht_capability_ele SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities. - HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities. - - // HT related information for "Peer" - u8 PeerHTCapBuf[32]; - u8 PeerHTInfoBuf[32]; - - // A-MSDU related - u8 bAMSDU_Support; // This indicates Tx A-MSDU capability - u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability - u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability - u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability - - // AMPDU related <2006.08.10 Emily> - u8 bAMPDUEnable; // This indicate Tx A-MPDU capability - u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability - u8 AMPDU_Factor; // This indicate Tx A-MPDU capability - u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability - u8 MPDU_Density; // This indicate Tx A-MPDU capability - u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability - - // Forced A-MPDU enable - HT_AGGRE_MODE_E ForcedAMPDUMode; - u8 ForcedAMPDUFactor; - u8 ForcedMPDUDensity; - - // Forced A-MSDU enable - HT_AGGRE_MODE_E ForcedAMSDUMode; - u16 ForcedAMSDUMaxSize; - - u8 bForcedShortGI; - - u8 CurrentOpMode; - - // MIMO PS related - u8 SelfMimoPs; - u8 PeerMimoPs; - - // 40MHz Channel Offset settings. - enum ht_extension_chan_offset CurSTAExtChnlOffset; - u8 bCurTxBW40MHz; // If we use 40 MHz to Tx - u8 PeerBandwidth; - - // For Bandwidth Switching - u8 bSwBwInProgress; - u8 SwBwStep; - //struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here. - - // For Realtek proprietary A-MPDU factor for aggregation - u8 bRegRT2RTAggregation; - u8 bCurrentRT2RTAggregation; - u8 bCurrentRT2RTLongSlotTime; - u8 szRT2RTAggBuffer[10]; - - // Rx Reorder control - u8 bRegRxReorderEnable; - u8 bCurRxReorderEnable; - u8 RxReorderWinSize; - u8 RxReorderPendingTime; - u16 RxReorderDropCounter; - -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - u8 UsbTxAggrNum; -#endif -#ifdef USB_RX_AGGREGATION_SUPPORT - u8 UsbRxFwAggrEn; - u8 UsbRxFwAggrPageNum; - u8 UsbRxFwAggrPacketNum; - u8 UsbRxFwAggrTimeout; -#endif - - // Add for Broadcom(Linksys) IOT. Joseph - u8 bIsPeerBcm; - - // For IOT issue. - u8 IOTPeer; - u32 IOTAction; -} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT; - -/* - * The Data structure is used to keep HT related variable for "each AP" - * when card is configured as "STA mode" - */ -typedef struct _BSS_HT { - u8 bdSupportHT; - - // HT related elements - u8 bdHTCapBuf[32]; - u16 bdHTCapLen; - u8 bdHTInfoBuf[32]; - u16 bdHTInfoLen; - - HT_SPEC_VER bdHTSpecVer; - //struct ht_capability_ele bdHTCapEle; - //HT_INFORMATION_ELE bdHTInfoEle; - - u8 bdRT2RTAggregation; - u8 bdRT2RTLongSlotTime; -} __attribute__ ((packed)) BSS_HT, *PBSS_HT; - -extern u8 MCS_FILTER_ALL[16]; -extern u8 MCS_FILTER_1SS[16]; - -/* - * 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set - * STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have - * to add a macro to judge wireless mode. - */ -#define PICK_RATE(_nLegacyRate, _nMcsRate) \ - (_nMcsRate == 0) ? (_nLegacyRate & 0x7f) : (_nMcsRate) -/* 2007/07/12 MH We only define legacy and HT wireless mode now. */ -#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK - -#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ - ((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ? \ - (LegacyRate) : \ - (PICK_RATE(LegacyRate, HTRate)) - -// MCS Bw 40 {1~7, 12~15,32} -#define RATE_ADPT_1SS_MASK 0xFF -#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily -#define RATE_ADPT_MCS32_MASK 0x01 - -#define IS_11N_MCS_RATE(rate) (rate & 0x80) - -typedef enum _HT_AGGRE_SIZE { - HT_AGG_SIZE_8K = 0, - HT_AGG_SIZE_16K = 1, - HT_AGG_SIZE_32K = 2, - HT_AGG_SIZE_64K = 3, -} HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E; - -/* Indicate different AP vendor for IOT issue */ -typedef enum _HT_IOT_PEER { - HT_IOT_PEER_UNKNOWN = 0, - HT_IOT_PEER_REALTEK = 1, - HT_IOT_PEER_BROADCOM = 2, - HT_IOT_PEER_RALINK = 3, - HT_IOT_PEER_ATHEROS = 4, - HT_IOT_PEER_CISCO = 5, - HT_IOT_PEER_MAX = 6 -} HT_IOT_PEER_E, *PHTIOT_PEER_E; - -/* - * IOT Action for different AP - */ -typedef enum _HT_IOT_ACTION { - HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, - HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, - HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, - HT_IOT_ACT_DISABLE_MCS15 = 0x00000008, - HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010, - HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020, - HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040, - HT_IOT_ACT_CDD_FSYNC = 0x00000080, - HT_IOT_ACT_PURE_N_MODE = 0x00000100, - HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, -} HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; - -#endif //_RTL819XU_HTTYPE_H_ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c deleted file mode 100644 index a93f09033d9d..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ /dev/null @@ -1,1295 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/* - * As this function is mainly ported from Windows driver, so leave the name - * little changed. If any confusion caused, tell me. Created by WB. 2008.05.08 - */ -#include "ieee80211.h" - -u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -u16 MCS_DATA_RATE[2][2][77] = { - { {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, - 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520, - 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195, - 195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260, - 286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429}, // Long GI, 20MHz - {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, - 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578, - 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217, - 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289, - 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477} }, // Short GI, 20MHz - { {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, - 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080, - 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405, - 405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540, - 594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, // Long GI, 40MHz - {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, - 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200, - 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450, - 450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600, - 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} } // Short GI, 40MHz -}; - -static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; -static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; -static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; -static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; -static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 -static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; -static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; -static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; -static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; -//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; -static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; -/* - * 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we - * put the code in other place?? - * static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; - */ -/* - *function: This function update default settings in pHTInfo structure - * input: PRT_HIGH_THROUGHPUT pHTInfo - * output: none - * return: none - * notice: These value need be modified if any changes. - */ -void HTUpdateDefaultSetting(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - //const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo; - - //printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p, offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo)); - //printk("===>ieee:%p,\n", ieee); - // ShortGI support - pHTInfo->bRegShortGI20MHz = 1; - pHTInfo->bRegShortGI40MHz = 1; - - // 40MHz channel support - pHTInfo->bRegBW40MHz = 1; - - // CCK rate support in 40MHz channel - if (pHTInfo->bRegBW40MHz) - pHTInfo->bRegSuppCCK = 1; - else - pHTInfo->bRegSuppCCK = true; - - // AMSDU related - pHTInfo->nAMSDU_MaxSize = 7935UL; - pHTInfo->bAMSDU_Support = 0; - - // AMPDU related - pHTInfo->bAMPDUEnable = 1; - pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k) - pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec - - // MIMO Power Save - pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.) - if (pHTInfo->SelfMimoPs == 2) - pHTInfo->SelfMimoPs = 3; - // 8190 only. Assign rate operation mode to firmware - ieee->bTxDisableRateFallBack = 0; - ieee->bTxUseDriverAssingedRate = 0; - - /* - * 8190 only, Realtek proprietary aggregation mode - * Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others - */ - pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others - - // For Rx Reorder Control - pHTInfo->bRegRxReorderEnable = 1; - pHTInfo->RxReorderWinSize = 64; - pHTInfo->RxReorderPendingTime = 30; - -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - pHTInfo->UsbTxAggrNum = 4; -#endif -#ifdef USB_RX_AGGREGATION_SUPPORT - pHTInfo->UsbRxFwAggrEn = 1; - pHTInfo->UsbRxFwAggrPageNum = 24; - pHTInfo->UsbRxFwAggrPacketNum = 8; - pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us -#endif -} - -/* - *function: This function print out each field on HT capability - * IE mainly from (Beacon/ProbeRsp/AssocReq) - * input: u8* CapIE //Capability IE to be printed out - * u8* TitleString //mainly print out caller function - * output: none - * return: none - * notice: Driver should not print out this message by default. - */ -void HTDebugHTCapability(u8 *CapIE, u8 *TitleString) -{ - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily - struct ht_capability_ele *pCapELE; - - if (!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) { - //EWC IE - IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __func__); - pCapELE = (struct ht_capability_ele *)(&CapIE[4]); - } else { - pCapELE = (struct ht_capability_ele *)(&CapIE[0]); - } - IEEE80211_DEBUG(IEEE80211_DL_HT, ". Called by %s\n", TitleString); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth) ? "20MHz" : "20/40MHz"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz) ? "YES" : "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz) ? "YES" : "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC) ? "YES" : "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize) ? "3839" : "7935"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk) ? "YES" : "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\ - pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]); -} - -/* - *function: This function print out each field on HT Information - * IE mainly from (Beacon/ProbeRsp) - * input: u8* InfoIE //Capability IE to be printed out - * u8* TitleString //mainly print out caller function - * output: none - * return: none - * notice: Driver should not print out this message by default. - */ -void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString) -{ - static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - PHT_INFORMATION_ELE pHTInfoEle; - - if (!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo))) { - // Not EWC IE - IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __func__); - pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]); - } else { - pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]); - } - - IEEE80211_DEBUG(IEEE80211_DL_HT, ". Called by %s\n", TitleString); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSecondary channel ="); - switch (pHTInfoEle->ExtChlOffset) { - case 0: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n"); - break; - case 1: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n"); - break; - case 2: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n"); - break; - case 3: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n"); - break; - } - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth) ? "20Mhz" : "40Mhz"); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = "); - switch (pHTInfoEle->OptMode) { - case 0: - IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n"); - break; - case 1: - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n"); - break; - case 2: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n"); - break; - case 3: - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n"); - break; - } - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\ - pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]); -} - -static u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - u8 is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0; - u8 isShortGI = (pHTInfo->bCurBW40MHz) ? - ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) : - ((pHTInfo->bCurShortGI20MHz) ? 1 : 0); - return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; -} - -/* - *function: This function returns current datarate. - * input: struct ieee80211_device* ieee - * u8 nDataRate - * output: none - * return: tx rate - * notice: quite unsure about how to use this function //wb - */ -u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate) -{ - //PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u16 CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; - u8 is40MHz = 0; - u8 isShortGI = 0; - - if (nDataRate < 12) { - return CCKOFDMRate[nDataRate]; - } else { - if (nDataRate >= 0x10 && nDataRate <= 0x1f) { //if(nDataRate > 11 && nDataRate < 28 ) - is40MHz = 0; - isShortGI = 0; - - // nDataRate = nDataRate - 12; - } else if (nDataRate >= 0x20 && nDataRate <= 0x2f) { //(27, 44) - is40MHz = 1; - isShortGI = 0; - - //nDataRate = nDataRate - 28; - } else if (nDataRate >= 0x30 && nDataRate <= 0x3f) { //(43, 60) - is40MHz = 0; - isShortGI = 1; - - //nDataRate = nDataRate - 44; - } else if (nDataRate >= 0x40 && nDataRate <= 0x4f) { //(59, 76) - is40MHz = 1; - isShortGI = 1; - - //nDataRate = nDataRate - 60; - } - return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate & 0xf]; - } -} - -bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee) -{ - bool retValue = false; - struct ieee80211_network *net = &ieee->current_network; - - if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || - (memcmp(net->bssid, PCI_RALINK, 3) == 0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || - (net->ralink_cap_exist)) - retValue = true; - else if ((memcmp(net->bssid, UNKNOWN_BORADCOM, 3) == 0) || - (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) == 0) || - (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) == 0) || - (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3) == 0) || - (net->broadcom_cap_exist)) - retValue = true; - else if (net->bssht.bdRT2RTAggregation) - retValue = true; - else - retValue = false; - - return retValue; -} - -/* - *function: This function returns peer IOT. - * input: struct ieee80211_device* ieee - * output: none - * return: - * notice: - */ -static void HTIOTPeerDetermine(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - struct ieee80211_network *net = &ieee->current_network; - - if (net->bssht.bdRT2RTAggregation) - pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; - else if (net->broadcom_cap_exist) - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; - else if ((memcmp(net->bssid, UNKNOWN_BORADCOM, 3) == 0) || - (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) == 0) || - (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) == 0) || - (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3) == 0)) - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; - else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || - (memcmp(net->bssid, PCI_RALINK, 3) == 0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || - net->ralink_cap_exist) - pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; - else if (net->atheros_cap_exist) - pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; - else if (memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) - pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; - else - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; - - IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer); -} - -/* - *function: Check whether driver should declare received rate up to MCS13 - * only since some chipset is not good at receiving MCS14~15 frame - * from some AP. - * input: struct ieee80211_device* ieee - * u8 * PeerMacAddr - * output: none - * return: return 1 if driver should declare MCS13 only(otherwise return 0) - */ -static u8 HTIOTActIsDisableMCS14(struct ieee80211_device *ieee, u8 *PeerMacAddr) -{ - return 0; -} - -/* - * Function: HTIOTActIsDisableMCS15 - * - * Overview: Check whether driver should declare capability of receiving - * MCS15 - * - * Input: - * PADAPTER Adapter, - * - * Output: None - * Return: true if driver should disable MCS15 - * 2008.04.15 Emily - */ -static bool HTIOTActIsDisableMCS15(struct ieee80211_device *ieee) -{ - bool retValue = false; - -#ifdef TODO - // Apply for 819u only -#if (HAL_CODE_BASE == RTL8192) - -#if (DEV_BUS_TYPE == USB_INTERFACE) - // Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15 - retValue = true; -#elif (DEV_BUS_TYPE == PCI_INTERFACE) - // Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12 -// if(pBssDesc->bCiscoCapExist) -// retValue = false; -// else - retValue = false; -#endif -#endif -#endif - // Jerry Chang suggest that 8190 1x2 does not need to disable MCS15 - - return retValue; -} - -/* - * Function: HTIOTActIsDisableMCSTwoSpatialStream - * - * Overview: Check whether driver should declare capability of receiving - * All 2 ss packets - * - * Input: - * PADAPTER Adapter, - * - * Output: None - * Return: true if driver should disable all two spatial stream packet - * 2008.04.21 Emily - */ -static bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device *ieee, - u8 *PeerMacAddr) -{ -#ifdef TODO - // Apply for 819u only -#endif - return false; -} - -/* - *function: Check whether driver should disable EDCA turbo mode - * input: struct ieee80211_device* ieee - * u8* PeerMacAddr - * output: none - * return: return 1 if driver should disable EDCA turbo mode - * (otherwise return 0) - */ -static u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device *ieee, - u8 *PeerMacAddr) -{ /* default enable EDCA Turbo mode. */ - return false; -} - -/* - *function: Check whether we need to use OFDM to sned MGNT frame for - * broadcom AP - * input: struct ieee80211_network *network //current network we live - * output: none - * return: return 1 if true - */ -static u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network) -{ - u8 retValue = 0; - - // 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP. - // 2008/01/28 MH We must prevent that we select null bssid to link. - - if (network->broadcom_cap_exist) - retValue = 1; - - return retValue; -} - -static u8 HTIOTActIsCCDFsync(u8 *PeerMacAddr) -{ - u8 retValue = 0; - - if ((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3) == 0) || - (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) == 0) || - (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) == 0)) - retValue = 1; - - return retValue; -} - -void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo) -{ - pHTInfo->IOTAction = 0; - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; -} - -/* - *function: Construct Capablility Element in Beacon... if HTEnable is turned on - * input: struct ieee80211_device* ieee - * u8* posHTCap //pointer to store Capability Ele - * u8* len //store length of CE - * u8 IsEncrypt //whether encrypt, needed further - * output: none - * return: none - * notice: posHTCap can't be null and should be initialized before. - */ -void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 IsEncrypt) -{ - PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; - struct ht_capability_ele *pCapELE = NULL; - //u8 bIsDeclareMCS13; - - if (!posHTCap || !pHT) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "posHTCap or pHTInfo can't be null in %s\n", - __func__); - return; - } - memset(posHTCap, 0, *len); - if (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) { - static const u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; - - memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); - pCapELE = (struct ht_capability_ele *)&posHTCap[4]; - } else { - pCapELE = (struct ht_capability_ele *)posHTCap; - } - - //HT capability info - pCapELE->AdvCoding = 0; // This feature is not supported now!! - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) - pCapELE->ChlWidth = 0; - else - pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); - -// pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0); - pCapELE->MimoPwrSave = pHT->SelfMimoPs; - pCapELE->GreenField = 0; // This feature is not supported now!! - pCapELE->ShortGI20Mhz = 1; // We can receive Short GI!! - pCapELE->ShortGI40Mhz = 1; // We can receive Short GI!! - //DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r", - //pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz); - pCapELE->TxSTBC = 1; - pCapELE->RxSTBC = 0; - pCapELE->DelayBA = 0; // Do not support now!! - pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; - pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); - pCapELE->PSMP = 0; // Do not support now!! - pCapELE->LSigTxopProtect = 0; // Do not support now!! - - /* - * MAC HT parameters info - * TODO: Nedd to take care of this part - */ - IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); - - if (IsEncrypt) { - pCapELE->MPDUDensity = 7; // 8us - pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K - } else { - pCapELE->MaxRxAMPDUFactor = 3; // 2 is for 32 K and 3 is 64K - pCapELE->MPDUDensity = 0; // no density - } - - //Supported MCS set - memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); - if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) - pCapELE->MCS[1] &= 0x7f; - - if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) - pCapELE->MCS[1] &= 0xbf; - - if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) - pCapELE->MCS[1] &= 0x00; - - /* - * 2008.06.12 - * For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7. - */ - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { - int i; - - for (i = 1; i < 16; i++) - pCapELE->MCS[i] = 0; - } - - //Extended HT Capability Info - memset(&pCapELE->ExtHTCapInfo, 0, 2); - - //TXBF Capabilities - memset(pCapELE->TxBFCap, 0, 4); - - //Antenna Selection Capabilities - pCapELE->ASCap = 0; -//add 2 to give space for element ID and len when construct frames - if (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) - *len = 30 + 2; - else - *len = 26 + 2; - -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2); - - /* - * Print each field in detail. Driver should not print out this message - * by default - */ -// HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()"); -} - -/* - *function: Construct Information Element in Beacon... if HTEnable is turned on - * input: struct ieee80211_device* ieee - * u8* posHTCap //pointer to store Information Ele - * u8* len //store len of - * u8 IsEncrypt //whether encrypt, needed further - * output: none - * return: none - * notice: posHTCap can't be null and be initialized before. - * Only AP and IBSS sta should do this - */ -void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 IsEncrypt) -{ - PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; - PHT_INFORMATION_ELE pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo; - - if (!posHTInfo || !pHTInfoEle) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "posHTInfo or pHTInfoEle can't be null in %s\n", - __func__); - return; - } - - memset(posHTInfo, 0, *len); - if ((ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) { //ap mode is not currently supported - pHTInfoEle->ControlChl = ieee->current_network.channel; - pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ? HT_EXTCHNL_OFFSET_NO_EXT : - (ieee->current_network.channel <= 6) ? - HT_EXTCHNL_OFFSET_UPPER : HT_EXTCHNL_OFFSET_LOWER); - pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; - pHTInfoEle->RIFS = 0; - pHTInfoEle->PSMPAccessOnly = 0; - pHTInfoEle->SrvIntGranularity = 0; - pHTInfoEle->OptMode = pHT->CurrentOpMode; - pHTInfoEle->NonGFDevPresent = 0; - pHTInfoEle->DualBeacon = 0; - pHTInfoEle->SecondaryBeacon = 0; - pHTInfoEle->LSigTxopProtectFull = 0; - pHTInfoEle->PcoActive = 0; - pHTInfoEle->PcoPhase = 0; - - memset(pHTInfoEle->BasicMSC, 0, 16); - - *len = 22 + 2; //same above - } else { - //STA should not generate High Throughput Information Element - *len = 0; - } - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2); - //HTDebugHTInfo(posHTInfo, "HTConstructInforElement"); -} - -/* - * According to experiment, Realtek AP to STA (based on rtl8190) may achieve - * best performance if both STA and AP set limitation of aggregation size to - * 32K, that is, set AMPDU density to 2 (Ref: IEEE 11n specification). - * However, if Realtek STA associates to other AP, STA should set limitation of - * aggregation size to 8K, otherwise, performance of traffic stream from STA to - * AP will be much less than the traffic stream from AP to STA if both of the - * stream runs concurrently at the same time. - * - * Frame Format - * Element ID Length OUI Type1 Reserved - * 1 byte 1 byte 3 bytes 1 byte 1 byte - * - * OUI = 0x00, 0xe0, 0x4c, - * Type = 0x02 - * Reserved = 0x00 - * - * 2007.8.21 by Emily - */ -/* - *function: Construct Information Element in Beacon... in RT2RT condition - * input: struct ieee80211_device* ieee - * u8* posRT2RTAgg //pointer to store Information Ele - * u8* len //store len - * output: none - * return: none - * notice: - */ -void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len) -{ - if (!posRT2RTAgg) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "posRT2RTAgg can't be null in %s\n", - __func__); - return; - } - memset(posRT2RTAgg, 0, *len); - *posRT2RTAgg++ = 0x00; - *posRT2RTAgg++ = 0xe0; - *posRT2RTAgg++ = 0x4c; - *posRT2RTAgg++ = 0x02; - *posRT2RTAgg++ = 0x01; - *posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02; - - if (ieee->bSupportRemoteWakeUp) - *posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW; - - *len = 6 + 2; - return; -#ifdef TODO -#if (HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE) - /* - //Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this - section of code. - if(IS_UNDER_11N_AES_MODE(Adapter)) - { - posRT2RTAgg->octet[5] |= RT_HT_CAP_USE_AMPDU; - }else - { - posRT2RTAgg->octet[5] &= 0xfb; - } - */ -#else - // Do Nothing -#endif - - posRT2RTAgg->Length = 6; -#endif -} - -/* - *function: Pick the right Rate Adaptive table to use - * input: struct ieee80211_device* ieee - * u8* pOperateMCS //A pointer to MCS rate bitmap - * return: always we return true - * notice: - */ -static u8 HT_PickMCSRate(struct ieee80211_device *ieee, u8 *pOperateMCS) -{ - if (!pOperateMCS) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "pOperateMCS can't be null in %s\n", - __func__); - return false; - } - - switch (ieee->mode) { - case IEEE_A: - case IEEE_B: - case IEEE_G: - //legacy rate routine handled at selectedrate - - //no MCS rate - memset(pOperateMCS, 0, 16); - break; - - case IEEE_N_24G: //assume CCK rate ok - case IEEE_N_5G: - // Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G. - // Legacy part shall be handled at SelectRateSet(). - - //HT part - // TODO: may be different if we have different number of antenna - pOperateMCS[0] &= RATE_ADPT_1SS_MASK; //support MCS 0~7 - pOperateMCS[1] &= RATE_ADPT_2SS_MASK; - pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; - break; - - //should never reach here - default: - break; - } - - return true; -} - -/* - * Description: - * This function will get the highest speed rate in input MCS set. - * - * /param Adapter Pionter to Adapter entity - * pMCSRateSet Pointer to MCS rate bitmap - * pMCSFilter Pointer to MCS rate filter - * - * /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter. - * - */ -/* - *function: This function will get the highest speed rate in input MCS set. - * input: struct ieee80211_device* ieee - * u8* pMCSRateSet //Pointer to MCS rate bitmap - * u8* pMCSFilter //Pointer to MCS rate filter - * return: Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter - * notice: - */ -u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter) -{ - u8 i, j; - u8 bitMap; - u8 mcsRate = 0; - u8 availableMcsRate[16]; - - if (!pMCSRateSet || !pMCSFilter) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "pMCSRateSet or pMCSFilter can't be null in %s\n", - __func__); - return false; - } - for (i = 0; i < 16; i++) - availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; - - for (i = 0; i < 16; i++) { - if (availableMcsRate[i] != 0) - break; - } - if (i == 16) - return false; - - for (i = 0; i < 16; i++) { - if (availableMcsRate[i] != 0) { - bitMap = availableMcsRate[i]; - for (j = 0; j < 8; j++) { - if ((bitMap % 2) != 0) { - if (HTMcsToDataRate(ieee, (8 * i + j)) > HTMcsToDataRate(ieee, mcsRate)) - mcsRate = (8 * i + j); - } - bitMap >>= 1; - } - } - } - return (mcsRate | 0x80); -} - -/* - * 1.Filter our operation rate set with AP's rate set - * 2.shall reference channel bandwidth, STBC, Antenna number - * 3.generate rate adative table for firmware - * David 20060906 - * - * \pHTSupportedCap: the connected STA's supported rate Capability element - */ -static u8 HTFilterMCSRate(struct ieee80211_device *ieee, u8 *pSupportMCS, - u8 *pOperateMCS) -{ - u8 i = 0; - - // filter out operational rate set not supported by AP, the length of it is 16 - for (i = 0; i <= 15; i++) - pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i] & pSupportMCS[i]; - - // TODO: adjust our operational rate set according to our channel bandwidth, STBC and Antenna number - /* - * TODO: fill suggested rate adaptive rate index and give firmware info - * using Tx command packet we also shall suggested the first start rate - * set according to our signal strength - */ - HT_PickMCSRate(ieee, pOperateMCS); - - // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) - pOperateMCS[1] = 0; - - /* - * For RTL819X, we support only MCS0~15. - * And also, we do not know how to use MCS32 now. - */ - for (i = 2; i <= 15; i++) - pOperateMCS[i] = 0; - - return true; -} - -void HTOnAssocRsp(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - struct ht_capability_ele *pPeerHTCap = NULL; - PHT_INFORMATION_ELE pPeerHTInfo = NULL; - u16 nMaxAMSDUSize = 0; - u8 *pMcsFilter = NULL; - - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily - static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - - if (!pHTInfo->bCurrentHTSupport) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, - "<=== %s: HT_DISABLE\n", - __func__); - return; - } - IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(struct ht_capability_ele)); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE)); - -// HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq"); -// HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq"); - // - if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) - pPeerHTCap = (struct ht_capability_ele *)(&pHTInfo->PeerHTCapBuf[4]); - else - pPeerHTCap = (struct ht_capability_ele *)(pHTInfo->PeerHTCapBuf); - - if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) - pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]); - else - pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf); - - //////////////////////////////////////////////////////// - // Configurations: - //////////////////////////////////////////////////////// - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, pPeerHTCap, sizeof(struct ht_capability_ele)); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE)); - // Config Supported Channel Width setting - // - HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), (enum ht_extension_chan_offset)(pPeerHTInfo->ExtChlOffset)); - - pHTInfo->bCurTxBW40MHz = (pPeerHTInfo->RecommemdedTxWidth == 1); - - /* - * Update short GI/ long GI setting - * - * TODO: - */ - pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz && - (pPeerHTCap->ShortGI20Mhz == 1); - pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz && - (pPeerHTCap->ShortGI40Mhz == 1); - - /* - * Config TX STBC setting - * - * TODO: - */ - - /* - * Config DSSS/CCK mode in 40MHz mode - * - * TODO: - */ - pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK && - (pPeerHTCap->DssCCk == 1); - - /* - * Config and configure A-MSDU setting - */ - pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; - - nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; - - if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) - pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; - else - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - /* - * Config A-MPDU setting - */ - pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; - - /* - * <1> Decide AMPDU Factor - * By Emily - */ - if (!pHTInfo->bRegRT2RTAggregation) { - // Decide AMPDU Factor according to protocol handshake - if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) - pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - } else { - /* - * Set MPDU density to 2 to Realtek AP, and set it to 0 for others - * Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily - */ - if (ieee->current_network.bssht.bdRT2RTAggregation) { - if (ieee->pairwise_key_type != KEY_TYPE_NA) - // Realtek may set 32k in security mode and 64k for others - pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; - } else { - pHTInfo->CurrentAMPDUFactor = min_t(u32, pPeerHTCap->MaxRxAMPDUFactor, - HT_AGG_SIZE_32K); - } - } - - /* - * <2> Set AMPDU Minimum MPDU Start Spacing - * 802.11n 3.0 section 9.7d.3 - */ - pHTInfo->CurrentMPDUDensity = max_t(u32, pHTInfo->MPDU_Density, - pPeerHTCap->MPDUDensity); - - if (ieee->pairwise_key_type != KEY_TYPE_NA) - pHTInfo->CurrentMPDUDensity = 7; // 8us - // Force TX AMSDU - - // Lanhsin: mark for tmp to avoid deauth by ap from s3 - //if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0) - if (0) { - pHTInfo->bCurrentAMPDUEnable = false; - pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; - pHTInfo->ForcedAMSDUMaxSize = 7935; - - pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K; - } - - // Rx Reorder Setting - pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; - - /* - * Filter out unsupported HT rate for this AP - * Update RATR table - * This is only for 8190 ,8192 or later product which using firmware to - * handle rate adaptive mechanism. - */ - - /* - * Handle Ralink AP bad MCS rate set condition. Joseph. - * This fix the bug of Ralink AP. This may be removed in the future. - */ - if (pPeerHTCap->MCS[0] == 0) - pPeerHTCap->MCS[0] = 0xff; - - HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); - - /* - * Config MIMO Power Save setting - */ - pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; - if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) - pMcsFilter = MCS_FILTER_1SS; - else - pMcsFilter = MCS_FILTER_ALL; - //WB add for MCS8 bug -// pMcsFilter = MCS_FILTER_1SS; - ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter); - ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - - /* - * Config current operation mode. - */ - pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; -} - -/* - *function: initialize HT info(struct PRT_HIGH_THROUGHPUT) - * input: struct ieee80211_device* ieee - * output: none - * return: none - * notice: This function is called when - * * (1) MPInitialization Phase - * * (2) Receiving of Deauthentication from AP - */ -// TODO: Should this funciton be called when receiving of Disassociation? -void HTInitializeHTInfo(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - /* - * These parameters will be reset when receiving deauthentication packet - */ - IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __func__); - pHTInfo->bCurrentHTSupport = false; - - // 40MHz channel support - pHTInfo->bCurBW40MHz = false; - pHTInfo->bCurTxBW40MHz = false; - - // Short GI support - pHTInfo->bCurShortGI20MHz = false; - pHTInfo->bCurShortGI40MHz = false; - pHTInfo->bForcedShortGI = false; - - /* - * CCK rate support - * This flag is set to true to support CCK rate by default. - * It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities - * only when associate to 11N BSS. - */ - pHTInfo->bCurSuppCCK = true; - - // AMSDU related - pHTInfo->bCurrent_AMSDU_Support = false; - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - - // AMPUD related - pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - - // Initialize all of the parameters related to 11n - memset(&pHTInfo->SelfHTCap, 0, sizeof(pHTInfo->SelfHTCap)); - memset(&pHTInfo->SelfHTInfo, 0, sizeof(pHTInfo->SelfHTInfo)); - memset(&pHTInfo->PeerHTCapBuf, 0, sizeof(pHTInfo->PeerHTCapBuf)); - memset(&pHTInfo->PeerHTInfoBuf, 0, sizeof(pHTInfo->PeerHTInfoBuf)); - - pHTInfo->bSwBwInProgress = false; - - // Set default IEEE spec for Draft N - pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; - - // Realtek proprietary aggregation mode - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - pHTInfo->IOTPeer = 0; - pHTInfo->IOTAction = 0; - - //MCS rate initialized here - { - u8 *RegHTSuppRateSets = &ieee->RegHTSuppRateSet[0]; - - RegHTSuppRateSets[0] = 0xFF; //support MCS 0~7 - RegHTSuppRateSets[1] = 0xFF; //support MCS 8~15 - RegHTSuppRateSets[4] = 0x01; //support MCS 32 - } -} - -/* - *function: initialize Bss HT structure(struct PBSS_HT) - * input: PBSS_HT pBssHT //to be initialized - * output: none - * return: none - * notice: This function is called when initialize network structure - */ -void HTInitializeBssDesc(PBSS_HT pBssHT) -{ - pBssHT->bdSupportHT = false; - memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); - pBssHT->bdHTCapLen = 0; - memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); - pBssHT->bdHTInfoLen = 0; - - pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE; - - pBssHT->bdRT2RTAggregation = false; - pBssHT->bdRT2RTLongSlotTime = false; -} - -/* - *function: initialize Bss HT structure(struct PBSS_HT) - * input: struct ieee80211_device *ieee - * struct ieee80211_network *pNetwork //usually current network - * we are live in - * output: none - * return: none - * notice: This function should ONLY be called before association - */ -void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// u16 nMaxAMSDUSize; -// struct ht_capability_ele *pPeerHTCap = (struct ht_capability_ele *)pNetwork->bssht.bdHTCapBuf; -// PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; -// u8* pMcsFilter; - u8 bIOTAction = 0; - - // - // Save Peer Setting before Association - // - IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __func__); - /*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/ -// if( pHTInfo->bEnableHT && pNetwork->bssht.bdSupportHT) - if (pNetwork->bssht.bdSupportHT) { - pHTInfo->bCurrentHTSupport = true; - pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; - - // Save HTCap and HTInfo information Element - if (pNetwork->bssht.bdHTCapLen > 0 && pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) - memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen); - - if (pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf)) - memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen); - - // Check whether RT to RT aggregation mode is enabled - if (pHTInfo->bRegRT2RTAggregation) { - pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation; - pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime; - } else { - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - } - - // Determine the IOT Peer Vendor. - HTIOTPeerDetermine(ieee); - - /* - * Decide IOT Action - * Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided - */ - pHTInfo->IOTAction = 0; - bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; - - bIOTAction = HTIOTActIsDisableMCS15(ieee); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; - - bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; - - bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; - - bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; - - bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid); - if (bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; - } else { - pHTInfo->bCurrentHTSupport = false; - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - - pHTInfo->IOTAction = 0; - } -} - -void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// struct ht_capability_ele *pPeerHTCap = (struct ht_capability_ele *)pNetwork->bssht.bdHTCapBuf; - PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; - - if (pHTInfo->bCurrentHTSupport) { - /* - * Config current operation mode. - */ - if (pNetwork->bssht.bdHTInfoLen != 0) - pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; - - /* - * - */ - } -} -EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting); - -/* - *function: check whether HT control field exists - * input: struct ieee80211_device *ieee - * u8* pFrame //coming skb->data - * output: none - * return: return true if HT control field exists(false otherwise) - * notice: - */ -u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame) -{ - if (ieee->pHTInfo->bCurrentHTSupport) { - if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n"); - return true; - } - } - return false; -} - -static void HTSetConnectBwModeCallback(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __func__); - - if (pHTInfo->bCurBW40MHz) { - if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, ieee->current_network.channel + 2); - else if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, ieee->current_network.channel - 2); - else - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); - } else { - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } - - pHTInfo->bSwBwInProgress = false; -} - -/* - * This function set bandwidth mode in protocol layer. - */ -void HTSetConnectBwMode(struct ieee80211_device *ieee, enum ht_channel_width Bandwidth, enum ht_extension_chan_offset Offset) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// u32 flags = 0; - - if (!pHTInfo->bRegBW40MHz) - return; - - // To reduce dummy operation -// if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) || -// (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset)) -// return; - -// spin_lock_irqsave(&(ieee->bw_spinlock), flags); - if (pHTInfo->bSwBwInProgress) { -// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); - return; - } - //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. - if (Bandwidth == HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))) { - // Handle Illegal extension channel offset!! - if (ieee->current_network.channel < 2 && Offset == HT_EXTCHNL_OFFSET_LOWER) - Offset = HT_EXTCHNL_OFFSET_NO_EXT; - if (Offset == HT_EXTCHNL_OFFSET_UPPER || Offset == HT_EXTCHNL_OFFSET_LOWER) { - pHTInfo->bCurBW40MHz = true; - pHTInfo->CurSTAExtChnlOffset = Offset; - } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; - } - } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; - } - - pHTInfo->bSwBwInProgress = true; - - /* - * TODO: 2007.7.13 by Emily Wait 2000ms in order to guarantee that - * switching bandwidth is executed after scan is finished. It is a - * temporal solution because software should ganrantee the last - * operation of switching bandwidth is executed properlly. - */ - HTSetConnectBwModeCallback(ieee); - -// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); -} diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h deleted file mode 100644 index 3052f53d2e7e..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __INC_QOS_TYPE_H -#define __INC_QOS_TYPE_H - -/* - * ACI/AIFSN Field. - * Ref: WMM spec 2.2.2: WME Parameter Element, p.12. - * Note: 1 Byte Length - */ -struct aci_aifsn { - u8 aifsn:4; - u8 acm:1; - u8 aci:2; - u8:1; -}; - -/* - * Direction Field Values. - * Ref: WMM spec 2.2.11: WME TSPEC Element, p.18. - */ -enum direction_value { - DIR_UP = 0, // 0x00 // UpLink - DIR_DOWN = 1, // 0x01 // DownLink - DIR_DIRECT = 2, // 0x10 // DirectLink - DIR_BI_DIR = 3, // 0x11 // Bi-Direction -}; - -/* - * TS Info field in WMM TSPEC Element. - * Ref: - * 1. WMM spec 2.2.11: WME TSPEC Element, p.18. - * 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h] - * Note: sizeof 3 Bytes - */ -struct qos_tsinfo { - u16 uc_traffic_type:1; //WMM is reserved - u16 uc_tsid:4; - u16 uc_direction:2; - u16 uc_access_policy:2; //WMM: bit8=0, bit7=1 - u16 uc_aggregation:1; //WMM is reserved - u16 uc_psb:1; //WMMSA is APSD - u16 uc_up:3; - u16 uc_ts_info_ack_policy:2; //WMM is reserved - u8 uc_schedule:1; //WMM is reserved - u8:7; -}; - -/* - * WMM TSPEC Body. - * Ref: WMM spec 2.2.11: WME TSPEC Element, p.16. - * Note: sizeof 55 bytes - */ -struct tspec_body { - struct qos_tsinfo ts_info; //u8 TSInfo[3]; - u16 nominal_msd_usize; - u16 max_msd_usize; - u32 min_service_itv; - u32 max_service_itv; - u32 inactivity_itv; - u32 suspen_itv; - u32 service_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_size; - u32 delay_bound; - u32 min_phy_rate; - u16 surplus_bandwidth_allowance; - u16 medium_time; -}; - -/* - * 802.11 Management frame Status Code field - */ -struct octet_string { - u8 *octet; - u16 length; -}; - -#define is_ac_valid(ac) (((ac) <= 7) ? true : false) - -#endif // #ifndef __INC_QOS_TYPE_H diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h deleted file mode 100644 index 7ed140009760..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _TSTYPE_H_ -#define _TSTYPE_H_ -#include "rtl819x_Qos.h" - -#define TS_ADDBA_DELAY 60 - -#define TOTAL_TS_NUM 16 -#define TCLAS_NUM 4 - -/* This define the Tx/Rx directions */ -enum tr_select { - TX_DIR = 0, - RX_DIR = 1, -}; - -union qos_tclas { - struct type_general { - u8 priority; - u8 classifier_type; - u8 mask; - } type_general; - - struct type0_eth { - u8 priority; - u8 classifier_type; - u8 mask; - u8 src_addr[6]; - u8 dst_addr[6]; - u16 type; - } type0_eth; - - struct type1_ipv4 { - u8 priority; - u8 classifier_type; - u8 mask; - u8 version; - u8 src_ip[4]; - u8 dst_ip[4]; - u16 src_port; - u16 dst_port; - u8 dscp; - u8 protocol; - u8 reserved; - } type1_ipv4; - - struct type1_ipv6 { - u8 priority; - u8 classifier_type; - u8 mask; - u8 version; - u8 src_ip[16]; - u8 dst_ip[16]; - u16 src_port; - u16 dst_port; - u8 flow_label[3]; - } type1_ipv6; - - struct type2_8021q { - u8 priority; - u8 classifier_type; - u8 mask; - u16 tag_type; - } type2_8021q; -}; - -struct ts_common_info { - struct list_head list; - struct timer_list setup_timer; - struct timer_list inact_timer; - u8 addr[6]; - struct tspec_body t_spec; - union qos_tclas t_class[TCLAS_NUM]; - u8 t_clas_proc; - u8 t_clas_num; -}; - -struct tx_ts_record { - struct ts_common_info ts_common_info; - u16 tx_cur_seq; - struct ba_record tx_pending_ba_record; - struct ba_record tx_admitted_ba_record; - u8 add_ba_req_in_progress; - u8 add_ba_req_delayed; - u8 using_ba; - struct timer_list ts_add_ba_timer; - u8 num; -}; - -struct rx_ts_record { - struct ts_common_info ts_common_info; - u16 rx_indicate_seq; - u16 rx_timeout_indicate_seq; - struct list_head rx_pending_pkt_list; - struct timer_list rx_pkt_pending_timer; - struct ba_record rx_admitted_ba_record; - u16 rx_last_seq_num; - u8 rx_last_frag_num; - u8 num; -}; - -#endif diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c deleted file mode 100644 index 3aabb401b15a..000000000000 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ /dev/null @@ -1,534 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "ieee80211.h" -#include -#include -#include "rtl819x_TS.h" - -static void TsSetupTimeOut(struct timer_list *unused) -{ - // Not implement yet - // This is used for WMMSA and ACM , that would send ADDTSReq frame. -} - -static void TsInactTimeout(struct timer_list *unused) -{ - // Not implement yet - // This is used for WMMSA and ACM. - // This function would be call when TS is no Tx/Rx for some period of time. -} - -/******************************************************************************************************************** - *function: I still not understand this function, so wait for further implementation - * input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer - * return: NULL - * notice: - ********************************************************************************************************************/ -static void RxPktPendingTimeout(struct timer_list *t) -{ - struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_pkt_pending_timer); - struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); - - struct rx_reorder_entry *pReorderEntry = NULL; - - //u32 flags = 0; - unsigned long flags = 0; - u8 index = 0; - bool bPktInBuf = false; - - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "==================>%s()\n", __func__); - if (pRxTs->rx_timeout_indicate_seq != 0xffff) { - // Indicate the pending packets sequentially according to SeqNum until meet the gap. - while (!list_empty(&pRxTs->rx_pending_pkt_list)) { - pReorderEntry = list_entry(pRxTs->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); - if (index == 0) - pRxTs->rx_indicate_seq = pReorderEntry->SeqNum; - - if (SN_LESS(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq) || - SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq)) { - list_del_init(&pReorderEntry->List); - - if (SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq)) - pRxTs->rx_indicate_seq = (pRxTs->rx_indicate_seq + 1) % 4096; - - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s: IndicateSeq: %d\n", __func__, pReorderEntry->SeqNum); - ieee->stats_IndicateArray[index] = pReorderEntry->prxb; - index++; - - list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); - } else { - bPktInBuf = true; - break; - } - } - } - - if (index > 0) { - // Set rx_timeout_indicate_seq to 0xffff to indicate no pending packets in buffer now. - pRxTs->rx_timeout_indicate_seq = 0xffff; - - // Indicate packets - if (index > REORDER_WIN_SIZE) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - return; - } - ieee80211_indicate_packets(ieee, ieee->stats_IndicateArray, index); - } - - if (bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) { - pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq; - mod_timer(&pRxTs->rx_pkt_pending_timer, - jiffies + msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime)); - } - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); -} - -/******************************************************************************************************************** - *function: Add BA timer function - * input: unsigned long data //acturally we send struct tx_ts_record or struct rx_ts_record to these timer - * return: NULL - * notice: - ********************************************************************************************************************/ -static void TsAddBaProcess(struct timer_list *t) -{ - struct tx_ts_record *pTxTs = from_timer(pTxTs, t, ts_add_ba_timer); - u8 num = pTxTs->num; - struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]); - - TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); - IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: ADDBA Req is started!! \n", __func__); -} - - -static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) -{ - eth_zero_addr(pTsCommonInfo->addr); - memset(&pTsCommonInfo->t_spec, 0, sizeof(struct tspec_body)); - memset(&pTsCommonInfo->t_class, 0, sizeof(union qos_tclas) * TCLAS_NUM); - pTsCommonInfo->t_clas_proc = 0; - pTsCommonInfo->t_clas_num = 0; -} - -static void ResetTxTsEntry(struct tx_ts_record *pTS) -{ - ResetTsCommonInfo(&pTS->ts_common_info); - pTS->tx_cur_seq = 0; - pTS->add_ba_req_in_progress = false; - pTS->add_ba_req_delayed = false; - pTS->using_ba = false; - ResetBaEntry(&pTS->tx_admitted_ba_record); //For BA Originator - ResetBaEntry(&pTS->tx_pending_ba_record); -} - -static void ResetRxTsEntry(struct rx_ts_record *pTS) -{ - ResetTsCommonInfo(&pTS->ts_common_info); - pTS->rx_indicate_seq = 0xffff; // This indicate the rx_indicate_seq is not used now!! - pTS->rx_timeout_indicate_seq = 0xffff; // This indicate the rx_timeout_indicate_seq is not used now!! - ResetBaEntry(&pTS->rx_admitted_ba_record); // For BA Recipient -} - -void TSInitialize(struct ieee80211_device *ieee) -{ - struct tx_ts_record *pTxTS = ieee->TxTsRecord; - struct rx_ts_record *pRxTS = ieee->RxTsRecord; - struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; - u8 count = 0; - IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __func__); - // Initialize Tx TS related info. - INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); - - for (count = 0; count < TOTAL_TS_NUM; count++) { - // - pTxTS->num = count; - // The timers for the operation of Traffic Stream and Block Ack. - // DLS related timer will be add here in the future!! - timer_setup(&pTxTS->ts_common_info.setup_timer, TsSetupTimeOut, - 0); - timer_setup(&pTxTS->ts_common_info.inact_timer, TsInactTimeout, - 0); - timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0); - timer_setup(&pTxTS->tx_pending_ba_record.timer, BaSetupTimeOut, - 0); - timer_setup(&pTxTS->tx_admitted_ba_record.timer, - TxBaInactTimeout, 0); - ResetTxTsEntry(pTxTS); - list_add_tail(&pTxTS->ts_common_info.list, &ieee->Tx_TS_Unused_List); - pTxTS++; - } - - // Initialize Rx TS related info. - INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); - for (count = 0; count < TOTAL_TS_NUM; count++) { - pRxTS->num = count; - INIT_LIST_HEAD(&pRxTS->rx_pending_pkt_list); - timer_setup(&pRxTS->ts_common_info.setup_timer, TsSetupTimeOut, - 0); - timer_setup(&pRxTS->ts_common_info.inact_timer, TsInactTimeout, - 0); - timer_setup(&pRxTS->rx_admitted_ba_record.timer, - RxBaInactTimeout, 0); - timer_setup(&pRxTS->rx_pkt_pending_timer, RxPktPendingTimeout, 0); - ResetRxTsEntry(pRxTS); - list_add_tail(&pRxTS->ts_common_info.list, &ieee->Rx_TS_Unused_List); - pRxTS++; - } - // Initialize unused Rx Reorder List. - INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); - for (count = 0; count < REORDER_ENTRY_NUM; count++) { - list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List); - if (count == (REORDER_ENTRY_NUM - 1)) - break; - pRxReorderEntry = &ieee->RxReorderEntry[count + 1]; - } -} - -static void AdmitTS(struct ieee80211_device *ieee, - struct ts_common_info *pTsCommonInfo, u32 InactTime) -{ - del_timer_sync(&pTsCommonInfo->setup_timer); - del_timer_sync(&pTsCommonInfo->inact_timer); - - if (InactTime != 0) - mod_timer(&pTsCommonInfo->inact_timer, - jiffies + msecs_to_jiffies(InactTime)); -} - - -static struct ts_common_info *SearchAdmitTRStream(struct ieee80211_device *ieee, - u8 *Addr, u8 TID, - enum tr_select TxRxSelect) -{ - //DIRECTION_VALUE dir; - u8 dir; - bool search_dir[4] = {0}; - struct list_head *psearch_list; //FIXME - struct ts_common_info *pRet = NULL; - if (ieee->iw_mode == IW_MODE_MASTER) { //ap mode - if (TxRxSelect == TX_DIR) { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR] = true; - } else { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR] = true; - } - } else if (ieee->iw_mode == IW_MODE_ADHOC) { - if (TxRxSelect == TX_DIR) - search_dir[DIR_UP] = true; - else - search_dir[DIR_DOWN] = true; - } else { - if (TxRxSelect == TX_DIR) { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } else { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR] = true; - search_dir[DIR_DIRECT] = true; - } - } - - if (TxRxSelect == TX_DIR) - psearch_list = &ieee->Tx_TS_Admit_List; - else - psearch_list = &ieee->Rx_TS_Admit_List; - - //for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++) - for (dir = 0; dir <= DIR_BI_DIR; dir++) { - if (!search_dir[dir]) - continue; - list_for_each_entry(pRet, psearch_list, list) { - // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.ts_info.ucTSID, pRet->TSpec.ts_info.ucDirection); - if (memcmp(pRet->addr, Addr, 6) == 0) - if (pRet->t_spec.ts_info.uc_tsid == TID) - if (pRet->t_spec.ts_info.uc_direction == dir) { - // printk("Bingo! got it\n"); - break; - } - } - if (&pRet->list != psearch_list) - break; - } - - if (&pRet->list != psearch_list) - return pRet; - else - return NULL; -} - -static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr, - struct tspec_body *pTSPEC, union qos_tclas *pTCLAS, u8 TCLAS_Num, - u8 TCLAS_Proc) -{ - u8 count; - - if (pTsCommonInfo == NULL) - return; - - memcpy(pTsCommonInfo->addr, Addr, 6); - - if (pTSPEC != NULL) - memcpy((u8 *)(&(pTsCommonInfo->t_spec)), (u8 *)pTSPEC, sizeof(struct tspec_body)); - - for (count = 0; count < TCLAS_Num; count++) - memcpy((u8 *)(&(pTsCommonInfo->t_class[count])), (u8 *)pTCLAS, sizeof(union qos_tclas)); - - pTsCommonInfo->t_clas_proc = TCLAS_Proc; - pTsCommonInfo->t_clas_num = TCLAS_Num; -} - - -bool GetTs( - struct ieee80211_device *ieee, - struct ts_common_info **ppTS, - u8 *Addr, - u8 TID, - enum tr_select TxRxSelect, //Rx:1, Tx:0 - bool bAddNewTs - ) -{ - u8 UP = 0; - // - // We do not build any TS for Broadcast or Multicast stream. - // So reject these kinds of search here. - // - if (is_multicast_ether_addr(Addr)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); - return false; - } - - if (ieee->current_network.qos_data.supported == 0) { - UP = 0; - } else { - // In WMM case: we use 4 TID only - if (!is_ac_valid(TID)) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __func__, TID); - return false; - } - - switch (TID) { - case 0: - case 3: - UP = 0; - break; - - case 1: - case 2: - UP = 2; - break; - - case 4: - case 5: - UP = 5; - break; - - case 6: - case 7: - UP = 7; - break; - } - } - - *ppTS = SearchAdmitTRStream( - ieee, - Addr, - UP, - TxRxSelect); - if (*ppTS != NULL) { - return true; - } else { - if (!bAddNewTs) { - IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP); - return false; - } else { - // - // Create a new Traffic stream for current Tx/Rx - // This is for EDCA and WMM to add a new TS. - // For HCCA or WMMSA, TS cannot be addmit without negotiation. - // - struct tspec_body TSpec; - struct qos_tsinfo *pTSInfo = &TSpec.ts_info; - struct list_head *pUnusedList = - (TxRxSelect == TX_DIR) ? - (&ieee->Tx_TS_Unused_List) : - (&ieee->Rx_TS_Unused_List); - - struct list_head *pAddmitList = - (TxRxSelect == TX_DIR) ? - (&ieee->Tx_TS_Admit_List) : - (&ieee->Rx_TS_Admit_List); - - enum direction_value Dir = (ieee->iw_mode == IW_MODE_MASTER) ? - ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) : - ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN); - IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n"); - if (!list_empty(pUnusedList)) { - (*ppTS) = list_entry(pUnusedList->next, struct ts_common_info, list); - list_del_init(&(*ppTS)->list); - if (TxRxSelect == TX_DIR) { - struct tx_ts_record *tmp = container_of(*ppTS, struct tx_ts_record, ts_common_info); - ResetTxTsEntry(tmp); - } else { - struct rx_ts_record *tmp = container_of(*ppTS, struct rx_ts_record, ts_common_info); - ResetRxTsEntry(tmp); - } - - IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr); - // Prepare TS Info related field - pTSInfo->uc_traffic_type = 0; // Traffic type: WMM is reserved in this field - pTSInfo->uc_tsid = UP; // TSID - pTSInfo->uc_direction = Dir; // Direction: if there is DirectLink, this need additional consideration. - pTSInfo->uc_access_policy = 1; // Access policy - pTSInfo->uc_aggregation = 0; // Aggregation - pTSInfo->uc_psb = 0; // Aggregation - pTSInfo->uc_up = UP; // User priority - pTSInfo->uc_ts_info_ack_policy = 0; // Ack policy - pTSInfo->uc_schedule = 0; // Schedule - - MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); - AdmitTS(ieee, *ppTS, 0); - list_add_tail(&((*ppTS)->list), pAddmitList); - // if there is DirectLink, we need to do additional operation here!! - - return true; - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __func__); - return false; - } - } - } -} - -static void RemoveTsEntry(struct ieee80211_device *ieee, struct ts_common_info *pTs, - enum tr_select TxRxSelect) -{ - //u32 flags = 0; - unsigned long flags = 0; - del_timer_sync(&pTs->setup_timer); - del_timer_sync(&pTs->inact_timer); - TsInitDelBA(ieee, pTs, TxRxSelect); - - if (TxRxSelect == RX_DIR) { - struct rx_reorder_entry *pRxReorderEntry; - struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs; - if (timer_pending(&pRxTS->rx_pkt_pending_timer)) - del_timer_sync(&pRxTS->rx_pkt_pending_timer); - - while (!list_empty(&pRxTS->rx_pending_pkt_list)) { - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - //pRxReorderEntry = list_entry(&pRxTS->rx_pending_pkt_list.prev,RX_REORDER_ENTRY,List); - pRxReorderEntry = list_entry(pRxTS->rx_pending_pkt_list.prev, struct rx_reorder_entry, List); - list_del_init(&pRxReorderEntry->List); - { - int i = 0; - struct ieee80211_rxb *prxb = pRxReorderEntry->prxb; - if (unlikely(!prxb)) { - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - return; - } - for (i = 0; i < prxb->nr_subframes; i++) - dev_kfree_skb(prxb->subframes[i]); - - kfree(prxb); - prxb = NULL; - } - list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - } - - } else { - struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs; - del_timer_sync(&pTxTS->ts_add_ba_timer); - } -} - -void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr) -{ - struct ts_common_info *pTS, *pTmpTS; - - printk("===========>%s,%pM\n", __func__, Addr); - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, list) { - if (memcmp(pTS->addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, list) { - if (memcmp(pTS->addr, Addr, 6) == 0) { - printk("====>remove Tx_TS_admin_list\n"); - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, list) { - if (memcmp(pTS->addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, list) { - if (memcmp(pTS->addr, Addr, 6) == 0) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List); - } - } -} - -void RemoveAllTS(struct ieee80211_device *ieee) -{ - struct ts_common_info *pTS, *pTmpTS; - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, list) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, list) { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, list) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, list) { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->list); - list_add_tail(&pTS->list, &ieee->Rx_TS_Unused_List); - } -} - -void TsStartAddBaProcess(struct ieee80211_device *ieee, struct tx_ts_record *pTxTS) -{ - if (!pTxTS->add_ba_req_in_progress) { - pTxTS->add_ba_req_in_progress = true; - if (pTxTS->add_ba_req_delayed) { - IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: Delayed Start ADDBA after 60 sec!!\n", __func__); - mod_timer(&pTxTS->ts_add_ba_timer, - jiffies + msecs_to_jiffies(TS_ADDBA_DELAY)); - } else { - IEEE80211_DEBUG(IEEE80211_DL_BA, "%s: Immediately Start ADDBA now!!\n", __func__); - mod_timer(&pTxTS->ts_add_ba_timer, jiffies + 10); //set 10 ticks - } - } else { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __func__); - } -} diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c deleted file mode 100644 index 2527cea60e3e..000000000000 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * This files contains card eeprom (93c46 or 93c56) programming routines, - * memory is addressed by 16 bits words. - * - * This is part of rtl8180 OpenSource driver. - * Copyright (C) Andrea Merello 2004 - * - * Parts of this driver are based on the GPL part of the - * official realtek driver. - * - * Parts of this driver are based on the rtl8180 driver skeleton - * from Patric Schenke & Andres Salomon. - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - * - * We want to thank the Authors of those projects and the Ndiswrapper - * project Authors. - */ - -#include "r8180_93cx6.h" - -static void eprom_cs(struct net_device *dev, short bit) -{ - u8 cmdreg; - int err; - - err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg); - if (err) - return; - if (bit) - /* enable EPROM */ - write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT); - else - /* disable EPROM */ - write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT); - - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - -static void eprom_ck_cycle(struct net_device *dev) -{ - u8 cmdreg; - int err; - - err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg); - if (err) - return; - write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT); - force_pci_posting(dev); - udelay(EPROM_DELAY); - - read_nic_byte_E(dev, EPROM_CMD, &cmdreg); - write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT); - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - -static void eprom_w(struct net_device *dev, short bit) -{ - u8 cmdreg; - int err; - - err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg); - if (err) - return; - if (bit) - write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT); - else - write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT); - - force_pci_posting(dev); - udelay(EPROM_DELAY); -} - -static short eprom_r(struct net_device *dev) -{ - u8 bit; - int err; - - err = read_nic_byte_E(dev, EPROM_CMD, &bit); - if (err) - return err; - - udelay(EPROM_DELAY); - - if (bit & EPROM_R_BIT) - return 1; - - return 0; -} - -static void eprom_send_bits_string(struct net_device *dev, short b[], int len) -{ - int i; - - for (i = 0; i < len; i++) { - eprom_w(dev, b[i]); - eprom_ck_cycle(dev); - } -} - -int eprom_read(struct net_device *dev, u32 addr) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - short read_cmd[] = {1, 1, 0}; - short addr_str[8]; - int i; - int addr_len; - u32 ret; - int err; - - ret = 0; - /* enable EPROM programming */ - write_nic_byte_E(dev, EPROM_CMD, - (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT)); - force_pci_posting(dev); - udelay(EPROM_DELAY); - - if (priv->epromtype == EPROM_93c56) { - addr_str[7] = addr & 1; - addr_str[6] = addr & BIT(1); - addr_str[5] = addr & BIT(2); - addr_str[4] = addr & BIT(3); - addr_str[3] = addr & BIT(4); - addr_str[2] = addr & BIT(5); - addr_str[1] = addr & BIT(6); - addr_str[0] = addr & BIT(7); - addr_len = 8; - } else { - addr_str[5] = addr & 1; - addr_str[4] = addr & BIT(1); - addr_str[3] = addr & BIT(2); - addr_str[2] = addr & BIT(3); - addr_str[1] = addr & BIT(4); - addr_str[0] = addr & BIT(5); - addr_len = 6; - } - eprom_cs(dev, 1); - eprom_ck_cycle(dev); - eprom_send_bits_string(dev, read_cmd, 3); - eprom_send_bits_string(dev, addr_str, addr_len); - - /* - * keep chip pin D to low state while reading. - * I'm unsure if it is necessary, but anyway shouldn't hurt - */ - eprom_w(dev, 0); - - for (i = 0; i < 16; i++) { - /* eeprom needs a clk cycle between writing opcode&adr - * and reading data. (eeprom outs a dummy 0) - */ - eprom_ck_cycle(dev); - err = eprom_r(dev); - if (err < 0) - return err; - - ret |= err << (15 - i); - } - - eprom_cs(dev, 0); - eprom_ck_cycle(dev); - - /* disable EPROM programming */ - write_nic_byte_E(dev, EPROM_CMD, - (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT)); - return ret; -} diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h deleted file mode 100644 index 0cdd00a4f7b8..000000000000 --- a/drivers/staging/rtl8192u/r8180_93cx6.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is part of rtl8187 OpenSource driver - * Copyright (C) Andrea Merello 2004-2005 - * Released under the terms of GPL (General Public Licence) - * - * Parts of this driver are based on the GPL part of the - * official realtek driver - * Parts of this driver are based on the rtl8180 driver skeleton - * from Patric Schenke & Andres Salomon - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - * - * We want to thank the Authors of such projects and the Ndiswrapper - * project Authors. - */ - -/*This files contains card eeprom (93c46 or 93c56) programming routines*/ -/*memory is addressed by WORDS*/ - -#include "r8192U.h" -#include "r8192U_hw.h" - -#define EPROM_DELAY 10 - -int eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */ diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c deleted file mode 100644 index 54747fda552f..000000000000 --- a/drivers/staging/rtl8192u/r8190_rtl8256.c +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * This is part of the rtl8192 driver - * - * This files contains programming code for the rtl8256 - * radio frontend. - * - * *Many* thanks to Realtek Corp. for their great support! - */ - -#include "r8192U.h" -#include "r8192U_hw.h" -#include "r819xU_phyreg.h" -#include "r819xU_phy.h" -#include "r8190_rtl8256.h" - -/* - * Forward declaration of local functions - */ -static void phy_rf8256_config_para_file(struct net_device *dev); - -/*-------------------------------------------------------------------------- - * Overview: set RF band width (20M or 40M) - * Input: struct net_device* dev - * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M - * Output: NONE - * Return: NONE - * Note: 8226 support both 20M and 40 MHz - *-------------------------------------------------------------------------- - */ -void phy_set_rf8256_bandwidth(struct net_device *dev, enum ht_channel_width Bandwidth) -{ - u8 eRFPath; - struct r8192_priv *priv = ieee80211_priv(dev); - - /* for(eRFPath = RF90_PATH_A; eRFPath NumTotalRFPath; - * eRFPath++) - */ - for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) { - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) - continue; - - switch (Bandwidth) { - case HT_CHANNEL_WIDTH_20: - if (priv->card_8192_version == VERSION_819XU_A || - priv->card_8192_version == VERSION_819XU_B) { - /* 8256 D-cut, E-cut, xiong: consider it later! */ - rtl8192_phy_SetRFReg(dev, - (enum rf90_radio_path_e)eRFPath, - 0x0b, bMask12Bits, 0x100); /* phy para:1ba */ - rtl8192_phy_SetRFReg(dev, - (enum rf90_radio_path_e)eRFPath, - 0x2c, bMask12Bits, 0x3d7); - rtl8192_phy_SetRFReg(dev, - (enum rf90_radio_path_e)eRFPath, - 0x0e, bMask12Bits, 0x021); - rtl8192_phy_SetRFReg(dev, - (enum rf90_radio_path_e)eRFPath, - 0x14, bMask12Bits, 0x5ab); - } else { - RT_TRACE(COMP_ERR, "%s(): unknown hardware version\n", __func__); - } - break; - case HT_CHANNEL_WIDTH_20_40: - if (priv->card_8192_version == VERSION_819XU_A || priv->card_8192_version == VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */ - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0b, bMask12Bits, 0x300); /* phy para:3ba */ - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x2c, bMask12Bits, 0x3df); - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0e, bMask12Bits, 0x0a1); - - if (priv->chan == 3 || priv->chan == 9) - /* I need to set priv->chan whenever current channel changes */ - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x14, bMask12Bits, 0x59b); - else - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x14, bMask12Bits, 0x5ab); - } else { - RT_TRACE(COMP_ERR, "%s(): unknown hardware version\n", __func__); - } - break; - default: - RT_TRACE(COMP_ERR, "%s(): unknown Bandwidth: %#X\n", __func__, Bandwidth); - break; - } - } -} - -/*-------------------------------------------------------------------------- - * Overview: Interface to config 8256 - * Input: struct net_device* dev - * Output: NONE - * Return: NONE - *-------------------------------------------------------------------------- - */ -void phy_rf8256_config(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - /* Initialize general global value - * - * TODO: Extend RF_PATH_C and RF_PATH_D in the future - */ - priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; - /* Config BB and RF */ - phy_rf8256_config_para_file(dev); -} - -/*-------------------------------------------------------------------------- - * Overview: Interface to config 8256 - * Input: struct net_device* dev - * Output: NONE - * Return: NONE - *-------------------------------------------------------------------------- - */ -static void phy_rf8256_config_para_file(struct net_device *dev) -{ - u32 u4RegValue = 0; - u8 eRFPath; - BB_REGISTER_DEFINITION_T *pPhyReg; - struct r8192_priv *priv = ieee80211_priv(dev); - u32 RegOffSetToBeCheck = 0x3; - u32 RegValueToBeCheck = 0x7f1; - u32 RF3_Final_Value = 0; - u8 ConstRetryTimes = 5, RetryTimes = 5; - u8 ret = 0; - /* Initialize RF */ - for (eRFPath = (enum rf90_radio_path_e)RF90_PATH_A; eRFPath < priv->NumTotalRFPath; eRFPath++) { - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) - continue; - - pPhyReg = &priv->PHYRegDef[eRFPath]; - - /* Joseph test for shorten RF config - * pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, rGlobalCtrl, bMaskDWord); - * ----Store original RFENV control type - */ - switch (eRFPath) { - case RF90_PATH_A: - case RF90_PATH_C: - u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); - break; - case RF90_PATH_B: - case RF90_PATH_D: - u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16); - break; - } - - /*----Set RF_ENV enable----*/ - rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); - - /*----Set RF_ENV output high----*/ - rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); - - /* Set bit number of Address and Data for RF register */ - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 */ - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? */ - - rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0, bMask12Bits, 0xbf); - - /* Check RF block (for FPGA platform only)---- - * TODO: this function should be removed on ASIC , Emily 2007.2.2 - */ - if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (enum rf90_radio_path_e)eRFPath)) { - RT_TRACE(COMP_ERR, "phy_rf8256_config():Check Radio[%d] Fail!!\n", eRFPath); - goto phy_RF8256_Config_ParaFile_Fail; - } - - RetryTimes = ConstRetryTimes; - RF3_Final_Value = 0; - /*----Initialize RF fom connfiguration file----*/ - switch (eRFPath) { - case RF90_PATH_A: - while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_B: - while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_C: - while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_D: - while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (enum rf90_radio_path_e)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (enum rf90_radio_path_e)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - } - - /*----Restore RFENV control type----*/ - switch (eRFPath) { - case RF90_PATH_A: - case RF90_PATH_C: - rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); - break; - case RF90_PATH_B: - case RF90_PATH_D: - rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue); - break; - } - - if (ret) { - RT_TRACE(COMP_ERR, "%s():Radio[%d] Fail!!", __func__, eRFPath); - goto phy_RF8256_Config_ParaFile_Fail; - } - } - - RT_TRACE(COMP_PHY, "PHY Initialization Success\n"); - return; - -phy_RF8256_Config_ParaFile_Fail: - RT_TRACE(COMP_ERR, "PHY Initialization failed\n"); -} - -void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel) -{ - u32 TxAGC = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - - TxAGC = powerlevel; - - if (priv->bDynamicTxLowPower) { - if (priv->CustomerID == RT_CID_819x_Netcore) - TxAGC = 0x22; - else - TxAGC += priv->CckPwEnl; - } - - if (TxAGC > 0x24) - TxAGC = 0x24; - rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); -} - -void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - /* Joseph TxPower for 8192 testing */ - u32 writeVal, powerBase0, powerBase1, writeVal_tmp; - u8 index = 0; - u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; - u8 byte0, byte1, byte2, byte3; - - powerBase0 = powerlevel + priv->TxPowerDiff; /* OFDM rates */ - powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | (powerBase0 << 8) | powerBase0; - powerBase1 = powerlevel; /* MCS rates */ - powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; - - for (index = 0; index < 6; index++) { - writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2) ? powerBase0 : powerBase1); - byte0 = (u8)(writeVal & 0x7f); - byte1 = (u8)((writeVal & 0x7f00) >> 8); - byte2 = (u8)((writeVal & 0x7f0000) >> 16); - byte3 = (u8)((writeVal & 0x7f000000) >> 24); - - if (byte0 > 0x24) - /* Max power index = 0x24 */ - byte0 = 0x24; - if (byte1 > 0x24) - byte1 = 0x24; - if (byte2 > 0x24) - byte2 = 0x24; - if (byte3 > 0x24) - byte3 = 0x24; - - /* for tx power track */ - if (index == 3) { - writeVal_tmp = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; - priv->Pwr_Track = writeVal_tmp; - } - - if (priv->bDynamicTxHighPower) { - /*Add by Jacken 2008/03/06 - *Emily, 20080613. Set low tx power for both MCS and legacy OFDM - */ - writeVal = 0x03030303; - } else { - writeVal = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; - } - rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); - } -} diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.h b/drivers/staging/rtl8192u/r8190_rtl8256.h deleted file mode 100644 index 9ea67f86f911..000000000000 --- a/drivers/staging/rtl8192u/r8190_rtl8256.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is part of the rtl8180-sa2400 driver - * released under the GPL (See file COPYING for details). - * Copyright (c) 2005 Andrea Merello - * - * - * This files contains programming code for the rtl8256 - * radio frontend. - * - * *Many* thanks to Realtek Corp. for their great support! - */ - -#ifndef RTL8225H -#define RTL8225H - -#define RTL819X_TOTAL_RF_PATH 2 /* for 8192U */ -void phy_set_rf8256_bandwidth(struct net_device *dev, - enum ht_channel_width bandwidth); -void phy_rf8256_config(struct net_device *dev); -void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel); -void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel); - -#endif diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h deleted file mode 100644 index ff0ada00bf41..000000000000 --- a/drivers/staging/rtl8192u/r8192U.h +++ /dev/null @@ -1,1129 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is part of rtl8187 OpenSource driver. - * Copyright (C) Andrea Merello 2004-2005 - * Released under the terms of GPL (General Public Licence) - * - * Parts of this driver are based on the GPL part of the - * official realtek driver - * - * Parts of this driver are based on the rtl8192 driver skeleton - * from Patric Schenke & Andres Salomon - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - * - * We want to thank the Authors of those projects and the Ndiswrapper - * project Authors. - */ - -#ifndef R8192U_H -#define R8192U_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ieee80211/ieee80211.h" - -#define RTL8192U -#define RTL819XU_MODULE_NAME "rtl819xU" -/* HW security */ -#define MAX_KEY_LEN 61 -#define KEY_BUF_SIZE 5 - -#define RX_SMOOTH_FACTOR 20 -#define DMESG(x, a...) no_printk(x, ##a) -#define DMESGW(x, a...) no_printk(x, ##a) -#define DMESGE(x, a...) no_printk(x, ##a) -extern u32 rt_global_debug_component; -#define RT_TRACE(component, x, args...) \ - do { \ - if (rt_global_debug_component & (component)) \ - pr_debug("RTL8192U: " x "\n", ##args); \ - } while (0) - -#define COMP_TRACE BIT(0) /* Function call tracing. */ -#define COMP_DBG BIT(1) -#define COMP_INIT BIT(2) /* Driver initialization/halt/reset. */ - -#define COMP_RECV BIT(3) /* Receive data path. */ -#define COMP_SEND BIT(4) /* Send data path. */ -#define COMP_IO BIT(5) -/* 802.11 Power Save mode or System/Device Power state. */ -#define COMP_POWER BIT(6) -/* 802.11 link related: join/start BSS, leave BSS. */ -#define COMP_EPROM BIT(7) -#define COMP_SWBW BIT(8) /* Bandwidth switch. */ -#define COMP_POWER_TRACKING BIT(9) /* 8190 TX Power Tracking */ -#define COMP_TURBO BIT(10) /* Turbo Mode */ -#define COMP_QOS BIT(11) -#define COMP_RATE BIT(12) /* Rate Adaptive mechanism */ -#define COMP_RM BIT(13) /* Radio Measurement */ -#define COMP_DIG BIT(14) -#define COMP_PHY BIT(15) -#define COMP_CH BIT(16) /* Channel setting debug */ -#define COMP_TXAGC BIT(17) /* Tx power */ -#define COMP_HIPWR BIT(18) /* High Power Mechanism */ -#define COMP_HALDM BIT(19) /* HW Dynamic Mechanism */ -#define COMP_SEC BIT(20) /* Event handling */ -#define COMP_LED BIT(21) -#define COMP_RF BIT(22) -#define COMP_RXDESC BIT(23) /* Rx desc information for SD3 debug */ - -/* 11n or 8190 specific code */ - -#define COMP_FIRMWARE BIT(24) /* Firmware downloading */ -#define COMP_HT BIT(25) /* 802.11n HT related information */ -#define COMP_AMSDU BIT(26) /* A-MSDU Debugging */ -#define COMP_SCAN BIT(27) -#define COMP_DOWN BIT(29) /* rm driver module */ -#define COMP_RESET BIT(30) /* Silent reset */ -#define COMP_ERR BIT(31) /* Error out, always on */ - -#define RTL819x_DEBUG -#ifdef RTL819x_DEBUG -#define RTL8192U_ASSERT(expr) \ - do { \ - if (!(expr)) { \ - pr_debug("Assertion failed! %s, %s, %s, line = %d\n", \ - #expr, __FILE__, __func__, __LINE__); \ - } \ - } while (0) -/* - * Debug out data buf. - * If you want to print DATA buffer related BA, - * please set ieee80211_debug_level to DATA|BA - */ -#define RT_DEBUG_DATA(level, data, datalen) \ - do { \ - if ((rt_global_debug_component & (level)) == (level)) { \ - int i; \ - u8 *pdata = (u8 *)data; \ - pr_debug("RTL8192U: %s()\n", __func__); \ - for (i = 0; i < (int)(datalen); i++) { \ - printk("%2x ", pdata[i]); \ - if ((i+1)%16 == 0) \ - printk("\n"); \ - } \ - printk("\n"); \ - } \ - } while (0) -#else -#define RTL8192U_ASSERT(expr) do {} while (0) -#define RT_DEBUG_DATA(level, data, datalen) do {} while (0) -#endif /* RTL8169_DEBUG */ - -/* Queue Select Value in TxDesc */ -#define QSLT_BK 0x1 -#define QSLT_BE 0x0 -#define QSLT_VI 0x4 -#define QSLT_VO 0x6 -#define QSLT_BEACON 0x10 -#define QSLT_HIGH 0x11 -#define QSLT_MGNT 0x12 -#define QSLT_CMD 0x13 - -#define DESC90_RATE1M 0x00 -#define DESC90_RATE2M 0x01 -#define DESC90_RATE5_5M 0x02 -#define DESC90_RATE11M 0x03 -#define DESC90_RATE6M 0x04 -#define DESC90_RATE9M 0x05 -#define DESC90_RATE12M 0x06 -#define DESC90_RATE18M 0x07 -#define DESC90_RATE24M 0x08 -#define DESC90_RATE36M 0x09 -#define DESC90_RATE48M 0x0a -#define DESC90_RATE54M 0x0b -#define DESC90_RATEMCS0 0x00 -#define DESC90_RATEMCS1 0x01 -#define DESC90_RATEMCS2 0x02 -#define DESC90_RATEMCS3 0x03 -#define DESC90_RATEMCS4 0x04 -#define DESC90_RATEMCS5 0x05 -#define DESC90_RATEMCS6 0x06 -#define DESC90_RATEMCS7 0x07 -#define DESC90_RATEMCS8 0x08 -#define DESC90_RATEMCS9 0x09 -#define DESC90_RATEMCS10 0x0a -#define DESC90_RATEMCS11 0x0b -#define DESC90_RATEMCS12 0x0c -#define DESC90_RATEMCS13 0x0d -#define DESC90_RATEMCS14 0x0e -#define DESC90_RATEMCS15 0x0f -#define DESC90_RATEMCS32 0x20 - -#define RTL819X_DEFAULT_RF_TYPE RF_1T2R - -#define IEEE80211_WATCH_DOG_TIME 2000 -#define PHY_Beacon_RSSI_SLID_WIN_MAX 10 -/* For Tx Power Tracking */ -#define OFDM_Table_Length 19 -#define CCK_Table_length 12 - -/* For rtl819x */ -struct tx_desc_819x_usb { - /* DWORD 0 */ - u16 PktSize; - u8 Offset; - u8 Reserved0:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - /* DWORD 1 */ - u8 TxFWInfoSize; - u8 RATid:3; - u8 DISFB:1; - u8 USERATE:1; - u8 MOREFRAG:1; - u8 NoEnc:1; - u8 PIFS:1; - u8 QueueSelect:5; - u8 NoACM:1; - u8 Reserved1:2; - u8 SecCAMID:5; - u8 SecDescAssign:1; - u8 SecType:2; - - /* DWORD 2 */ - u16 TxBufferSize; - u8 ResvForPaddingLen:7; - u8 Reserved3:1; - u8 Reserved4; - - /* DWORD 3, 4, 5 */ - u32 Reserved5; - u32 Reserved6; - u32 Reserved7; -}; - -struct tx_desc_cmd_819x_usb { - /* DWORD 0 */ - u16 Reserved0; - u8 Reserved1; - u8 Reserved2:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - /* DOWRD 1 */ - u8 TxFWInfoSize; - u8 Reserved3; - u8 QueueSelect; - u8 Reserved4; - - /* DOWRD 2 */ - u16 TxBufferSize; - u16 Reserved5; - - /* DWORD 3, 4, 5 */ - u32 Reserved6; - u32 Reserved7; - u32 Reserved8; -}; - -struct tx_fwinfo_819x_usb { - /* DOWRD 0 */ - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; /* Error out, always on */ - u8 TxBandwidth:1; /* Used for HT MCS rate only */ - u8 TxSubCarrier:2; /* Used for legacy OFDM rate only */ - u8 STBC:2; - u8 AllowAggregation:1; - /* Interpret RtsRate field as high throughput data rate */ - u8 RtsHT:1; - u8 RtsShort:1; /* Short PLCP for CCK or short GI for 11n MCS */ - u8 RtsBandwidth:1; /* Used for HT MCS rate only */ - u8 RtsSubcarrier:2;/* Used for legacy OFDM rate only */ - u8 RtsSTBC:2; - /* Enable firmware to recalculate and assign packet duration */ - u8 EnableCPUDur:1; - - /* DWORD 1 */ - u32 RxMF:2; - u32 RxAMD:3; - /* 1 indicate Tx info gathered by firmware and returned by Rx Cmd */ - u32 TxPerPktInfoFeedback:1; - u32 Reserved1:2; - u32 TxAGCOffSet:4; - u32 TxAGCSign:1; - u32 Tx_INFO_RSVD:6; - u32 PacketID:13; -}; - -struct rtl8192_rx_info { - struct urb *urb; - struct net_device *dev; - u8 out_pipe; -}; - -struct rx_desc_819x_usb { - /* DOWRD 0 */ - u16 Length:14; - u16 CRC32:1; - u16 ICV:1; - u8 RxDrvInfoSize; - u8 Shift:2; - u8 PHYStatus:1; - u8 SWDec:1; - u8 Reserved1:4; - - /* DWORD 1 */ - u32 Reserved2; -}; - -struct rx_drvinfo_819x_usb { - /* DWORD 0 */ - u16 Reserved1:12; - u16 PartAggr:1; - u16 FirstAGGR:1; - u16 Reserved2:2; - - u8 RxRate:7; - u8 RxHT:1; - - u8 BW:1; - u8 SPLCP:1; - u8 Reserved3:2; - u8 PAM:1; - u8 Mcast:1; - u8 Bcast:1; - u8 Reserved4:1; - - /* DWORD 1 */ - u32 TSFL; - -}; - -/* Support till 64 bit bus width OS */ -#define MAX_DEV_ADDR_SIZE 8 -/* For RTL8190 */ -#define MAX_FIRMWARE_INFORMATION_SIZE 32 -#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) -#define ENCRYPTION_MAX_OVERHEAD 128 -#define USB_HWDESC_HEADER_LEN sizeof(struct tx_desc_819x_usb) -#define TX_PACKET_SHIFT_BYTES (USB_HWDESC_HEADER_LEN + sizeof(struct tx_fwinfo_819x_usb)) -#define MAX_FRAGMENT_COUNT 8 -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE -#define MAX_TRANSMIT_BUFFER_SIZE 32000 -#else -#define MAX_TRANSMIT_BUFFER_SIZE 8000 -#endif -/* Octets for crc32 (FCS, ICV) */ -#define scrclng 4 - -enum rf_op_type { - RF_OP_By_SW_3wire = 0, - RF_OP_By_FW, - RF_OP_MAX -}; - -/* 8190 Loopback Mode definition */ -typedef enum _rtl819xUsb_loopback { - RTL819xU_NO_LOOPBACK = 0, - RTL819xU_MAC_LOOPBACK = 1, - RTL819xU_DMA_LOOPBACK = 2, - RTL819xU_CCK_LOOPBACK = 3, -} rtl819xUsb_loopback_e; - -/* due to rtl8192 firmware */ -typedef enum _desc_packet_type_e { - DESC_PACKET_TYPE_INIT = 0, - DESC_PACKET_TYPE_NORMAL = 1, -} desc_packet_type_e; - -typedef enum _firmware_status { - FW_STATUS_0_INIT = 0, - FW_STATUS_1_MOVE_BOOT_CODE = 1, - FW_STATUS_2_MOVE_MAIN_CODE = 2, - FW_STATUS_3_TURNON_CPU = 3, - FW_STATUS_4_MOVE_DATA_CODE = 4, - FW_STATUS_5_READY = 5, -} firmware_status_e; - -typedef struct _fw_seg_container { - u16 seg_size; - u8 *seg_ptr; -} fw_seg_container, *pfw_seg_container; -typedef struct _rt_firmware { - firmware_status_e firmware_status; - u16 cmdpacket_frag_threshold; -#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 - u8 firmware_buf[RTL8190_MAX_FIRMWARE_CODE_SIZE]; - u16 firmware_buf_size; -} rt_firmware, *prt_firmware; - -/* Add this to 9100 bytes to receive A-MSDU from RT-AP */ -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -typedef struct _rt_firmware_info_819xUsb { - u8 sz_info[16]; -} rt_firmware_info_819xUsb, *prt_firmware_info_819xUsb; - -/* Firmware Queue Layout */ -#define NUM_OF_FIRMWARE_QUEUE 10 -#define NUM_OF_PAGES_IN_FW 0x100 - -#ifdef USE_ONE_PIPE -#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x000 -#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x000 -#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x0ff -#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x000 -#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0 -#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x00 -#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x0 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0x00 -#else - -#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x020 -#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x020 -#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x040 -#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x040 -#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x4 -#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x20 -#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0x18 - -#endif - -#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000 -#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08 -#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18 -#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT 0x08 -#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 - -/* - * ================================================================= - * ================================================================= - */ - -#define EPROM_93c46 0 -#define EPROM_93c56 1 - -#define DEFAULT_FRAG_THRESHOLD 2342U -#define MIN_FRAG_THRESHOLD 256U -#define DEFAULT_BEACONINTERVAL 0x64U -#define DEFAULT_BEACON_ESSID "Rtl819xU" - -#define DEFAULT_SSID "" -#define DEFAULT_RETRY_RTS 7 -#define DEFAULT_RETRY_DATA 7 -#define PRISM_HDR_SIZE 64 - -#define PHY_RSSI_SLID_WIN_MAX 100 - -typedef enum _WIRELESS_MODE { - WIRELESS_MODE_UNKNOWN = 0x00, - WIRELESS_MODE_A = 0x01, - WIRELESS_MODE_B = 0x02, - WIRELESS_MODE_G = 0x04, - WIRELESS_MODE_AUTO = 0x08, - WIRELESS_MODE_N_24G = 0x10, - WIRELESS_MODE_N_5G = 0x20 -} WIRELESS_MODE; - -#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) - -typedef struct buffer { - struct buffer *next; - u32 *buf; - -} buffer; - -typedef struct rtl_reg_debug { - unsigned int cmd; - struct { - unsigned char type; - unsigned char addr; - unsigned char page; - unsigned char length; - } head; - unsigned char buf[0xff]; -} rtl_reg_debug; - -typedef struct _rt_9x_tx_rate_history { - u32 cck[4]; - u32 ofdm[8]; - u32 ht_mcs[4][16]; -} rt_tx_rahis_t, *prt_tx_rahis_t; -typedef struct _RT_SMOOTH_DATA_4RF { - s8 elements[4][100]; /* array to store values */ - u32 index; /* index to current array to store */ - u32 TotalNum; /* num of valid elements */ - u32 TotalVal[4]; /* sum of valid elements */ -} RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF; - -/* This maybe changed for D-cut larger aggregation size */ -#define MAX_8192U_RX_SIZE 8192 -/* Stats seems messed up, clean it ASAP */ -typedef struct Stats { - unsigned long txrdu; - unsigned long rxok; - unsigned long rxframgment; - unsigned long rxurberr; - unsigned long rxstaterr; - /* 0: Total, 1: OK, 2: CRC, 3: ICV */ - unsigned long received_rate_histogram[4][32]; - /* 0: Long preamble/GI, 1: Short preamble/GI */ - unsigned long received_preamble_GI[2][32]; - /* level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K) */ - unsigned long rx_AMPDUsize_histogram[5]; - /* level: (<5), (5~10), (10~20), (20~40), (>40) */ - unsigned long rx_AMPDUnum_histogram[5]; - unsigned long numpacket_matchbssid; - unsigned long numpacket_toself; - unsigned long num_process_phyinfo; - unsigned long numqry_phystatus; - unsigned long numqry_phystatusCCK; - unsigned long numqry_phystatusHT; - /* 0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate */ - unsigned long received_bwtype[5]; - unsigned long txnperr; - unsigned long txnpdrop; - unsigned long txresumed; - unsigned long txnpokint; - unsigned long txoverflow; - unsigned long txlpokint; - unsigned long txlpdrop; - unsigned long txlperr; - unsigned long txbeokint; - unsigned long txbedrop; - unsigned long txbeerr; - unsigned long txbkokint; - unsigned long txbkdrop; - unsigned long txbkerr; - unsigned long txviokint; - unsigned long txvidrop; - unsigned long txvierr; - unsigned long txvookint; - unsigned long txvodrop; - unsigned long txvoerr; - unsigned long txbeaconokint; - unsigned long txbeacondrop; - unsigned long txbeaconerr; - unsigned long txmanageokint; - unsigned long txmanagedrop; - unsigned long txmanageerr; - unsigned long txdatapkt; - unsigned long txfeedback; - unsigned long txfeedbackok; - - unsigned long txoktotal; - unsigned long txokbytestotal; - unsigned long txokinperiod; - unsigned long txmulticast; - unsigned long txbytesmulticast; - unsigned long txbroadcast; - unsigned long txbytesbroadcast; - unsigned long txunicast; - unsigned long txbytesunicast; - - unsigned long rxoktotal; - unsigned long rxbytesunicast; - unsigned long txfeedbackfail; - unsigned long txerrtotal; - unsigned long txerrbytestotal; - unsigned long txerrmulticast; - unsigned long txerrbroadcast; - unsigned long txerrunicast; - unsigned long txretrycount; - unsigned long txfeedbackretry; - u8 last_packet_rate; - unsigned long slide_signal_strength[100]; - unsigned long slide_evm[100]; - /* For recording sliding window's RSSI value */ - unsigned long slide_rssi_total; - /* For recording sliding window's EVM value */ - unsigned long slide_evm_total; - /* Transformed in dbm. Beautified signal strength for UI, not correct */ - long signal_strength; - long signal_quality; - long last_signal_strength_inpercent; - /* Correct smoothed ss in dbm, only used in driver - * to report real power now - */ - long recv_signal_power; - u8 rx_rssi_percentage[4]; - u8 rx_evm_percentage[2]; - long rxSNRdB[4]; - rt_tx_rahis_t txrate; - /* For beacon RSSI */ - u32 Slide_Beacon_pwdb[100]; - u32 Slide_Beacon_Total; - RT_SMOOTH_DATA_4RF cck_adc_pwdb; - - u32 CurrentShowTxate; -} Stats; - -/* Bandwidth Offset */ -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 - -typedef struct ChnlAccessSetting { - u16 SIFS_Timer; - u16 DIFS_Timer; - u16 SlotTimeTimer; - u16 EIFS_Timer; - u16 CWminIndex; - u16 CWmaxIndex; -} *PCHANNEL_ACCESS_SETTING, CHANNEL_ACCESS_SETTING; - -typedef struct _BB_REGISTER_DEFINITION { - /* set software control: 0x870~0x877 [8 bytes] */ - u32 rfintfs; - /* readback data: 0x8e0~0x8e7 [8 bytes] */ - u32 rfintfi; - /* output data: 0x860~0x86f [16 bytes] */ - u32 rfintfo; - /* output enable: 0x860~0x86f [16 bytes] */ - u32 rfintfe; - /* LSSI data: 0x840~0x84f [16 bytes] */ - u32 rf3wireOffset; - /* BB Band Select: 0x878~0x87f [8 bytes] */ - u32 rfLSSI_Select; - /* Tx gain stage: 0x80c~0x80f [4 bytes] */ - u32 rfTxGainStage; - /* wire parameter control1: 0x820~0x823, 0x828~0x82b, - * 0x830~0x833, 0x838~0x83b [16 bytes] - */ - u32 rfHSSIPara1; - /* wire parameter control2: 0x824~0x827, 0x82c~0x82f, - * 0x834~0x837, 0x83c~0x83f [16 bytes] - */ - u32 rfHSSIPara2; - /* Tx Rx antenna control: 0x858~0x85f [16 bytes] */ - u32 rfSwitchControl; - /* AGC parameter control1: 0xc50~0xc53, 0xc58~0xc5b, - * 0xc60~0xc63, 0xc68~0xc6b [16 bytes] - */ - u32 rfAGCControl1; - /* AGC parameter control2: 0xc54~0xc57, 0xc5c~0xc5f, - * 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] - */ - u32 rfAGCControl2; - /* OFDM Rx IQ imbalance matrix: 0xc14~0xc17, 0xc1c~0xc1f, - * 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] - */ - u32 rfRxIQImbalance; - /* Rx IQ DC offset and Rx digital filter, Rx DC notch filter: - * 0xc10~0xc13, 0xc18~0xc1b, - * 0xc20~0xc23, 0xc28~0xc2b [16 bytes] - */ - u32 rfRxAFE; - /* OFDM Tx IQ imbalance matrix: 0xc80~0xc83, 0xc88~0xc8b, - * 0xc90~0xc93, 0xc98~0xc9b [16 bytes] - */ - u32 rfTxIQImbalance; - /* Tx IQ DC Offset and Tx DFIR type: - * 0xc84~0xc87, 0xc8c~0xc8f, - * 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] - */ - u32 rfTxAFE; - /* LSSI RF readback data: 0x8a0~0x8af [16 bytes] */ - u32 rfLSSIReadBack; -} BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; - -typedef enum _RT_RF_TYPE_819xU { - RF_TYPE_MIN = 0, - RF_8225, - RF_8256, - RF_8258, - RF_PSEUDO_11N = 4, -} RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU; - -/* 2007/10/08 MH Define RATR state. */ -enum dynamic_ratr_state { - DM_RATR_STA_HIGH = 0, - DM_RATR_STA_MIDDLE = 1, - DM_RATR_STA_LOW = 2, - DM_RATR_STA_MAX -}; - -typedef struct _rate_adaptive { - u8 rate_adaptive_disabled; - enum dynamic_ratr_state ratr_state; - u16 reserve; - - u32 high_rssi_thresh_for_ra; - u32 high2low_rssi_thresh_for_ra; - u8 low2high_rssi_thresh_for_ra40M; - u32 low_rssi_thresh_for_ra40M; - u8 low2high_rssi_thresh_for_ra20M; - u32 low_rssi_thresh_for_ra20M; - u32 upper_rssi_threshold_ratr; - u32 middle_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr_40M; - u32 low_rssi_threshold_ratr_20M; - u8 ping_rssi_enable; - u32 ping_rssi_ratr; - u32 ping_rssi_thresh_for_ra; - u32 last_ratr; - -} rate_adaptive, *prate_adaptive; - -#define TxBBGainTableLength 37 -#define CCKTxBBGainTableLength 23 - -typedef struct _txbbgain_struct { - long txbb_iq_amplifygain; - u32 txbbgain_value; -} txbbgain_struct, *ptxbbgain_struct; - -typedef struct _ccktxbbgain_struct { - /* The value is from a22 to a29, one byte one time is much safer */ - u8 ccktxbb_valuearray[8]; -} ccktxbbgain_struct, *pccktxbbgain_struct; - -typedef struct _init_gain { - u8 xaagccore1; - u8 xbagccore1; - u8 xcagccore1; - u8 xdagccore1; - u8 cca; - -} init_gain, *pinit_gain; - -typedef struct _phy_ofdm_rx_status_report_819xusb { - u8 trsw_gain_X[4]; - u8 pwdb_all; - u8 cfosho_X[4]; - u8 cfotail_X[4]; - u8 rxevm_X[2]; - u8 rxsnr_X[4]; - u8 pdsnr_X[2]; - u8 csi_current_X[2]; - u8 csi_target_X[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 sgi_en; - u8 rxsc_sgien_exflg; -} phy_sts_ofdm_819xusb_t; - -typedef struct _phy_cck_rx_status_report_819xusb { - /* For CCK rate descriptor. This is an unsigned 8:1 variable. - * LSB bit presend 0.5. And MSB 7 bts presend a signed value. - * Range from -64~+63.5. - */ - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -} phy_sts_cck_819xusb_t; - -struct phy_ofdm_rx_status_rxsc_sgien_exintfflag { - u8 reserved:4; - u8 rxsc:2; - u8 sgi_en:1; - u8 ex_intf_flag:1; -}; - -typedef enum _RT_CUSTOMER_ID { - RT_CID_DEFAULT = 0, - RT_CID_8187_ALPHA0 = 1, - RT_CID_8187_SERCOMM_PS = 2, - RT_CID_8187_HW_LED = 3, - RT_CID_8187_NETGEAR = 4, - RT_CID_WHQL = 5, - RT_CID_819x_CAMEO = 6, - RT_CID_819x_RUNTOP = 7, - RT_CID_819x_Senao = 8, - RT_CID_TOSHIBA = 9, - RT_CID_819x_Netcore = 10, - RT_CID_Nettronix = 11, - RT_CID_DLINK = 12, - RT_CID_PRONET = 13, -} RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; - -/* - * ========================================================================== - * LED customization. - * ========================================================================== - */ - -typedef enum _LED_STRATEGY_8190 { - SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */ - SW_LED_MODE1, /* SW control for PCI Express */ - SW_LED_MODE2, /* SW control for Cameo. */ - SW_LED_MODE3, /* SW control for RunTop. */ - SW_LED_MODE4, /* SW control for Netcore. */ - /* HW control 2 LEDs, LED0 and LED1 (4 different control modes) */ - HW_LED, -} LED_STRATEGY_8190, *PLED_STRATEGY_8190; - -typedef enum _RESET_TYPE { - RESET_TYPE_NORESET = 0x00, - RESET_TYPE_NORMAL = 0x01, - RESET_TYPE_SILENT = 0x02 -} RESET_TYPE; - -/* The simple tx command OP code. */ -typedef enum _tag_TxCmd_Config_Index { - TXCMD_TXRA_HISTORY_CTRL = 0xFF900000, - TXCMD_RESET_TX_PKT_BUFF = 0xFF900001, - TXCMD_RESET_RX_PKT_BUFF = 0xFF900002, - TXCMD_SET_TX_DURATION = 0xFF900003, - TXCMD_SET_RX_RSSI = 0xFF900004, - TXCMD_SET_TX_PWR_TRACKING = 0xFF900005, - TXCMD_XXXX_CTRL, -} DCMD_TXCMD_OP; - -enum version_819xu { - VERSION_819XU_A, // A-cut - VERSION_819XU_B, // B-cut - VERSION_819XU_C,// C-cut -}; - -//added for different RF type -enum rt_rf_type { - RF_1T2R = 0, - RF_2T4R, -}; - -typedef struct r8192_priv { - struct usb_device *udev; - /* For maintain info from eeprom */ - short epromtype; - u16 eeprom_vid; - u16 eeprom_pid; - u8 eeprom_CustomerID; - u8 eeprom_ChannelPlan; - RT_CUSTOMER_ID CustomerID; - LED_STRATEGY_8190 LedStrategy; - u8 txqueue_to_outpipemap[9]; - int irq; - struct ieee80211_device *ieee80211; - - /* O: rtl8192, 1: rtl8185 V B/C, 2: rtl8185 V D */ - short card_8192; - /* If TCR reports card V B/C, this discriminates */ - enum version_819xu card_8192_version; - short enable_gpio0; - enum card_type { - PCI, MINIPCI, CARDBUS, USB - } card_type; - short hw_plcp_len; - short plcp_preamble_mode; - - spinlock_t irq_lock; - spinlock_t tx_lock; - struct mutex mutex; - - u16 irq_mask; - short chan; - short sens; - short max_sens; - - short up; - /* If 1, allow bad crc frame, reception in monitor mode */ - short crcmon; - - struct mutex wx_mutex; - - enum rt_rf_type rf_type; /* 0: 1T2R, 1: 2T4R */ - RT_RF_TYPE_819xU rf_chip; - - short (*rf_set_sens)(struct net_device *dev, short sens); - u8 (*rf_set_chan)(struct net_device *dev, u8 ch); - void (*rf_close)(struct net_device *dev); - void (*rf_init)(struct net_device *dev); - short promisc; - /* Stats */ - struct Stats stats; - struct iw_statistics wstats; - - /* RX stuff */ - struct urb **rx_urb; - struct urb **rx_cmd_urb; -#ifdef THOMAS_BEACON - u32 *oldaddr; -#endif -#ifdef THOMAS_TASKLET - atomic_t irt_counter; /* count for irq_rx_tasklet */ -#endif -#ifdef JACKSON_NEW_RX - struct sk_buff **pp_rxskb; - int rx_inx; -#endif - - struct sk_buff_head rx_queue; - struct sk_buff_head skb_queue; - struct work_struct qos_activate; - short tx_urb_index; - atomic_t tx_pending[0x10]; /* UART_PRIORITY + 1 */ - - struct tasklet_struct irq_rx_tasklet; - struct urb *rxurb_task; - - /* Tx Related variables */ - u16 ShortRetryLimit; - u16 LongRetryLimit; - u32 TransmitConfig; - u8 RegCWinMin; /* For turbo mode CW adaptive */ - - u32 LastRxDescTSFHigh; - u32 LastRxDescTSFLow; - - /* Rx Related variables */ - u16 EarlyRxThreshold; - u32 ReceiveConfig; - u8 AcmControl; - - u8 RFProgType; - - u8 retry_data; - u8 retry_rts; - u16 rts; - - struct ChnlAccessSetting ChannelAccessSetting; - struct work_struct reset_wq; - -/**********************************************************/ - /* For rtl819xUsb */ - u16 basic_rate; - u8 short_preamble; - u8 slot_time; - bool bDcut; - bool bCurrentRxAggrEnable; - enum rf_op_type Rf_Mode; /* For Firmware RF -R/W switch */ - prt_firmware pFirmware; - rtl819xUsb_loopback_e LoopbackMode; - u16 EEPROMTxPowerDiff; - u8 EEPROMThermalMeter; - u8 EEPROMPwDiff; - u8 EEPROMCrystalCap; - u8 EEPROM_Def_Ver; - u8 EEPROMTxPowerLevelCCK; /* CCK channel 1~14 */ - u8 EEPROMTxPowerLevelCCK_V1[3]; - u8 EEPROMTxPowerLevelOFDM24G[3]; /* OFDM 2.4G channel 1~14 */ - u8 EEPROMTxPowerLevelOFDM5G[24]; /* OFDM 5G */ - - /* PHY related */ - BB_REGISTER_DEFINITION_T PHYRegDef[4]; /* Radio A/B/C/D */ - /* Read/write are allow for following hardware information variables */ - u32 MCSTxPowerLevelOriginalOffset[6]; - u32 CCKTxPowerLevelOriginalOffset; - u8 TxPowerLevelCCK[14]; /* CCK channel 1~14 */ - u8 TxPowerLevelOFDM24G[14]; /* OFDM 2.4G channel 1~14 */ - u8 TxPowerLevelOFDM5G[14]; /* OFDM 5G */ - u32 Pwr_Track; - u8 TxPowerDiff; - u8 AntennaTxPwDiff[2]; /* Antenna gain offset, 0: B, 1: C, 2: D */ - u8 CrystalCap; - u8 ThermalMeter[2]; /* index 0: RFIC0, index 1: RFIC1 */ - - u8 CckPwEnl; - /* Use to calculate PWBD */ - u8 bCckHighPower; - long undecorated_smoothed_pwdb; - - /* For set channel */ - u8 SwChnlInProgress; - u8 SwChnlStage; - u8 SwChnlStep; - u8 SetBWModeInProgress; - enum ht_channel_width CurrentChannelBW; - u8 ChannelPlan; - /* 8190 40MHz mode */ - /* Control channel sub-carrier */ - u8 nCur40MhzPrimeSC; - /* Test for shorten RF configuration time. - * We save RF reg0 in this variable to reduce RF reading. - */ - u32 RfReg0Value[4]; - u8 NumTotalRFPath; - bool brfpath_rxenable[4]; - /* RF set related */ - bool SetRFPowerStateInProgress; - struct timer_list watch_dog_timer; - - /* For dynamic mechanism */ - /* Tx Power Control for Near/Far Range */ - bool bdynamic_txpower; - bool bDynamicTxHighPower; - bool bDynamicTxLowPower; - bool bLastDTPFlag_High; - bool bLastDTPFlag_Low; - - bool bstore_last_dtpflag; - /* Define to discriminate on High power State or - * on sitesurvey to change Tx gain index - */ - bool bstart_txctrl_bydtp; - rate_adaptive rate_adaptive; - /* TX power tracking - * OPEN/CLOSE TX POWER TRACKING - */ - txbbgain_struct txbbgain_table[TxBBGainTableLength]; - u8 txpower_count; /* For 6 sec do tracking again */ - bool btxpower_trackingInit; - u8 OFDM_index; - u8 CCK_index; - /* CCK TX Power Tracking */ - ccktxbbgain_struct cck_txbbgain_table[CCKTxBBGainTableLength]; - ccktxbbgain_struct cck_txbbgain_ch14_table[CCKTxBBGainTableLength]; - u8 rfa_txpowertrackingindex; - u8 rfa_txpowertrackingindex_real; - u8 rfa_txpowertracking_default; - u8 rfc_txpowertrackingindex; - u8 rfc_txpowertrackingindex_real; - - s8 cck_present_attenuation; - u8 cck_present_attenuation_20Mdefault; - u8 cck_present_attenuation_40Mdefault; - s8 cck_present_attenuation_difference; - bool btxpower_tracking; - bool bcck_in_ch14; - bool btxpowerdata_readfromEEPORM; - u16 TSSI_13dBm; - init_gain initgain_backup; - u8 DefaultInitialGain[4]; - /* For EDCA Turbo mode */ - bool bis_any_nonbepkts; - bool bcurrent_turbo_EDCA; - bool bis_cur_rdlstate; - struct delayed_work fsync_work; - bool bfsync_processing; /* 500ms Fsync timer is active or not */ - u32 rate_record; - u32 rateCountDiffRecord; - u32 ContinueDiffCount; - bool bswitch_fsync; - - u8 framesync; - u32 framesyncC34; - u8 framesyncMonitor; - u16 nrxAMPDU_size; - u8 nrxAMPDU_aggr_num; - - /* For gpio */ - bool bHwRadioOff; - - u32 reset_count; - bool bpbc_pressed; - u32 txpower_checkcnt; - u32 txpower_tracking_callback_cnt; - u8 thermal_read_val[40]; - u8 thermal_readback_index; - u32 ccktxpower_adjustcnt_not_ch14; - u32 ccktxpower_adjustcnt_ch14; - u8 tx_fwinfo_force_subcarriermode; - u8 tx_fwinfo_force_subcarrierval; - /* For silent reset */ - RESET_TYPE ResetProgress; - bool bForcedSilentReset; - bool bDisableNormalResetCheck; - u16 TxCounter; - u16 RxCounter; - int IrpPendingCount; - bool bResetInProgress; - bool force_reset; - u8 InitialGainOperateType; - - u16 SifsTime; - - /* Define work item */ - - struct delayed_work update_beacon_wq; - struct delayed_work watch_dog_wq; - struct delayed_work txpower_tracking_wq; - struct delayed_work rfpath_check_wq; - struct delayed_work gpio_change_rf_wq; - struct delayed_work initialgain_operate_wq; - struct workqueue_struct *priv_wq; - - /* debugfs */ - struct dentry *debugfs_dir; -} r8192_priv; - -/* For rtl8187B */ -typedef enum{ - BULK_PRIORITY = 0x01, - LOW_PRIORITY, - NORM_PRIORITY, - VO_PRIORITY, - VI_PRIORITY, - BE_PRIORITY, - BK_PRIORITY, - RSVD2, - RSVD3, - BEACON_PRIORITY, - HIGH_PRIORITY, - MANAGE_PRIORITY, - RSVD4, - RSVD5, - UART_PRIORITY -} priority_t; - -typedef enum { - NIC_8192U = 1, - NIC_8190P = 2, - NIC_8192E = 3, -} nic_t; - -bool init_firmware(struct net_device *dev); -short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb); -short rtl8192_tx(struct net_device *dev, struct sk_buff *skb); - -int read_nic_byte(struct net_device *dev, int x, u8 *data); -int read_nic_byte_E(struct net_device *dev, int x, u8 *data); -int read_nic_dword(struct net_device *dev, int x, u32 *data); -int read_nic_word(struct net_device *dev, int x, u16 *data); -int write_nic_byte(struct net_device *dev, int x, u8 y); -int write_nic_byte_E(struct net_device *dev, int x, u8 y); -int write_nic_word(struct net_device *dev, int x, u16 y); -int write_nic_dword(struct net_device *dev, int x, u32 y); -void force_pci_posting(struct net_device *dev); - -void rtl8192_rtx_disable(struct net_device *dev); -void rtl8192_rx_enable(struct net_device *dev); - -void rtl8192_update_msr(struct net_device *dev); -int rtl8192_down(struct net_device *dev); -int rtl8192_up(struct net_device *dev); -void rtl8192_commit(struct net_device *dev); -void rtl8192_set_chan(struct net_device *dev, short ch); -void rtl8192_set_rxconf(struct net_device *dev); -void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate); - -void EnableHWSecurityConfig8192(struct net_device *dev); -void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, - const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); - -void rtl8192_debugfs_init_one(struct net_device *dev); -void rtl8192_debugfs_exit_one(struct net_device *dev); -void rtl8192_debugfs_rename_one(struct net_device *dev); -void rtl8192_debugfs_init(void); -void rtl8192_debugfs_exit(void); - -#endif diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c deleted file mode 100644 index 0a60ef20107c..000000000000 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ /dev/null @@ -1,4800 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192U - * - * Based on the r8187 driver, which is: - * Copyright 2004-2005 Andrea Merello , et al. - * - * Contact Information: - * Jerry chuang - */ - -#ifndef CONFIG_FORCE_HARD_FLOAT -double __floatsidf(int i) -{ - return i; -} - -unsigned int __fixunsdfsi(double d) -{ - return d; -} - -double __adddf3(double a, double b) -{ - return a + b; -} - -double __addsf3(float a, float b) -{ - return a + b; -} - -double __subdf3(double a, double b) -{ - return a - b; -} - -double __extendsfdf2(float a) -{ - return a; -} -#endif - -#define CONFIG_RTL8192_IO_MAP - -#include -#include "r8192U_hw.h" -#include "r8192U.h" -#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */ -#include "r8180_93cx6.h" /* Card EEPROM */ -#include "r8192U_wx.h" -#include "r819xU_phy.h" -#include "r819xU_phyreg.h" -#include "r819xU_cmdpkt.h" -#include "r8192U_dm.h" -#include -#include -#include -/* FIXME: check if 2.6.7 is ok */ - -#include "ieee80211/dot11d.h" -/* set here to open your trace code. */ -u32 rt_global_debug_component = COMP_DOWN | - COMP_SEC | - COMP_ERR; /* always open err flags on */ - -#define TOTAL_CAM_ENTRY 32 -#define CAM_CONTENT_COUNT 8 - -static const struct usb_device_id rtl8192_usb_id_tbl[] = { - /* Realtek */ - {USB_DEVICE(0x0bda, 0x8709)}, - /* Corega */ - {USB_DEVICE(0x07aa, 0x0043)}, - /* Belkin */ - {USB_DEVICE(0x050d, 0x805E)}, - /* Sitecom */ - {USB_DEVICE(0x0df6, 0x0031)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9201)}, - /* Dlink */ - {USB_DEVICE(0x2001, 0x3301)}, - /* Zinwell */ - {USB_DEVICE(0x5a57, 0x0290)}, - /* LG */ - {USB_DEVICE(0x043e, 0x7a01)}, - {} -}; - -MODULE_LICENSE("GPL"); -MODULE_VERSION("V 1.1"); -MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl); -MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards"); - -static char *ifname = "wlan%d"; -static int hwwep = 1; /* default use hw. set 0 to use software security */ - -module_param(ifname, charp, 0644); -module_param(hwwep, int, 0644); - -MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); -MODULE_PARM_DESC(hwwep, " Try to use hardware security support. "); - -static int rtl8192_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id); -static void rtl8192_usb_disconnect(struct usb_interface *intf); - -static struct usb_driver rtl8192_usb_driver = { - .name = RTL819XU_MODULE_NAME, /* Driver name */ - .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */ - .probe = rtl8192_usb_probe, /* probe fn */ - .disconnect = rtl8192_usb_disconnect, /* remove fn */ - .suspend = NULL, /* PM suspend fn */ - .resume = NULL, /* PM resume fn */ -}; - -struct CHANNEL_LIST { - u8 Channel[32]; - u8 Len; -}; - -static struct CHANNEL_LIST ChannelPlan[] = { - /* FCC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, - /* IC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, - /* ETSI */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, - /* Spain. Change to ETSI. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* France. Change to ETSI. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* MKK */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, - /* MKK1 */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, - /* Israel. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* For 11a , TELEC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, - /* MIC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, - /* For Global Domain. 1-11:active scan, 12-14 passive scan. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} -}; - -static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv) -{ - int i, max_chan = -1, min_chan = -1; - struct ieee80211_device *ieee = priv->ieee80211; - - switch (channel_plan) { - case COUNTRY_CODE_FCC: - case COUNTRY_CODE_IC: - case COUNTRY_CODE_ETSI: - case COUNTRY_CODE_SPAIN: - case COUNTRY_CODE_FRANCE: - case COUNTRY_CODE_MKK: - case COUNTRY_CODE_MKK1: - case COUNTRY_CODE_ISRAEL: - case COUNTRY_CODE_TELEC: - case COUNTRY_CODE_MIC: - rtl8192u_dot11d_init(ieee); - ieee->bGlobalDomain = false; - /* actually 8225 & 8256 rf chips only support B,G,24N mode */ - if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) { - min_chan = 1; - max_chan = 14; - } else { - RT_TRACE(COMP_ERR, - "unknown rf chip, can't set channel map in function:%s()\n", - __func__); - } - if (ChannelPlan[channel_plan].Len != 0) { - /* Clear old channel map */ - memset(GET_DOT11D_INFO(ieee)->channel_map, 0, - sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - /* Set new channel map */ - for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { - if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan) - break; - GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1; - } - } - break; - - case COUNTRY_CODE_GLOBAL_DOMAIN: - /* this flag enabled to follow 11d country IE setting, - * otherwise, it shall follow global domain settings. - */ - GET_DOT11D_INFO(ieee)->dot11d_enabled = 0; - dot11d_reset(ieee); - ieee->bGlobalDomain = true; - break; - - default: - break; - } -} - -static void CamResetAllEntry(struct net_device *dev) -{ - u32 ulcommand = 0; - /* In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA - * associate to AP. However, ResetKey is called on - * OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest. In this - * condition, Cam can not be reset because upper layer will not set - * this static key again. - */ - ulcommand |= BIT(31) | BIT(30); - write_nic_dword(dev, RWCAM, ulcommand); -} - -int write_nic_byte_E(struct net_device *dev, int indx, u8 data) -{ - int status; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u8 *usbdata = kzalloc(sizeof(data), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - *usbdata = data; - - status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, - indx | 0xfe00, 0, usbdata, 1, 500); - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status); - return status; - } - return 0; -} - -int read_nic_byte_E(struct net_device *dev, int indx, u8 *data) -{ - int status; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u8 *usbdata = kzalloc(sizeof(u8), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - - status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, - indx | 0xfe00, 0, usbdata, 1, 500); - *data = *usbdata; - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s failure status: %d\n", __func__, status); - return status; - } - - return 0; -} - -/* as 92U has extend page from 4 to 16, so modify functions below. */ -int write_nic_byte(struct net_device *dev, int indx, u8 data) -{ - int status; - - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u8 *usbdata = kzalloc(sizeof(data), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - *usbdata = data; - - status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 1, 500); - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status); - return status; - } - - return 0; -} - -int write_nic_word(struct net_device *dev, int indx, u16 data) -{ - int status; - - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u16 *usbdata = kzalloc(sizeof(data), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - *usbdata = data; - - status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 2, 500); - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status); - return status; - } - - return 0; -} - -int write_nic_dword(struct net_device *dev, int indx, u32 data) -{ - int status; - - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u32 *usbdata = kzalloc(sizeof(data), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - *usbdata = data; - - status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 4, 500); - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s TimeOut! status: %d\n", __func__, status); - return status; - } - - return 0; -} - -int read_nic_byte(struct net_device *dev, int indx, u8 *data) -{ - int status; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u8 *usbdata = kzalloc(sizeof(u8), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - - status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 1, 500); - *data = *usbdata; - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s failure status: %d\n", __func__, status); - return status; - } - - return 0; -} - -int read_nic_word(struct net_device *dev, int indx, u16 *data) -{ - int status; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u16 *usbdata = kzalloc(sizeof(u16), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - - status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 2, 500); - *data = *usbdata; - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s failure status: %d\n", __func__, status); - return status; - } - - return 0; -} - -static int read_nic_word_E(struct net_device *dev, int indx, u16 *data) -{ - int status; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u16 *usbdata = kzalloc(sizeof(u16), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - - status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, - indx | 0xfe00, 0, usbdata, 2, 500); - *data = *usbdata; - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s failure status: %d\n", __func__, status); - return status; - } - - return 0; -} - -int read_nic_dword(struct net_device *dev, int indx, u32 *data) -{ - int status; - - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct usb_device *udev = priv->udev; - u32 *usbdata = kzalloc(sizeof(u32), GFP_KERNEL); - - if (!usbdata) - return -ENOMEM; - - status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, - (indx & 0xff) | 0xff00, (indx >> 8) & 0x0f, - usbdata, 4, 500); - *data = *usbdata; - kfree(usbdata); - - if (status < 0) { - netdev_err(dev, "%s failure status: %d\n", __func__, status); - return status; - } - - return 0; -} - -/* u8 read_phy_cck(struct net_device *dev, u8 adr); */ -/* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */ -/* this might still called in what was the PHY rtl8185/rtl8192 common code - * plans are to possibility turn it again in one common code... - */ -inline void force_pci_posting(struct net_device *dev) -{ -} - -static struct net_device_stats *rtl8192_stats(struct net_device *dev); -static void rtl8192_restart(struct work_struct *work); -static void watch_dog_timer_callback(struct timer_list *t); - -/**************************************************************************** - * -----------------------------MISC STUFF------------------------- - *****************************************************************************/ - -short check_nic_enough_desc(struct net_device *dev, int queue_index) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int used = atomic_read(&priv->tx_pending[queue_index]); - - return (used < MAX_TX_URB); -} - -static void tx_timeout(struct net_device *dev, unsigned int txqueue) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - schedule_work(&priv->reset_wq); -} - -void rtl8192_update_msr(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 msr; - - read_nic_byte(dev, MSR, &msr); - msr &= ~MSR_LINK_MASK; - - /* do not change in link_state != WLAN_LINK_ASSOCIATED. - * msr must be updated if the state is ASSOCIATING. - * this is intentional and make sense for ad-hoc and - * master (see the create BSS/IBSS func) - */ - if (priv->ieee80211->state == IEEE80211_LINKED) { - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) - msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); - else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); - else if (priv->ieee80211->iw_mode == IW_MODE_MASTER) - msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); - - } else { - msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); - } - - write_nic_byte(dev, MSR, msr); -} - -void rtl8192_set_chan(struct net_device *dev, short ch) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - - RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch); - priv->chan = ch; - - /* this hack should avoid frame TX during channel setting*/ - - /* need to implement rf set channel here */ - - if (priv->rf_set_chan) - priv->rf_set_chan(dev, priv->chan); - mdelay(10); -} - -static void rtl8192_rx_isr(struct urb *urb); - -static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats) -{ - return (sizeof(struct rx_desc_819x_usb) + pstats->RxDrvInfoSize - + pstats->RxBufShift); -} - -void rtl8192_rx_enable(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct urb *entry; - struct sk_buff *skb; - struct rtl8192_rx_info *info; - - /* nomal packet rx procedure */ - while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) { - skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL); - if (!skb) - break; - entry = usb_alloc_urb(0, GFP_KERNEL); - if (!entry) { - kfree_skb(skb); - break; - } - usb_fill_bulk_urb(entry, priv->udev, - usb_rcvbulkpipe(priv->udev, 3), - skb_tail_pointer(skb), - RX_URB_SIZE, rtl8192_rx_isr, skb); - info = (struct rtl8192_rx_info *)skb->cb; - info->urb = entry; - info->dev = dev; - info->out_pipe = 3; /* denote rx normal packet queue */ - skb_queue_tail(&priv->rx_queue, skb); - usb_submit_urb(entry, GFP_KERNEL); - } - - /* command packet rx procedure */ - while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) { - skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL); - if (!skb) - break; - entry = usb_alloc_urb(0, GFP_KERNEL); - if (!entry) { - kfree_skb(skb); - break; - } - usb_fill_bulk_urb(entry, priv->udev, - usb_rcvbulkpipe(priv->udev, 9), - skb_tail_pointer(skb), - RX_URB_SIZE, rtl8192_rx_isr, skb); - info = (struct rtl8192_rx_info *)skb->cb; - info->urb = entry; - info->dev = dev; - info->out_pipe = 9; /* denote rx cmd packet queue */ - skb_queue_tail(&priv->rx_queue, skb); - usb_submit_urb(entry, GFP_KERNEL); - } -} - -void rtl8192_set_rxconf(struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - u32 rxconf; - - read_nic_dword(dev, RCR, &rxconf); - rxconf = rxconf & ~MAC_FILTER_MASK; - rxconf = rxconf | RCR_AMF; - rxconf = rxconf | RCR_ADF; - rxconf = rxconf | RCR_AB; - rxconf = rxconf | RCR_AM; - - if (dev->flags & IFF_PROMISC) - DMESG("NIC in promisc mode"); - - if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || - dev->flags & IFF_PROMISC) { - rxconf = rxconf | RCR_AAP; - } else { - rxconf = rxconf | RCR_APM; - rxconf = rxconf | RCR_CBSSID; - } - - if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) { - rxconf = rxconf | RCR_AICV; - rxconf = rxconf | RCR_APWRMGT; - } - - if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) - rxconf = rxconf | RCR_ACRC32; - - rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK; - rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE << RX_FIFO_THRESHOLD_SHIFT); - rxconf = rxconf & ~MAX_RX_DMA_MASK; - rxconf = rxconf | ((u32)7 << RCR_MXDMA_OFFSET); - - rxconf = rxconf | RCR_ONLYERLPKT; - - write_nic_dword(dev, RCR, rxconf); -} - -void rtl8192_rtx_disable(struct net_device *dev) -{ - u8 cmd; - struct r8192_priv *priv = ieee80211_priv(dev); - struct sk_buff *skb; - struct rtl8192_rx_info *info; - - read_nic_byte(dev, CMDR, &cmd); - write_nic_byte(dev, CMDR, cmd & ~(CR_TE | CR_RE)); - force_pci_posting(dev); - mdelay(10); - - while ((skb = __skb_dequeue(&priv->rx_queue))) { - info = (struct rtl8192_rx_info *)skb->cb; - if (!info->urb) - continue; - - usb_kill_urb(info->urb); - kfree_skb(skb); - } - - if (skb_queue_len(&priv->skb_queue)) - netdev_warn(dev, "skb_queue not empty\n"); - - skb_queue_purge(&priv->skb_queue); -} - -/* The prototype of rx_isr has changed since one version of Linux Kernel */ -static void rtl8192_rx_isr(struct urb *urb) -{ - struct sk_buff *skb = (struct sk_buff *)urb->context; - struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; - struct net_device *dev = info->dev; - struct r8192_priv *priv = ieee80211_priv(dev); - int out_pipe = info->out_pipe; - int err; - - if (!priv->up) - return; - - if (unlikely(urb->status)) { - info->urb = NULL; - priv->stats.rxstaterr++; - priv->ieee80211->stats.rx_errors++; - usb_free_urb(urb); - return; - } - skb_unlink(skb, &priv->rx_queue); - skb_put(skb, urb->actual_length); - - skb_queue_tail(&priv->skb_queue, skb); - tasklet_schedule(&priv->irq_rx_tasklet); - - skb = dev_alloc_skb(RX_URB_SIZE); - if (unlikely(!skb)) { - usb_free_urb(urb); - netdev_err(dev, "%s(): can't alloc skb\n", __func__); - /* TODO check rx queue length and refill *somewhere* */ - return; - } - - usb_fill_bulk_urb(urb, priv->udev, - usb_rcvbulkpipe(priv->udev, out_pipe), - skb_tail_pointer(skb), - RX_URB_SIZE, rtl8192_rx_isr, skb); - - info = (struct rtl8192_rx_info *)skb->cb; - info->urb = urb; - info->dev = dev; - info->out_pipe = out_pipe; - - urb->transfer_buffer = skb_tail_pointer(skb); - urb->context = skb; - skb_queue_tail(&priv->rx_queue, skb); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -EPERM) - netdev_err(dev, - "can not submit rxurb, err is %x, URB status is %x\n", - err, urb->status); -} - -static u32 rtl819xusb_rx_command_packet(struct net_device *dev, - struct ieee80211_rx_stats *pstats) -{ - u32 status; - - status = cmpk_message_handle_rx(dev, pstats); - if (status) - DMESG("rxcommandpackethandle819xusb: It is a command packet\n"); - - return status; -} - -static void rtl8192_data_hard_stop(struct net_device *dev) -{ - /* FIXME !! */ -} - -static void rtl8192_data_hard_resume(struct net_device *dev) -{ - /* FIXME !! */ -} - -/* this function TX data frames when the ieee80211 stack requires this. - * It checks also if we need to stop the ieee tx queue, eventually do it - */ -static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, - int rate) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - unsigned long flags; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - /* shall not be referred by command packet */ - RTL8192U_ASSERT(queue_index != TXCMD_QUEUE); - - spin_lock_irqsave(&priv->tx_lock, flags); - - *(struct net_device **)(skb->cb) = dev; - tcb_desc->bTxEnableFwCalcDur = 1; - skb_push(skb, priv->ieee80211->tx_headroom); - rtl8192_tx(dev, skb); - - spin_unlock_irqrestore(&priv->tx_lock, flags); -} - -/* This is a rough attempt to TX a frame - * This is called by the ieee 80211 stack to TX management frames. - * If the ring is full packet are dropped (for data frame the queue - * is stopped before this can happen). - */ -static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - int ret; - unsigned long flags; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - spin_lock_irqsave(&priv->tx_lock, flags); - - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - if (queue_index == TXCMD_QUEUE) { - skb_push(skb, USB_HWDESC_HEADER_LEN); - rtl819xU_tx_cmd(dev, skb); - ret = 1; - } else { - skb_push(skb, priv->ieee80211->tx_headroom); - ret = rtl8192_tx(dev, skb); - } - - spin_unlock_irqrestore(&priv->tx_lock, flags); - - return ret; -} - -static void rtl8192_tx_isr(struct urb *tx_urb) -{ - struct sk_buff *skb = (struct sk_buff *)tx_urb->context; - struct net_device *dev; - struct r8192_priv *priv = NULL; - struct cb_desc *tcb_desc; - u8 queue_index; - - if (!skb) - return; - - dev = *(struct net_device **)(skb->cb); - tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - queue_index = tcb_desc->queue_index; - - priv = ieee80211_priv(dev); - - if (tcb_desc->queue_index != TXCMD_QUEUE) { - if (tx_urb->status == 0) { - netif_trans_update(dev); - priv->stats.txoktotal++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - priv->stats.txbytesunicast += - (skb->len - priv->ieee80211->tx_headroom); - } else { - priv->ieee80211->stats.tx_errors++; - /* TODO */ - } - } - - /* free skb and tx_urb */ - dev_kfree_skb_any(skb); - usb_free_urb(tx_urb); - atomic_dec(&priv->tx_pending[queue_index]); - - /* - * Handle HW Beacon: - * We had transfer our beacon frame to host controller at this moment. - * - * - * Caution: - * Handling the wait queue of command packets. - * For Tx command packets, we must not do TCB fragment because it is - * not handled right now. We must cut the packets to match the size of - * TX_CMD_PKT before we send it. - */ - - /* Handle MPDU in wait queue. */ - if (queue_index != BEACON_QUEUE) { - /* Don't send data frame during scanning.*/ - if ((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0) && - (!(priv->ieee80211->queue_stop))) { - skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index])); - if (skb) - priv->ieee80211->softmac_hard_start_xmit(skb, - dev); - - return; /* avoid further processing AMSDU */ - } - } -} - -static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_network *net; - u8 i = 0, basic_rate = 0; - - net = &priv->ieee80211->current_network; - - for (i = 0; i < net->rates_len; i++) { - basic_rate = net->rates[i] & 0x7f; - switch (basic_rate) { - case MGN_1M: - *rate_config |= RRSR_1M; - break; - case MGN_2M: - *rate_config |= RRSR_2M; - break; - case MGN_5_5M: - *rate_config |= RRSR_5_5M; - break; - case MGN_11M: - *rate_config |= RRSR_11M; - break; - case MGN_6M: - *rate_config |= RRSR_6M; - break; - case MGN_9M: - *rate_config |= RRSR_9M; - break; - case MGN_12M: - *rate_config |= RRSR_12M; - break; - case MGN_18M: - *rate_config |= RRSR_18M; - break; - case MGN_24M: - *rate_config |= RRSR_24M; - break; - case MGN_36M: - *rate_config |= RRSR_36M; - break; - case MGN_48M: - *rate_config |= RRSR_48M; - break; - case MGN_54M: - *rate_config |= RRSR_54M; - break; - } - } - for (i = 0; i < net->rates_ex_len; i++) { - basic_rate = net->rates_ex[i] & 0x7f; - switch (basic_rate) { - case MGN_1M: - *rate_config |= RRSR_1M; - break; - case MGN_2M: - *rate_config |= RRSR_2M; - break; - case MGN_5_5M: - *rate_config |= RRSR_5_5M; - break; - case MGN_11M: - *rate_config |= RRSR_11M; - break; - case MGN_6M: - *rate_config |= RRSR_6M; - break; - case MGN_9M: - *rate_config |= RRSR_9M; - break; - case MGN_12M: - *rate_config |= RRSR_12M; - break; - case MGN_18M: - *rate_config |= RRSR_18M; - break; - case MGN_24M: - *rate_config |= RRSR_24M; - break; - case MGN_36M: - *rate_config |= RRSR_36M; - break; - case MGN_48M: - *rate_config |= RRSR_48M; - break; - case MGN_54M: - *rate_config |= RRSR_54M; - break; - } - } -} - -#define SHORT_SLOT_TIME 9 -#define NON_SHORT_SLOT_TIME 20 - -static void rtl8192_update_cap(struct net_device *dev, u16 cap) -{ - u32 tmp = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_network *net = &priv->ieee80211->current_network; - - priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE; - tmp = priv->basic_rate; - if (priv->short_preamble) - tmp |= BRSR_AckShortPmb; - write_nic_dword(dev, RRSR, tmp); - - if (net->mode & (IEEE_G | IEEE_N_24G)) { - u8 slot_time = 0; - - if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && - (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) - /* short slot time */ - slot_time = SHORT_SLOT_TIME; - else /* long slot time */ - slot_time = NON_SHORT_SLOT_TIME; - priv->slot_time = slot_time; - write_nic_byte(dev, SLOT_TIME, slot_time); - } -} - -static void rtl8192_net_update(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_network *net; - u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; - u16 rate_config = 0; - - net = &priv->ieee80211->current_network; - - rtl8192_config_rate(dev, &rate_config); - priv->basic_rate = rate_config & 0x15f; - - write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]); - write_nic_word(dev, BSSIDR + 4, ((u16 *)net->bssid)[2]); - - rtl8192_update_msr(dev); - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { - write_nic_word(dev, ATIMWND, 2); - write_nic_word(dev, BCN_DMATIME, 1023); - write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); - write_nic_word(dev, BCN_DRV_EARLY_INT, 1); - write_nic_byte(dev, BCN_ERR_THRESH, 100); - BcnTimeCfg |= (BcnCW << BCN_TCFG_CW_SHIFT); - /* TODO: BcnIFS may required to be changed on ASIC */ - BcnTimeCfg |= BcnIFS << BCN_TCFG_IFS; - - write_nic_word(dev, BCN_TCFG, BcnTimeCfg); - } -} - -/* temporary hw beacon is not used any more. - * open it when necessary - */ -void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate) -{ -} - -short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int status; - struct urb *tx_urb; - unsigned int idx_pipe; - struct tx_desc_cmd_819x_usb *pdesc = (struct tx_desc_cmd_819x_usb *)skb->data; - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - atomic_inc(&priv->tx_pending[queue_index]); - tx_urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!tx_urb) { - dev_kfree_skb(skb); - return -ENOMEM; - } - - memset(pdesc, 0, USB_HWDESC_HEADER_LEN); - /* Tx descriptor ought to be set according to the skb->cb */ - pdesc->FirstSeg = 1; - pdesc->LastSeg = 1; - pdesc->CmdInit = tcb_desc->bCmdOrInit; - pdesc->TxBufferSize = tcb_desc->txbuf_size; - pdesc->OWN = 1; - pdesc->LINIP = tcb_desc->bLastIniPkt; - - /*--------------------------------------------------------------------- - * Fill up USB_OUT_CONTEXT. - *--------------------------------------------------------------------- - */ - idx_pipe = 0x04; - usb_fill_bulk_urb(tx_urb, priv->udev, - usb_sndbulkpipe(priv->udev, idx_pipe), - skb->data, skb->len, rtl8192_tx_isr, skb); - - status = usb_submit_urb(tx_urb, GFP_ATOMIC); - - if (!status) - return 0; - - DMESGE("Error TX CMD URB, error %d", status); - dev_kfree_skb(skb); - usb_free_urb(tx_urb); - return -1; -} - -/* - * Mapping Software/Hardware descriptor queue id to "Queue Select Field" - * in TxFwInfo data structure - * 2006.10.30 by Emily - * - * \param QUEUEID Software Queue - */ -static u8 MapHwQueueToFirmwareQueue(u8 QueueID) -{ - u8 QueueSelect = 0x0; /* default set to */ - - switch (QueueID) { - case BE_QUEUE: - QueueSelect = QSLT_BE; - break; - - case BK_QUEUE: - QueueSelect = QSLT_BK; - break; - - case VO_QUEUE: - QueueSelect = QSLT_VO; - break; - - case VI_QUEUE: - QueueSelect = QSLT_VI; - break; - case MGNT_QUEUE: - QueueSelect = QSLT_MGNT; - break; - - case BEACON_QUEUE: - QueueSelect = QSLT_BEACON; - break; - - /* TODO: mark other queue selection until we verify it is OK */ - /* TODO: Remove Assertions */ - case TXCMD_QUEUE: - QueueSelect = QSLT_CMD; - break; - case HIGH_QUEUE: - QueueSelect = QSLT_HIGH; - break; - - default: - RT_TRACE(COMP_ERR, - "TransmitTCB(): Impossible Queue Selection: %d\n", - QueueID); - break; - } - return QueueSelect; -} - -static u8 MRateToHwRate8190Pci(u8 rate) -{ - u8 ret = DESC90_RATE1M; - - switch (rate) { - case MGN_1M: - ret = DESC90_RATE1M; - break; - case MGN_2M: - ret = DESC90_RATE2M; - break; - case MGN_5_5M: - ret = DESC90_RATE5_5M; - break; - case MGN_11M: - ret = DESC90_RATE11M; - break; - case MGN_6M: - ret = DESC90_RATE6M; - break; - case MGN_9M: - ret = DESC90_RATE9M; - break; - case MGN_12M: - ret = DESC90_RATE12M; - break; - case MGN_18M: - ret = DESC90_RATE18M; - break; - case MGN_24M: - ret = DESC90_RATE24M; - break; - case MGN_36M: - ret = DESC90_RATE36M; - break; - case MGN_48M: - ret = DESC90_RATE48M; - break; - case MGN_54M: - ret = DESC90_RATE54M; - break; - - /* HT rate since here */ - case MGN_MCS0: - ret = DESC90_RATEMCS0; - break; - case MGN_MCS1: - ret = DESC90_RATEMCS1; - break; - case MGN_MCS2: - ret = DESC90_RATEMCS2; - break; - case MGN_MCS3: - ret = DESC90_RATEMCS3; - break; - case MGN_MCS4: - ret = DESC90_RATEMCS4; - break; - case MGN_MCS5: - ret = DESC90_RATEMCS5; - break; - case MGN_MCS6: - ret = DESC90_RATEMCS6; - break; - case MGN_MCS7: - ret = DESC90_RATEMCS7; - break; - case MGN_MCS8: - ret = DESC90_RATEMCS8; - break; - case MGN_MCS9: - ret = DESC90_RATEMCS9; - break; - case MGN_MCS10: - ret = DESC90_RATEMCS10; - break; - case MGN_MCS11: - ret = DESC90_RATEMCS11; - break; - case MGN_MCS12: - ret = DESC90_RATEMCS12; - break; - case MGN_MCS13: - ret = DESC90_RATEMCS13; - break; - case MGN_MCS14: - ret = DESC90_RATEMCS14; - break; - case MGN_MCS15: - ret = DESC90_RATEMCS15; - break; - case (0x80 | 0x20): - ret = DESC90_RATEMCS32; - break; - - default: - break; - } - return ret; -} - -static u8 QueryIsShort(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc) -{ - u8 tmp_Short; - - tmp_Short = (TxHT == 1) ? - ((tcb_desc->bUseShortGI) ? 1 : 0) : - ((tcb_desc->bUseShortPreamble) ? 1 : 0); - - if (TxHT == 1 && TxRate != DESC90_RATEMCS15) - tmp_Short = 0; - - return tmp_Short; -} - -static void tx_zero_isr(struct urb *tx_urb) -{ -} - -/* - * The tx procedure is just as following, - * skb->cb will contain all the following information, - * priority, morefrag, rate, &dev. - */ -short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - struct tx_desc_819x_usb *tx_desc = (struct tx_desc_819x_usb *)skb->data; - struct tx_fwinfo_819x_usb *tx_fwinfo = - (struct tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN); - struct usb_device *udev = priv->udev; - int pend; - int status, rt = -1; - struct urb *tx_urb = NULL, *tx_urb_zero = NULL; - unsigned int idx_pipe; - - pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]); - /* we are locked here so the two atomic_read and inc are executed - * without interleaves - * !!! For debug purpose - */ - if (pend > MAX_TX_URB) { - netdev_dbg(dev, "To discard skb packet!\n"); - dev_kfree_skb_any(skb); - return -1; - } - - tx_urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!tx_urb) { - dev_kfree_skb_any(skb); - return -ENOMEM; - } - - /* Fill Tx firmware info */ - memset(tx_fwinfo, 0, sizeof(struct tx_fwinfo_819x_usb)); - /* DWORD 0 */ - tx_fwinfo->TxHT = (tcb_desc->data_rate & 0x80) ? 1 : 0; - tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate); - tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur; - tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, - tcb_desc); - if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */ - tx_fwinfo->AllowAggregation = 1; - /* DWORD 1 */ - tx_fwinfo->RxMF = tcb_desc->ampdu_factor; - tx_fwinfo->RxAMD = tcb_desc->ampdu_density & 0x07; - } else { - tx_fwinfo->AllowAggregation = 0; - /* DWORD 1 */ - tx_fwinfo->RxMF = 0; - tx_fwinfo->RxAMD = 0; - } - - /* Protection mode related */ - tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0; - tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0; - tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0; - tx_fwinfo->RtsHT = (tcb_desc->rts_rate & 0x80) ? 1 : 0; - tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate); - tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0; - tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0; - tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) : - (tcb_desc->bRTSUseShortGI ? 1 : 0); - - /* Set Bandwidth and sub-channel settings. */ - if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) { - if (tcb_desc->bPacketBW) { - tx_fwinfo->TxBandwidth = 1; - /* use duplicated mode */ - tx_fwinfo->TxSubCarrier = 0; - } else { - tx_fwinfo->TxBandwidth = 0; - tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC; - } - } else { - tx_fwinfo->TxBandwidth = 0; - tx_fwinfo->TxSubCarrier = 0; - } - - /* Fill Tx descriptor */ - memset(tx_desc, 0, sizeof(struct tx_desc_819x_usb)); - /* DWORD 0 */ - tx_desc->LINIP = 0; - tx_desc->CmdInit = 1; - tx_desc->Offset = sizeof(struct tx_fwinfo_819x_usb) + 8; - tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff; - - /*DWORD 1*/ - tx_desc->SecCAMID = 0; - tx_desc->RATid = tcb_desc->RATRIndex; - tx_desc->NoEnc = 1; - tx_desc->SecType = 0x0; - if (tcb_desc->bHwSec) { - switch (priv->ieee80211->pairwise_key_type) { - case KEY_TYPE_WEP40: - case KEY_TYPE_WEP104: - tx_desc->SecType = 0x1; - tx_desc->NoEnc = 0; - break; - case KEY_TYPE_TKIP: - tx_desc->SecType = 0x2; - tx_desc->NoEnc = 0; - break; - case KEY_TYPE_CCMP: - tx_desc->SecType = 0x3; - tx_desc->NoEnc = 0; - break; - case KEY_TYPE_NA: - tx_desc->SecType = 0x0; - tx_desc->NoEnc = 1; - break; - } - } - - tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index); - tx_desc->TxFWInfoSize = sizeof(struct tx_fwinfo_819x_usb); - - tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack; - tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate; - - /* Fill fields that are required to be initialized in - * all of the descriptors - */ - /* DWORD 0 */ - tx_desc->FirstSeg = 1; - tx_desc->LastSeg = 1; - tx_desc->OWN = 1; - - /* DWORD 2 */ - tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN); - idx_pipe = 0x5; - - /* To submit bulk urb */ - usb_fill_bulk_urb(tx_urb, udev, - usb_sndbulkpipe(udev, idx_pipe), skb->data, - skb->len, rtl8192_tx_isr, skb); - - status = usb_submit_urb(tx_urb, GFP_ATOMIC); - if (!status) { - /* We need to send 0 byte packet whenever - * 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has - * been transmitted. Otherwise, it will be halt to wait for - * another packet. - */ - bool bSend0Byte = false; - u8 zero = 0; - - if (udev->speed == USB_SPEED_HIGH) { - if (skb->len > 0 && skb->len % 512 == 0) - bSend0Byte = true; - } else { - if (skb->len > 0 && skb->len % 64 == 0) - bSend0Byte = true; - } - if (bSend0Byte) { - tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC); - if (!tx_urb_zero) { - rt = -ENOMEM; - goto error; - } - usb_fill_bulk_urb(tx_urb_zero, udev, - usb_sndbulkpipe(udev, idx_pipe), - &zero, 0, tx_zero_isr, dev); - status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC); - if (status) { - RT_TRACE(COMP_ERR, - "Error TX URB for zero byte %d, error %d", - atomic_read(&priv->tx_pending[tcb_desc->queue_index]), - status); - goto error; - } - } - netif_trans_update(dev); - atomic_inc(&priv->tx_pending[tcb_desc->queue_index]); - return 0; - } - - RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", - atomic_read(&priv->tx_pending[tcb_desc->queue_index]), - status); - -error: - dev_kfree_skb_any(skb); - usb_free_urb(tx_urb); - usb_free_urb(tx_urb_zero); - return rt; -} - -static short rtl8192_usb_initendpoints(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->rx_urb = kmalloc_array(MAX_RX_URB + 1, sizeof(struct urb *), - GFP_KERNEL); - if (!priv->rx_urb) - return -ENOMEM; - -#ifndef JACKSON_NEW_RX - for (i = 0; i < (MAX_RX_URB + 1); i++) { - priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->rx_urb[i]) - return -ENOMEM; - - priv->rx_urb[i]->transfer_buffer = - kmalloc(RX_URB_SIZE, GFP_KERNEL); - if (!priv->rx_urb[i]->transfer_buffer) - return -ENOMEM; - - priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE; - } -#endif - -#ifdef THOMAS_BEACON - { - long align = 0; - void *oldaddr, *newaddr; - - priv->rx_urb[16] = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->rx_urb[16]) - return -ENOMEM; - priv->oldaddr = kmalloc(16, GFP_KERNEL); - if (!priv->oldaddr) - return -ENOMEM; - oldaddr = priv->oldaddr; - align = ((long)oldaddr) & 3; - if (align) { - newaddr = oldaddr + 4 - align; - priv->rx_urb[16]->transfer_buffer_length = 16 - 4 + align; - } else { - newaddr = oldaddr; - priv->rx_urb[16]->transfer_buffer_length = 16; - } - priv->rx_urb[16]->transfer_buffer = newaddr; - } -#endif - - memset(priv->rx_urb, 0, sizeof(struct urb *) * MAX_RX_URB); - priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *), - GFP_KERNEL); - if (!priv->pp_rxskb) { - kfree(priv->rx_urb); - - priv->pp_rxskb = NULL; - priv->rx_urb = NULL; - - DMESGE("Endpoint Alloc Failure"); - return -ENOMEM; - } - - netdev_dbg(dev, "End of initendpoints\n"); - return 0; -} - -#ifdef THOMAS_BEACON -static void rtl8192_usb_deleteendpoints(struct net_device *dev) -{ - int i; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->rx_urb) { - for (i = 0; i < (MAX_RX_URB + 1); i++) { - usb_kill_urb(priv->rx_urb[i]); - usb_free_urb(priv->rx_urb[i]); - } - kfree(priv->rx_urb); - priv->rx_urb = NULL; - } - kfree(priv->oldaddr); - priv->oldaddr = NULL; - - kfree(priv->pp_rxskb); - priv->pp_rxskb = NULL; -} -#else -void rtl8192_usb_deleteendpoints(struct net_device *dev) -{ - int i; - struct r8192_priv *priv = ieee80211_priv(dev); - -#ifndef JACKSON_NEW_RX - - if (priv->rx_urb) { - for (i = 0; i < (MAX_RX_URB + 1); i++) { - usb_kill_urb(priv->rx_urb[i]); - kfree(priv->rx_urb[i]->transfer_buffer); - usb_free_urb(priv->rx_urb[i]); - } - kfree(priv->rx_urb); - priv->rx_urb = NULL; - } -#else - kfree(priv->rx_urb); - priv->rx_urb = NULL; - kfree(priv->oldaddr); - priv->oldaddr = NULL; - - kfree(priv->pp_rxskb); - priv->pp_rxskb = 0; - -#endif -} -#endif - -static void rtl8192_update_ratr_table(struct net_device *dev); -static void rtl8192_link_change(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - if (ieee->state == IEEE80211_LINKED) { - rtl8192_net_update(dev); - rtl8192_update_ratr_table(dev); - /* Add this as in pure N mode, wep encryption will use software - * way, but there is no chance to set this as wep will not set - * group key in wext. - */ - if (ieee->pairwise_key_type == KEY_TYPE_WEP40 || - ieee->pairwise_key_type == KEY_TYPE_WEP104) - EnableHWSecurityConfig8192(dev); - } - /*update timing params*/ - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { - u32 reg = 0; - - read_nic_dword(dev, RCR, ®); - if (priv->ieee80211->state == IEEE80211_LINKED) - priv->ReceiveConfig = reg |= RCR_CBSSID; - else - priv->ReceiveConfig = reg &= ~RCR_CBSSID; - write_nic_dword(dev, RCR, reg); - } -} - -static const struct ieee80211_qos_parameters def_qos_parameters = { - {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, - {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, - {2, 2, 2, 2},/* aifs */ - {0, 0, 0, 0},/* flags */ - {0, 0, 0, 0} /* tx_op_limit */ -}; - -static void rtl8192_update_beacon(struct work_struct *work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, - update_beacon_wq.work); - struct net_device *dev = priv->ieee80211->dev; - struct ieee80211_device *ieee = priv->ieee80211; - struct ieee80211_network *net = &ieee->current_network; - - if (ieee->pHTInfo->bCurrentHTSupport) - HTUpdateSelfAndPeerSetting(ieee, net); - ieee->pHTInfo->bCurrentRT2RTLongSlotTime = - net->bssht.bdRT2RTLongSlotTime; - rtl8192_update_cap(dev, net->capability); -} - -/* - * background support to run QoS activate functionality - */ -static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, - EDCAPARA_VI, EDCAPARA_VO}; -static void rtl8192_qos_activate(struct work_struct *work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, - qos_activate); - struct net_device *dev = priv->ieee80211->dev; - struct ieee80211_qos_parameters *qos_parameters = - &priv->ieee80211->current_network.qos_data.parameters; - u8 mode = priv->ieee80211->current_network.mode; - u32 u1bAIFS; - u32 u4bAcParam; - u32 op_limit; - u32 cw_max; - u32 cw_min; - int i; - - mutex_lock(&priv->mutex); - if (priv->ieee80211->state != IEEE80211_LINKED) - goto success; - RT_TRACE(COMP_QOS, - "qos active process with associate response received\n"); - /* It better set slot time at first - * - * For we just support b/g mode at present, let the slot time at - * 9/20 selection - * - * update the ac parameter to related registers - */ - for (i = 0; i < QOS_QUEUE_NUM; i++) { - /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ - u1bAIFS = qos_parameters->aifs[i] * ((mode & (IEEE_G | IEEE_N_24G)) ? 9 : 20) + aSifsTime; - u1bAIFS <<= AC_PARAM_AIFS_OFFSET; - op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[i]); - op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET; - cw_max = (u32)le16_to_cpu(qos_parameters->cw_max[i]); - cw_max <<= AC_PARAM_ECW_MAX_OFFSET; - cw_min = (u32)le16_to_cpu(qos_parameters->cw_min[i]); - cw_min <<= AC_PARAM_ECW_MIN_OFFSET; - u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS; - write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); - } - -success: - mutex_unlock(&priv->mutex); -} - -static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, - int active_network, - struct ieee80211_network *network) -{ - int ret = 0; - u32 size = sizeof(struct ieee80211_qos_parameters); - - if (priv->ieee80211->state != IEEE80211_LINKED) - return ret; - - if (priv->ieee80211->iw_mode != IW_MODE_INFRA) - return ret; - - if (network->flags & NETWORK_HAS_QOS_MASK) { - if (active_network && - (network->flags & NETWORK_HAS_QOS_PARAMETERS)) - network->qos_data.active = network->qos_data.supported; - - if ((network->qos_data.active == 1) && (active_network == 1) && - (network->flags & NETWORK_HAS_QOS_PARAMETERS) && - (network->qos_data.old_param_count != - network->qos_data.param_count)) { - network->qos_data.old_param_count = - network->qos_data.param_count; - schedule_work(&priv->qos_activate); - RT_TRACE(COMP_QOS, - "QoS parameters change call qos_activate\n"); - } - } else { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &def_qos_parameters, size); - - if ((network->qos_data.active == 1) && (active_network == 1)) { - schedule_work(&priv->qos_activate); - RT_TRACE(COMP_QOS, - "QoS was disabled call qos_activate\n"); - } - network->qos_data.active = 0; - network->qos_data.supported = 0; - } - - return 0; -} - -/* handle and manage frame from beacon and probe response */ -static int rtl8192_handle_beacon(struct net_device *dev, - struct ieee80211_beacon *beacon, - struct ieee80211_network *network) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - rtl8192_qos_handle_probe_response(priv, 1, network); - schedule_delayed_work(&priv->update_beacon_wq, 0); - return 0; -} - -/* - * handling the beaconing responses. if we get different QoS setting - * off the network from the associated setting, adjust the QoS - * setting - */ -static int rtl8192_qos_association_resp(struct r8192_priv *priv, - struct ieee80211_network *network) -{ - unsigned long flags; - u32 size = sizeof(struct ieee80211_qos_parameters); - int set_qos_param = 0; - - if (!priv || !network) - return 0; - - if (priv->ieee80211->state != IEEE80211_LINKED) - return 0; - - if (priv->ieee80211->iw_mode != IW_MODE_INFRA) - return 0; - - spin_lock_irqsave(&priv->ieee80211->lock, flags); - if (network->flags & NETWORK_HAS_QOS_PARAMETERS) { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &network->qos_data.parameters, - sizeof(struct ieee80211_qos_parameters)); - priv->ieee80211->current_network.qos_data.active = 1; - set_qos_param = 1; - /* update qos parameter for current network */ - priv->ieee80211->current_network.qos_data.old_param_count = - priv->ieee80211->current_network.qos_data.param_count; - priv->ieee80211->current_network.qos_data.param_count = - network->qos_data.param_count; - } else { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &def_qos_parameters, size); - priv->ieee80211->current_network.qos_data.active = 0; - priv->ieee80211->current_network.qos_data.supported = 0; - set_qos_param = 1; - } - - spin_unlock_irqrestore(&priv->ieee80211->lock, flags); - - RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, - network->flags, - priv->ieee80211->current_network.qos_data.active); - if (set_qos_param == 1) - schedule_work(&priv->qos_activate); - - return 0; -} - -static int rtl8192_handle_assoc_response(struct net_device *dev, - struct ieee80211_assoc_response_frame *resp, - struct ieee80211_network *network) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - rtl8192_qos_association_resp(priv, network); - return 0; -} - -static void rtl8192_update_ratr_table(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - u8 *pMcsRate = ieee->dot11HTOperationalRateSet; - u32 ratr_value = 0; - u8 rate_index = 0; - - rtl8192_config_rate(dev, (u16 *)(&ratr_value)); - ratr_value |= (*(u16 *)(pMcsRate)) << 12; - switch (ieee->mode) { - case IEEE_A: - ratr_value &= 0x00000FF0; - break; - case IEEE_B: - ratr_value &= 0x0000000F; - break; - case IEEE_G: - ratr_value &= 0x00000FF7; - break; - case IEEE_N_24G: - case IEEE_N_5G: - if (ieee->pHTInfo->PeerMimoPs == MIMO_PS_STATIC) { - ratr_value &= 0x0007F007; - } else { - if (priv->rf_type == RF_1T2R) - ratr_value &= 0x000FF007; - else - ratr_value &= 0x0F81F007; - } - break; - default: - break; - } - ratr_value &= 0x0FFFFFFF; - if (ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) - ratr_value |= 0x80000000; - else if (!ieee->pHTInfo->bCurTxBW40MHz && - ieee->pHTInfo->bCurShortGI20MHz) - ratr_value |= 0x80000000; - write_nic_dword(dev, RATR0 + rate_index * 4, ratr_value); - write_nic_byte(dev, UFWP, 1); -} - -static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04}; -static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; -static bool GetNmodeSupportBySecCfg8192(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - struct ieee80211_network *network = &ieee->current_network; - int wpa_ie_len = ieee->wpa_ie_len; - struct ieee80211_crypt_data *crypt; - int encrypt; - - crypt = ieee->crypt[ieee->tx_keyidx]; - /* we use connecting AP's capability instead of only security config - * on our driver to distinguish whether it should use N mode or G mode - */ - encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || - (ieee->host_encrypt && crypt && crypt->ops && - (strcmp(crypt->ops->name, "WEP") == 0)); - - /* simply judge */ - if (encrypt && (wpa_ie_len == 0)) { - /* wep encryption, no N mode setting */ - return false; - } else if ((wpa_ie_len != 0)) { - /* parse pairwise key type */ - if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]), ccmp_ie, 4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4)))) - return true; - else - return false; - } else { - return true; - } - - return true; -} - -static bool GetHalfNmodeSupportByAPs819xUsb(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return priv->ieee80211->bHalfWirelessN24GMode; -} - -static void rtl8192_refresh_supportrate(struct r8192_priv *priv) -{ - struct ieee80211_device *ieee = priv->ieee80211; - /* We do not consider set support rate for ABG mode, only - * HT MCS rate is set here. - */ - if (ieee->mode == WIRELESS_MODE_N_24G || - ieee->mode == WIRELESS_MODE_N_5G) - memcpy(ieee->Regdot11HTOperationalRateSet, - ieee->RegHTSuppRateSet, 16); - else - memset(ieee->Regdot11HTOperationalRateSet, 0, 16); -} - -static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 ret = 0; - - switch (priv->rf_chip) { - case RF_8225: - case RF_8256: - case RF_PSEUDO_11N: - ret = WIRELESS_MODE_N_24G | WIRELESS_MODE_G | WIRELESS_MODE_B; - break; - case RF_8258: - ret = WIRELESS_MODE_A | WIRELESS_MODE_N_5G; - break; - default: - ret = WIRELESS_MODE_B; - break; - } - return ret; -} - -static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev); - - if (wireless_mode == WIRELESS_MODE_AUTO || - (wireless_mode & bSupportMode) == 0) { - if (bSupportMode & WIRELESS_MODE_N_24G) { - wireless_mode = WIRELESS_MODE_N_24G; - } else if (bSupportMode & WIRELESS_MODE_N_5G) { - wireless_mode = WIRELESS_MODE_N_5G; - } else if ((bSupportMode & WIRELESS_MODE_A)) { - wireless_mode = WIRELESS_MODE_A; - } else if ((bSupportMode & WIRELESS_MODE_G)) { - wireless_mode = WIRELESS_MODE_G; - } else if ((bSupportMode & WIRELESS_MODE_B)) { - wireless_mode = WIRELESS_MODE_B; - } else { - RT_TRACE(COMP_ERR, - "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", - __func__, bSupportMode); - wireless_mode = WIRELESS_MODE_B; - } - } - priv->ieee80211->mode = wireless_mode; - - if (wireless_mode == WIRELESS_MODE_N_24G || - wireless_mode == WIRELESS_MODE_N_5G) - priv->ieee80211->pHTInfo->bEnableHT = 1; - else - priv->ieee80211->pHTInfo->bEnableHT = 0; - RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); - rtl8192_refresh_supportrate(priv); -} - -/* init priv variables here. only non_zero value should be initialized here. */ -static int rtl8192_init_priv_variable(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 i; - - priv->card_8192 = NIC_8192U; - priv->chan = 1; /* set to channel 1 */ - priv->ieee80211->mode = WIRELESS_MODE_AUTO; /* SET AUTO */ - priv->ieee80211->iw_mode = IW_MODE_INFRA; - priv->ieee80211->ieee_up = 0; - priv->retry_rts = DEFAULT_RETRY_RTS; - priv->retry_data = DEFAULT_RETRY_DATA; - priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD; - priv->ieee80211->rate = 110; /* 11 mbps */ - priv->ieee80211->short_slot = 1; - priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - priv->CckPwEnl = 6; - /* for silent reset */ - priv->IrpPendingCount = 1; - priv->ResetProgress = RESET_TYPE_NORESET; - priv->bForcedSilentReset = false; - priv->bDisableNormalResetCheck = false; - priv->force_reset = false; - - /* we don't use FW read/write RF until stable firmware is available. */ - priv->ieee80211->FwRWRF = 0; - priv->ieee80211->current_network.beacon_interval = - DEFAULT_BEACONINTERVAL; - priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN | - IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | - IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE | - IEEE_SOFTMAC_BEACONS; - - priv->ieee80211->active_scan = 1; - priv->ieee80211->modulation = - IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; - priv->ieee80211->host_encrypt = 1; - priv->ieee80211->host_decrypt = 1; - priv->ieee80211->start_send_beacons = NULL; - priv->ieee80211->stop_send_beacons = NULL; - priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit; - priv->ieee80211->set_chan = rtl8192_set_chan; - priv->ieee80211->link_change = rtl8192_link_change; - priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit; - priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop; - priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume; - priv->ieee80211->init_wmmparam_flag = 0; - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc; - priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES; - priv->ieee80211->qos_support = 1; - - priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode; - priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response; - priv->ieee80211->handle_beacon = rtl8192_handle_beacon; - - priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192; - priv->ieee80211->GetHalfNmodeSupportByAPsHandler = - GetHalfNmodeSupportByAPs819xUsb; - priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode; - - priv->ieee80211->InitialGainHandler = InitialGain819xUsb; - priv->card_type = USB; - priv->ShortRetryLimit = 0x30; - priv->LongRetryLimit = 0x30; - priv->EarlyRxThreshold = 7; - priv->enable_gpio0 = 0; - priv->TransmitConfig = - /* Max DMA Burst Size per Tx DMA Burst, 7: reserved. */ - (TCR_MXDMA_2048 << TCR_MXDMA_OFFSET) | - /* Short retry limit */ - (priv->ShortRetryLimit << TCR_SRL_OFFSET) | - /* Long retry limit */ - (priv->LongRetryLimit << TCR_LRL_OFFSET) | - /* FALSE: HW provides PLCP length and LENGEXT - * TRUE: SW provides them - */ - (false ? TCR_SAT : 0); - priv->ReceiveConfig = - /* accept management/data */ - RCR_AMF | RCR_ADF | - /* accept control frame for SW AP needs PS-poll */ - RCR_ACF | - /* accept BC/MC/UC */ - RCR_AB | RCR_AM | RCR_APM | - /* Max DMA Burst Size per Rx DMA Burst, 7: unlimited. */ - ((u32)7 << RCR_MXDMA_OFFSET) | - /* Rx FIFO Threshold, 7: No Rx threshold. */ - (priv->EarlyRxThreshold << RX_FIFO_THRESHOLD_SHIFT) | - (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT : 0); - - priv->AcmControl = 0; - priv->pFirmware = kzalloc(sizeof(rt_firmware), GFP_KERNEL); - if (!priv->pFirmware) - return -ENOMEM; - - /* rx related queue */ - skb_queue_head_init(&priv->rx_queue); - skb_queue_head_init(&priv->skb_queue); - - /* Tx related queue */ - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_head_init(&priv->ieee80211->skb_waitQ[i]); - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_head_init(&priv->ieee80211->skb_aggQ[i]); - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ[i]); - priv->rf_set_chan = rtl8192_phy_SwChnl; - - return 0; -} - -/* init lock here */ -static void rtl8192_init_priv_lock(struct r8192_priv *priv) -{ - spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->irq_lock); - mutex_init(&priv->wx_mutex); - mutex_init(&priv->mutex); -} - -static void rtl819x_watchdog_wqcallback(struct work_struct *work); - -static void rtl8192_irq_rx_tasklet(struct tasklet_struct *t); -/* init tasklet and wait_queue here. only 2.6 above kernel is considered */ -#define DRV_NAME "wlan0" -static void rtl8192_init_priv_task(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - INIT_WORK(&priv->reset_wq, rtl8192_restart); - - INIT_DELAYED_WORK(&priv->watch_dog_wq, - rtl819x_watchdog_wqcallback); - INIT_DELAYED_WORK(&priv->txpower_tracking_wq, - dm_txpower_trackingcallback); - INIT_DELAYED_WORK(&priv->rfpath_check_wq, - dm_rf_pathcheck_workitemcallback); - INIT_DELAYED_WORK(&priv->update_beacon_wq, - rtl8192_update_beacon); - INIT_DELAYED_WORK(&priv->initialgain_operate_wq, - InitialGainOperateWorkItemCallBack); - INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); - - tasklet_setup(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet); -} - -static void rtl8192_get_eeprom_size(struct net_device *dev) -{ - u16 curCR = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__); - read_nic_word_E(dev, EPROM_CMD, &curCR); - RT_TRACE(COMP_EPROM, - "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR); - /* whether need I consider BIT(5?) */ - priv->epromtype = - (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46; - RT_TRACE(COMP_EPROM, - "<===========%s(), epromtype:%d\n", __func__, priv->epromtype); -} - -/* used to swap endian. as ntohl & htonl are not necessary - * to swap endian, so use this instead. - */ -static inline u16 endian_swap(u16 *data) -{ - u16 tmp = *data; - *data = (tmp >> 8) | (tmp << 8); - return *data; -} - -static int rtl8192_read_eeprom_info(struct net_device *dev) -{ - u16 wEPROM_ID = 0; - u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02}; - u8 bLoad_From_EEPOM = false; - struct r8192_priv *priv = ieee80211_priv(dev); - u16 tmpValue = 0; - int i; - int ret; - - RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__); - ret = eprom_read(dev, 0); /* first read EEPROM ID out; */ - if (ret < 0) - return ret; - wEPROM_ID = (u16)ret; - RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID); - - if (wEPROM_ID != RTL8190_EEPROM_ID) - RT_TRACE(COMP_ERR, - "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", - wEPROM_ID, RTL8190_EEPROM_ID); - else - bLoad_From_EEPOM = true; - - if (bLoad_From_EEPOM) { - tmpValue = eprom_read(dev, EEPROM_VID >> 1); - ret = eprom_read(dev, EEPROM_VID >> 1); - if (ret < 0) - return ret; - tmpValue = (u16)ret; - priv->eeprom_vid = endian_swap(&tmpValue); - ret = eprom_read(dev, EEPROM_PID >> 1); - if (ret < 0) - return ret; - priv->eeprom_pid = (u16)ret; - ret = eprom_read(dev, EEPROM_CHANNEL_PLAN >> 1); - if (ret < 0) - return ret; - tmpValue = (u16)ret; - priv->eeprom_ChannelPlan = (tmpValue & 0xff00) >> 8; - priv->btxpowerdata_readfromEEPORM = true; - ret = eprom_read(dev, (EEPROM_CUSTOMER_ID >> 1)) >> 8; - if (ret < 0) - return ret; - priv->eeprom_CustomerID = (u16)ret; - } else { - priv->eeprom_vid = 0; - priv->eeprom_pid = 0; - priv->card_8192_version = VERSION_819XU_B; - priv->eeprom_ChannelPlan = 0; - priv->eeprom_CustomerID = 0; - } - RT_TRACE(COMP_EPROM, - "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", - priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, - priv->eeprom_ChannelPlan); - /* set channelplan from eeprom */ - priv->ChannelPlan = priv->eeprom_ChannelPlan; - if (bLoad_From_EEPOM) { - u8 addr[ETH_ALEN]; - - for (i = 0; i < 6; i += 2) { - ret = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1)); - if (ret < 0) - return ret; - *(u16 *)(&addr[i]) = (u16)ret; - } - eth_hw_addr_set(dev, addr); - } else { - eth_hw_addr_set(dev, bMac_Tmp_Addr); - /* should I set IDR0 here? */ - } - RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr); - priv->rf_type = RTL819X_DEFAULT_RF_TYPE; /* default 1T2R */ - priv->rf_chip = RF_8256; - - if (priv->card_8192_version == VERSION_819XU_A) { - /* read Tx power gain offset of legacy OFDM to HT rate */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_TX_POWER_DIFF >> 1)); - if (ret < 0) - return ret; - priv->EEPROMTxPowerDiff = ((u16)ret & 0xff00) >> 8; - } else - priv->EEPROMTxPowerDiff = EEPROM_DEFAULT_TX_POWER; - RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff); - /* read ThermalMeter from EEPROM */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_THERMAL_METER >> 1)); - if (ret < 0) - return ret; - priv->EEPROMThermalMeter = (u8)((u16)ret & 0x00ff); - } else - priv->EEPROMThermalMeter = EEPROM_DEFAULT_THERNAL_METER; - RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter); - /* for tx power track */ - priv->TSSI_13dBm = priv->EEPROMThermalMeter * 100; - /* read antenna tx power offset of B/C/D to A from EEPROM */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_PW_DIFF >> 1)); - if (ret < 0) - return ret; - priv->EEPROMPwDiff = ((u16)ret & 0x0f00) >> 8; - } else - priv->EEPROMPwDiff = EEPROM_DEFAULT_PW_DIFF; - RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff); - /* Read CrystalCap from EEPROM */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_CRYSTAL_CAP >> 1)); - if (ret < 0) - return ret; - priv->EEPROMCrystalCap = (u16)ret & 0x0f; - } else - priv->EEPROMCrystalCap = EEPROM_DEFAULT_CRYSTAL_CAP; - RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap); - /* get per-channel Tx power level */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_VER >> 1)); - if (ret < 0) - return ret; - priv->EEPROM_Def_Ver = ((u16)ret & 0xff00) >> 8; - } else - priv->EEPROM_Def_Ver = 1; - RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver); - if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */ - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_CCK >> 1)); - if (ret < 0) - return ret; - priv->EEPROMTxPowerLevelCCK = ((u16)ret & 0xff00) >> 8; - } else - priv->EEPROMTxPowerLevelCCK = 0x10; - RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK); - for (i = 0; i < 3; i++) { - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_OFDM_24G + i) >> 1); - if (ret < 0) - return ret; - if (((EEPROM_TX_PW_INDEX_OFDM_24G + i) % 2) == 0) - tmpValue = (u16)ret & 0x00ff; - else - tmpValue = ((u16)ret & 0xff00) >> 8; - } else { - tmpValue = 0x10; - } - priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)tmpValue; - RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK); - } - } else if (priv->EEPROM_Def_Ver == 1) { - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, EEPROM_TX_PW_INDEX_CCK_V1 >> 1); - if (ret < 0) - return ret; - tmpValue = ((u16)ret & 0xff00) >> 8; - } else { - tmpValue = 0x10; - } - priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue; - - if (bLoad_From_EEPOM) { - ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_CCK_V1 + 2) >> 1); - if (ret < 0) - return ret; - tmpValue = (u16)ret; - } else - tmpValue = 0x1010; - *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue; - if (bLoad_From_EEPOM) - tmpValue = eprom_read(dev, - EEPROM_TX_PW_INDEX_OFDM_24G_V1 >> 1); - else - tmpValue = 0x1010; - *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue; - if (bLoad_From_EEPOM) - tmpValue = eprom_read(dev, (EEPROM_TX_PW_INDEX_OFDM_24G_V1 + 2) >> 1); - else - tmpValue = 0x10; - priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue; - } /* endif EEPROM_Def_Ver == 1 */ - - /* update HAL variables */ - for (i = 0; i < 14; i++) { - if (i <= 3) - priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0]; - else if (i >= 4 && i <= 9) - priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1]; - else - priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2]; - } - - for (i = 0; i < 14; i++) { - if (priv->EEPROM_Def_Ver == 0) { - if (i <= 3) - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]); - else if (i >= 4 && i <= 9) - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK; - else - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]); - } else if (priv->EEPROM_Def_Ver == 1) { - if (i <= 3) - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0]; - else if (i >= 4 && i <= 9) - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1]; - else - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2]; - } - } - priv->TxPowerDiff = priv->EEPROMPwDiff; - /* Antenna B gain offset to antenna A, bit0~3 */ - priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf); - /* Antenna C gain offset to antenna A, bit4~7 */ - priv->AntennaTxPwDiff[1] = - (priv->EEPROMTxPowerDiff & 0xf0) >> 4; - /* CrystalCap, bit12~15 */ - priv->CrystalCap = priv->EEPROMCrystalCap; - /* ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 - * 92U does not enable TX power tracking. - */ - priv->ThermalMeter[0] = priv->EEPROMThermalMeter; - } /* end if VersionID == VERSION_819XU_A */ - - /* for dlink led */ - switch (priv->eeprom_CustomerID) { - case EEPROM_CID_RUNTOP: - priv->CustomerID = RT_CID_819x_RUNTOP; - break; - - case EEPROM_CID_DLINK: - priv->CustomerID = RT_CID_DLINK; - break; - - default: - priv->CustomerID = RT_CID_DEFAULT; - break; - } - - switch (priv->CustomerID) { - case RT_CID_819x_RUNTOP: - priv->LedStrategy = SW_LED_MODE2; - break; - - case RT_CID_DLINK: - priv->LedStrategy = SW_LED_MODE4; - break; - - default: - priv->LedStrategy = SW_LED_MODE0; - break; - } - - if (priv->rf_type == RF_1T2R) - RT_TRACE(COMP_EPROM, "\n1T2R config\n"); - else - RT_TRACE(COMP_EPROM, "\n2T4R config\n"); - - /* We can only know RF type in the function. So we have to init - * DIG RATR table again. - */ - init_rate_adaptive(dev); - - RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__); - - return 0; -} - -static short rtl8192_get_channel_map(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN) { - netdev_err(dev, - "rtl8180_init: Error channel plan! Set to default.\n"); - priv->ChannelPlan = 0; - } - RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan); - - rtl819x_set_channel_map(priv->ChannelPlan, priv); - return 0; -} - -static short rtl8192_init(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int err; - - memset(&(priv->stats), 0, sizeof(struct Stats)); - memset(priv->txqueue_to_outpipemap, 0, 9); -#ifdef PIPE12 - { - int i = 0; - static const u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5}; - - memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9); - } -#else - { - static const u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 0, 4, 4}; - - memcpy(priv->txqueue_to_outpipemap, queuetopipe, 9); - } -#endif - err = rtl8192_init_priv_variable(dev); - if (err) - return err; - - rtl8192_init_priv_lock(priv); - rtl8192_init_priv_task(dev); - rtl8192_get_eeprom_size(dev); - err = rtl8192_read_eeprom_info(dev); - if (err) { - DMESG("Reading EEPROM info failed"); - return err; - } - rtl8192_get_channel_map(dev); - init_hal_dm(dev); - timer_setup(&priv->watch_dog_timer, watch_dog_timer_callback, 0); - if (rtl8192_usb_initendpoints(dev) != 0) { - DMESG("Endopoints initialization failed"); - return -ENOMEM; - } - - return 0; -} - -/****************************************************************************** - *function: This function actually only set RRSR, RATR and BW_OPMODE registers - * not to do all the hw config as its name says - * input: net_device dev - * output: none - * return: none - * notice: This part need to modified according to the rate set we filtered - * ****************************************************************************/ -static void rtl8192_hwconfig(struct net_device *dev) -{ - u32 regRATR = 0, regRRSR = 0; - u8 regBwOpMode = 0, regTmp = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - u32 ratr_value = 0; - - /* Set RRSR, RATR, and BW_OPMODE registers */ - switch (priv->ieee80211->mode) { - case WIRELESS_MODE_B: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK; - regRRSR = RATE_ALL_CCK; - break; - case WIRELESS_MODE_A: - regBwOpMode = BW_OPMODE_5G | BW_OPMODE_20MHZ; - regRATR = RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_G: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_AUTO: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_N_24G: - /* It support CCK rate by default. CCK rate will be filtered - * out only when associated AP does not support it. - */ - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_N_5G: - regBwOpMode = BW_OPMODE_5G; - regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | - RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_OFDM_AG; - break; - } - - write_nic_byte(dev, BW_OPMODE, regBwOpMode); - ratr_value = regRATR; - if (priv->rf_type == RF_1T2R) - ratr_value &= ~(RATE_ALL_OFDM_2SS); - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); - read_nic_byte(dev, 0x313, ®Tmp); - regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); - write_nic_dword(dev, RRSR, regRRSR); - - /* Set Retry Limit here */ - write_nic_word(dev, RETRY_LIMIT, - priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | - priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT); - /* Set Contention Window here */ - - /* Set Tx AGC */ - - /* Set Tx Antenna including Feedback control */ - - /* Set Auto Rate fallback control */ -} - -/* InitializeAdapter and PhyCfg */ -static bool rtl8192_adapter_start(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 dwRegRead = 0; - bool init_status = true; - u8 SECR_value = 0x0; - u8 tmp; - - RT_TRACE(COMP_INIT, "====>%s()\n", __func__); - priv->Rf_Mode = RF_OP_By_SW_3wire; - /* for ASIC power on sequence */ - write_nic_byte_E(dev, 0x5f, 0x80); - mdelay(50); - write_nic_byte_E(dev, 0x5f, 0xf0); - write_nic_byte_E(dev, 0x5d, 0x00); - write_nic_byte_E(dev, 0x5e, 0x80); - write_nic_byte(dev, 0x17, 0x37); - mdelay(10); - priv->pFirmware->firmware_status = FW_STATUS_0_INIT; - /* config CPUReset Register */ - /* Firmware Reset or not? */ - read_nic_dword(dev, CPU_GEN, &dwRegRead); - dwRegRead |= CPU_GEN_SYSTEM_RESET; /* do nothing here? */ - - write_nic_dword(dev, CPU_GEN, dwRegRead); - /* config BB. */ - rtl8192_BBConfig(dev); - - /* Loopback mode or not */ - priv->LoopbackMode = RTL819xU_NO_LOOPBACK; - - read_nic_dword(dev, CPU_GEN, &dwRegRead); - if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK) - dwRegRead = (dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | - CPU_GEN_NO_LOOPBACK_SET; - else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK) - dwRegRead |= CPU_CCK_LOOPBACK; - else - RT_TRACE(COMP_ERR, - "Serious error in %s(): wrong loopback mode setting(%d)\n", - __func__, priv->LoopbackMode); - - write_nic_dword(dev, CPU_GEN, dwRegRead); - - /* after reset cpu, we need wait for a seconds to write in register. */ - udelay(500); - - /* add for new bitfile:usb suspend reset pin set to 1. Do we need? */ - read_nic_byte_E(dev, 0x5f, &tmp); - write_nic_byte_E(dev, 0x5f, tmp | 0x20); - - /* Set Hardware */ - rtl8192_hwconfig(dev); - - /* turn on Tx/Rx */ - write_nic_byte(dev, CMDR, CR_RE | CR_TE); - - /* set IDR0 here */ - write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); - write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]); - - /* set RCR */ - write_nic_dword(dev, RCR, priv->ReceiveConfig); - - /* Initialize Number of Reserved Pages in Firmware Queue */ - write_nic_dword(dev, RQPN1, - NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VO << RSVD_FW_QUEUE_PAGE_VO_SHIFT); - write_nic_dword(dev, RQPN2, - NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT); - write_nic_dword(dev, RQPN3, - APPLIED_RESERVED_QUEUE_IN_FW | - NUM_OF_PAGE_IN_FW_QUEUE_BCN << RSVD_FW_QUEUE_PAGE_BCN_SHIFT); - write_nic_dword(dev, RATR0 + 4 * 7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK)); - - /* Set AckTimeout */ - /* TODO: (it value is only for FPGA version). need to be changed!! */ - write_nic_byte(dev, ACK_TIMEOUT, 0x30); - - if (priv->ResetProgress == RESET_TYPE_NORESET) - rtl8192_SetWirelessMode(dev, priv->ieee80211->mode); - if (priv->ResetProgress == RESET_TYPE_NORESET) { - CamResetAllEntry(dev); - SECR_value |= SCR_TxEncEnable; - SECR_value |= SCR_RxDecEnable; - SECR_value |= SCR_NoSKMC; - write_nic_byte(dev, SECR, SECR_value); - } - - /* Beacon related */ - write_nic_word(dev, ATIMWND, 2); - write_nic_word(dev, BCN_INTERVAL, 100); - -#define DEFAULT_EDCA 0x005e4332 - { - int i; - - for (i = 0; i < QOS_QUEUE_NUM; i++) - write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA); - } - - rtl8192_phy_configmac(dev); - - if (priv->card_8192_version == VERSION_819XU_A) { - rtl8192_phy_getTxPower(dev); - rtl8192_phy_setTxPower(dev, priv->chan); - } - - /* Firmware download */ - init_status = init_firmware(dev); - if (!init_status) { - RT_TRACE(COMP_ERR, "ERR!!! %s(): Firmware download is failed\n", - __func__); - return init_status; - } - RT_TRACE(COMP_INIT, "%s():after firmware download\n", __func__); - - /* config RF. */ - if (priv->ResetProgress == RESET_TYPE_NORESET) { - rtl8192_phy_RFConfig(dev); - RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __func__); - } - - if (priv->ieee80211->FwRWRF) - /* We can force firmware to do RF-R/W */ - priv->Rf_Mode = RF_OP_By_FW; - else - priv->Rf_Mode = RF_OP_By_SW_3wire; - - rtl8192_phy_updateInitGain(dev); - /*--set CCK and OFDM Block "ON"--*/ - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); - - if (priv->ResetProgress == RESET_TYPE_NORESET) { - /* if D or C cut */ - u8 tmpvalue; - - read_nic_byte(dev, 0x301, &tmpvalue); - if (tmpvalue == 0x03) { - priv->bDcut = true; - RT_TRACE(COMP_POWER_TRACKING, "D-cut\n"); - } else { - priv->bDcut = false; - RT_TRACE(COMP_POWER_TRACKING, "C-cut\n"); - } - dm_initialize_txpower_tracking(dev); - - if (priv->bDcut) { - u32 i, TempCCk; - u32 tmpRegA = rtl8192_QueryBBReg(dev, - rOFDM0_XATxIQImbalance, - bMaskDWord); - - for (i = 0; i < TxBBGainTableLength; i++) { - if (tmpRegA == priv->txbbgain_table[i].txbbgain_value) { - priv->rfa_txpowertrackingindex = (u8)i; - priv->rfa_txpowertrackingindex_real = - (u8)i; - priv->rfa_txpowertracking_default = - priv->rfa_txpowertrackingindex; - break; - } - } - - TempCCk = rtl8192_QueryBBReg(dev, - rCCK0_TxFilter1, - bMaskByte2); - - for (i = 0; i < CCKTxBBGainTableLength; i++) { - if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) { - priv->cck_present_attenuation_20Mdefault = (u8)i; - break; - } - } - priv->cck_present_attenuation_40Mdefault = 0; - priv->cck_present_attenuation_difference = 0; - priv->cck_present_attenuation = - priv->cck_present_attenuation_20Mdefault; - } - } - write_nic_byte(dev, 0x87, 0x0); - - return init_status; -} - -/* this configures registers for beacon tx and enables it via - * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might - * be used to stop beacon transmission - */ -/*************************************************************************** - * -------------------------------NET STUFF--------------------------- - ***************************************************************************/ - -static struct net_device_stats *rtl8192_stats(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return &priv->ieee80211->stats; -} - -static bool HalTxCheckStuck819xUsb(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u16 RegTxCounter; - bool bStuck = false; - - read_nic_word(dev, 0x128, &RegTxCounter); - RT_TRACE(COMP_RESET, - "%s():RegTxCounter is %d,TxCounter is %d\n", __func__, - RegTxCounter, priv->TxCounter); - if (priv->TxCounter == RegTxCounter) - bStuck = true; - - priv->TxCounter = RegTxCounter; - - return bStuck; -} - -/* - * - * First added: 2006.11.19 by emily - */ -static RESET_TYPE TxCheckStuck(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 QueueID; - bool bCheckFwTxCnt = false; - - /* Decide such threshold according to current power save mode */ - - for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) { - if (QueueID == TXCMD_QUEUE) - continue; - if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0)) - continue; - - bCheckFwTxCnt = true; - } - if (bCheckFwTxCnt) { - if (HalTxCheckStuck819xUsb(dev)) { - RT_TRACE(COMP_RESET, - "%s: Fw indicates no Tx condition!\n", - __func__); - return RESET_TYPE_SILENT; - } - } - return RESET_TYPE_NORESET; -} - -static bool HalRxCheckStuck819xUsb(struct net_device *dev) -{ - u16 RegRxCounter; - struct r8192_priv *priv = ieee80211_priv(dev); - bool bStuck = false; - static u8 rx_chk_cnt; - - read_nic_word(dev, 0x130, &RegRxCounter); - RT_TRACE(COMP_RESET, - "%s(): RegRxCounter is %d,RxCounter is %d\n", __func__, - RegRxCounter, priv->RxCounter); - /* If rssi is small, we should check rx for long time because of bad rx. - * or maybe it will continuous silent reset every 2 seconds. - */ - rx_chk_cnt++; - if (priv->undecorated_smoothed_pwdb >= (RATE_ADAPTIVE_TH_HIGH + 5)) { - rx_chk_cnt = 0; /* high rssi, check rx stuck right now. */ - } else if (priv->undecorated_smoothed_pwdb < (RATE_ADAPTIVE_TH_HIGH + 5) && - ((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_40M) || - (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_20M))) { - if (rx_chk_cnt < 2) - return bStuck; - - rx_chk_cnt = 0; - } else if (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_40M) || - (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 && priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_20M)) && - priv->undecorated_smoothed_pwdb >= VERY_LOW_RSSI) { - if (rx_chk_cnt < 4) - return bStuck; - - rx_chk_cnt = 0; - } else { - if (rx_chk_cnt < 8) - return bStuck; - - rx_chk_cnt = 0; - } - - if (priv->RxCounter == RegRxCounter) - bStuck = true; - - priv->RxCounter = RegRxCounter; - - return bStuck; -} - -static RESET_TYPE RxCheckStuck(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - bool bRxCheck = false; - - if (priv->IrpPendingCount > 1) - bRxCheck = true; - - if (bRxCheck) { - if (HalRxCheckStuck819xUsb(dev)) { - RT_TRACE(COMP_RESET, "RxStuck Condition\n"); - return RESET_TYPE_SILENT; - } - } - return RESET_TYPE_NORESET; -} - -/* - * This function is called by Checkforhang to check whether we should - * ask OS to reset driver - * - * Note:NIC with USB interface sholud not call this function because we - * cannot scan descriptor to judge whether there is tx stuck. - * Note: This function may be required to be rewrite for Vista OS. - * <<>> - * - * 8185 and 8185b does not implement this function. - */ -static RESET_TYPE rtl819x_ifcheck_resetornot(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - RESET_TYPE TxResetType = RESET_TYPE_NORESET; - RESET_TYPE RxResetType = RESET_TYPE_NORESET; - RT_RF_POWER_STATE rfState; - - rfState = priv->ieee80211->eRFPowerState; - - TxResetType = TxCheckStuck(dev); - if (rfState != eRfOff || - (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) { - /* If driver is in the status of firmware download failure, - * driver skips RF initialization and RF is in turned off - * state. Driver should check whether Rx stuck and do silent - * reset. And if driver is in firmware download failure status, - * driver should initialize RF in the following silent reset - * procedure - * - * Driver should not check RX stuck in IBSS mode because it is - * required to set Check BSSID in order to send beacon, - * however, if check BSSID is set, STA cannot hear any packet - * at all. - */ - RxResetType = RxCheckStuck(dev); - } - if (TxResetType == RESET_TYPE_NORMAL || - RxResetType == RESET_TYPE_NORMAL) { - return RESET_TYPE_NORMAL; - } else if (TxResetType == RESET_TYPE_SILENT || - RxResetType == RESET_TYPE_SILENT) { - RT_TRACE(COMP_RESET, "%s():silent reset\n", __func__); - return RESET_TYPE_SILENT; - } else { - return RESET_TYPE_NORESET; - } -} - -static void rtl8192_cancel_deferred_work(struct r8192_priv *priv); -static int _rtl8192_up(struct net_device *dev); -static int rtl8192_close(struct net_device *dev); - -static void CamRestoreAllEntry(struct net_device *dev) -{ - u8 EntryId = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - u8 *MacAddr = priv->ieee80211->current_network.bssid; - - static u8 CAM_CONST_ADDR[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; - static u8 CAM_CONST_BROAD[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - RT_TRACE(COMP_SEC, "%s:\n", __func__); - - if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) || - (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) { - for (EntryId = 0; EntryId < 4; EntryId++) { - MacAddr = CAM_CONST_ADDR[EntryId]; - setKey(dev, EntryId, EntryId, - priv->ieee80211->pairwise_key_type, - MacAddr, 0, NULL); - } - - } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) { - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type, - (const u8 *)dev->dev_addr, 0, NULL); - else - setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type, - MacAddr, 0, NULL); - } else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) { - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type, - (const u8 *)dev->dev_addr, 0, NULL); - else - setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type, - MacAddr, 0, NULL); - } - - if (priv->ieee80211->group_key_type == KEY_TYPE_TKIP) { - MacAddr = CAM_CONST_BROAD; - for (EntryId = 1; EntryId < 4; EntryId++) { - setKey(dev, EntryId, EntryId, - priv->ieee80211->group_key_type, - MacAddr, 0, NULL); - } - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, 0, 0, priv->ieee80211->group_key_type, - CAM_CONST_ADDR[0], 0, NULL); - } else if (priv->ieee80211->group_key_type == KEY_TYPE_CCMP) { - MacAddr = CAM_CONST_BROAD; - for (EntryId = 1; EntryId < 4; EntryId++) { - setKey(dev, EntryId, EntryId, - priv->ieee80211->group_key_type, - MacAddr, 0, NULL); - } - - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, 0, 0, priv->ieee80211->group_key_type, - CAM_CONST_ADDR[0], 0, NULL); - } -} - -/* This function is used to fix Tx/Rx stop bug temporarily. - * This function will do "system reset" to NIC when Tx or Rx is stuck. - * The method checking Tx/Rx stuck of this function is supported by FW, - * which reports Tx and Rx counter to register 0x128 and 0x130. - */ -static void rtl819x_ifsilentreset(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 reset_times = 0; - int reset_status = 0; - struct ieee80211_device *ieee = priv->ieee80211; - - /* If we need to check CCK stop, please uncomment this line. */ - /* bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); */ - - if (priv->ResetProgress == RESET_TYPE_NORESET) { -RESET_START: - - RT_TRACE(COMP_RESET, "=========>Reset progress!!\n"); - - /* Set the variable for reset. */ - priv->ResetProgress = RESET_TYPE_SILENT; - mutex_lock(&priv->wx_mutex); - if (priv->up == 0) { - RT_TRACE(COMP_ERR, - "%s():the driver is not up! return\n", - __func__); - mutex_unlock(&priv->wx_mutex); - return; - } - priv->up = 0; - RT_TRACE(COMP_RESET, - "%s():======>start to down the driver\n", - __func__); - - rtl8192_rtx_disable(dev); - rtl8192_cancel_deferred_work(priv); - deinit_hal_dm(dev); - del_timer_sync(&priv->watch_dog_timer); - - ieee->sync_scan_hurryup = 1; - if (ieee->state == IEEE80211_LINKED) { - mutex_lock(&ieee->wx_mutex); - netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n"); - ieee80211_stop_send_beacons(priv->ieee80211); - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - ieee80211_stop_scan(ieee); - netif_carrier_off(dev); - mutex_unlock(&ieee->wx_mutex); - } else { - netdev_dbg(dev, "ieee->state is NOT LINKED\n"); - ieee80211_softmac_stop_protocol(priv->ieee80211); - } - mutex_unlock(&priv->wx_mutex); - RT_TRACE(COMP_RESET, - "%s():<==========down process is finished\n", - __func__); - RT_TRACE(COMP_RESET, - "%s():===========>start up the driver\n", - __func__); - reset_status = _rtl8192_up(dev); - - RT_TRACE(COMP_RESET, - "%s():<===========up process is finished\n", - __func__); - if (reset_status == -EAGAIN) { - if (reset_times < 3) { - reset_times++; - goto RESET_START; - } else { - RT_TRACE(COMP_ERR, - " ERR!!! %s(): Reset Failed!!\n", - __func__); - } - } - ieee->is_silent_reset = 1; - EnableHWSecurityConfig8192(dev); - if (ieee->state == IEEE80211_LINKED && - ieee->iw_mode == IW_MODE_INFRA) { - ieee->set_chan(ieee->dev, - ieee->current_network.channel); - - queue_work(ieee->wq, &ieee->associate_complete_wq); - - } else if (ieee->state == IEEE80211_LINKED && - ieee->iw_mode == IW_MODE_ADHOC) { - ieee->set_chan(ieee->dev, - ieee->current_network.channel); - ieee->link_change(ieee->dev); - - ieee80211_start_send_beacons(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - netif_carrier_on(ieee->dev); - } - - CamRestoreAllEntry(dev); - - priv->ResetProgress = RESET_TYPE_NORESET; - priv->reset_count++; - - priv->bForcedSilentReset = false; - priv->bResetInProgress = false; - - /* For test --> force write UFWP. */ - write_nic_byte(dev, UFWP, 1); - RT_TRACE(COMP_RESET, - "Reset finished!! ====>[%d]\n", - priv->reset_count); - } -} - -static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, - u32 *TotalRxDataNum) -{ - u16 SlotIndex; - u16 i; - - *TotalRxBcnNum = 0; - *TotalRxDataNum = 0; - - SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++) % - (priv->ieee80211->LinkDetectInfo.SlotNum); - priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = - priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod; - priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = - priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod; - for (i = 0; i < priv->ieee80211->LinkDetectInfo.SlotNum; i++) { - *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i]; - *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i]; - } -} - -static void rtl819x_watchdog_wqcallback(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct r8192_priv *priv = container_of(dwork, - struct r8192_priv, watch_dog_wq); - struct net_device *dev = priv->ieee80211->dev; - struct ieee80211_device *ieee = priv->ieee80211; - RESET_TYPE ResetType = RESET_TYPE_NORESET; - static u8 check_reset_cnt; - bool bBusyTraffic = false; - u32 TotalRxBcnNum = 0; - u32 TotalRxDataNum = 0; - - if (!priv->up) - return; - hal_dm_watchdog(dev); - - /* to get busy traffic condition */ - if (ieee->state == IEEE80211_LINKED) { - if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 || - ieee->LinkDetectInfo.NumTxOkInPeriod > 666) { - bBusyTraffic = true; - } - ieee->LinkDetectInfo.NumRxOkInPeriod = 0; - ieee->LinkDetectInfo.NumTxOkInPeriod = 0; - ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; - } - /* for AP roaming */ - if (priv->ieee80211->state == IEEE80211_LINKED && - priv->ieee80211->iw_mode == IW_MODE_INFRA) { - rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); - if ((TotalRxBcnNum + TotalRxDataNum) == 0) { -#ifdef TODO - if (rfState == eRfOff) - RT_TRACE(COMP_ERR, "========>%s()\n", __func__); -#endif - netdev_dbg(dev, - "===>%s(): AP is power off, connect another one\n", - __func__); - priv->ieee80211->state = IEEE80211_ASSOCIATING; - notify_wx_assoc_event(priv->ieee80211); - RemovePeerTS(priv->ieee80211, - priv->ieee80211->current_network.bssid); - priv->ieee80211->link_change(dev); - queue_work(priv->ieee80211->wq, - &priv->ieee80211->associate_procedure_wq); - } - } - priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0; - priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0; - /* check if reset the driver */ - if (check_reset_cnt++ >= 3) { - ResetType = rtl819x_ifcheck_resetornot(dev); - check_reset_cnt = 3; - } - /* This is control by OID set in Pomelo */ - if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET && - (priv->bForcedSilentReset || - (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { - RT_TRACE(COMP_RESET, - "%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n", - __func__, priv->force_reset, priv->ResetProgress, - priv->bForcedSilentReset, - priv->bDisableNormalResetCheck, ResetType); - rtl819x_ifsilentreset(dev); - } - priv->force_reset = false; - priv->bForcedSilentReset = false; - priv->bResetInProgress = false; - RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); -} - -static void watch_dog_timer_callback(struct timer_list *t) -{ - struct r8192_priv *priv = from_timer(priv, t, watch_dog_timer); - - schedule_delayed_work(&priv->watch_dog_wq, 0); - mod_timer(&priv->watch_dog_timer, - jiffies + msecs_to_jiffies(IEEE80211_WATCH_DOG_TIME)); -} - -static int _rtl8192_up(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int init_status = 0; - - priv->up = 1; - priv->ieee80211->ieee_up = 1; - RT_TRACE(COMP_INIT, "Bringing up iface"); - init_status = rtl8192_adapter_start(dev); - if (!init_status) { - RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization failed!\n", - __func__); - priv->up = priv->ieee80211->ieee_up = 0; - return -EAGAIN; - } - RT_TRACE(COMP_INIT, "start adapter finished\n"); - rtl8192_rx_enable(dev); - if (priv->ieee80211->state != IEEE80211_LINKED) - ieee80211_softmac_start_protocol(priv->ieee80211); - ieee80211_reset_queue(priv->ieee80211); - watch_dog_timer_callback(&priv->watch_dog_timer); - if (!netif_queue_stopped(dev)) - netif_start_queue(dev); - else - netif_wake_queue(dev); - - return 0; -} - -static int rtl8192_open(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - ret = rtl8192_up(dev); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -int rtl8192_up(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->up == 1) - return -1; - - return _rtl8192_up(dev); -} - -static int rtl8192_close(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - - ret = rtl8192_down(dev); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -int rtl8192_down(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int i; - - if (priv->up == 0) - return -1; - - priv->up = 0; - priv->ieee80211->ieee_up = 0; - RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__); - /* FIXME */ - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - - rtl8192_rtx_disable(dev); - - /* Tx related queue release */ - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_purge(&priv->ieee80211->skb_waitQ[i]); - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_purge(&priv->ieee80211->skb_aggQ[i]); - - for (i = 0; i < MAX_QUEUE_SIZE; i++) - skb_queue_purge(&priv->ieee80211->skb_drv_aggQ[i]); - - /* as cancel_delayed_work will del work->timer, so if work is not - * defined as struct delayed_work, it will corrupt - */ - rtl8192_cancel_deferred_work(priv); - deinit_hal_dm(dev); - del_timer_sync(&priv->watch_dog_timer); - - ieee80211_softmac_stop_protocol(priv->ieee80211); - memset(&priv->ieee80211->current_network, 0, - offsetof(struct ieee80211_network, list)); - RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__); - - return 0; -} - -void rtl8192_commit(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->up == 0) - return; - priv->up = 0; - - rtl8192_cancel_deferred_work(priv); - del_timer_sync(&priv->watch_dog_timer); - - ieee80211_softmac_stop_protocol(priv->ieee80211); - - rtl8192_rtx_disable(dev); - _rtl8192_up(dev); -} - -static void rtl8192_restart(struct work_struct *work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, - reset_wq); - struct net_device *dev = priv->ieee80211->dev; - - mutex_lock(&priv->wx_mutex); - - rtl8192_commit(dev); - - mutex_unlock(&priv->wx_mutex); -} - -static void r8192_set_multicast(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - short promisc; - - /* FIXME FIXME */ - - promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - - if (promisc != priv->promisc) - - priv->promisc = promisc; -} - -static int r8192_set_mac_adr(struct net_device *dev, void *mac) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct sockaddr *addr = mac; - - mutex_lock(&priv->wx_mutex); - - eth_hw_addr_set(dev, addr->sa_data); - - schedule_work(&priv->reset_wq); - mutex_unlock(&priv->wx_mutex); - - return 0; -} - -/* based on ipw2200 driver */ -static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct iwreq *wrq = (struct iwreq *)rq; - int ret = -1; - struct ieee80211_device *ieee = priv->ieee80211; - u32 key[4]; - u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - struct iw_point *p = &wrq->u.data; - struct ieee_param *ipw = NULL; - - mutex_lock(&priv->wx_mutex); - - if (p->length < sizeof(struct ieee_param) || !p->pointer) { - ret = -EINVAL; - goto out; - } - - ipw = memdup_user(p->pointer, p->length); - if (IS_ERR(ipw)) { - ret = PTR_ERR(ipw); - goto out; - } - - switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - /* parse here for HW security */ - if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) { - if (ipw->u.crypt.set_tx) { - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) { - ieee->pairwise_key_type = KEY_TYPE_CCMP; - } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) { - ieee->pairwise_key_type = KEY_TYPE_TKIP; - } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { - if (ipw->u.crypt.key_len == 13) - ieee->pairwise_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->pairwise_key_type = KEY_TYPE_WEP40; - } else { - ieee->pairwise_key_type = KEY_TYPE_NA; - } - - if (ieee->pairwise_key_type) { - memcpy((u8 *)key, ipw->u.crypt.key, 16); - EnableHWSecurityConfig8192(dev); - /* We fill both index entry and 4th - * entry for pairwise key as in IPW - * interface, adhoc will only get here, - * so we need index entry for its - * default key serching! - */ - setKey(dev, 4, ipw->u.crypt.idx, - ieee->pairwise_key_type, - (u8 *)ieee->ap_mac_addr, - 0, key); - if (ieee->auth_mode != 2) - setKey(dev, ipw->u.crypt.idx, - ipw->u.crypt.idx, - ieee->pairwise_key_type, - (u8 *)ieee->ap_mac_addr, - 0, key); - } - } else { - memcpy((u8 *)key, ipw->u.crypt.key, 16); - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) { - ieee->group_key_type = KEY_TYPE_CCMP; - } else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) { - ieee->group_key_type = KEY_TYPE_TKIP; - } else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { - if (ipw->u.crypt.key_len == 13) - ieee->group_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->group_key_type = KEY_TYPE_WEP40; - } else { - ieee->group_key_type = KEY_TYPE_NA; - } - - if (ieee->group_key_type) { - setKey(dev, ipw->u.crypt.idx, - /* KeyIndex */ - ipw->u.crypt.idx, - /* KeyType */ - ieee->group_key_type, - /* MacAddr */ - broadcast_addr, - /* DefaultKey */ - 0, - /* KeyContent */ - key); - } - } - } - ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, - &wrq->u.data); - break; - - default: - ret = -EOPNOTSUPP; - break; - } - kfree(ipw); - ipw = NULL; -out: - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static u8 HwRateToMRate90(bool bIsHT, u8 rate) -{ - u8 ret_rate = 0xff; - - if (!bIsHT) { - switch (rate) { - case DESC90_RATE1M: - ret_rate = MGN_1M; - break; - case DESC90_RATE2M: - ret_rate = MGN_2M; - break; - case DESC90_RATE5_5M: - ret_rate = MGN_5_5M; - break; - case DESC90_RATE11M: - ret_rate = MGN_11M; - break; - case DESC90_RATE6M: - ret_rate = MGN_6M; - break; - case DESC90_RATE9M: - ret_rate = MGN_9M; - break; - case DESC90_RATE12M: - ret_rate = MGN_12M; - break; - case DESC90_RATE18M: - ret_rate = MGN_18M; - break; - case DESC90_RATE24M: - ret_rate = MGN_24M; - break; - case DESC90_RATE36M: - ret_rate = MGN_36M; - break; - case DESC90_RATE48M: - ret_rate = MGN_48M; - break; - case DESC90_RATE54M: - ret_rate = MGN_54M; - break; - - default: - ret_rate = 0xff; - RT_TRACE(COMP_RECV, - "%s: Non supported Rate [%x], bIsHT = %d!!!\n", - __func__, rate, bIsHT); - break; - } - - } else { - switch (rate) { - case DESC90_RATEMCS0: - ret_rate = MGN_MCS0; - break; - case DESC90_RATEMCS1: - ret_rate = MGN_MCS1; - break; - case DESC90_RATEMCS2: - ret_rate = MGN_MCS2; - break; - case DESC90_RATEMCS3: - ret_rate = MGN_MCS3; - break; - case DESC90_RATEMCS4: - ret_rate = MGN_MCS4; - break; - case DESC90_RATEMCS5: - ret_rate = MGN_MCS5; - break; - case DESC90_RATEMCS6: - ret_rate = MGN_MCS6; - break; - case DESC90_RATEMCS7: - ret_rate = MGN_MCS7; - break; - case DESC90_RATEMCS8: - ret_rate = MGN_MCS8; - break; - case DESC90_RATEMCS9: - ret_rate = MGN_MCS9; - break; - case DESC90_RATEMCS10: - ret_rate = MGN_MCS10; - break; - case DESC90_RATEMCS11: - ret_rate = MGN_MCS11; - break; - case DESC90_RATEMCS12: - ret_rate = MGN_MCS12; - break; - case DESC90_RATEMCS13: - ret_rate = MGN_MCS13; - break; - case DESC90_RATEMCS14: - ret_rate = MGN_MCS14; - break; - case DESC90_RATEMCS15: - ret_rate = MGN_MCS15; - break; - case DESC90_RATEMCS32: - ret_rate = 0x80 | 0x20; - break; - - default: - ret_rate = 0xff; - RT_TRACE(COMP_RECV, - "%s: Non supported Rate [%x], bIsHT = %d!!!\n", - __func__, rate, bIsHT); - break; - } - } - - return ret_rate; -} - -/* - * Function: UpdateRxPktTimeStamp - * Overview: Record the TSF time stamp when receiving a packet - * - * Input: - * PADAPTER Adapter - * PRT_RFD pRfd, - * - * Output: - * PRT_RFD pRfd - * (pRfd->Status.TimeStampHigh is updated) - * (pRfd->Status.TimeStampLow is updated) - * Return: - * None - */ -static void UpdateRxPktTimeStamp8190(struct net_device *dev, - struct ieee80211_rx_stats *stats) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - - if (stats->bIsAMPDU && !stats->bFirstMPDU) { - stats->mac_time[0] = priv->LastRxDescTSFLow; - stats->mac_time[1] = priv->LastRxDescTSFHigh; - } else { - priv->LastRxDescTSFLow = stats->mac_time[0]; - priv->LastRxDescTSFHigh = stats->mac_time[1]; - } -} - -/* 0-100 index. */ -static long rtl819x_translate_todbm(u8 signal_strength_index) -{ - long signal_power; /* in dBm. */ - - /* Translate to dBm (x=0.5y-95). */ - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -/* We can not declare RSSI/EVM total value of sliding window to - * be a local static. Otherwise, it may increase when we return from S3/S4. The - * value will be kept in memory or disk. Declare the value in the adaptor - * and it will be reinitialized when returned from S3/S4. - */ -static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer, - struct ieee80211_rx_stats *pprevious_stats, - struct ieee80211_rx_stats *pcurrent_stats) -{ - bool bcheck = false; - u8 rfpath; - u32 nspatial_stream, tmp_val; - static u32 slide_rssi_index, slide_rssi_statistics; - static u32 slide_evm_index, slide_evm_statistics; - static u32 last_rssi, last_evm; - - static u32 slide_beacon_adc_pwdb_index; - static u32 slide_beacon_adc_pwdb_statistics; - static u32 last_beacon_adc_pwdb; - - struct rtl_80211_hdr_3addr *hdr; - u16 sc; - unsigned int seq; - - hdr = (struct rtl_80211_hdr_3addr *)buffer; - sc = le16_to_cpu(hdr->seq_ctl); - seq = WLAN_GET_SEQ_SEQ(sc); - /* to record the sequence number */ - pcurrent_stats->Seq_Num = seq; - - /* Check whether we should take the previous packet into accounting */ - if (!pprevious_stats->bIsAMPDU) { - /* if previous packet is not aggregated packet */ - bcheck = true; - } - - if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { - slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; - last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; - priv->stats.slide_rssi_total -= last_rssi; - } - priv->stats.slide_rssi_total += pprevious_stats->SignalStrength; - - priv->stats.slide_signal_strength[slide_rssi_index++] = - pprevious_stats->SignalStrength; - if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) - slide_rssi_index = 0; - - /* <1> Showed on UI for user, in dbm */ - tmp_val = priv->stats.slide_rssi_total / slide_rssi_statistics; - priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val); - pcurrent_stats->rssi = priv->stats.signal_strength; - - /* If the previous packet does not match the criteria, neglect it */ - if (!pprevious_stats->bPacketMatchBSSID) { - if (!pprevious_stats->bToSelfBA) - return; - } - - if (!bcheck) - return; - - /* only rtl8190 supported - * rtl8190_process_cck_rxpathsel(priv,pprevious_stats); - */ - - /* Check RSSI */ - priv->stats.num_process_phyinfo++; - - /* record the general signal strength to the sliding window. */ - - /* <2> Showed on UI for engineering - * hardware does not provide rssi information for each rf path in CCK - */ - if (!pprevious_stats->bIsCCK && - (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA)) { - for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++) { - if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, - rfpath)) - continue; - if (priv->stats.rx_rssi_percentage[rfpath] == 0) - priv->stats.rx_rssi_percentage[rfpath] = - pprevious_stats->RxMIMOSignalStrength[rfpath]; - if (pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) { - priv->stats.rx_rssi_percentage[rfpath] = - ((priv->stats.rx_rssi_percentage[rfpath] * (RX_SMOOTH_FACTOR - 1)) + - (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (RX_SMOOTH_FACTOR); - priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1; - } else { - priv->stats.rx_rssi_percentage[rfpath] = - ((priv->stats.rx_rssi_percentage[rfpath] * (RX_SMOOTH_FACTOR - 1)) + - (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (RX_SMOOTH_FACTOR); - } - RT_TRACE(COMP_DBG, - "priv->stats.rx_rssi_percentage[rfPath] = %d\n", - priv->stats.rx_rssi_percentage[rfpath]); - } - } - - /* Check PWDB. */ - RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n", - pprevious_stats->bIsCCK ? "CCK" : "OFDM", - pprevious_stats->RxPWDBAll); - - if (pprevious_stats->bPacketBeacon) { - /* record the beacon pwdb to the sliding window. */ - if (slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) { - slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX; - last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index]; - priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb; - } - priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll; - priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll; - slide_beacon_adc_pwdb_index++; - if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) - slide_beacon_adc_pwdb_index = 0; - pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total / slide_beacon_adc_pwdb_statistics; - if (pprevious_stats->RxPWDBAll >= 3) - pprevious_stats->RxPWDBAll -= 3; - } - - RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n", - pprevious_stats->bIsCCK ? "CCK" : "OFDM", - pprevious_stats->RxPWDBAll); - - if (pprevious_stats->bPacketToSelf || - pprevious_stats->bPacketBeacon || - pprevious_stats->bToSelfBA) { - if (priv->undecorated_smoothed_pwdb < 0) - /* initialize */ - priv->undecorated_smoothed_pwdb = - pprevious_stats->RxPWDBAll; - if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) { - priv->undecorated_smoothed_pwdb = - (((priv->undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + - (pprevious_stats->RxPWDBAll)) / (RX_SMOOTH_FACTOR); - priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1; - } else { - priv->undecorated_smoothed_pwdb = - (((priv->undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + - (pprevious_stats->RxPWDBAll)) / (RX_SMOOTH_FACTOR); - } - } - - /* Check EVM */ - /* record the general EVM to the sliding window. */ - if (pprevious_stats->SignalQuality) { - if (pprevious_stats->bPacketToSelf || - pprevious_stats->bPacketBeacon || - pprevious_stats->bToSelfBA) { - if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { - slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; - last_evm = priv->stats.slide_evm[slide_evm_index]; - priv->stats.slide_evm_total -= last_evm; - } - - priv->stats.slide_evm_total += - pprevious_stats->SignalQuality; - - priv->stats.slide_evm[slide_evm_index++] = - pprevious_stats->SignalQuality; - if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) - slide_evm_index = 0; - - /* <1> Showed on UI for user, in percentage. */ - tmp_val = priv->stats.slide_evm_total / - slide_evm_statistics; - priv->stats.signal_quality = tmp_val; - /* Showed on UI for user in Windows Vista, - * for Link quality. - */ - priv->stats.last_signal_strength_inpercent = tmp_val; - } - - /* <2> Showed on UI for engineering */ - if (pprevious_stats->bPacketToSelf || - pprevious_stats->bPacketBeacon || - pprevious_stats->bToSelfBA) { - for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { /* 2 spatial stream */ - if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) { - if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */ - priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream]; - priv->stats.rx_evm_percentage[nspatial_stream] = - ((priv->stats.rx_evm_percentage[nspatial_stream] * (RX_SMOOTH_FACTOR - 1)) + - (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] * 1)) / (RX_SMOOTH_FACTOR); - } - } - } - } -} - -/*----------------------------------------------------------------------------- - * Function: rtl819x_query_rxpwrpercentage() - * - * Overview: - * - * Input: char antpower - * - * Output: NONE - * - * Return: 0-100 percentage - *--------------------------------------------------------------------------- - */ -static u8 rtl819x_query_rxpwrpercentage(s8 antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; - -} /* QueryRxPwrPercentage */ - -static u8 rtl819x_evm_dbtopercentage(s8 value) -{ - s8 ret_val = clamp(-value, 0, 33) * 3; - - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} - -/* We want good-looking for signal strength/quality */ -static long rtl819x_signal_scale_mapping(long currsig) -{ - long retsig; - - /* Step 1. Scale mapping. */ - if (currsig >= 61 && currsig <= 100) - retsig = 90 + ((currsig - 60) / 4); - else if (currsig >= 41 && currsig <= 60) - retsig = 78 + ((currsig - 40) / 2); - else if (currsig >= 31 && currsig <= 40) - retsig = 66 + (currsig - 30); - else if (currsig >= 21 && currsig <= 30) - retsig = 54 + (currsig - 20); - else if (currsig >= 5 && currsig <= 20) - retsig = 42 + (((currsig - 5) * 2) / 3); - else if (currsig == 4) - retsig = 36; - else if (currsig == 3) - retsig = 27; - else if (currsig == 2) - retsig = 18; - else if (currsig == 1) - retsig = 9; - else - retsig = currsig; - - return retsig; -} - -static inline bool rx_hal_is_cck_rate(struct rx_drvinfo_819x_usb *pdrvinfo) -{ - if (pdrvinfo->RxHT) - return false; - - switch (pdrvinfo->RxRate) { - case DESC90_RATE1M: - case DESC90_RATE2M: - case DESC90_RATE5_5M: - case DESC90_RATE11M: - return true; - default: - return false; - } -} - -static void rtl8192_query_rxphystatus(struct r8192_priv *priv, - struct ieee80211_rx_stats *pstats, - struct rx_drvinfo_819x_usb *pdrvinfo, - struct ieee80211_rx_stats *precord_stats, - bool bpacket_match_bssid, - bool bpacket_toself, - bool bPacketBeacon, - bool bToSelfBA) -{ - phy_sts_ofdm_819xusb_t *pofdm_buf; - phy_sts_cck_819xusb_t *pcck_buf; - struct phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc; - u8 *prxpkt; - u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg; - s8 rx_pwr[4], rx_pwr_all = 0; - s8 rx_snrX, rx_evmX; - u8 evm, pwdb_all; - u32 RSSI, total_rssi = 0; - u8 is_cck_rate = 0; - u8 rf_rx_num = 0; - u8 sq; - - priv->stats.numqry_phystatus++; - - is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); - - /* Record it for next packet processing */ - memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats)); - pstats->bPacketMatchBSSID = - precord_stats->bPacketMatchBSSID = bpacket_match_bssid; - pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; - pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate; - pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; - pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; - - prxpkt = (u8 *)pdrvinfo; - - /* Move pointer to the 16th bytes. Phy status start address. */ - prxpkt += sizeof(struct rx_drvinfo_819x_usb); - - /* Initial the cck and ofdm buffer pointer */ - pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt; - pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt; - - pstats->RxMIMOSignalQuality[0] = -1; - pstats->RxMIMOSignalQuality[1] = -1; - precord_stats->RxMIMOSignalQuality[0] = -1; - precord_stats->RxMIMOSignalQuality[1] = -1; - - if (is_cck_rate) { - /* (1)Hardware does not provide RSSI for CCK */ - - /* (2)PWDB, Average PWDB calculated by hardware - * (for rate adaptive) - */ - u8 report; - - priv->stats.numqry_phystatusCCK++; - - if (!priv->bCckHighPower) { - report = pcck_buf->cck_agc_rpt & 0xc0; - report >>= 6; - switch (report) { - case 0x3: - rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x2: - rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x1: - rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x0: - rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - } - } else { - report = pcck_buf->cck_agc_rpt & 0x60; - report >>= 5; - switch (report) { - case 0x3: - rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f) << 1); - break; - } - } - - pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RecvSignalPower = pwdb_all; - - /* (3) Get Signal Quality (EVM) */ - - if (pstats->RxPWDBAll > 40) { - sq = 100; - } else { - sq = pcck_buf->sq_rpt; - - if (pcck_buf->sq_rpt > 64) - sq = 0; - else if (pcck_buf->sq_rpt < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - pstats->SignalQuality = precord_stats->SignalQuality = sq; - pstats->RxMIMOSignalQuality[0] = - precord_stats->RxMIMOSignalQuality[0] = sq; - pstats->RxMIMOSignalQuality[1] = - precord_stats->RxMIMOSignalQuality[1] = -1; - - } else { - priv->stats.numqry_phystatusHT++; - - /* (1)Get RSSI for HT rate */ - for (i = RF90_PATH_A; i < priv->NumTotalRFPath; i++) { - /* We will judge RF RX path now. */ - if (priv->brfpath_rxenable[i]) - rf_rx_num++; - else - continue; - - if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i)) - continue; - - rx_pwr[i] = - ((pofdm_buf->trsw_gain_X[i] & 0x3F) * 2) - 106; - - /* Get Rx snr value in DB */ - tmp_rxsnr = pofdm_buf->rxsnr_X[i]; - rx_snrX = (s8)(tmp_rxsnr); - rx_snrX /= 2; - priv->stats.rxSNRdB[i] = (long)rx_snrX; - - /* Translate DBM to percentage. */ - RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); - total_rssi += RSSI; - - /* Record Signal Strength for next packet */ - pstats->RxMIMOSignalStrength[i] = (u8)RSSI; - precord_stats->RxMIMOSignalStrength[i] = (u8)RSSI; - } - - /* (2)PWDB, Average PWDB calculated by hardware - * (for rate adaptive) - */ - rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106; - pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); - - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RxPower = precord_stats->RxPower = rx_pwr_all; - - /* (3)EVM of HT rate */ - if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 && - pdrvinfo->RxRate <= DESC90_RATEMCS15) - /* both spatial stream make sense */ - max_spatial_stream = 2; - else - /* only spatial stream 1 makes sense */ - max_spatial_stream = 1; - - for (i = 0; i < max_spatial_stream; i++) { - tmp_rxevm = pofdm_buf->rxevm_X[i]; - rx_evmX = (s8)(tmp_rxevm); - - /* Do not use shift operation like "rx_evmX >>= 1" - * because the compiler of free build environment will - * set the most significant bit to "zero" when doing - * shifting operation which may change a negative value - * to positive one, then the dbm value (which is - * supposed to be negative) is not correct anymore. - */ - rx_evmX /= 2; /* dbm */ - - evm = rtl819x_evm_dbtopercentage(rx_evmX); - if (i == 0) - /* Fill value in RFD, Get the first spatial - * stream only - */ - pstats->SignalQuality = - precord_stats->SignalQuality = - evm & 0xff; - pstats->RxMIMOSignalQuality[i] = - precord_stats->RxMIMOSignalQuality[i] = - evm & 0xff; - } - - /* record rx statistics for debug */ - rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg; - prxsc = (struct phy_ofdm_rx_status_rxsc_sgien_exintfflag *) - &rxsc_sgien_exflg; - if (pdrvinfo->BW) /* 40M channel */ - priv->stats.received_bwtype[1 + prxsc->rxsc]++; - else /* 20M channel */ - priv->stats.received_bwtype[0]++; - } - - /* UI BSS List signal strength(in percentage), make it good looking, - * from 0~100. It is assigned to the BSS List in - * GetValueFromBeaconOrProbeRsp(). - */ - if (is_cck_rate) { - pstats->SignalStrength = - precord_stats->SignalStrength = - (u8)(rtl819x_signal_scale_mapping((long)pwdb_all)); - } else { - /* We can judge RX path number now. */ - if (rf_rx_num != 0) { - pstats->SignalStrength = - precord_stats->SignalStrength = - (u8)(rtl819x_signal_scale_mapping((long)(total_rssi /= rf_rx_num))); - } - } -} /* QueryRxPhyStatus8190Pci */ - -static void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats, - struct ieee80211_rx_stats *ptarget_stats) -{ - ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; - ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; - ptarget_stats->Seq_Num = psrc_stats->Seq_Num; -} - -static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, - struct ieee80211_rx_stats *pstats, - struct rx_drvinfo_819x_usb *pdrvinfo) -{ - /* TODO: We must only check packet for current MAC address. - * Not finish - */ - struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; - struct net_device *dev = info->dev; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - bool bpacket_match_bssid, bpacket_toself; - bool bPacketBeacon = false, bToSelfBA = false; - static struct ieee80211_rx_stats previous_stats; - struct rtl_80211_hdr_3addr *hdr; - u16 fc, type; - - /* Get Signal Quality for only RX data queue (but not command queue) */ - - u8 *tmp_buf; - u8 *praddr; - - /* Get MAC frame start address. */ - tmp_buf = (u8 *)skb->data; - - hdr = (struct rtl_80211_hdr_3addr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - - /* Check if the received packet is acceptable. */ - bpacket_match_bssid = (type != IEEE80211_FTYPE_CTL) && - (ether_addr_equal(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3)) - && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV); - bpacket_toself = bpacket_match_bssid && - (ether_addr_equal(praddr, priv->ieee80211->dev->dev_addr)); - - if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON) - bPacketBeacon = true; - if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) { - if ((ether_addr_equal(praddr, dev->dev_addr))) - bToSelfBA = true; - } - - if (bpacket_match_bssid) - priv->stats.numpacket_matchbssid++; - if (bpacket_toself) - priv->stats.numpacket_toself++; - /* Process PHY information for previous packet (RSSI/PWDB/EVM) - * Because phy information is contained in the last packet of AMPDU - * only, so driver should process phy information of previous packet - */ - rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats); - rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, - bpacket_match_bssid, bpacket_toself, - bPacketBeacon, bToSelfBA); - rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats); -} - -/* - * Function: UpdateReceivedRateHistogramStatistics - * Overview: Record the received data rate - * - * Input: - * struct net_device *dev - * struct ieee80211_rx_stats *stats - * - * Output: - * - * (priv->stats.ReceivedRateHistogram[] is updated) - * Return: - * None - */ -static void -UpdateReceivedRateHistogramStatistics8190(struct net_device *dev, - struct ieee80211_rx_stats *stats) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - /* 0: Total, 1:OK, 2:CRC, 3:ICV */ - u32 rcvType = 1; - u32 rateIndex; - /* 1: short preamble/GI, 0: long preamble/GI */ - u32 preamble_guardinterval; - - if (stats->bCRC) - rcvType = 2; - else if (stats->bICV) - rcvType = 3; - - if (stats->bShortPreamble) - preamble_guardinterval = 1; /* short */ - else - preamble_guardinterval = 0; /* long */ - - switch (stats->rate) { - /* CCK rate */ - case MGN_1M: - rateIndex = 0; - break; - case MGN_2M: - rateIndex = 1; - break; - case MGN_5_5M: - rateIndex = 2; - break; - case MGN_11M: - rateIndex = 3; - break; - /* Legacy OFDM rate */ - case MGN_6M: - rateIndex = 4; - break; - case MGN_9M: - rateIndex = 5; - break; - case MGN_12M: - rateIndex = 6; - break; - case MGN_18M: - rateIndex = 7; - break; - case MGN_24M: - rateIndex = 8; - break; - case MGN_36M: - rateIndex = 9; - break; - case MGN_48M: - rateIndex = 10; - break; - case MGN_54M: - rateIndex = 11; - break; - /* 11n High throughput rate */ - case MGN_MCS0: - rateIndex = 12; - break; - case MGN_MCS1: - rateIndex = 13; - break; - case MGN_MCS2: - rateIndex = 14; - break; - case MGN_MCS3: - rateIndex = 15; - break; - case MGN_MCS4: - rateIndex = 16; - break; - case MGN_MCS5: - rateIndex = 17; - break; - case MGN_MCS6: - rateIndex = 18; - break; - case MGN_MCS7: - rateIndex = 19; - break; - case MGN_MCS8: - rateIndex = 20; - break; - case MGN_MCS9: - rateIndex = 21; - break; - case MGN_MCS10: - rateIndex = 22; - break; - case MGN_MCS11: - rateIndex = 23; - break; - case MGN_MCS12: - rateIndex = 24; - break; - case MGN_MCS13: - rateIndex = 25; - break; - case MGN_MCS14: - rateIndex = 26; - break; - case MGN_MCS15: - rateIndex = 27; - break; - default: - rateIndex = 28; - break; - } - priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++; - priv->stats.received_rate_histogram[0][rateIndex]++; /* total */ - priv->stats.received_rate_histogram[rcvType][rateIndex]++; -} - -static void query_rxdesc_status(struct sk_buff *skb, - struct ieee80211_rx_stats *stats, - bool bIsRxAggrSubframe) -{ - struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; - struct net_device *dev = info->dev; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct rx_drvinfo_819x_usb *driver_info = NULL; - - /* Get Rx Descriptor Information */ - struct rx_desc_819x_usb *desc = (struct rx_desc_819x_usb *)skb->data; - - stats->Length = desc->Length; - stats->RxDrvInfoSize = desc->RxDrvInfoSize; - stats->RxBufShift = 0; - stats->bICV = desc->ICV; - stats->bCRC = desc->CRC32; - stats->bHwError = stats->bCRC | stats->bICV; - /* RTL8190 set this bit to indicate that Hw does not decrypt packet */ - stats->Decrypted = !desc->SWDec; - - if ((priv->ieee80211->pHTInfo->bCurrentHTSupport) && - (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)) - stats->bHwError = false; - else - stats->bHwError = stats->bCRC | stats->bICV; - - if (stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE) - stats->bHwError |= 1; - /* Get Driver Info */ - /* TODO: Need to verify it on FGPA platform - * Driver info are written to the RxBuffer following rx desc - */ - if (stats->RxDrvInfoSize != 0) { - driver_info = (struct rx_drvinfo_819x_usb *)(skb->data - + sizeof(struct rx_desc_819x_usb) - + stats->RxBufShift - ); - /* unit: 0.5M */ - /* TODO */ - if (!stats->bHwError) { - u8 ret_rate; - - ret_rate = HwRateToMRate90(driver_info->RxHT, - driver_info->RxRate); - if (ret_rate == 0xff) { - /* Abnormal Case: Receive CRC OK packet with Rx - * descriptor indicating non supported rate. - * Special Error Handling here - */ - - stats->bHwError = 1; - /* Set 1M rate by default */ - stats->rate = MGN_1M; - } else { - stats->rate = ret_rate; - } - } else { - stats->rate = 0x02; - } - - stats->bShortPreamble = driver_info->SPLCP; - - UpdateReceivedRateHistogramStatistics8190(dev, stats); - - stats->bIsAMPDU = (driver_info->PartAggr == 1); - stats->bFirstMPDU = (driver_info->PartAggr == 1) && - (driver_info->FirstAGGR == 1); - stats->TimeStampLow = driver_info->TSFL; - - UpdateRxPktTimeStamp8190(dev, stats); - - /* Rx A-MPDU */ - if (driver_info->FirstAGGR == 1 || driver_info->PartAggr == 1) - RT_TRACE(COMP_RXDESC, - "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n", - driver_info->FirstAGGR, driver_info->PartAggr); - } - - skb_pull(skb, sizeof(struct rx_desc_819x_usb)); - /* Get Total offset of MPDU Frame Body */ - if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) { - stats->bShift = 1; - skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize); - } - - if (driver_info) { - stats->RxIs40MHzPacket = driver_info->BW; - TranslateRxSignalStuff819xUsb(skb, stats, driver_info); - } -} - -static void rtl8192_rx_nomal(struct sk_buff *skb) -{ - struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; - struct net_device *dev = info->dev; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct ieee80211_rx_stats stats = { - .signal = 0, - .noise = 0x100 - 98, - .rate = 0, - .freq = IEEE80211_24GHZ_BAND, - }; - u32 rx_pkt_len = 0; - struct rtl_80211_hdr_1addr *ieee80211_hdr = NULL; - bool unicast_packet = false; - - /* 20 is for ps-poll */ - if ((skb->len >= (20 + sizeof(struct rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) { - /* first packet should not contain Rx aggregation header */ - query_rxdesc_status(skb, &stats, false); - /* TODO */ - /* hardware related info */ - /* Process the MPDU received */ - skb_trim(skb, skb->len - 4/*sCrcLng*/); - - rx_pkt_len = skb->len; - ieee80211_hdr = (struct rtl_80211_hdr_1addr *)skb->data; - unicast_packet = false; - if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) { - /* TODO */ - } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) { - /* TODO */ - } else { - /* unicast packet */ - unicast_packet = true; - } - - if (!ieee80211_rx(priv->ieee80211, skb, &stats)) { - dev_kfree_skb_any(skb); - } else { - priv->stats.rxoktotal++; - if (unicast_packet) - priv->stats.rxbytesunicast += rx_pkt_len; - } - } else { - priv->stats.rxurberr++; - netdev_dbg(dev, "actual_length: %d\n", skb->len); - dev_kfree_skb_any(skb); - } -} - -static void rtl819xusb_process_received_packet(struct net_device *dev, - struct ieee80211_rx_stats *pstats) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Get shifted bytes of Starting address of 802.11 header. */ - pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats); -#ifdef TODO /* about HCT */ - if (!Adapter->bInHctTest) - CountRxErrStatistics(Adapter, pRfd); -#endif -#ifdef ENABLE_PS /* for adding ps function in future */ - RT_RF_POWER_STATE rtState; - /* When RF is off, we should not count the packet for hw/sw synchronize - * reason, ie. there may be a duration while sw switch is changed and - * hw switch is being changed. - */ - Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, - (u8 *)(&rtState)); - if (rtState == eRfOff) - return; -#endif - priv->stats.rxframgment++; - -#ifdef TODO - RmMonitorSignalStrength(Adapter, pRfd); -#endif - /* We have to release RFD and return if rx pkt is cmd pkt. */ - if (rtl819xusb_rx_command_packet(dev, pstats)) - return; - -#ifdef SW_CRC_CHECK - SwCrcCheck(); -#endif -} - -static void query_rx_cmdpkt_desc_status(struct sk_buff *skb, - struct ieee80211_rx_stats *stats) -{ - struct rx_desc_819x_usb *desc = (struct rx_desc_819x_usb *)skb->data; - - /* Get Rx Descriptor Information */ - stats->virtual_address = (u8 *)skb->data; - stats->Length = desc->Length; - stats->RxDrvInfoSize = 0; - stats->RxBufShift = 0; - stats->packetlength = stats->Length - scrclng; - stats->fraglength = stats->packetlength; - stats->fragoffset = 0; - stats->ntotalfrag = 1; -} - -static void rtl8192_rx_cmd(struct sk_buff *skb) -{ - struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; - struct net_device *dev = info->dev; - /* TODO */ - struct ieee80211_rx_stats stats = { - .signal = 0, - .noise = 0x100 - 98, - .rate = 0, - .freq = IEEE80211_24GHZ_BAND, - }; - - if ((skb->len >= (20 + sizeof(struct rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) { - query_rx_cmdpkt_desc_status(skb, &stats); - /* prfd->queue_id = 1; */ - - /* Process the command packet received. */ - - rtl819xusb_process_received_packet(dev, &stats); - - dev_kfree_skb_any(skb); - } -} - -static void rtl8192_irq_rx_tasklet(struct tasklet_struct *t) -{ - struct r8192_priv *priv = from_tasklet(priv, t, irq_rx_tasklet); - struct sk_buff *skb; - struct rtl8192_rx_info *info; - - while (NULL != (skb = skb_dequeue(&priv->skb_queue))) { - info = (struct rtl8192_rx_info *)skb->cb; - switch (info->out_pipe) { - /* Nomal packet pipe */ - case 3: - priv->IrpPendingCount--; - rtl8192_rx_nomal(skb); - break; - - /* Command packet pipe */ - case 9: - RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n", - info->out_pipe); - - rtl8192_rx_cmd(skb); - break; - - default: /* should never get here! */ - RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n", - info->out_pipe); - dev_kfree_skb(skb); - break; - } - } -} - -static const struct net_device_ops rtl8192_netdev_ops = { - .ndo_open = rtl8192_open, - .ndo_stop = rtl8192_close, - .ndo_get_stats = rtl8192_stats, - .ndo_tx_timeout = tx_timeout, - .ndo_do_ioctl = rtl8192_ioctl, - .ndo_set_rx_mode = r8192_set_multicast, - .ndo_set_mac_address = r8192_set_mac_adr, - .ndo_validate_addr = eth_validate_addr, - .ndo_start_xmit = ieee80211_xmit, -}; - -/**************************************************************************** - * ---------------------------- USB_STUFF--------------------------- - *****************************************************************************/ - -static int rtl8192_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct net_device *dev = NULL; - struct r8192_priv *priv = NULL; - struct usb_device *udev = interface_to_usbdev(intf); - int ret; - - RT_TRACE(COMP_INIT, "Oops: i'm coming\n"); - - dev = alloc_ieee80211(sizeof(struct r8192_priv)); - if (!dev) - return -ENOMEM; - - usb_set_intfdata(intf, dev); - SET_NETDEV_DEV(dev, &intf->dev); - priv = ieee80211_priv(dev); - priv->ieee80211 = netdev_priv(dev); - priv->udev = udev; - - dev->netdev_ops = &rtl8192_netdev_ops; - - dev->wireless_handlers = &r8192_wx_handlers_def; - - dev->type = ARPHRD_ETHER; - - dev->watchdog_timeo = HZ * 3; - - if (dev_alloc_name(dev, ifname) < 0) { - RT_TRACE(COMP_INIT, - "Oops: devname already taken! Trying wlan%%d...\n"); - ifname = "wlan%d"; - dev_alloc_name(dev, ifname); - } - - RT_TRACE(COMP_INIT, "Driver probe completed1\n"); - if (rtl8192_init(dev) != 0) { - RT_TRACE(COMP_ERR, "Initialization failed"); - ret = -ENODEV; - goto fail; - } - netif_carrier_off(dev); - netif_stop_queue(dev); - - ret = register_netdev(dev); - if (ret) - goto fail2; - - RT_TRACE(COMP_INIT, "dev name=======> %s\n", dev->name); - rtl8192_debugfs_init_one(dev); - - RT_TRACE(COMP_INIT, "Driver probe completed\n"); - return 0; - -fail2: - rtl8192_down(dev); -fail: - kfree(priv->pFirmware); - priv->pFirmware = NULL; - rtl8192_usb_deleteendpoints(dev); - msleep(10); - free_ieee80211(dev); - - RT_TRACE(COMP_ERR, "wlan driver load failed\n"); - return ret; -} - -/* detach all the work and timer structure declared or inititialize - * in r8192U_init function. - */ -static void rtl8192_cancel_deferred_work(struct r8192_priv *priv) -{ - cancel_work_sync(&priv->reset_wq); - cancel_delayed_work(&priv->watch_dog_wq); - cancel_delayed_work(&priv->update_beacon_wq); - cancel_work_sync(&priv->qos_activate); -} - -static void rtl8192_usb_disconnect(struct usb_interface *intf) -{ - struct net_device *dev = usb_get_intfdata(intf); - struct r8192_priv *priv = ieee80211_priv(dev); - - - RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n"); - rtl8192_debugfs_exit_one(dev); - - unregister_netdev(dev); - - rtl8192_down(dev); - kfree(priv->pFirmware); - priv->pFirmware = NULL; - rtl8192_usb_deleteendpoints(dev); - usleep_range(10000, 11000); - free_ieee80211(dev); - - RT_TRACE(COMP_DOWN, "wlan driver removed\n"); -} - -static int rtl8192_usb_netdev_event(struct notifier_block *nb, unsigned long event, - void *data) -{ - struct net_device *netdev = netdev_notifier_info_to_dev(data); - - if (netdev->netdev_ops != &rtl8192_netdev_ops) - goto out; - - switch (event) { - case NETDEV_CHANGENAME: - rtl8192_debugfs_rename_one(netdev); - break; - default: - break; - } - -out: - return NOTIFY_DONE; -} - -static struct notifier_block rtl8192_usb_netdev_notifier = { - .notifier_call = rtl8192_usb_netdev_event, -}; - -static int __init rtl8192_usb_module_init(void) -{ - int ret; - - pr_info("\nLinux kernel driver for RTL8192 based WLAN cards\n"); - pr_info("Copyright (c) 2007-2008, Realsil Wlan\n"); - RT_TRACE(COMP_INIT, "Initializing module"); - RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT); - - ret = register_netdevice_notifier(&rtl8192_usb_netdev_notifier); - if (ret) { - pr_err("register_netdevice_notifier failed %d\n", ret); - return ret; - } - - rtl8192_debugfs_init(); - ret = ieee80211_debug_init(); - if (ret) { - pr_err("ieee80211_debug_init() failed %d\n", ret); - goto debugfs_exit; - } - - ret = ieee80211_crypto_init(); - if (ret) { - pr_err("ieee80211_crypto_init() failed %d\n", ret); - goto debug_exit; - } - - ret = ieee80211_crypto_tkip_init(); - if (ret) { - pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret); - goto crypto_exit; - } - - ret = ieee80211_crypto_ccmp_init(); - if (ret) { - pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret); - goto crypto_tkip_exit; - } - - ret = ieee80211_crypto_wep_init(); - if (ret) { - pr_err("ieee80211_crypto_wep_init() failed %d\n", ret); - goto crypto_ccmp_exit; - } - - ret = usb_register(&rtl8192_usb_driver); - if (ret) - goto crypto_wep_exit; - return ret; - -crypto_wep_exit: - ieee80211_crypto_wep_exit(); -crypto_ccmp_exit: - ieee80211_crypto_ccmp_exit(); -crypto_tkip_exit: - ieee80211_crypto_tkip_exit(); -crypto_exit: - ieee80211_crypto_deinit(); -debug_exit: - ieee80211_debug_exit(); -debugfs_exit: - rtl8192_debugfs_exit(); - unregister_netdevice_notifier(&rtl8192_usb_netdev_notifier); - return ret; -} - -static void __exit rtl8192_usb_module_exit(void) -{ - usb_deregister(&rtl8192_usb_driver); - ieee80211_crypto_wep_exit(); - ieee80211_crypto_ccmp_exit(); - ieee80211_crypto_tkip_exit(); - ieee80211_crypto_deinit(); - ieee80211_debug_exit(); - rtl8192_debugfs_exit(); - unregister_netdevice_notifier(&rtl8192_usb_netdev_notifier); - RT_TRACE(COMP_DOWN, "Exiting"); -} - -void EnableHWSecurityConfig8192(struct net_device *dev) -{ - u8 SECR_value = 0x0; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; - if (((ieee->pairwise_key_type == KEY_TYPE_WEP40) || (ieee->pairwise_key_type == KEY_TYPE_WEP104)) && (priv->ieee80211->auth_mode != 2)) { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } - /* add HWSec active enable here. - * default using hwsec. when peer AP is in N mode only and - * pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates - * it), use software security. when peer AP is in b,g,n mode mixed and - * pairwise_key_type is none_aes, use g mode hw security. - */ - - ieee->hwsec_active = 1; - - /* add hwsec_support flag to totol control hw_sec on/off */ - if ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_PURE_N_MODE) || !hwwep) { - ieee->hwsec_active = 0; - SECR_value &= ~SCR_RxDecEnable; - } - RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", - __func__, ieee->hwsec_active, ieee->pairwise_key_type, - SECR_value); - write_nic_byte(dev, SECR, SECR_value); -} - -void setKey(struct net_device *dev, u8 entryno, u8 keyindex, u16 keytype, - const u8 *macaddr, u8 defaultkey, u32 *keycontent) -{ - u32 target_command = 0; - u32 target_content = 0; - u16 us_config = 0; - u8 i; - - if (entryno >= TOTAL_CAM_ENTRY) - RT_TRACE(COMP_ERR, "cam entry exceeds in %s\n", __func__); - - RT_TRACE(COMP_SEC, - "====>to %s, dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", - __func__, dev, entryno, keyindex, keytype, macaddr); - - if (defaultkey) - us_config |= BIT(15) | (keytype << 2); - else - us_config |= BIT(15) | (keytype << 2) | keyindex; - - for (i = 0; i < CAM_CONTENT_COUNT; i++) { - target_command = i + CAM_CONTENT_COUNT * entryno; - target_command |= BIT(31) | BIT(16); - - if (i == 0) { /* MAC|Config */ - target_content = (u32)(*(macaddr + 0)) << 16 | - (u32)(*(macaddr + 1)) << 24 | - (u32)us_config; - - write_nic_dword(dev, WCAMI, target_content); - write_nic_dword(dev, RWCAM, target_command); - } else if (i == 1) { /* MAC */ - target_content = (u32)(*(macaddr + 2)) | - (u32)(*(macaddr + 3)) << 8 | - (u32)(*(macaddr + 4)) << 16 | - (u32)(*(macaddr + 5)) << 24; - write_nic_dword(dev, WCAMI, target_content); - write_nic_dword(dev, RWCAM, target_command); - } else { - /* Key Material */ - if (keycontent) { - write_nic_dword(dev, WCAMI, - *(keycontent + i - 2)); - write_nic_dword(dev, RWCAM, target_command); - } - } - } -} - -/*************************************************************************** - * ------------------- module init / exit stubs ---------------- - ****************************************************************************/ -module_init(rtl8192_usb_module_init); -module_exit(rtl8192_usb_module_exit); diff --git a/drivers/staging/rtl8192u/r8192U_debugfs.c b/drivers/staging/rtl8192u/r8192U_debugfs.c deleted file mode 100644 index fe8ef72506ee..000000000000 --- a/drivers/staging/rtl8192u/r8192U_debugfs.c +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/**************************************************************************** - * -----------------------------DEGUGFS STUFF------------------------- - ****************************************************************************/ -#include -#include -#include "r8192U.h" - -#define KBUILD_MODNAME "r8192u_usb" - -static int rtl8192_usb_stats_ap_show(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - struct ieee80211_network *target; - - list_for_each_entry(target, &ieee->network_list, list) { - const char *wpa = "non_WPA"; - - if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0) - wpa = "WPA"; - - seq_printf(m, "%s %s\n", target->ssid, wpa); - } - - return 0; -} - -static int rtl8192_usb_registers_show(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - int i, n, max = 0xff; - u8 byte_rd; - - seq_puts(m, "\n####################page 0##################\n "); - - for (n = 0; n <= max;) { - seq_printf(m, "\nD: %2x > ", n); - - for (i = 0; i < 16 && n <= max; i++, n++) { - read_nic_byte(dev, 0x000 | n, &byte_rd); - seq_printf(m, "%2x ", byte_rd); - } - } - - seq_puts(m, "\n####################page 1##################\n "); - for (n = 0; n <= max;) { - seq_printf(m, "\nD: %2x > ", n); - - for (i = 0; i < 16 && n <= max; i++, n++) { - read_nic_byte(dev, 0x100 | n, &byte_rd); - seq_printf(m, "%2x ", byte_rd); - } - } - - seq_puts(m, "\n####################page 3##################\n "); - for (n = 0; n <= max;) { - seq_printf(m, "\nD: %2x > ", n); - - for (i = 0; i < 16 && n <= max; i++, n++) { - read_nic_byte(dev, 0x300 | n, &byte_rd); - seq_printf(m, "%2x ", byte_rd); - } - } - - seq_putc(m, '\n'); - return 0; -} - -static int rtl8192_usb_stats_tx_show(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct r8192_priv *priv = ieee80211_priv(dev); - - seq_printf(m, - "TX VI priority ok int: %lu\n" - "TX VI priority error int: %lu\n" - "TX VO priority ok int: %lu\n" - "TX VO priority error int: %lu\n" - "TX BE priority ok int: %lu\n" - "TX BE priority error int: %lu\n" - "TX BK priority ok int: %lu\n" - "TX BK priority error int: %lu\n" - "TX MANAGE priority ok int: %lu\n" - "TX MANAGE priority error int: %lu\n" - "TX BEACON priority ok int: %lu\n" - "TX BEACON priority error int: %lu\n" - "TX queue resume: %lu\n" - "TX queue stopped?: %d\n" - "TX fifo overflow: %lu\n" - "TX VI queue: %d\n" - "TX VO queue: %d\n" - "TX BE queue: %d\n" - "TX BK queue: %d\n" - "TX VI dropped: %lu\n" - "TX VO dropped: %lu\n" - "TX BE dropped: %lu\n" - "TX BK dropped: %lu\n" - "TX total data packets %lu\n", - priv->stats.txviokint, - priv->stats.txvierr, - priv->stats.txvookint, - priv->stats.txvoerr, - priv->stats.txbeokint, - priv->stats.txbeerr, - priv->stats.txbkokint, - priv->stats.txbkerr, - priv->stats.txmanageokint, - priv->stats.txmanageerr, - priv->stats.txbeaconokint, - priv->stats.txbeaconerr, - priv->stats.txresumed, - netif_queue_stopped(dev), - priv->stats.txoverflow, - atomic_read(&(priv->tx_pending[VI_PRIORITY])), - atomic_read(&(priv->tx_pending[VO_PRIORITY])), - atomic_read(&(priv->tx_pending[BE_PRIORITY])), - atomic_read(&(priv->tx_pending[BK_PRIORITY])), - priv->stats.txvidrop, - priv->stats.txvodrop, - priv->stats.txbedrop, - priv->stats.txbkdrop, - priv->stats.txdatapkt - ); - - return 0; -} - -static int rtl8192_usb_stats_rx_show(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct r8192_priv *priv = ieee80211_priv(dev); - - seq_printf(m, - "RX packets: %lu\n" - "RX urb status error: %lu\n" - "RX invalid urb error: %lu\n", - priv->stats.rxoktotal, - priv->stats.rxstaterr, - priv->stats.rxurberr); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_rx); -DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_tx); -DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_stats_ap); -DEFINE_SHOW_ATTRIBUTE(rtl8192_usb_registers); - -void rtl8192_debugfs_init_one(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct dentry *parent_dir = debugfs_lookup(KBUILD_MODNAME, NULL); - struct dentry *dir = debugfs_create_dir(dev->name, parent_dir); - - debugfs_create_file("stats-rx", 0444, dir, dev, &rtl8192_usb_stats_rx_fops); - debugfs_create_file("stats-tx", 0444, dir, dev, &rtl8192_usb_stats_tx_fops); - debugfs_create_file("stats-ap", 0444, dir, dev, &rtl8192_usb_stats_ap_fops); - debugfs_create_file("registers", 0444, dir, dev, &rtl8192_usb_registers_fops); - - priv->debugfs_dir = dir; -} - -void rtl8192_debugfs_exit_one(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - debugfs_remove_recursive(priv->debugfs_dir); -} - -void rtl8192_debugfs_rename_one(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct dentry *parent_dir = debugfs_lookup(KBUILD_MODNAME, NULL); - - debugfs_rename(parent_dir, priv->debugfs_dir, parent_dir, dev->name); -} - -void rtl8192_debugfs_init(void) -{ - debugfs_create_dir(KBUILD_MODNAME, NULL); -} - -void rtl8192_debugfs_exit(void) -{ - debugfs_remove_recursive(debugfs_lookup(KBUILD_MODNAME, NULL)); -} diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c deleted file mode 100644 index cbae852478ea..000000000000 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ /dev/null @@ -1,2821 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/*++ - * Copyright-c Realtek Semiconductor Corp. All rights reserved. - * - * Module Name: - * r8192U_dm.c - * - * Abstract: - * HW dynamic mechanism. - *-- - */ -#include "r8192U.h" -#include "r8192U_dm.h" -#include "r8192U_hw.h" -#include "r819xU_phy.h" -#include "r819xU_phyreg.h" -#include "r8190_rtl8256.h" -#include "r819xU_cmdpkt.h" -/*---------------------------Define Local Constant---------------------------*/ -/* Indicate different AP vendor for IOT issue. */ -static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { - 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f -}; - -static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { - 0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f -}; - -#define RTK_UL_EDCA 0xa44f -#define RTK_DL_EDCA 0x5e4322 -/*---------------------------Define Local Constant---------------------------*/ - - -/*------------------------Define global variable-----------------------------*/ -/* Debug variable ? */ -struct dig dm_digtable; -/* Store current software write register content for MAC PHY. */ -u8 dm_shadow[16][256] = { {0} }; -/* For Dynamic Rx Path Selection by Signal Strength */ -static struct dynamic_rx_path_sel DM_RxPathSelTable; - -extern void dm_check_fsync(struct net_device *dev); - -/* DM --> Rate Adaptive */ -static void dm_check_rate_adaptive(struct net_device *dev); - -/* DM --> Bandwidth switch */ -static void dm_init_bandwidth_autoswitch(struct net_device *dev); -static void dm_bandwidth_autoswitch(struct net_device *dev); - -/* DM --> TX power control */ -static void dm_check_txpower_tracking(struct net_device *dev); - -/* DM --> Dynamic Init Gain by RSSI */ -static void dm_dig_init(struct net_device *dev); -static void dm_ctrl_initgain_byrssi(struct net_device *dev); -static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); -static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev); -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev); -static void dm_initial_gain(struct net_device *dev); -static void dm_pd_th(struct net_device *dev); -static void dm_cs_ratio(struct net_device *dev); - -static void dm_init_ctstoself(struct net_device *dev); -/* DM --> EDCA turbo mode control */ -static void dm_check_edca_turbo(struct net_device *dev); - -/* DM --> Check PBC */ -static void dm_check_pbc_gpio(struct net_device *dev); - -/* DM --> Check current RX RF path state */ -static void dm_check_rx_path_selection(struct net_device *dev); -static void dm_init_rxpath_selection(struct net_device *dev); -static void dm_rxpath_sel_byrssi(struct net_device *dev); - -/* DM --> Fsync for broadcom ap */ -static void dm_init_fsync(struct net_device *dev); -static void dm_deInit_fsync(struct net_device *dev); - -/* Added by vivi, 20080522 */ -static void dm_check_txrateandretrycount(struct net_device *dev); - -/*---------------------Define local function prototype-----------------------*/ - -/*---------------------Define of Tx Power Control For Near/Far Range --------*/ /*Add by Jacken 2008/02/18 */ -static void dm_init_dynamic_txpower(struct net_device *dev); -static void dm_dynamic_txpower(struct net_device *dev); - -/* DM --> For rate adaptive and DIG, we must send RSSI to firmware */ -static void dm_send_rssi_tofw(struct net_device *dev); -static void dm_ctstoself(struct net_device *dev); -/*---------------------------Define function prototype------------------------*/ -/* ================================================================================ - * HW Dynamic mechanism interface. - * ================================================================================ - * - * - * Description: - * Prepare SW resource for HW dynamic mechanism. - * - * Assumption: - * This function is only invoked at driver initialization once. - */ -void init_hal_dm(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */ - priv->undecorated_smoothed_pwdb = -1; - - /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */ - dm_init_dynamic_txpower(dev); - init_rate_adaptive(dev); - dm_dig_init(dev); - dm_init_edca_turbo(dev); - dm_init_bandwidth_autoswitch(dev); - dm_init_fsync(dev); - dm_init_rxpath_selection(dev); - dm_init_ctstoself(dev); - -} /* InitHalDm */ - -void deinit_hal_dm(struct net_device *dev) -{ - dm_deInit_fsync(dev); -} - -#ifdef USB_RX_AGGREGATION_SUPPORT -void dm_CheckRxAggregation(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - static unsigned long lastTxOkCnt; - static unsigned long lastRxOkCnt; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - - if ((curTxOkCnt + curRxOkCnt) < 15000000) - return; - - if (curTxOkCnt > 4*curRxOkCnt) { - if (priv->bCurrentRxAggrEnable) { - write_nic_dword(dev, 0x1a8, 0); - priv->bCurrentRxAggrEnable = false; - } - } else { - if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) { - u32 ulValue; - - ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) | - (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout); - /* If usb rx firmware aggregation is enabled, - * when anyone of three threshold conditions above is reached, - * firmware will send aggregated packet to driver. - */ - write_nic_dword(dev, 0x1a8, ulValue); - priv->bCurrentRxAggrEnable = true; - } - } - - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; -} /* dm_CheckEdcaTurbo */ -#endif - -void hal_dm_watchdog(struct net_device *dev) -{ - /*Add by amy 2008/05/15 ,porting from windows code.*/ - dm_check_rate_adaptive(dev); - dm_dynamic_txpower(dev); - dm_check_txrateandretrycount(dev); - dm_check_txpower_tracking(dev); - dm_ctrl_initgain_byrssi(dev); - dm_check_edca_turbo(dev); - dm_bandwidth_autoswitch(dev); - dm_check_rx_path_selection(dev); - dm_check_fsync(dev); - - /* Add by amy 2008-05-15 porting from windows code. */ - dm_check_pbc_gpio(dev); - dm_send_rssi_tofw(dev); - dm_ctstoself(dev); -#ifdef USB_RX_AGGREGATION_SUPPORT - dm_CheckRxAggregation(dev); -#endif -} /* HalDmWatchDog */ - -/* Decide Rate Adaptive Set according to distance (signal strength) - * 01/11/2008 MHC Modify input arguments and RATR table level. - * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call - * the function after making sure RF_Type. - */ -void init_rate_adaptive(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; - - pra->ratr_state = DM_RATR_STA_MAX; - pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH; - pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5; - pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5; - - pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5; - pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M; - pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M; - - if (priv->CustomerID == RT_CID_819x_Netcore) - pra->ping_rssi_enable = 1; - else - pra->ping_rssi_enable = 0; - pra->ping_rssi_thresh_for_ra = 15; - - if (priv->rf_type == RF_2T4R) { - /* 07/10/08 MH Modify for RA smooth scheme. - * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code. - */ - pra->upper_rssi_threshold_ratr = 0x8f0f0000; - pra->middle_rssi_threshold_ratr = 0x8f0ff000; - pra->low_rssi_threshold_ratr = 0x8f0ff001; - pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; - pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; - pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */ - } else if (priv->rf_type == RF_1T2R) { - pra->upper_rssi_threshold_ratr = 0x000f0000; - pra->middle_rssi_threshold_ratr = 0x000ff000; - pra->low_rssi_threshold_ratr = 0x000ff001; - pra->low_rssi_threshold_ratr_40M = 0x000ff005; - pra->low_rssi_threshold_ratr_20M = 0x000ff001; - pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */ - } - -} /* InitRateAdaptive */ - -/*----------------------------------------------------------------------------- - * Function: dm_check_rate_adaptive() - * - * Overview: - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_check_rate_adaptive(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; - u32 currentRATR, targetRATR = 0; - u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; - bool bshort_gi_enabled = false; - static u8 ping_rssi_state; - - if (!priv->up) { - RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); - return; - } - - if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */ - return; - - /* TODO: Only 11n mode is implemented currently, */ - if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G || - priv->ieee80211->mode == WIRELESS_MODE_N_5G)) - return; - - if (priv->ieee80211->state == IEEE80211_LINKED) { - - /* Check whether Short GI is enabled */ - bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || - (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); - - pra->upper_rssi_threshold_ratr = - (pra->upper_rssi_threshold_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - pra->middle_rssi_threshold_ratr = - (pra->middle_rssi_threshold_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - } else { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - } - /* cosa add for test */ - pra->ping_rssi_ratr = - (pra->ping_rssi_ratr & (~BIT(31))) | - ((bshort_gi_enabled) ? BIT(31) : 0); - - /* 2007/10/08 MH We support RA smooth scheme now. When it is the first - * time to link with AP. We will not change upper/lower threshold. If - * STA stay in high or low level, we must change two different threshold - * to prevent jumping frequently. - */ - if (pra->ratr_state == DM_RATR_STA_HIGH) { - HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? - (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); - } else if (pra->ratr_state == DM_RATR_STA_LOW) { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? - (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M); - } else { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? - (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); - } - - if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) { - pra->ratr_state = DM_RATR_STA_HIGH; - targetRATR = pra->upper_rssi_threshold_ratr; - } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) { - pra->ratr_state = DM_RATR_STA_MIDDLE; - targetRATR = pra->middle_rssi_threshold_ratr; - } else { - pra->ratr_state = DM_RATR_STA_LOW; - targetRATR = pra->low_rssi_threshold_ratr; - } - - /* cosa add for test */ - if (pra->ping_rssi_enable) { - if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) { - if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || - ping_rssi_state) { - pra->ratr_state = DM_RATR_STA_LOW; - targetRATR = pra->ping_rssi_ratr; - ping_rssi_state = 1; - } - } else { - ping_rssi_state = 0; - } - } - - /* 2008.04.01 - * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - */ - if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev)) - targetRATR &= 0xf00fffff; - - /* Check whether updating of RATR0 is required */ - read_nic_dword(dev, RATR0, ¤tRATR); - if (targetRATR != currentRATR) { - u32 ratr_value; - - ratr_value = targetRATR; - RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR); - if (priv->rf_type == RF_1T2R) - ratr_value &= ~(RATE_ALL_OFDM_2SS); - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); - - pra->last_ratr = targetRATR; - } - - } else { - pra->ratr_state = DM_RATR_STA_MAX; - } - -} /* dm_CheckRateAdaptive */ - -static void dm_init_bandwidth_autoswitch(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; - priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; - priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false; - -} /* dm_init_bandwidth_autoswitch */ - -static void dm_bandwidth_autoswitch(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable) - return; - if (!priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz) { /* If send packets in 40 Mhz in 20/40 */ - if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz) - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true; - } else { /* in force send packets in 20 Mhz in 20/40 */ - if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz) - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; - } -} /* dm_BandwidthAutoSwitch */ - -/* OFDM default at 0db, index=6. */ -static u32 OFDMSwingTable[OFDM_Table_Length] = { - 0x7f8001fe, /* 0, +6db */ - 0x71c001c7, /* 1, +5db */ - 0x65400195, /* 2, +4db */ - 0x5a400169, /* 3, +3db */ - 0x50800142, /* 4, +2db */ - 0x47c0011f, /* 5, +1db */ - 0x40000100, /* 6, +0db ===> default, upper for higher temperature, lower for low temperature */ - 0x390000e4, /* 7, -1db */ - 0x32c000cb, /* 8, -2db */ - 0x2d4000b5, /* 9, -3db */ - 0x288000a2, /* 10, -4db */ - 0x24000090, /* 11, -5db */ - 0x20000080, /* 12, -6db */ - 0x1c800072, /* 13, -7db */ - 0x19800066, /* 14, -8db */ - 0x26c0005b, /* 15, -9db */ - 0x24400051, /* 16, -10db */ - 0x12000048, /* 17, -11db */ - 0x10000040 /* 18, -12db */ -}; - -static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0db ===> CCK40M default */ - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 1, -1db */ - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 2, -2db */ - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 3, -3db */ - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 4, -4db */ - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 5, -5db */ - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 6, -6db ===> CCK20M default */ - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 7, -7db */ - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 8, -8db */ - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 9, -9db */ - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 10, -10db */ - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} /* 11, -11db */ -}; - -static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0db ===> CCK40M default */ - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 1, -1db */ - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 2, -2db */ - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 3, -3db */ - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 4, -4db */ - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 5, -5db */ - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 6, -6db ===> CCK20M default */ - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 7, -7db */ - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 8, -8db */ - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 9, -9db */ - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 10, -10db */ - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} /* 11, -11db */ -}; - -static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - bool viviflag = false; - struct tx_config_cmd tx_cmd; - u8 powerlevelOFDM24G; - int i = 0, j = 0, k = 0; - u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0}; - u32 Value; - u8 Pwr_Flag; - u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0; - bool rtStatus = true; - u32 delta = 0; - - write_nic_byte(dev, 0x1ba, 0); - - priv->ieee80211->bdynamic_txpower_enable = false; - - powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); - RF_Type = priv->rf_type; - Value = (RF_Type<<8) | powerlevelOFDM24G; - - RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G); - - for (j = 0; j <= 30; j++) { /* fill tx_cmd */ - tx_cmd.cmd_op = TXCMD_SET_TX_PWR_TRACKING; - tx_cmd.cmd_length = sizeof(tx_cmd.cmd_op); - tx_cmd.cmd_value = Value; - rtStatus = SendTxCommandPacket(dev, &tx_cmd, sizeof(struct tx_config_cmd)); - if (rtStatus == RT_STATUS_FAILURE) - RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n"); - usleep_range(1000, 2000); - for (i = 0; i <= 30; i++) { - read_nic_byte(dev, 0x1ba, &Pwr_Flag); - - if (Pwr_Flag == 0) { - usleep_range(1000, 2000); - continue; - } - read_nic_word(dev, 0x13c, &Avg_TSSI_Meas); - if (Avg_TSSI_Meas == 0) { - write_nic_byte(dev, 0x1ba, 0); - break; - } - - for (k = 0; k < 5; k++) { - if (k != 4) - read_nic_byte(dev, 0x134+k, &tmp_report[k]); - else - read_nic_byte(dev, 0x13e, &tmp_report[k]); - RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]); - } - - /* check if the report value is right */ - for (k = 0; k < 5; k++) { - if (tmp_report[k] <= 20) { - viviflag = true; - break; - } - } - if (viviflag) { - write_nic_byte(dev, 0x1ba, 0); - viviflag = false; - RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n"); - for (k = 0; k < 5; k++) - tmp_report[k] = 0; - break; - } - - for (k = 0; k < 5; k++) - Avg_TSSI_Meas_from_driver += tmp_report[k]; - - Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5; - RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver); - TSSI_13dBm = priv->TSSI_13dBm; - RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm); - - if (Avg_TSSI_Meas_from_driver > TSSI_13dBm) - delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; - else - delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver; - - if (delta <= E_FOR_TX_POWER_TRACK) { - priv->ieee80211->bdynamic_txpower_enable = true; - write_nic_byte(dev, 0x1ba, 0); - RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation); - return; - } - if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) { - if (priv->rfa_txpowertrackingindex > 0) { - priv->rfa_txpowertrackingindex--; - if (priv->rfa_txpowertrackingindex_real > 4) { - priv->rfa_txpowertrackingindex_real--; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); - } - } - } else { - if (priv->rfa_txpowertrackingindex < 36) { - priv->rfa_txpowertrackingindex++; - priv->rfa_txpowertrackingindex_real++; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); - } - } - priv->cck_present_attenuation_difference - = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; - - if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) - priv->cck_present_attenuation - = priv->cck_present_attenuation_20Mdefault + priv->cck_present_attenuation_difference; - else - priv->cck_present_attenuation - = priv->cck_present_attenuation_40Mdefault + priv->cck_present_attenuation_difference; - - if (priv->cck_present_attenuation > -1 && priv->cck_present_attenuation < 23) { - if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation); - - if (priv->cck_present_attenuation_difference <= -12 || priv->cck_present_attenuation_difference >= 24) { - priv->ieee80211->bdynamic_txpower_enable = true; - write_nic_byte(dev, 0x1ba, 0); - RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); - return; - } - - write_nic_byte(dev, 0x1ba, 0); - Avg_TSSI_Meas_from_driver = 0; - for (k = 0; k < 5; k++) - tmp_report[k] = 0; - break; - } - } - priv->ieee80211->bdynamic_txpower_enable = true; - write_nic_byte(dev, 0x1ba, 0); -} - -static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev) -{ -#define ThermalMeterVal 9 - struct r8192_priv *priv = ieee80211_priv(dev); - u32 tmpRegA, TempCCk; - u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; - int i = 0, CCKSwingNeedUpdate = 0; - - if (!priv->btxpower_trackingInit) { - /* Query OFDM default setting */ - tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); - for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */ - if (tmpRegA == OFDMSwingTable[i]) { - priv->OFDM_index = (u8)i; - RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n", - rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index); - } - } - - /* Query CCK default setting From 0xa22 */ - TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); - for (i = 0; i < CCK_Table_length; i++) { - if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) { - priv->CCK_index = (u8) i; - RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n", - rCCK0_TxFilter1, TempCCk, priv->CCK_index); - break; - } - } - priv->btxpower_trackingInit = true; - return; - } - - /* ========================== - * this is only for test, should be masked - * ========================== - */ - - /* read and filter out unreasonable value */ - tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); /* 0x12: RF Reg[10:7] */ - RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA); - if (tmpRegA < 3 || tmpRegA > 13) - return; - if (tmpRegA >= 12) /* if over 12, TP will be bad when high temperature */ - tmpRegA = 12; - RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA); - priv->ThermalMeter[0] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */ - priv->ThermalMeter[1] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */ - - /* Get current RF-A temperature index */ - if (priv->ThermalMeter[0] >= (u8)tmpRegA) { /* lower temperature */ - tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); - tmpCCK40Mindex = tmpCCK20Mindex - 6; - if (tmpOFDMindex >= OFDM_Table_Length) - tmpOFDMindex = OFDM_Table_Length-1; - if (tmpCCK20Mindex >= CCK_Table_length) - tmpCCK20Mindex = CCK_Table_length-1; - if (tmpCCK40Mindex >= CCK_Table_length) - tmpCCK40Mindex = CCK_Table_length-1; - } else { - tmpval = (u8)tmpRegA - priv->ThermalMeter[0]; - - if (tmpval >= 6) { - /* higher temperature */ - tmpOFDMindex = 0; - tmpCCK20Mindex = 0; - } else { - /* max to +6dB */ - tmpOFDMindex = 6 - tmpval; - tmpCCK20Mindex = 6 - tmpval; - } - tmpCCK40Mindex = 0; - } - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) /* 40M */ - tmpCCKindex = tmpCCK40Mindex; - else - tmpCCKindex = tmpCCK20Mindex; - - if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - CCKSwingNeedUpdate = 1; - } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - CCKSwingNeedUpdate = 1; - } - - if (priv->CCK_index != tmpCCKindex) { - priv->CCK_index = tmpCCKindex; - CCKSwingNeedUpdate = 1; - } - - if (CCKSwingNeedUpdate) { - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - if (priv->OFDM_index != tmpOFDMindex) { - priv->OFDM_index = tmpOFDMindex; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); - RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", - priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]); - } - priv->txpower_count = 0; -} - -void dm_txpower_trackingcallback(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq); - struct net_device *dev = priv->ieee80211->dev; - - if (priv->bDcut) - dm_TXPowerTrackingCallback_TSSI(dev); - else - dm_TXPowerTrackingCallback_ThermalMeter(dev); -} - -static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Initial the Tx BB index and mapping value */ - priv->txbbgain_table[0].txbb_iq_amplifygain = 12; - priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe; - priv->txbbgain_table[1].txbb_iq_amplifygain = 11; - priv->txbbgain_table[1].txbbgain_value = 0x788001e2; - priv->txbbgain_table[2].txbb_iq_amplifygain = 10; - priv->txbbgain_table[2].txbbgain_value = 0x71c001c7; - priv->txbbgain_table[3].txbb_iq_amplifygain = 9; - priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae; - priv->txbbgain_table[4].txbb_iq_amplifygain = 8; - priv->txbbgain_table[4].txbbgain_value = 0x65400195; - priv->txbbgain_table[5].txbb_iq_amplifygain = 7; - priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f; - priv->txbbgain_table[6].txbb_iq_amplifygain = 6; - priv->txbbgain_table[6].txbbgain_value = 0x5a400169; - priv->txbbgain_table[7].txbb_iq_amplifygain = 5; - priv->txbbgain_table[7].txbbgain_value = 0x55400155; - priv->txbbgain_table[8].txbb_iq_amplifygain = 4; - priv->txbbgain_table[8].txbbgain_value = 0x50800142; - priv->txbbgain_table[9].txbb_iq_amplifygain = 3; - priv->txbbgain_table[9].txbbgain_value = 0x4c000130; - priv->txbbgain_table[10].txbb_iq_amplifygain = 2; - priv->txbbgain_table[10].txbbgain_value = 0x47c0011f; - priv->txbbgain_table[11].txbb_iq_amplifygain = 1; - priv->txbbgain_table[11].txbbgain_value = 0x43c0010f; - priv->txbbgain_table[12].txbb_iq_amplifygain = 0; - priv->txbbgain_table[12].txbbgain_value = 0x40000100; - priv->txbbgain_table[13].txbb_iq_amplifygain = -1; - priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2; - priv->txbbgain_table[14].txbb_iq_amplifygain = -2; - priv->txbbgain_table[14].txbbgain_value = 0x390000e4; - priv->txbbgain_table[15].txbb_iq_amplifygain = -3; - priv->txbbgain_table[15].txbbgain_value = 0x35c000d7; - priv->txbbgain_table[16].txbb_iq_amplifygain = -4; - priv->txbbgain_table[16].txbbgain_value = 0x32c000cb; - priv->txbbgain_table[17].txbb_iq_amplifygain = -5; - priv->txbbgain_table[17].txbbgain_value = 0x300000c0; - priv->txbbgain_table[18].txbb_iq_amplifygain = -6; - priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5; - priv->txbbgain_table[19].txbb_iq_amplifygain = -7; - priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab; - priv->txbbgain_table[20].txbb_iq_amplifygain = -8; - priv->txbbgain_table[20].txbbgain_value = 0x288000a2; - priv->txbbgain_table[21].txbb_iq_amplifygain = -9; - priv->txbbgain_table[21].txbbgain_value = 0x26000098; - priv->txbbgain_table[22].txbb_iq_amplifygain = -10; - priv->txbbgain_table[22].txbbgain_value = 0x24000090; - priv->txbbgain_table[23].txbb_iq_amplifygain = -11; - priv->txbbgain_table[23].txbbgain_value = 0x22000088; - priv->txbbgain_table[24].txbb_iq_amplifygain = -12; - priv->txbbgain_table[24].txbbgain_value = 0x20000080; - priv->txbbgain_table[25].txbb_iq_amplifygain = -13; - priv->txbbgain_table[25].txbbgain_value = 0x1a00006c; - priv->txbbgain_table[26].txbb_iq_amplifygain = -14; - priv->txbbgain_table[26].txbbgain_value = 0x1c800072; - priv->txbbgain_table[27].txbb_iq_amplifygain = -15; - priv->txbbgain_table[27].txbbgain_value = 0x18000060; - priv->txbbgain_table[28].txbb_iq_amplifygain = -16; - priv->txbbgain_table[28].txbbgain_value = 0x19800066; - priv->txbbgain_table[29].txbb_iq_amplifygain = -17; - priv->txbbgain_table[29].txbbgain_value = 0x15800056; - priv->txbbgain_table[30].txbb_iq_amplifygain = -18; - priv->txbbgain_table[30].txbbgain_value = 0x26c0005b; - priv->txbbgain_table[31].txbb_iq_amplifygain = -19; - priv->txbbgain_table[31].txbbgain_value = 0x14400051; - priv->txbbgain_table[32].txbb_iq_amplifygain = -20; - priv->txbbgain_table[32].txbbgain_value = 0x24400051; - priv->txbbgain_table[33].txbb_iq_amplifygain = -21; - priv->txbbgain_table[33].txbbgain_value = 0x1300004c; - priv->txbbgain_table[34].txbb_iq_amplifygain = -22; - priv->txbbgain_table[34].txbbgain_value = 0x12000048; - priv->txbbgain_table[35].txbb_iq_amplifygain = -23; - priv->txbbgain_table[35].txbbgain_value = 0x11000044; - priv->txbbgain_table[36].txbb_iq_amplifygain = -24; - priv->txbbgain_table[36].txbbgain_value = 0x10000040; - - /* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - * This Table is for CH1~CH13 - */ - priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04; - - priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04; - - priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01; - - /* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - * This Table is for CH14 - */ - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00; - - priv->btxpower_tracking = true; - priv->txpower_count = 0; - priv->btxpower_trackingInit = false; -} - -static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism - * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w - * 3-wire by driver causes RF to go into a wrong state. - */ - if (priv->ieee80211->FwRWRF) - priv->btxpower_tracking = true; - else - priv->btxpower_tracking = false; - priv->txpower_count = 0; - priv->btxpower_trackingInit = false; -} - -void dm_initialize_txpower_tracking(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bDcut) - dm_InitializeTXPowerTracking_TSSI(dev); - else - dm_InitializeTXPowerTracking_ThermalMeter(dev); -} /* dm_InitializeTXPowerTracking */ - -static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u32 tx_power_track_counter; - - if (!priv->btxpower_tracking) - return; - if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0)) - queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0); - tx_power_track_counter++; -} - -static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u8 TM_Trigger; - if (!priv->btxpower_tracking) - return; - if (priv->txpower_count <= 2) { - priv->txpower_count++; - return; - } - - if (!TM_Trigger) { - /* Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash - * actually write reg0x02 bit1=0, then bit1=1. - * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); - */ - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - TM_Trigger = 1; - return; - } - queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0); - TM_Trigger = 0; -} - -static void dm_check_txpower_tracking(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - -#ifdef RTL8190P - dm_CheckTXPowerTracking_TSSI(dev); -#else - if (priv->bDcut) - dm_CheckTXPowerTracking_TSSI(dev); - else - dm_CheckTXPowerTracking_ThermalMeter(dev); -#endif - -} /* dm_CheckTXPowerTracking */ - -static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) -{ - u32 TempVal; - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Write 0xa22 0xa23 */ - TempVal = 0; - if (!bInCH14) { - /* Write 0xa22 0xa23 */ - TempVal = priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] + - (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8); - - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - /* Write 0xa24 ~ 0xa27 */ - TempVal = priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] + - (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) + - (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+ - (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - /* Write 0xa28 0xa29 */ - TempVal = priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] + - (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8); - - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } else { - TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] + - (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8); - - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - /* Write 0xa24 ~ 0xa27 */ - TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] + - (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) + - (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+ - (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - /* Write 0xa28 0xa29 */ - TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] + - (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8); - - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - } -} - -static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) -{ - u32 TempVal; - struct r8192_priv *priv = ieee80211_priv(dev); - - TempVal = 0; - if (!bInCH14) { - /* Write 0xa22 0xa23 */ - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8); - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter1, TempVal); - /* Write 0xa24 ~ 0xa27 */ - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter2, TempVal); - /* Write 0xa28 0xa29 */ - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8); - - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_DebugPort, TempVal); - } else { - /* Write 0xa22 0xa23 */ - TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + - (CCKSwingTable_Ch14[priv->CCK_index][1]<<8); - - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter1, TempVal); - /* Write 0xa24 ~ 0xa27 */ - TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + - (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ - (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter2, TempVal); - /* Write 0xa28 0xa29 */ - TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + - (CCKSwingTable_Ch14[priv->CCK_index][7]<<8); - - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_DebugPort, TempVal); - } -} - -void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) -{ /* dm_CCKTxPowerAdjust */ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bDcut) - dm_CCKTxPowerAdjust_TSSI(dev, binch14); - else - dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); -} - -#ifndef RTL8192U -static void dm_txpower_reset_recovery( - struct net_device *dev -) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attenuation); - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain); - -} /* dm_TXPowerResetRecovery */ - -void dm_restore_dynamic_mechanism_state(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 reg_ratr = priv->rate_adaptive.last_ratr; - - if (!priv->up) { - RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); - return; - } - - /* Restore previous state for rate adaptive */ - if (priv->rate_adaptive.rate_adaptive_disabled) - return; - /* TODO: Only 11n mode is implemented currently, */ - if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G || - priv->ieee80211->mode == WIRELESS_MODE_N_5G)) - return; - - { - /* 2007/11/15 MH Copy from 8190PCI. */ - u32 ratr_value; - - ratr_value = reg_ratr; - if (priv->rf_type == RF_1T2R) { /* 1T2R, Spatial Stream 2 should be disabled */ - ratr_value &= ~(RATE_ALL_OFDM_2SS); - } - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); - } - /* Restore TX Power Tracking Index */ - if (priv->btxpower_trackingInit && priv->btxpower_tracking) - dm_txpower_reset_recovery(dev); - - /* Restore BB Initial Gain */ - dm_bb_initialgain_restore(dev); - -} /* DM_RestoreDynamicMechanismState */ - -static void dm_bb_initialgain_restore(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 bit_mask = 0x7f; /* Bit0~ Bit6 */ - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - /* Disable Initial Gain */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */ - rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1); - bit_mask = bMaskByte2; - rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); - - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca); - /* Enable Initial Gain */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */ - -} /* dm_BBInitialGainRestore */ - -static void dm_bb_initialgain_backup(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */ - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */ - priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask); - priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask); - priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask); - priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask); - bit_mask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); - - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca); - -} /* dm_BBInitialGainBakcup */ - -#endif -/*----------------------------------------------------------------------------- - * Function: dm_dig_init() - * - * Overview: Set DIG scheme init value. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_dig_init(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - /* 2007/10/05 MH Disable DIG scheme now. Not tested. */ - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; - dm_digtable.dig_algorithm_switch = 0; - - /* 2007/10/04 MH Define init gain threshold. */ - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - - dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; - - dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; - dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; - - dm_digtable.rssi_val = 50; /* for new dig debug rssi value */ - dm_digtable.backoff_val = DM_DIG_BACKOFF; - if (priv->CustomerID == RT_CID_819x_Netcore) - dm_digtable.rx_gain_range_min = DM_DIG_MIN_NETCORE; - else - dm_digtable.rx_gain_range_min = DM_DIG_MIN; - -} /* dm_dig_init */ - -/*----------------------------------------------------------------------------- - * Function: dm_ctrl_initgain_byrssi() - * - * Overview: Driver must monitor RSSI and notify firmware to change initial - * gain according to different threshold. BB team provide the - * suggested solution. - * - * Input: struct net_device *dev - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_ctrl_initgain_byrssi(struct net_device *dev) -{ - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); - else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - dm_ctrl_initgain_byrssi_by_driverrssi(dev); - /* ; */ - else - return; -} - -static void dm_ctrl_initgain_byrssi_by_driverrssi( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 i; - static u8 fw_dig; - - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm_switch) /* if switched algorithm, we have to disable FW Dig. */ - fw_dig = 0; - - if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */ - /* FW DIG Off */ - for (i = 0; i < 3; i++) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */ - fw_dig++; - dm_digtable.dig_state = DM_STA_DIG_OFF; /* fw dig off. */ - } - - if (priv->ieee80211->state == IEEE80211_LINKED) - dm_digtable.cur_connect_state = DIG_CONNECT; - else - dm_digtable.cur_connect_state = DIG_DISCONNECT; - - dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; - dm_initial_gain(dev); - dm_pd_th(dev); - dm_cs_ratio(dev); - if (dm_digtable.dig_algorithm_switch) - dm_digtable.dig_algorithm_switch = 0; - dm_digtable.pre_connect_state = dm_digtable.cur_connect_state; - -} /* dm_CtrlInitGainByRssi */ - -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u32 reset_cnt; - u8 i; - - if (!dm_digtable.dig_enable_flag) - return; - - if (dm_digtable.dig_algorithm_switch) { - dm_digtable.dig_state = DM_STA_DIG_MAX; - /* Fw DIG On. */ - for (i = 0; i < 3; i++) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite.*/ - dm_digtable.dig_algorithm_switch = 0; - } - - if (priv->ieee80211->state != IEEE80211_LINKED) - return; - - /* For smooth, we can not change DIG state. */ - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) - return; - - /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold - * and then execute the step below. - */ - if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) { - /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters - * will be reset to init value. We must prevent the condition. - */ - if (dm_digtable.dig_state == DM_STA_DIG_OFF && - (priv->reset_count == reset_cnt)) { - return; - } - reset_cnt = priv->reset_count; - - /* If DIG is off, DIG high power state must reset. */ - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.dig_state = DM_STA_DIG_OFF; - - /* 1.1 DIG Off. */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */ - - /* 1.2 Set initial gain. */ - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17); - - /* 1.3 Lower PD_TH for OFDM. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. - * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - */ - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); - - /* 1.4 Lower CS ratio for CCK. */ - write_nic_byte(dev, 0xa0a, 0x08); - - /* 1.5 Higher EDCCA. */ - return; - } - - /* 2. When RSSI increase, We have to judge if it is larger than a threshold - * and then execute the step below. - */ - if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { - u8 reset_flag = 0; - - if (dm_digtable.dig_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt)) { - dm_ctrl_initgain_byrssi_highpwr(dev); - return; - } - if (priv->reset_count != reset_cnt) - reset_flag = 1; - - reset_cnt = priv->reset_count; - - dm_digtable.dig_state = DM_STA_DIG_ON; - - /* 2.1 Set initial gain. - * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. - */ - if (reset_flag == 1) { - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c); - } else { - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20); - } - - /* 2.2 Higher PD_TH for OFDM. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. - * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - */ - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); - - /* 2.3 Higher CS ratio for CCK. */ - write_nic_byte(dev, 0xa0a, 0xcd); - - /* 2.4 Lower EDCCA. - * 2008/01/11 MH 90/92 series are the same. - */ - - /* 2.5 DIG On. */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */ - } - - dm_ctrl_initgain_byrssi_highpwr(dev); - -} /* dm_CtrlInitGainByRssi */ - -/*----------------------------------------------------------------------------- - * Function: dm_ctrl_initgain_byrssi_highpwr() - * - * Overview: - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_ctrl_initgain_byrssi_highpwr( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u32 reset_cnt_highpwr; - - /* For smooth, we can not change high power DIG state in the range. */ - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) - return; - - /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if - * it is larger than a threshold and then execute the step below. - * - * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. - */ - if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt_highpwr)) - return; - dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; - - /* 3.1 Higher PD_TH for OFDM for high power state. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); - } else { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF && - (priv->reset_count == reset_cnt_highpwr)) - return; - dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; - - if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && - priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { - /* 3.2 Recover PD_TH for OFDM for normal power region. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); - } - } - - reset_cnt_highpwr = priv->reset_count; - -} /* dm_CtrlInitGainByRssiHighPwr */ - -static void dm_initial_gain( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 initial_gain = 0; - static u8 initialized, force_write; - static u32 reset_cnt; - u8 tmp; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } - - if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) { - if (dm_digtable.cur_connect_state == DIG_CONNECT) { - if ((dm_digtable.rssi_val + 10 - dm_digtable.backoff_val) > DM_DIG_MAX) - dm_digtable.cur_ig_value = DM_DIG_MAX; - else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; - } else { /* current state is disconnected */ - if (dm_digtable.cur_ig_value == 0) - dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; - else - dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; - } - } else { /* disconnected -> connected or connected -> disconnected */ - dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; - dm_digtable.pre_ig_value = 0; - } - - /* if silent reset happened, we should rewrite the values back */ - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - - read_nic_byte(dev, rOFDM0_XAAGCCore1, &tmp); - if (dm_digtable.pre_ig_value != tmp) - force_write = 1; - - { - if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) - || !initialized || force_write) { - initial_gain = (u8)dm_digtable.cur_ig_value; - /* Set initial gain. */ - write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); - dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; - initialized = 1; - force_write = 0; - } - } -} - -static void dm_pd_th( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u8 initialized, force_write; - static u32 reset_cnt; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } - - if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) { - if (dm_digtable.cur_connect_state == DIG_CONNECT) { - if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) - dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; - else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && - (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) - dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; - else - dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; - } else { - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - } else { /* disconnected -> connected or connected -> disconnected */ - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - - /* if silent reset happened, we should rewrite the values back */ - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - - { - if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || - (initialized <= 3) || force_write) { - if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { - /* Lower PD_TH for OFDM. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. - * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - */ - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); - } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) { - /* Higher PD_TH for OFDM. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. - * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - */ - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); - } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) { - /* Higher PD_TH for OFDM for high power state. */ - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); - } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); - } - dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; - if (initialized <= 3) - initialized++; - force_write = 0; - } - } -} - -static void dm_cs_ratio( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static u8 initialized, force_write; - static u32 reset_cnt; - - if (dm_digtable.dig_algorithm_switch) { - initialized = 0; - reset_cnt = 0; - } - - if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) { - if (dm_digtable.cur_connect_state == DIG_CONNECT) { - if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; - else - dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; - } else { - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - } - } else /* disconnected -> connected or connected -> disconnected */ - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - - /* if silent reset happened, we should rewrite the values back */ - if (priv->reset_count != reset_cnt) { - force_write = 1; - reset_cnt = priv->reset_count; - } - - { - if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || - !initialized || force_write) { - if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) { - /* Lower CS ratio for CCK. */ - write_nic_byte(dev, 0xa0a, 0x08); - } else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) { - /* Higher CS ratio for CCK. */ - write_nic_byte(dev, 0xa0a, 0xcd); - } - dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; - initialized = 1; - force_write = 0; - } - } -} - -void dm_init_edca_turbo(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->bcurrent_turbo_EDCA = false; - priv->ieee80211->bis_any_nonbepkts = false; - priv->bis_cur_rdlstate = false; -} /* dm_init_edca_turbo */ - -static void dm_check_edca_turbo( - struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - - /* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */ - static unsigned long lastTxOkCnt; - static unsigned long lastRxOkCnt; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - /* Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters - * should follow the settings from QAP. By Bruce, 2007-12-07. - */ - if (priv->ieee80211->state != IEEE80211_LINKED) - goto dm_CheckEdcaTurbo_EXIT; - /* We do not turn on EDCA turbo mode for some AP that has IOT issue */ - if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) - goto dm_CheckEdcaTurbo_EXIT; - - if (!priv->ieee80211->bis_any_nonbepkts) { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - /* For RT-AP, we needs to turn it on when Rx>Tx */ - if (curRxOkCnt > 4*curTxOkCnt) { - if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { - write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); - priv->bis_cur_rdlstate = true; - } - } else { - if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { - write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); - priv->bis_cur_rdlstate = false; - } - } - - priv->bcurrent_turbo_EDCA = true; - } else { - /* Turn Off EDCA turbo here. - * Restore original EDCA according to the declaration of AP. - */ - if (priv->bcurrent_turbo_EDCA) { - u8 u1bAIFS; - u32 u4bAcParam, op_limit, cw_max, cw_min; - - struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; - u8 mode = priv->ieee80211->mode; - - /* For Each time updating EDCA parameter, reset EDCA turbo mode status. */ - dm_init_edca_turbo(dev); - - u1bAIFS = qos_parameters->aifs[0] * ((mode & (IEEE_G | IEEE_N_24G)) ? 9 : 20) + aSifsTime; - - op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[0]); - cw_max = (u32)le16_to_cpu(qos_parameters->cw_max[0]); - cw_min = (u32)le16_to_cpu(qos_parameters->cw_min[0]); - - op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET; - cw_max <<= AC_PARAM_ECW_MAX_OFFSET; - cw_min <<= AC_PARAM_ECW_MIN_OFFSET; - u1bAIFS <<= AC_PARAM_AIFS_OFFSET; - - u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS; - cpu_to_le32s(&u4bAcParam); - - write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); - - /* Check ACM bit. - * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. - */ - { - /* TODO: Modified this part and try to set acm control in only 1 IO processing!! */ - - struct aci_aifsn *pAciAifsn = (struct aci_aifsn *)&(qos_parameters->aifs[0]); - u8 AcmCtrl; - - read_nic_byte(dev, AcmHwCtrl, &AcmCtrl); - - if (pAciAifsn->acm) { /* acm bit is 1. */ - AcmCtrl |= AcmHw_BeqEn; - } else { /* ACM bit is 0. */ - AcmCtrl &= (~AcmHw_BeqEn); - } - - RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl); - write_nic_byte(dev, AcmHwCtrl, AcmCtrl); - } - priv->bcurrent_turbo_EDCA = false; - } - } - -dm_CheckEdcaTurbo_EXIT: - /* Set variables for next time. */ - priv->ieee80211->bis_any_nonbepkts = false; - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; -} /* dm_CheckEdcaTurbo */ - -static void dm_init_ctstoself(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->ieee80211->bCTSToSelfEnable = true; - priv->ieee80211->CTSToSelfTH = CTS_TO_SELF_TH_VAL; -} - -static void dm_ctstoself(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - static unsigned long lastTxOkCnt; - static unsigned long lastRxOkCnt; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - if (!priv->ieee80211->bCTSToSelfEnable) { - pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - return; - } - /* 1. Uplink - * 2. Linksys350/Linksys300N - * 3. <50 disable, >55 enable - */ - - if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */ - pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - } else { /* uplink */ - pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - } - - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; - } -} - -/*----------------------------------------------------------------------------- - * Function: dm_check_pbc_gpio() - * - * Overview: Check if PBC button is pressed. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_check_pbc_gpio(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 tmp1byte; - - read_nic_byte(dev, GPI, &tmp1byte); - if (tmp1byte == 0xff) - return; - - if (tmp1byte & BIT(6) || tmp1byte & BIT(0)) { - /* Here we only set bPbcPressed to TRUE - * After trigger PBC, the variable will be set to FALSE - */ - RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); - priv->bpbc_pressed = true; - } -} - -/*----------------------------------------------------------------------------- - * Function: DM_RFPathCheckWorkItemCallBack() - * - * Overview: Check if Current RF RX path is enabled - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -void dm_rf_pathcheck_workitemcallback(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq); - struct net_device *dev = priv->ieee80211->dev; - u8 rfpath = 0, i; - - /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will - * always be the same. We only read 0xc04 now. - */ - read_nic_byte(dev, 0xc04, &rfpath); - - /* Check Bit 0-3, it means if RF A-D is enabled. */ - for (i = 0; i < RF90_PATH_MAX; i++) { - if (rfpath & (0x01<brfpath_rxenable[i] = true; - else - priv->brfpath_rxenable[i] = false; - } - - dm_rxpath_sel_byrssi(dev); -} /* DM_RFPathCheckWorkItemCallBack */ - -static void dm_init_rxpath_selection(struct net_device *dev) -{ - u8 i; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->CustomerID == RT_CID_819x_Netcore) - DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2; - else - DM_RxPathSelTable.cck_method = CCK_RX_VERSION_1; - DM_RxPathSelTable.disabled_rf = 0; - for (i = 0; i < 4; i++) { - DM_RxPathSelTable.rf_rssi[i] = 50; - DM_RxPathSelTable.cck_pwdb_sta[i] = -64; - DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; - } -} - -static void dm_rxpath_sel_byrssi(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0; - u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0; - u8 cck_default_Rx = 0x2; /* RF-C */ - u8 cck_optional_Rx = 0x3; /* RF-D */ - long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0; - u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0; - u8 cur_rf_rssi; - long cur_cck_pwdb; - static u8 disabled_rf_cnt, cck_Rx_Path_initialized; - u8 update_cck_rx_path; - - if (priv->rf_type != RF_2T4R) - return; - - if (!cck_Rx_Path_initialized) { - read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_rx_path); - DM_RxPathSelTable.cck_rx_path &= 0xf; - cck_Rx_Path_initialized = 1; - } - - read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabled_rf); - DM_RxPathSelTable.disabled_rf = ~DM_RxPathSelTable.disabled_rf & 0xf; - - if (priv->ieee80211->mode == WIRELESS_MODE_B) { - DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2; /* pure B mode, fixed cck version2 */ - } - - /* decide max/sec/min rssi index */ - for (i = 0; i < RF90_PATH_MAX; i++) { - DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; - - if (priv->brfpath_rxenable[i]) { - rf_num++; - cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; - - if (rf_num == 1) { /* find first enabled rf path and the rssi values */ - /* initialize, set all rssi index to the same one */ - max_rssi_index = min_rssi_index = sec_rssi_index = i; - tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; - } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */ - if (cur_rf_rssi >= tmp_max_rssi) { - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } else { - tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; - sec_rssi_index = min_rssi_index = i; - } - } else { - if (cur_rf_rssi > tmp_max_rssi) { - tmp_sec_rssi = tmp_max_rssi; - sec_rssi_index = max_rssi_index; - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } else if (cur_rf_rssi == tmp_max_rssi) { /* let sec and min point to the different index */ - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) { - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } else if (cur_rf_rssi == tmp_sec_rssi) { - if (tmp_sec_rssi == tmp_min_rssi) { - /* let sec and min point to the different index */ - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } else { - /* This case we don't need to set any index */ - } - } else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) { - /* This case we don't need to set any index */ - } else if (cur_rf_rssi == tmp_min_rssi) { - if (tmp_sec_rssi == tmp_min_rssi) { - /* let sec and min point to the different index */ - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } else { - /* This case we don't need to set any index */ - } - } else if (cur_rf_rssi < tmp_min_rssi) { - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } - } - } - } - - rf_num = 0; - /* decide max/sec/min cck pwdb index */ - if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) { - for (i = 0; i < RF90_PATH_MAX; i++) { - if (priv->brfpath_rxenable[i]) { - rf_num++; - cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i]; - - if (rf_num == 1) { /* find first enabled rf path and the rssi values */ - /* initialize, set all rssi index to the same one */ - cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i; - tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb; - } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */ - if (cur_cck_pwdb >= tmp_cck_max_pwdb) { - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } else { - tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i; - } - } else { - if (cur_cck_pwdb > tmp_cck_max_pwdb) { - tmp_cck_sec_pwdb = tmp_cck_max_pwdb; - cck_rx_ver2_sec_index = cck_rx_ver2_max_index; - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } else if (cur_cck_pwdb == tmp_cck_max_pwdb) { - /* let sec and min point to the different index */ - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) { - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { - /* let sec and min point to the different index */ - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - /* otherwise we don't need to set any index */ - } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) { - /* This case we don't need to set any index */ - } else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { - /* let sec and min point to the different index */ - tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; - /* otherwise we don't need to set any index */ - } else if (cur_cck_pwdb < tmp_cck_min_pwdb) { - tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; - } - } - } - } - } - - /* Set CCK Rx path - * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path. - */ - update_cck_rx_path = 0; - if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) { - cck_default_Rx = cck_rx_ver2_max_index; - cck_optional_Rx = cck_rx_ver2_sec_index; - if (tmp_cck_max_pwdb != -64) - update_cck_rx_path = 1; - } - - if (tmp_min_rssi < RX_PATH_SELECTION_SS_TH_LOW && disabled_rf_cnt < 2) { - if ((tmp_max_rssi - tmp_min_rssi) >= RX_PATH_SELECTION_DIFF_TH) { - /* record the enabled rssi threshold */ - DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5; - /* disable the BB Rx path, OFDM */ - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<> i) & 0x1) { /* disabled rf */ - if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) { - /* enable the BB Rx path */ - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<priv_wq, &priv->rfpath_check_wq, 0); -} /* dm_CheckRxRFPath */ - -static void dm_init_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->ieee80211->fsync_time_interval = 500; - priv->ieee80211->fsync_rate_bitmap = 0x0f000800; - priv->ieee80211->fsync_rssi_threshold = 30; - priv->ieee80211->bfsync_enable = false; - priv->ieee80211->fsync_multiple_timeinterval = 3; - priv->ieee80211->fsync_firstdiff_ratethreshold = 100; - priv->ieee80211->fsync_seconddiff_ratethreshold = 200; - priv->ieee80211->fsync_state = Default_Fsync; - priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */ - INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback); -} - -static void dm_deInit_fsync(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - cancel_delayed_work_sync(&priv->fsync_work); -} - -void dm_fsync_work_callback(struct work_struct *work) -{ - struct r8192_priv *priv = - container_of(work, struct r8192_priv, fsync_work.work); - struct net_device *dev = priv->ieee80211->dev; - u32 rate_index, rate_count = 0, rate_count_diff = 0; - bool bSwitchFromCountDiff = false; - bool bDoubleTimeInterval = false; - - if (priv->ieee80211->state == IEEE80211_LINKED && - priv->ieee80211->bfsync_enable && - (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) { - /* Count rate 54, MCS [7], [12, 13, 14, 15] */ - u32 rate_bitmap; - - for (rate_index = 0; rate_index <= 27; rate_index++) { - rate_bitmap = 1 << rate_index; - if (priv->ieee80211->fsync_rate_bitmap & rate_bitmap) - rate_count += priv->stats.received_rate_histogram[1][rate_index]; - } - - if (rate_count < priv->rate_record) - rate_count_diff = 0xffffffff - rate_count + priv->rate_record; - else - rate_count_diff = rate_count - priv->rate_record; - if (rate_count_diff < priv->rateCountDiffRecord) { - u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; - /* Continue count */ - if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) - priv->ContinueDiffCount++; - else - priv->ContinueDiffCount = 0; - - /* Continue count over */ - if (priv->ContinueDiffCount >= 2) { - bSwitchFromCountDiff = true; - priv->ContinueDiffCount = 0; - } - } else { - /* Stop the continued count */ - priv->ContinueDiffCount = 0; - } - - /* If Count diff <= FsyncRateCountThreshold */ - if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) { - bSwitchFromCountDiff = true; - priv->ContinueDiffCount = 0; - } - priv->rate_record = rate_count; - priv->rateCountDiffRecord = rate_count_diff; - RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync); - /* if we never receive those mcs rate and rssi > 30 % then switch fsyn */ - if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) { - bDoubleTimeInterval = true; - priv->bswitch_fsync = !priv->bswitch_fsync; - if (priv->bswitch_fsync) { - write_nic_byte(dev, 0xC36, 0x1c); - write_nic_byte(dev, 0xC3e, 0x90); - } else { - write_nic_byte(dev, 0xC36, 0x5c); - write_nic_byte(dev, 0xC3e, 0x96); - } - } else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) { - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - write_nic_byte(dev, 0xC36, 0x5c); - write_nic_byte(dev, 0xC3e, 0x96); - } - } - if (bDoubleTimeInterval) { - cancel_delayed_work_sync(&priv->fsync_work); - schedule_delayed_work(&priv->fsync_work, - msecs_to_jiffies(priv - ->ieee80211->fsync_time_interval * - priv->ieee80211->fsync_multiple_timeinterval)); - } else { - cancel_delayed_work_sync(&priv->fsync_work); - schedule_delayed_work(&priv->fsync_work, - msecs_to_jiffies(priv - ->ieee80211->fsync_time_interval)); - } - } else { - /* Let Register return to default value; */ - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - write_nic_byte(dev, 0xC36, 0x5c); - write_nic_byte(dev, 0xC3e, 0x96); - } - priv->ContinueDiffCount = 0; - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); - } - RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); - RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync); -} - -static void dm_StartHWFsync(struct net_device *dev) -{ - RT_TRACE(COMP_HALDM, "%s\n", __func__); - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf); - write_nic_byte(dev, 0xc3b, 0x41); -} - -static void dm_EndSWFsync(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_HALDM, "%s\n", __func__); - cancel_delayed_work_sync(&priv->fsync_work); - - /* Let Register return to default value; */ - if (priv->bswitch_fsync) { - priv->bswitch_fsync = false; - - write_nic_byte(dev, 0xC36, 0x5c); - - write_nic_byte(dev, 0xC3e, 0x96); - } - - priv->ContinueDiffCount = 0; - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); -} - -static void dm_StartSWFsync(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 rateIndex; - u32 rateBitmap; - - RT_TRACE(COMP_HALDM, "%s\n", __func__); - /* Initial rate record to zero, start to record. */ - priv->rate_record = 0; - /* Initialize continue diff count to zero, start to record. */ - priv->ContinueDiffCount = 0; - priv->rateCountDiffRecord = 0; - priv->bswitch_fsync = false; - - if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) { - priv->ieee80211->fsync_firstdiff_ratethreshold = 600; - priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff; - } else { - priv->ieee80211->fsync_firstdiff_ratethreshold = 200; - priv->ieee80211->fsync_seconddiff_ratethreshold = 200; - } - for (rateIndex = 0; rateIndex <= 27; rateIndex++) { - rateBitmap = 1 << rateIndex; - if (priv->ieee80211->fsync_rate_bitmap & rateBitmap) - priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex]; - } - cancel_delayed_work_sync(&priv->fsync_work); - schedule_delayed_work(&priv->fsync_work, - msecs_to_jiffies(priv->ieee80211->fsync_time_interval)); - - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); -} - -static void dm_EndHWFsync(struct net_device *dev) -{ - RT_TRACE(COMP_HALDM, "%s\n", __func__); - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); - write_nic_byte(dev, 0xc3b, 0x49); -} - -void dm_check_fsync(struct net_device *dev) -{ -#define RegC38_Default 0 -#define RegC38_NonFsync_Other_AP 1 -#define RegC38_Fsync_AP_BCM 2 - struct r8192_priv *priv = ieee80211_priv(dev); - static u8 reg_c38_State = RegC38_Default; - static u32 reset_cnt; - - RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval); - RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold); - - if (priv->ieee80211->state == IEEE80211_LINKED && - (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) { - if (priv->ieee80211->bfsync_enable == 0) { - switch (priv->ieee80211->fsync_state) { - case Default_Fsync: - dm_StartHWFsync(dev); - priv->ieee80211->fsync_state = HW_Fsync; - break; - case SW_Fsync: - dm_EndSWFsync(dev); - dm_StartHWFsync(dev); - priv->ieee80211->fsync_state = HW_Fsync; - break; - case HW_Fsync: - default: - break; - } - } else { - switch (priv->ieee80211->fsync_state) { - case Default_Fsync: - dm_StartSWFsync(dev); - priv->ieee80211->fsync_state = SW_Fsync; - break; - case HW_Fsync: - dm_EndHWFsync(dev); - dm_StartSWFsync(dev); - priv->ieee80211->fsync_state = SW_Fsync; - break; - case SW_Fsync: - default: - break; - } - } - if (priv->framesyncMonitor) { - if (reg_c38_State != RegC38_Fsync_AP_BCM) { - /* For broadcom AP we write different default value */ - write_nic_byte(dev, rOFDM0_RxDetector3, 0x95); - - reg_c38_State = RegC38_Fsync_AP_BCM; - } - } - } else { - switch (priv->ieee80211->fsync_state) { - case HW_Fsync: - dm_EndHWFsync(dev); - priv->ieee80211->fsync_state = Default_Fsync; - break; - case SW_Fsync: - dm_EndSWFsync(dev); - priv->ieee80211->fsync_state = Default_Fsync; - break; - case Default_Fsync: - default: - break; - } - - if (priv->framesyncMonitor) { - if (priv->ieee80211->state == IEEE80211_LINKED) { - if (priv->undecorated_smoothed_pwdb <= REG_C38_TH) { - if (reg_c38_State != RegC38_NonFsync_Other_AP) { - write_nic_byte(dev, rOFDM0_RxDetector3, 0x90); - - reg_c38_State = RegC38_NonFsync_Other_AP; - } - } else if (priv->undecorated_smoothed_pwdb >= (REG_C38_TH + 5)) { - if (reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } else { - if (reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } - } - if (priv->framesyncMonitor) { - if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */ - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - reset_cnt = priv->reset_count; - } - } else { - if (reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } -} - -/*---------------------------Define function prototype------------------------*/ -/*----------------------------------------------------------------------------- - * Function: DM_DynamicTxPower() - * - * Overview: Detect Signal strength to control TX Registry - Tx Power Control For Near/Far Range - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - *--------------------------------------------------------------------------- - */ -static void dm_init_dynamic_txpower(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */ - priv->ieee80211->bdynamic_txpower_enable = true; /* Default to enable Tx Power Control */ - priv->bLastDTPFlag_High = false; - priv->bLastDTPFlag_Low = false; - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; -} - -static void dm_dynamic_txpower(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - unsigned int txhipower_threshold = 0; - unsigned int txlowpower_threshold = 0; - - if (!priv->ieee80211->bdynamic_txpower_enable) { - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; - return; - } - if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) { - txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH; - txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; - } else { - txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH; - txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; - } - - RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb); - - if (priv->ieee80211->state == IEEE80211_LINKED) { - if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) { - priv->bDynamicTxHighPower = true; - priv->bDynamicTxLowPower = false; - } else { - /* high power state check */ - if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower) - priv->bDynamicTxHighPower = false; - - /* low power state check */ - if (priv->undecorated_smoothed_pwdb < 35) - priv->bDynamicTxLowPower = true; - else if (priv->undecorated_smoothed_pwdb >= 40) - priv->bDynamicTxLowPower = false; - } - } else { - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; - } - - if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) || - (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) { - RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel); - -#if defined(RTL8190P) || defined(RTL8192E) - SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel); -#endif - - rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel); - /*pHalData->bStartTxCtrlByTPCNFR = FALSE; Clear th flag of Set TX Power from Sitesurvey*/ - } - priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; - priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; - -} /* dm_dynamic_txpower */ - -/* added by vivi, for read tx rate and retrycount */ -static void dm_check_txrateandretrycount(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - /* for 11n tx rate */ - read_nic_byte(dev, CURRENT_TX_RATE_REG, &ieee->softmac_stats.CurrentShowTxate); - /* for initial tx rate */ - read_nic_byte(dev, INITIAL_TX_RATE_REG, &ieee->softmac_stats.last_packet_rate); - /* for tx retry count */ - read_nic_dword(dev, TX_RETRY_COUNT_REG, &ieee->softmac_stats.txretrycount); -} - -static void dm_send_rssi_tofw(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* If we test chariot, we should stop the TX command ? - * Because 92E will always silent reset when we send tx command. We use register - * 0x1e0(byte) to notify driver. - */ - write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); -} - -/*---------------------------Define function prototype------------------------*/ diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h deleted file mode 100644 index f4eb18216677..000000000000 --- a/drivers/staging/rtl8192u/r8192U_dm.h +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/***************************************************************************** - * Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved. - * - * Module: Hal819xUsbDM.h (RTL8192 Header H File) - * - * - * Note: For dynamic control definition constant structure. - * - * - * Export: - * - * Abbrev: - * - * History: - * Data Who Remark - * 10/04/2007 MHC Create initial version. - * - *****************************************************************************/ - /* Check to see if the file has been included already. */ -#ifndef __R8192UDM_H__ -#define __R8192UDM_H__ - -/*--------------------------Define Parameters-------------------------------*/ -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 -#define DM_DIG_HIGH_PWR_THRESH_LOW 70 - -#define BW_AUTO_SWITCH_HIGH_LOW 25 -#define BW_AUTO_SWITCH_LOW_HIGH 30 - -#define DM_DIG_BACKOFF 12 -#define DM_DIG_MAX 0x36 -#define DM_DIG_MIN 0x1c -#define DM_DIG_MIN_NETCORE 0x12 - -#define RX_PATH_SELECTION_SS_TH_LOW 30 -#define RX_PATH_SELECTION_DIFF_TH 18 - -#define RATE_ADAPTIVE_TH_HIGH 50 -#define RATE_ADAPTIVE_TH_LOW_20M 30 -#define RATE_ADAPTIVE_TH_LOW_40M 10 -#define VERY_LOW_RSSI 15 -#define CTS_TO_SELF_TH_VAL 30 - -/* defined by vivi, for tx power track */ -#define E_FOR_TX_POWER_TRACK 300 -/* Dynamic Tx Power Control Threshold */ -#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68 -#define TX_POWER_NEAR_FIELD_THRESH_LOW 62 -/* added by amy for atheros AP */ -#define TX_POWER_ATHEROAP_THRESH_HIGH 78 -#define TX_POWER_ATHEROAP_THRESH_LOW 72 - -/* defined by vivi, for showing on UI */ -#define CURRENT_TX_RATE_REG 0x1b8 -#define INITIAL_TX_RATE_REG 0x1b9 -#define TX_RETRY_COUNT_REG 0x1ac -#define REG_C38_TH 20 -/*--------------------------Define Parameters-------------------------------*/ - -/*------------------------------Define structure----------------------------*/ - -enum dig_algorithm { - DIG_ALGO_BY_FALSE_ALARM = 0, - DIG_ALGO_BY_RSSI = 1, -}; - -enum dynamic_init_gain_state { - DM_STA_DIG_OFF = 0, - DM_STA_DIG_ON, - DM_STA_DIG_MAX -}; - -enum dig_connect { - DIG_DISCONNECT = 0, - DIG_CONNECT = 1, -}; - -enum dig_pkt_detection_threshold { - DIG_PD_AT_LOW_POWER = 0, - DIG_PD_AT_NORMAL_POWER = 1, - DIG_PD_AT_HIGH_POWER = 2, -}; - -enum dig_cck_cs_ratio_state { - DIG_CS_RATIO_LOWER = 0, - DIG_CS_RATIO_HIGHER = 1, -}; - -/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */ -struct dig { - u8 dig_enable_flag; - enum dig_algorithm dig_algorithm; - u8 dig_algorithm_switch; - - long rssi_low_thresh; - long rssi_high_thresh; - - long rssi_high_power_lowthresh; - long rssi_high_power_highthresh; - - enum dynamic_init_gain_state dig_state; - enum dynamic_init_gain_state dig_highpwr_state; - enum dig_connect cur_connect_state; - enum dig_connect pre_connect_state; - - enum dig_pkt_detection_threshold curpd_thstate; - enum dig_pkt_detection_threshold prepd_thstate; - enum dig_cck_cs_ratio_state curcs_ratio_state; - enum dig_cck_cs_ratio_state precs_ratio_state; - - u32 pre_ig_value; - u32 cur_ig_value; - - u8 backoff_val; - u8 rx_gain_range_min; - - long rssi_val; -}; - -enum cck_rx_path_method { - CCK_RX_VERSION_1 = 0, - CCK_RX_VERSION_2 = 1, -}; - -struct dynamic_rx_path_sel { - enum cck_rx_path_method cck_method; - u8 cck_rx_path; - - u8 disabled_rf; - - u8 rf_rssi[4]; - u8 rf_enable_rssi_th[4]; - long cck_pwdb_sta[4]; -}; - -struct tx_config_cmd { - u32 cmd_op; /* Command packet type. */ - u32 cmd_length; /* Command packet length. */ - u32 cmd_value; -}; - -/*------------------------------Define structure----------------------------*/ - -/*------------------------Export global variable----------------------------*/ -extern struct dig dm_digtable; -extern u8 dm_shadow[16][256]; -/*------------------------Export global variable----------------------------*/ - -/*------------------------Export Marco Definition---------------------------*/ - -/*------------------------Export Marco Definition---------------------------*/ - -/*--------------------------Exported Function prototype---------------------*/ -void init_hal_dm(struct net_device *dev); -void deinit_hal_dm(struct net_device *dev); -void hal_dm_watchdog(struct net_device *dev); -void init_rate_adaptive(struct net_device *dev); -void dm_txpower_trackingcallback(struct work_struct *work); -void dm_restore_dynamic_mechanism_state(struct net_device *dev); -void dm_force_tx_fw_info(struct net_device *dev, - u32 force_type, u32 force_value); -void dm_init_edca_turbo(struct net_device *dev); -void dm_rf_operation_test_callback(unsigned long data); -void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -void dm_fsync_work_callback(struct work_struct *work); -void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); -void dm_initialize_txpower_tracking(struct net_device *dev); -/*--------------------------Exported Function prototype---------------------*/ - -#endif /*__R8192UDM_H__ */ - -/* End of r8192U_dm.h */ diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h deleted file mode 100644 index 217e77766442..000000000000 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ /dev/null @@ -1,246 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is part of rtl8187 OpenSource driver. - * Copyright (C) Andrea Merello 2004-2005 - * - * Parts of this driver are based on the GPL part of the - * official Realtek driver. - * Parts of this driver are based on the rtl8180 driver skeleton - * from Patric Schenke & Andres Salomon. - * Parts of this driver are based on the Intel Pro Wireless - * 2100 GPL driver. - * - * We want to thank the Authors of those projects - * and the Ndiswrapper project Authors. - */ - -/* Mariusz Matuszek added full registers definition with Realtek's name */ - -/* this file contains register definitions for the rtl8187 MAC controller */ -#ifndef R8192_HW -#define R8192_HW - -#define RTL8187_REQT_READ 0xc0 -#define RTL8187_REQT_WRITE 0x40 -#define RTL8187_REQ_GET_REGS 0x05 -#define RTL8187_REQ_SET_REGS 0x05 - -#define MAX_TX_URB 5 -#define MAX_RX_URB 16 - -#define R8180_MAX_RETRY 255 - -#define RX_URB_SIZE 9100 - -#define RTL8190_EEPROM_ID 0x8129 -#define EEPROM_VID 0x02 -#define EEPROM_PID 0x04 -#define EEPROM_NODE_ADDRESS_BYTE_0 0x0C - -#define EEPROM_TX_POWER_DIFF 0x1F -#define EEPROM_THERMAL_METER 0x20 -#define EEPROM_PW_DIFF 0x21 //0x21 -#define EEPROM_CRYSTAL_CAP 0x22 //0x22 - -#define EEPROM_TX_PW_INDEX_CCK 0x23 //0x23 -#define EEPROM_TX_PW_INDEX_OFDM_24G 0x24 //0x24~0x26 -#define EEPROM_TX_PW_INDEX_CCK_V1 0x29 //0x29~0x2B -#define EEPROM_TX_PW_INDEX_OFDM_24G_V1 0x2C //0x2C~0x2E -#define EEPROM_TX_PW_INDEX_VER 0x27 //0x27 - -#define EEPROM_DEFAULT_THERNAL_METER 0x7 -#define EEPROM_DEFAULT_PW_DIFF 0x4 -#define EEPROM_DEFAULT_CRYSTAL_CAP 0x5 -#define EEPROM_DEFAULT_TX_POWER 0x1010 -#define EEPROM_CUSTOMER_ID 0x7B //0x7B:CustomerID -#define EEPROM_CHANNEL_PLAN 0x16 //0x7C - -#define EEPROM_CID_RUNTOP 0x2 -#define EEPROM_CID_DLINK 0x8 - -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - -//#endif -enum _RTL8192Usb_HW { - MAC0 = 0x000, - MAC4 = 0x004, - -#define BB_GLOBAL_RESET_BIT 0x1 - BB_GLOBAL_RESET = 0x020, // BasebandGlobal Reset Register - BSSIDR = 0x02E, // BSSID Register - CMDR = 0x037, // Command register -#define CR_RE 0x08 -#define CR_TE 0x04 - SIFS = 0x03E, // SIFS register - -#define TCR_MXDMA_2048 7 -#define TCR_LRL_OFFSET 0 -#define TCR_SRL_OFFSET 8 -#define TCR_MXDMA_OFFSET 21 -#define TCR_SAT BIT(24) // Enable Rate depedent ack timeout timer - RCR = 0x044, // Receive Configuration Register -#define MAC_FILTER_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(5) | \ - BIT(12) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | \ - BIT(22) | BIT(23)) -#define RX_FIFO_THRESHOLD_MASK (BIT(13) | BIT(14) | BIT(15)) -#define RX_FIFO_THRESHOLD_SHIFT 13 -#define RX_FIFO_THRESHOLD_NONE 7 -#define MAX_RX_DMA_MASK (BIT(8) | BIT(9) | BIT(10)) -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 -#define RCR_ONLYERLPKT BIT(31) // Early Receiving based on Packet Size. -#define RCR_CBSSID BIT(23) // Accept BSSID match packet -#define RCR_APWRMGT BIT(22) // Accept power management packet -#define RCR_AMF BIT(20) // Accept management type frame -#define RCR_ACF BIT(19) // Accept control type frame -#define RCR_ADF BIT(18) // Accept data type frame -#define RCR_AICV BIT(12) // Accept ICV error packet -#define RCR_ACRC32 BIT(5) // Accept CRC32 error packet -#define RCR_AB BIT(3) // Accept broadcast packet -#define RCR_AM BIT(2) // Accept multicast packet -#define RCR_APM BIT(1) // Accept physical match packet -#define RCR_AAP BIT(0) // Accept all unicast packet - SLOT_TIME = 0x049, // Slot Time Register - ACK_TIMEOUT = 0x04c, // Ack Timeout Register - EDCAPARA_BE = 0x050, // EDCA Parameter of AC BE - EDCAPARA_BK = 0x054, // EDCA Parameter of AC BK - EDCAPARA_VO = 0x058, // EDCA Parameter of AC VO - EDCAPARA_VI = 0x05C, // EDCA Parameter of AC VI - BCN_TCFG = 0x062, // Beacon Time Configuration -#define BCN_TCFG_CW_SHIFT 8 -#define BCN_TCFG_IFS 0 - BCN_INTERVAL = 0x070, // Beacon Interval (TU) - ATIMWND = 0x072, // ATIM Window Size (TU) - BCN_DRV_EARLY_INT = 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT - BCN_DMATIME = 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA - BCN_ERR_THRESH = 0x078, // Beacon Error Threshold - RWCAM = 0x0A0, //IN 8190 Data Sheet is called CAMcmd - WCAMI = 0x0A4, // Software write CAM input content - SECR = 0x0B0, //Security Configuration Register -#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key -#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key -#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption -#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption -#define SCR_SKByA2 BIT(4) //Search kEY BY A2 -#define SCR_NoSKMC BIT(5) //No Key Search for Multicast - -//---------------------------------------------------------------------------- -// 8190 CPU General Register (offset 0x100, 4 byte) -//---------------------------------------------------------------------------- -#define CPU_CCK_LOOPBACK 0x00030000 -#define CPU_GEN_SYSTEM_RESET 0x00000001 -#define CPU_GEN_FIRMWARE_RESET 0x00000008 -#define CPU_GEN_BOOT_RDY 0x00000010 -#define CPU_GEN_FIRM_RDY 0x00000020 -#define CPU_GEN_PUT_CODE_OK 0x00000080 -#define CPU_GEN_BB_RST 0x00000100 -#define CPU_GEN_PWR_STB_CPU 0x00000004 -#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19 -#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1 - CPU_GEN = 0x100, // CPU Reset Register - - AcmHwCtrl = 0x171, // ACM Hardware Control Register -//---------------------------------------------------------------------------- -//// -//// 8190 AcmHwCtrl bits (offset 0x171, 1 byte) -////---------------------------------------------------------------------------- -// -#define AcmHw_BeqEn BIT(1) - - RQPN1 = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk - RQPN2 = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High - RQPN3 = 0x188, // Reserved Queue Page Number, Bcn, Public, - QPNR = 0x1D0, //0x1F0, // Queue Packet Number report per TID - -#define BW_OPMODE_5G BIT(1) -#define BW_OPMODE_20MHZ BIT(2) - BW_OPMODE = 0x300, // Bandwidth operation mode - MSR = 0x303, // Media Status register -#define MSR_LINK_MASK (BIT(0) | BIT(1)) -#define MSR_LINK_MANAGED 2 -#define MSR_LINK_NONE 0 -#define MSR_LINK_SHIFT 0 -#define MSR_LINK_ADHOC 1 -#define MSR_LINK_MASTER 3 - RETRY_LIMIT = 0x304, // Retry Limit [15:8]-short, [7:0]-long -#define RETRY_LIMIT_SHORT_SHIFT 8 -#define RETRY_LIMIT_LONG_SHIFT 0 - RRSR = 0x310, // Response Rate Set -#define RRSR_1M BIT(0) -#define RRSR_2M BIT(1) -#define RRSR_5_5M BIT(2) -#define RRSR_11M BIT(3) -#define RRSR_6M BIT(4) -#define RRSR_9M BIT(5) -#define RRSR_12M BIT(6) -#define RRSR_18M BIT(7) -#define RRSR_24M BIT(8) -#define RRSR_36M BIT(9) -#define RRSR_48M BIT(10) -#define RRSR_54M BIT(11) -#define BRSR_AckShortPmb BIT(23) // CCK ACK: use Short Preamble or not. - UFWP = 0x318, - RATR0 = 0x320, // Rate Adaptive Table register1 - DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI -//---------------------------------------------------------------------------- -// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte) -//---------------------------------------------------------------------------- -//CCK -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -//OFDM -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -//MCS 1 Spatial Stream -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -//MCS 2 Spatial Stream -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 -// ALL CCK Rate -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ - RATR_24M | RATR_36M | RATR_48M | RATR_54M) -#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | RATR_MCS3 |\ - RATR_MCS4 | RATR_MCS5 | RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | RATR_MCS11 |\ - RATR_MCS12 | RATR_MCS13 | RATR_MCS14 | RATR_MCS15) - EPROM_CMD = 0xfe58, -#define Cmd9346CR_9356SEL BIT(4) -#define EPROM_CMD_OPERATING_MODE_SHIFT 6 -#define EPROM_CMD_NORMAL 0 -#define EPROM_CMD_PROGRAM 2 -#define EPROM_CS_BIT BIT(3) -#define EPROM_CK_BIT BIT(2) -#define EPROM_W_BIT BIT(1) -#define EPROM_R_BIT BIT(0) -}; - -//---------------------------------------------------------------------------- -// 818xB AnaParm & AnaParm2 Register -//---------------------------------------------------------------------------- -#define GPI 0x108 -#endif diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c deleted file mode 100644 index 203ea3bfc843..000000000000 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ /dev/null @@ -1,943 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * This file contains wireless extension handlers. - * - * This is part of rtl8180 OpenSource driver. - * Copyright (C) Andrea Merello 2004-2005 - * - * Parts of this driver are based on the GPL part - * of the official realtek driver. - * - * Parts of this driver are based on the rtl8180 driver skeleton - * from Patric Schenke & Andres Salomon. - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - * - * We want to thank the Authors of those projects and the Ndiswrapper - * project Authors. - * - *****************************************************************************/ - -#include -#include "r8192U.h" -#include "r8192U_hw.h" - -#include "ieee80211/dot11d.h" -#include "r8192U_wx.h" - -#define RATE_COUNT 12 -static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, - 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; - -#ifndef ENETDOWN -#define ENETDOWN 1 -#endif - -static int r8192_wx_get_freq(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b); -} - -static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b); -} - -static int r8192_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra); -} - -static int r8192_wx_set_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra); -} - -static int r8192_wx_set_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra); -} - -static int r8192_wx_force_reset(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra); - priv->force_reset = *extra; - mutex_unlock(&priv->wx_mutex); - return 0; -} - -static int r8192_wx_set_rawtx(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_set_crcmon(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int *parms = (int *)extra; - int enable = (parms[0] > 0); - - mutex_lock(&priv->wx_mutex); - - if (enable) - priv->crcmon = 1; - else - priv->crcmon = 0; - - DMESG("bad CRC in monitor mode are %s", - priv->crcmon ? "accepted" : "rejected"); - - mutex_unlock(&priv->wx_mutex); - - return 0; -} - -static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b); - - rtl8192_set_rxconf(dev); - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -struct iw_range_with_scan_capa { - /* Informative stuff (to choose between different interface) */ - __u32 throughput; /* To give an idea... */ - /* In theory this value should be the maximum benchmarked - * TCP/IP throughput, because with most of these devices the - * bit rate is meaningless (overhead an co) to estimate how - * fast the connection will go and pick the fastest one. - * I suggest people to play with Netperf or any benchmark... - */ - - /* NWID (or domain id) */ - __u32 min_nwid; /* Minimal NWID we are able to set */ - __u32 max_nwid; /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ - __u16 old_num_channels; - __u8 old_num_frequency; - - /* Scan capabilities */ - __u8 scan_capa; -}; - -static int rtl8180_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range; - struct r8192_priv *priv = ieee80211_priv(dev); - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - /* Let's try to keep this struct in the same order as in - * linux/include/wireless.h - */ - - /* TODO: See what values we can set, and remove the ones we can't - * set, or fill them with some default data. - */ - - /* ~5 Mb/s real (802.11b) */ - range->throughput = 5 * 1000 * 1000; - - /* TODO: Not used in 802.11b? */ - /* range->min_nwid; */ /* Minimal NWID we are able to set */ - /* TODO: Not used in 802.11b? */ - /* range->max_nwid; */ /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ - /* range->old_num_channels; */ - /* range->old_num_frequency; */ - /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */ - if (priv->rf_set_sens) - range->sensitivity = priv->max_sens; /* signal level threshold range */ - - range->max_qual.qual = 100; - /* TODO: Find real max RSSI and stick here */ - range->max_qual.level = 0; - range->max_qual.noise = 0x100 - 98; - range->max_qual.updated = 7; /* Updated all three */ - - range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 0x100 - 78; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - - range->num_bitrates = RATE_COUNT; - - for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = rtl8180_rates[i]; - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->min_pmp = 0; - range->max_pmp = 5000000; - range->min_pmt = 0; - range->max_pmt = 65535 * 1000; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; - - /* range->retry_capa; */ /* What retry options are supported */ - /* range->retry_flags; */ /* How to decode max/min retry limit */ - /* range->r_time_flags; */ /* How to decode max/min retry life */ - /* range->min_retry; */ /* Minimal number of retries */ - /* range->max_retry; */ /* Maximal number of retries */ - /* range->min_r_time; */ /* Minimal retry lifetime */ - /* range->max_r_time; */ /* Maximal retry lifetime */ - - for (i = 0, val = 0; i < 14; i++) { - /* Include only legal frequencies for some countries */ - if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i + 1]) { - range->freq[val].i = i + 1; - range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; - range->freq[val].e = 1; - val++; - } else { - /* FIXME: do we need to set anything for channels */ - /* we don't use ? */ - } - - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - range->num_channels = val; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - tmp->scan_capa = 0x01; - return 0; -} - -static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - int ret = 0; - - if (!priv->up) - return -ENETDOWN; - - if (priv->ieee80211->LinkDetectInfo.bBusyTraffic) - return -EAGAIN; - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)b; - - if (req->essid_len) { - int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); - - ieee->current_network.ssid_len = len; - memcpy(ieee->current_network.ssid, req->essid, len); - } - } - - mutex_lock(&priv->wx_mutex); - if (priv->ieee80211->state != IEEE80211_LINKED) { - priv->ieee80211->scanning = 0; - ieee80211_softmac_scan_syncro(priv->ieee80211); - ret = 0; - } else { - ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b); - } - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (!priv->up) - return -ENETDOWN; - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int r8192_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); -} - -static int r8192_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (wrqu->frag.disabled) { - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - } else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - - priv->ieee80211->fts = wrqu->frag.value & ~0x1; - } - - return 0; -} - -static int r8192_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - wrqu->frag.value = priv->ieee80211->fts; - wrqu->frag.fixed = 0; /* no auto select */ - wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); - - return 0; -} - -static int r8192_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - /* struct sockaddr *temp = (struct sockaddr *)awrq; */ - mutex_lock(&priv->wx_mutex); - - ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra); - - mutex_unlock(&priv->wx_mutex); - - return ret; -} - -static int r8192_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra); -} - -static int r8192_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); -} - -static int r8192_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - int ret; - u32 hwkey[4] = {0, 0, 0, 0}; - u8 mask = 0xff; - u32 key_idx = 0; - u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; - int i; - - if (!priv->up) - return -ENETDOWN; - - mutex_lock(&priv->wx_mutex); - - RT_TRACE(COMP_SEC, "Setting SW wep key"); - ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key); - - mutex_unlock(&priv->wx_mutex); - - /* sometimes, the length is zero while we do not type key value */ - if (wrqu->encoding.length != 0) { - for (i = 0; i < 4; i++) { - hwkey[i] |= key[4 * i + 0] & mask; - if (i == 1 && (4 * i + 1) == wrqu->encoding.length) - mask = 0x00; - if (i == 3 && (4 * i + 1) == wrqu->encoding.length) - mask = 0x00; - hwkey[i] |= (key[4 * i + 1] & mask) << 8; - hwkey[i] |= (key[4 * i + 2] & mask) << 16; - hwkey[i] |= (key[4 * i + 3] & mask) << 24; - } - - #define CONF_WEP40 0x4 - #define CONF_WEP104 0x14 - - switch (wrqu->encoding.flags & IW_ENCODE_INDEX) { - case 0: - key_idx = ieee->tx_keyidx; - break; - case 1: - key_idx = 0; - break; - case 2: - key_idx = 1; - break; - case 3: - key_idx = 2; - break; - case 4: - key_idx = 3; - break; - default: - break; - } - - if (wrqu->encoding.length == 0x5) { - ieee->pairwise_key_type = KEY_TYPE_WEP40; - EnableHWSecurityConfig8192(dev); - - setKey(dev, - key_idx, /* EntryNo */ - key_idx, /* KeyIndex */ - KEY_TYPE_WEP40, /* KeyType */ - zero_addr[key_idx], - 0, /* DefaultKey */ - hwkey); /* KeyContent */ - } else if (wrqu->encoding.length == 0xd) { - ieee->pairwise_key_type = KEY_TYPE_WEP104; - EnableHWSecurityConfig8192(dev); - - setKey(dev, - key_idx, /* EntryNo */ - key_idx, /* KeyIndex */ - KEY_TYPE_WEP104, /* KeyType */ - zero_addr[key_idx], - 0, /* DefaultKey */ - hwkey); /* KeyContent */ - } else { - netdev_warn(dev, "wrong type in WEP, not WEP40 and WEP104\n"); - } - } - - return ret; -} - -static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, - union iwreq_data *wrqu, char *p) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int *parms = (int *)p; - int mode = parms[0]; - - priv->ieee80211->active_scan = mode; - - return 1; -} - -static int r8192_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int err = 0; - - mutex_lock(&priv->wx_mutex); - - if (wrqu->retry.flags & IW_RETRY_LIFETIME || - wrqu->retry.disabled){ - err = -EINVAL; - goto exit; - } - if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { - err = -EINVAL; - goto exit; - } - - if (wrqu->retry.value > R8180_MAX_RETRY) { - err = -EINVAL; - goto exit; - } - if (wrqu->retry.flags & IW_RETRY_MAX) { - priv->retry_rts = wrqu->retry.value; - DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); - - } else { - priv->retry_data = wrqu->retry.value; - DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); - } - - /* FIXME ! - * We might try to write directly the TX config register - * or to restart just the (R)TX process. - * I'm unsure if whole reset is really needed - */ - - rtl8192_commit(dev); -exit: - mutex_unlock(&priv->wx_mutex); - - return err; -} - -static int r8192_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - wrqu->retry.disabled = 0; /* can't be disabled */ - - if ((wrqu->retry.flags & IW_RETRY_TYPE) == - IW_RETRY_LIFETIME) - return -EINVAL; - - if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - wrqu->retry.value = priv->retry_rts; - } else { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; - wrqu->retry.value = priv->retry_data; - } - - return 0; -} - -static int r8192_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (!priv->rf_set_sens) - return -1; /* we have not this support for this radio */ - wrqu->sens.value = priv->sens; - return 0; -} - -static int r8192_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - short err = 0; - - mutex_lock(&priv->wx_mutex); - if (!priv->rf_set_sens) { - err = -1; /* we have not this support for this radio */ - goto exit; - } - if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) - priv->sens = wrqu->sens.value; - else - err = -EINVAL; - -exit: - mutex_unlock(&priv->wx_mutex); - - return err; -} - -/* hw security need to reorganized. */ -static int r8192_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - mutex_lock(&priv->wx_mutex); - ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); - - { - u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 zero[6] = {0}; - u32 key[4] = {0}; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct iw_point *encoding = &wrqu->encoding; - u8 idx = 0, alg = 0, group = 0; - - if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE) - /* none is not allowed to use hwsec WB 2008.07.01 */ - goto end_hw_sec; - - /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */ - alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP : ext->alg; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) - idx--; - group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; - - if ((!group) || (ieee->iw_mode == IW_MODE_ADHOC) || (alg == KEY_TYPE_WEP40)) { - if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) - alg = KEY_TYPE_WEP104; - ieee->pairwise_key_type = alg; - EnableHWSecurityConfig8192(dev); - } - memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */ - - if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { - setKey(dev, - idx, /* EntryNao */ - idx, /* KeyIndex */ - alg, /* KeyType */ - zero, /* MacAddr */ - 0, /* DefaultKey */ - key); /* KeyContent */ - } else if (group) { - ieee->group_key_type = alg; - setKey(dev, - idx, /* EntryNo */ - idx, /* KeyIndex */ - alg, /* KeyType */ - broadcast_addr, /* MacAddr */ - 0, /* DefaultKey */ - key); /* KeyContent */ - } else { /* pairwise key */ - setKey(dev, - 4, /* EntryNo */ - idx, /* KeyIndex */ - alg, /* KeyType */ - (u8 *)ieee->ap_mac_addr,/* MacAddr */ - 0, /* DefaultKey */ - key); /* KeyContent */ - } - } - -end_hw_sec: - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int r8192_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - ret = ieee80211_wx_set_auth(priv->ieee80211, info, &data->param, extra); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int r8192_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); - - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int r8192_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - - mutex_lock(&priv->wx_mutex); - ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); - mutex_unlock(&priv->wx_mutex); - return ret; -} - -static int dummy(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - return -1; -} - -static iw_handler r8192_wx_handlers[] = { - NULL, /* SIOCSIWCOMMIT */ - r8192_wx_get_name, /* SIOCGIWNAME */ - dummy, /* SIOCSIWNWID */ - dummy, /* SIOCGIWNWID */ - r8192_wx_set_freq, /* SIOCSIWFREQ */ - r8192_wx_get_freq, /* SIOCGIWFREQ */ - r8192_wx_set_mode, /* SIOCSIWMODE */ - r8192_wx_get_mode, /* SIOCGIWMODE */ - r8192_wx_set_sens, /* SIOCSIWSENS */ - r8192_wx_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - rtl8180_wx_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - dummy, /* SIOCSIWSPY */ - dummy, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - r8192_wx_set_wap, /* SIOCSIWAP */ - r8192_wx_get_wap, /* SIOCGIWAP */ - r8192_wx_set_mlme, /* MLME-- */ - dummy, /* SIOCGIWAPLIST -- deprecated */ - r8192_wx_set_scan, /* SIOCSIWSCAN */ - r8192_wx_get_scan, /* SIOCGIWSCAN */ - r8192_wx_set_essid, /* SIOCSIWESSID */ - r8192_wx_get_essid, /* SIOCGIWESSID */ - dummy, /* SIOCSIWNICKN */ - dummy, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - r8192_wx_set_rate, /* SIOCSIWRATE */ - r8192_wx_get_rate, /* SIOCGIWRATE */ - r8192_wx_set_rts, /* SIOCSIWRTS */ - r8192_wx_get_rts, /* SIOCGIWRTS */ - r8192_wx_set_frag, /* SIOCSIWFRAG */ - r8192_wx_get_frag, /* SIOCGIWFRAG */ - dummy, /* SIOCSIWTXPOW */ - dummy, /* SIOCGIWTXPOW */ - r8192_wx_set_retry, /* SIOCSIWRETRY */ - r8192_wx_get_retry, /* SIOCGIWRETRY */ - r8192_wx_set_enc, /* SIOCSIWENCODE */ - r8192_wx_get_enc, /* SIOCGIWENCODE */ - r8192_wx_set_power, /* SIOCSIWPOWER */ - r8192_wx_get_power, /* SIOCGIWPOWER */ - NULL, /*---hole---*/ - NULL, /*---hole---*/ - r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */ - NULL, /* SIOCSIWGENIE */ - - r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */ - NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */ - r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ - NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */ - NULL, /* SIOCSIWPMKSA */ - NULL, /*---hole---*/ - -}; - -static const struct iw_priv_args r8192_private_args[] = { - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" - }, - { - SIOCIWFIRSTPRIV + 0x1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" - - }, - { - SIOCIWFIRSTPRIV + 0x2, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" - }, - { - SIOCIWFIRSTPRIV + 0x3, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" - } -}; - -static iw_handler r8192_private_handler[] = { - r8192_wx_set_crcmon, - r8192_wx_set_scan_type, - r8192_wx_set_rawtx, - r8192_wx_force_reset, -}; - -struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - struct iw_statistics *wstats = &priv->wstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - - if (ieee->state < IEEE80211_LINKED) { - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; - } - - tmp_level = (&ieee->current_network)->stats.rssi; - tmp_qual = (&ieee->current_network)->stats.signal; - tmp_noise = (&ieee->current_network)->stats.noise; - - wstats->qual.level = tmp_level; - wstats->qual.qual = tmp_qual; - wstats->qual.noise = tmp_noise; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; -} - -const struct iw_handler_def r8192_wx_handlers_def = { - .standard = r8192_wx_handlers, - .num_standard = ARRAY_SIZE(r8192_wx_handlers), - .private = r8192_private_handler, - .num_private = ARRAY_SIZE(r8192_private_handler), - .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), - .get_wireless_stats = r8192_get_wireless_stats, - .private_args = (struct iw_priv_args *)r8192_private_args, -}; diff --git a/drivers/staging/rtl8192u/r8192U_wx.h b/drivers/staging/rtl8192u/r8192U_wx.h deleted file mode 100644 index 27423cd64b4c..000000000000 --- a/drivers/staging/rtl8192u/r8192U_wx.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is part of rtl8180 OpenSource driver - v 0.3 - * Copyright (C) Andrea Merello 2004 - * - * Parts of this driver are based on the GPL part of the official realtek driver - * Parts of this driver are based on the rtl8180 driver skeleton from Patric - * Schenke & Andres Salomon - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - * - * We want to thank the Authors of such projects and the Ndiswrapper project - * Authors. - */ - -/* this file (will) contains wireless extension handlers */ - -#ifndef R8180_WX_H -#define R8180_WX_H - -extern const struct iw_handler_def r8192_wx_handlers_def; -/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */ -struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); - -#endif diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c deleted file mode 100644 index 30a320422358..000000000000 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ /dev/null @@ -1,508 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. - * - * Module: r819xusb_cmdpkt.c - * (RTL8190 TX/RX command packet handler Source C File) - * - * Note: The module is responsible for handling TX and RX command packet. - * 1. TX : Send set and query configuration command packet. - * 2. RX : Receive tx feedback, beacon state, query configuration - * command packet. - * - * Function: - * - * Export: - * - * Abbrev: - * - * History: - * - * Date Who Remark - * 05/06/2008 amy Create initial version porting from - * windows driver. - * - ******************************************************************************/ -#include "r8192U.h" -#include "r819xU_cmdpkt.h" - -rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct sk_buff *skb; - struct cb_desc *tcb_desc; - - /* Get TCB and local buffer from common pool. - * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) - */ - skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); - if (!skb) - return RT_STATUS_FAILURE; - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; - tcb_desc->bLastIniPkt = 0; - skb_reserve(skb, USB_HWDESC_HEADER_LEN); - skb_put_data(skb, pData, DataLen); - tcb_desc->txbuf_size = (u16)DataLen; - - if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || - (priv->ieee80211->queue_stop)) { - RT_TRACE(COMP_FIRMWARE, "=== NULL packet ======> tx full!\n"); - skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); - } else { - priv->ieee80211->softmac_hard_start_xmit(skb, dev); - } - - return RT_STATUS_SUCCESS; -} - -static void cmpk_count_txstatistic(struct net_device *dev, struct cmd_pkt_tx_feedback *pstx_fb) -{ - struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef ENABLE_PS - RT_RF_POWER_STATE rtState; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - /* When RF is off, we should not count the packet for hw/sw synchronize - * reason, ie. there may be a duration while sw switch is changed and - * hw switch is being changed. - */ - if (rtState == eRfOff) - return; -#endif - -#ifdef TODO - if (pAdapter->bInHctTest) - return; -#endif - /* We can not know the packet length and transmit type: - * broadcast or uni or multicast. So the relative statistics - * must be collected in tx feedback info. - */ - if (pstx_fb->tok) { - priv->stats.txfeedbackok++; - priv->stats.txoktotal++; - priv->stats.txokbytestotal += pstx_fb->pkt_length; - priv->stats.txokinperiod++; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) { - priv->stats.txmulticast++; - priv->stats.txbytesmulticast += pstx_fb->pkt_length; - } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { - priv->stats.txbroadcast++; - priv->stats.txbytesbroadcast += pstx_fb->pkt_length; - } else { - priv->stats.txunicast++; - priv->stats.txbytesunicast += pstx_fb->pkt_length; - } - } else { - priv->stats.txfeedbackfail++; - priv->stats.txerrtotal++; - priv->stats.txerrbytestotal += pstx_fb->pkt_length; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - priv->stats.txerrmulticast++; - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - priv->stats.txerrbroadcast++; - else - priv->stats.txerrunicast++; - } - - priv->stats.txretrycount += pstx_fb->retry_cnt; - priv->stats.txfeedbackretry += pstx_fb->retry_cnt; -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_feedback() - * - * Overview: The function is responsible for extract the message inside TX - * feedbck message from firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. - * Please refer to chapter "TX Feedback Element". - * We have to read 20 bytes in the command packet. - * - * Input: struct net_device *dev - * u8 *pmsg - Msg Ptr of the command packet. - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/08/2008 amy Create Version 0 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct cmd_pkt_tx_feedback rx_tx_fb; - - priv->stats.txfeedback++; - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - * windows OS. So we have to read the content byte by byte or transfer - * endian type before copy the message copy. - */ - /* Use pointer to transfer structure memory. */ - memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(struct cmd_pkt_tx_feedback)); - /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_txstatistic(dev, &rx_tx_fb); - /* Comment previous method for TX statistic function. */ - /* Collect info TX feedback packet to fill TCB. */ - /* We can not know the packet length and transmit type: broadcast or uni - * or multicast. - */ -} - -static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u16 tx_rate; - - /* 87B have to S/W beacon for DTM encryption_cmn. */ - if (priv->ieee80211->current_network.mode == IEEE_A || - priv->ieee80211->current_network.mode == IEEE_N_5G || - (priv->ieee80211->current_network.mode == IEEE_N_24G && - (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { - tx_rate = 60; - DMESG("send beacon frame tx rate is 6Mbpm\n"); - } else { - tx_rate = 10; - DMESG("send beacon frame tx rate is 1Mbpm\n"); - } - - rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */ -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_interrupt_status() - * - * Overview: The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. - * Please refer to chapter "Interrupt Status Element". - * - * Input: struct net_device *dev - * u8 *pmsg - Message Pointer of the command packet. - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Add this for rtl8192 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) -{ - struct cmd_pkt_interrupt_status rx_intr_status; /* */ - struct r8192_priv *priv = ieee80211_priv(dev); - - DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - * windows OS. So we have to read the content byte by byte or transfer - * endian type before copy the message copy. - */ - rx_intr_status.length = pmsg[1]; - if (rx_intr_status.length != (sizeof(struct cmd_pkt_interrupt_status) - 2)) { - DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); - return; - } - - /* Statistics of beacon for ad-hoc mode. */ - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { - /* 2 maybe need endian transform? */ - rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); - - DMESG("interrupt status = 0x%x\n", - rx_intr_status.interrupt_status); - - if (rx_intr_status.interrupt_status & ISR_TX_BCN_OK) { - priv->ieee80211->bibsscoordinator = true; - priv->stats.txbeaconokint++; - } else if (rx_intr_status.interrupt_status & ISR_TX_BCN_ERR) { - priv->ieee80211->bibsscoordinator = false; - priv->stats.txbeaconerr++; - } - - if (rx_intr_status.interrupt_status & ISR_BCN_TIMER_INTR) - cmdpkt_beacontimerinterrupt_819xusb(dev); - } - - /* Other information in interrupt status we need? */ - - DMESG("<---- cmpk_handle_interrupt_status()\n"); -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_count_tx_status() - * - * Overview: Count aggregated tx status from firmwar of one type rx command - * packet element id = RX_TX_STATUS. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -static void cmpk_count_tx_status(struct net_device *dev, - cmpk_tx_status_t *pstx_status) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - -#ifdef ENABLE_PS - - RT_RF_POWER_STATE rtstate; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - /* When RF is off, we should not count the packet for hw/sw synchronize - * reason, ie. there may be a duration while sw switch is changed and - * hw switch is being changed. - */ - if (rtState == eRfOff) - return; -#endif - - priv->stats.txfeedbackok += pstx_status->txok; - priv->stats.txoktotal += pstx_status->txok; - - priv->stats.txfeedbackfail += pstx_status->txfail; - priv->stats.txerrtotal += pstx_status->txfail; - - priv->stats.txretrycount += pstx_status->txretry; - priv->stats.txfeedbackretry += pstx_status->txretry; - - priv->stats.txmulticast += pstx_status->txmcok; - priv->stats.txbroadcast += pstx_status->txbcok; - priv->stats.txunicast += pstx_status->txucok; - - priv->stats.txerrmulticast += pstx_status->txmcfail; - priv->stats.txerrbroadcast += pstx_status->txbcfail; - priv->stats.txerrunicast += pstx_status->txucfail; - - priv->stats.txbytesmulticast += pstx_status->txmclength; - priv->stats.txbytesbroadcast += pstx_status->txbclength; - priv->stats.txbytesunicast += pstx_status->txuclength; - - priv->stats.last_packet_rate = pstx_status->rate; -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_status() - * - * Overview: Firmware add a new tx feedback status to reduce rx command - * packet buffer operation load. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) -{ - cmpk_tx_status_t rx_tx_sts; - - memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t)); - /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_tx_status(dev, &rx_tx_sts); -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_handle_tx_rate_history() - * - * Overview: Firmware add a new tx rate history - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) -{ - cmpk_tx_rahis_t *ptxrate; - u8 i, j; - u16 length = sizeof(cmpk_tx_rahis_t); - u32 *ptemp; - struct r8192_priv *priv = ieee80211_priv(dev); - -#ifdef ENABLE_PS - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, - (pu1Byte)(&rtState)); - - /* When RF is off, we should not count the packet for hw/sw synchronize - * reason, ie. there may be a duration while sw switch is changed and - * hw switch is being changed. - */ - if (rtState == eRfOff) - return; -#endif - - ptemp = (u32 *)pmsg; - - /* Do endian transfer to word alignment(16 bits) for windows system. - * You must do different endian transfer for linux and MAC OS - */ - for (i = 0; i < (length/4); i++) { - u16 temp1, temp2; - - temp1 = ptemp[i] & 0x0000FFFF; - temp2 = ptemp[i] >> 16; - ptemp[i] = (temp1 << 16) | temp2; - } - - ptxrate = (cmpk_tx_rahis_t *)pmsg; - - if (!ptxrate) - return; - - for (i = 0; i < 16; i++) { - /* Collect CCK rate packet num */ - if (i < 4) - priv->stats.txrate.cck[i] += ptxrate->cck[i]; - - /* Collect OFDM rate packet num */ - if (i < 8) - priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; - - for (j = 0; j < 4; j++) - priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; - } -} - -/*----------------------------------------------------------------------------- - * Function: cmpk_message_handle_rx() - * - * Overview: In the function, we will capture different RX command packet - * info. Every RX command packet element has different message - * length and meaning in content. We only support three type of RX - * command packet now. Please refer to document - * ws-06-0063-rtl8190-command-packet-specification. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/06/2008 amy Create Version 0 porting from windows code. - * - *--------------------------------------------------------------------------- - */ -u32 cmpk_message_handle_rx(struct net_device *dev, - struct ieee80211_rx_stats *pstats) -{ - int total_length; - u8 cmd_length, exe_cnt = 0; - u8 element_id; - u8 *pcmd_buff; - - /* 0. Check inpt arguments. It is a command queue message or - * pointer is null. - */ - if (!pstats) - return 0; /* This is not a command packet. */ - - /* 1. Read received command packet message length from RFD. */ - total_length = pstats->Length; - - /* 2. Read virtual address from RFD. */ - pcmd_buff = pstats->virtual_address; - - /* 3. Read command packet element id and length. */ - element_id = pcmd_buff[0]; - - /* 4. Check every received command packet content according to different - * element type. Because FW may aggregate RX command packet to - * minimize transmit time between DRV and FW. - */ - /* Add a counter to prevent the lock in the loop from being held too - * long - */ - while (total_length > 0 && exe_cnt++ < 100) { - /* We support aggregation of different cmd in the same packet */ - element_id = pcmd_buff[0]; - - switch (element_id) { - case RX_TX_FEEDBACK: - cmpk_handle_tx_feedback(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_INTERRUPT_STATUS: - cmpk_handle_interrupt_status(dev, pcmd_buff); - cmd_length = sizeof(struct cmd_pkt_interrupt_status); - break; - - case BOTH_QUERY_CONFIG: - cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; - break; - - case RX_TX_STATUS: - cmpk_handle_tx_status(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_STS_SIZE; - break; - - case RX_TX_PER_PKT_FEEDBACK: - /* You must at lease add a switch case element here, - * Otherwise, we will jump to default case. - */ - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_TX_RATE_HISTORY: - cmpk_handle_tx_rate_history(dev, pcmd_buff); - cmd_length = CMPK_TX_RAHIS_SIZE; - break; - - default: - - RT_TRACE(COMP_ERR, "---->%s():unknown CMD Element\n", - __func__); - return 1; /* This is a command packet. */ - } - - total_length -= cmd_length; - pcmd_buff += cmd_length; - } - return 1; /* This is a command packet. */ -} diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.h b/drivers/staging/rtl8192u/r819xU_cmdpkt.h deleted file mode 100644 index be45cd609d67..000000000000 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.h +++ /dev/null @@ -1,190 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef R819XUSB_CMDPKT_H -#define R819XUSB_CMDPKT_H -/* Different command packet have dedicated message length and definition. */ -#define CMPK_RX_TX_FB_SIZE sizeof(struct cmd_pkt_tx_feedback) /* 20 */ -#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(struct cmd_pkt_set_configuration) /* 16 */ -#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t) -#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) - -/* 2008/05/08 amy For USB constant. */ -#define ISR_TX_BCN_OK BIT(27) /* Transmit Beacon OK */ -#define ISR_TX_BCN_ERR BIT(26) /* Transmit Beacon Error */ -#define ISR_BCN_TIMER_INTR BIT(13) /* Beacon Timer Interrupt */ - -/* Define element ID of command packet. */ - -/*------------------------------Define structure----------------------------*/ -/* Define different command packet structure. */ -/* 1. RX side: TX feedback packet. */ -struct cmd_pkt_tx_feedback { - /* DWORD 0 */ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - /* Change tx feedback info field. */ - /*------TX Feedback Info Field */ - u8 TID:4; - u8 fail_reason:3; - u8 tok:1; /* Transmit ok. */ - u8 reserve1:4; - u8 pkt_type:2; - u8 bandwidth:1; - u8 qos_pkt:1; - - /* DWORD 1 */ - u8 reserve2; - /*------TX Feedback Info Field */ - u8 retry_cnt; - u16 pkt_id; - - /* DWORD 3 */ - u16 seq_num; - u8 s_rate; /* Start rate. */ - u8 f_rate; /* Final rate. */ - - /* DWORD 4 */ - u8 s_rts_rate; - u8 f_rts_rate; - u16 pkt_length; - - /* DWORD 5 */ - u16 reserve3; - u16 duration; -}; - -/* 2. RX side: Interrupt status packet. It includes Beacon State, - * Beacon Timer Interrupt and other useful information in MAC ISR Reg. - */ -struct cmd_pkt_interrupt_status { - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve; - u32 interrupt_status; /* Interrupt Status. */ -}; - -/* 3. TX side: Set configuration packet. */ -struct cmd_pkt_set_configuration { - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve1; - /* Configuration info. */ - u8 cfg_reserve1:3; - u8 cfg_size:2; - u8 cfg_type:2; - u8 cfg_action:1; - u8 cfg_reserve2; - u8 cfg_page:4; - u8 cfg_reserve3:4; - u8 cfg_offset; - u32 value; - u32 mask; -}; - -/* 4. Both side : TX/RX query configuration packet. The query structure is the - * same as set configuration. - */ -#define cmpk_query_cfg cmd_pkt_set_configuration - -/* 5. Multi packet feedback status. */ -typedef struct tag_tx_stats_feedback { - /* For endian transfer --> Driver will not the same as - * firmware structure. - */ - /* DW 0 */ - u16 reserve1; - u8 length; /* Command packet length */ - u8 element_id; /* Command packet type */ - - /* DW 1 */ - u16 txfail; /* Tx fail count */ - u16 txok; /* Tx ok count */ - - /* DW 2 */ - u16 txmcok; /* Tx multicast */ - u16 txretry; /* Tx retry count */ - - /* DW 3 */ - u16 txucok; /* Tx unicast */ - u16 txbcok; /* Tx broadcast */ - - /* DW 4 */ - u16 txbcfail; - u16 txmcfail; - - /* DW 5 */ - u16 reserve2; - u16 txucfail; - - /* DW 6-8 */ - u32 txmclength; - u32 txbclength; - u32 txuclength; - - /* DW 9 */ - u16 reserve3_23; - u8 reserve3_1; - u8 rate; -} __packed cmpk_tx_status_t; - -/* 6. Debug feedback message. */ -/* Define RX debug message */ -typedef struct tag_rx_debug_message_feedback { - /* For endian transfer --> for driver */ - /* DW 0 */ - u16 reserve1; - u8 length; /* Command packet length */ - u8 element_id; /* Command packet type */ - - /* DW 1-?? */ - /* Variable debug message. */ - -} cmpk_rx_dbginfo_t; - -/* Define transmit rate history. For big endian format. */ -typedef struct tag_tx_rate_history { - /* For endian transfer --> for driver */ - /* DW 0 */ - u8 element_id; /* Command packet type */ - u8 length; /* Command packet length */ - u16 reserved1; - - /* DW 1-2 CCK rate counter */ - u16 cck[4]; - - /* DW 3-6 */ - u16 ofdm[8]; - - /* DW 7-14 BW=0 SG=0 - * DW 15-22 BW=1 SG=0 - * DW 23-30 BW=0 SG=1 - * DW 31-38 BW=1 SG=1 - */ - u16 ht_mcs[4][16]; - -} __packed cmpk_tx_rahis_t; - -typedef enum tag_command_packet_directories { - RX_TX_FEEDBACK = 0, - RX_INTERRUPT_STATUS = 1, - TX_SET_CONFIG = 2, - BOTH_QUERY_CONFIG = 3, - RX_TX_STATUS = 4, - RX_DBGINFO_FEEDBACK = 5, - RX_TX_PER_PKT_FEEDBACK = 6, - RX_TX_RATE_HISTORY = 7, - RX_CMD_ELE_MAX -} cmpk_element_e; - -typedef enum _rt_status { - RT_STATUS_SUCCESS, - RT_STATUS_FAILURE, - RT_STATUS_PENDING, - RT_STATUS_RESOURCE -} rt_status, *prt_status; - -u32 cmpk_message_handle_rx(struct net_device *dev, - struct ieee80211_rx_stats *pstats); -rt_status SendTxCommandPacket(struct net_device *dev, - void *pData, u32 DataLen); - -#endif diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c deleted file mode 100644 index 4f8629e47e82..000000000000 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/************************************************************************************************** - * Procedure: Init boot code/firmware code/data session - * - * Description: This routine will initialize firmware. If any error occurs during the initialization - * process, the routine shall terminate immediately and return fail. - * NIC driver should call NdisOpenFile only from MiniportInitialize. - * - * Arguments: The pointer of the adapter - - * Returns: - * NDIS_STATUS_FAILURE - the following initialization process should be terminated - * NDIS_STATUS_SUCCESS - if firmware initialization process success - **************************************************************************************************/ - -#include "r8192U.h" -#include "r8192U_hw.h" -#include "r819xU_firmware_img.h" -#include "r819xU_firmware.h" -#include - -static void firmware_init_param(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - rt_firmware *pfirmware = priv->pFirmware; - - pfirmware->cmdpacket_frag_threshold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE); -} - -/* - * segment the img and use the ptr and length to remember info on each segment - * - */ -static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, - u32 buffer_len) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - bool rt_status = true; - u16 frag_threshold; - u16 frag_length, frag_offset = 0; - int i; - - rt_firmware *pfirmware = priv->pFirmware; - struct sk_buff *skb; - unsigned char *seg_ptr; - struct cb_desc *tcb_desc; - u8 bLastIniPkt; - u8 index; - - firmware_init_param(dev); - /* Fragmentation might be required */ - frag_threshold = pfirmware->cmdpacket_frag_threshold; - do { - if ((buffer_len - frag_offset) > frag_threshold) { - frag_length = frag_threshold; - bLastIniPkt = 0; - } else { - frag_length = buffer_len - frag_offset; - bLastIniPkt = 1; - } - - /* Allocate skb buffer to contain firmware info and tx descriptor info - * add 4 to avoid packet appending overflow. - */ - skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); - if (!skb) - return false; - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); - tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; - tcb_desc->bLastIniPkt = bLastIniPkt; - - skb_reserve(skb, USB_HWDESC_HEADER_LEN); - seg_ptr = skb->data; - /* - * Transform from little endian to big endian - * and pending zero - */ - for (i = 0; i < frag_length; i += 4) { - *seg_ptr++ = ((i+0) < frag_length)?code_virtual_address[i+3] : 0; - *seg_ptr++ = ((i+1) < frag_length)?code_virtual_address[i+2] : 0; - *seg_ptr++ = ((i+2) < frag_length)?code_virtual_address[i+1] : 0; - *seg_ptr++ = ((i+3) < frag_length)?code_virtual_address[i+0] : 0; - } - tcb_desc->txbuf_size = (u16)i; - skb_put(skb, i); - - index = tcb_desc->queue_index; - if (!priv->ieee80211->check_nic_enough_desc(dev, index) || - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[index])) || - (priv->ieee80211->queue_stop)) { - RT_TRACE(COMP_FIRMWARE, "=====================================================> tx full!\n"); - skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); - } else { - priv->ieee80211->softmac_hard_start_xmit(skb, dev); - } - - code_virtual_address += frag_length; - frag_offset += frag_length; - - } while (frag_offset < buffer_len); - - return rt_status; -} - -/* - * Procedure: Check whether main code is download OK. If OK, turn on CPU - * - * Description: CPU register locates in different page against general register. - * Switch to CPU register in the begin and switch back before return - * - * - * Arguments: The pointer of the adapter - * - * Returns: - * NDIS_STATUS_FAILURE - the following initialization process should - * be terminated - * NDIS_STATUS_SUCCESS - if firmware initialization process success - */ -static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) -{ - bool rt_status = true; - int check_putcodeOK_time = 200000, check_bootOk_time = 200000; - u32 CPU_status = 0; - - /* Check whether put code OK */ - do { - read_nic_dword(dev, CPU_GEN, &CPU_status); - - if (CPU_status&CPU_GEN_PUT_CODE_OK) - break; - - } while (check_putcodeOK_time--); - - if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) { - RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n"); - goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; - } else { - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n"); - } - - /* Turn On CPU */ - read_nic_dword(dev, CPU_GEN, &CPU_status); - write_nic_byte(dev, CPU_GEN, - (u8)((CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff)); - mdelay(1000); - - /* Check whether CPU boot OK */ - do { - read_nic_dword(dev, CPU_GEN, &CPU_status); - - if (CPU_status&CPU_GEN_BOOT_RDY) - break; - } while (check_bootOk_time--); - - if (!(CPU_status&CPU_GEN_BOOT_RDY)) - goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; - else - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); - - return rt_status; - -CPUCheckMainCodeOKAndTurnOnCPU_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = false; - return rt_status; -} - -static bool CPUcheck_firmware_ready(struct net_device *dev) -{ - bool rt_status = true; - int check_time = 200000; - u32 CPU_status = 0; - - /* Check Firmware Ready */ - do { - read_nic_dword(dev, CPU_GEN, &CPU_status); - - if (CPU_status&CPU_GEN_FIRM_RDY) - break; - - } while (check_time--); - - if (!(CPU_status&CPU_GEN_FIRM_RDY)) - goto CPUCheckFirmwareReady_Fail; - else - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n"); - - return rt_status; - -CPUCheckFirmwareReady_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = false; - return rt_status; -} - -bool init_firmware(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - bool rt_status = true; - - u32 file_length = 0; - u8 *mapped_file = NULL; - u32 init_step = 0; - enum opt_rst_type_e rst_opt = OPT_SYSTEM_RESET; - enum firmware_init_step_e starting_state = FW_INIT_STEP0_BOOT; - - rt_firmware *pfirmware = priv->pFirmware; - const struct firmware *fw_entry; - const char *fw_name[3] = { "RTL8192U/boot.img", - "RTL8192U/main.img", - "RTL8192U/data.img"}; - int rc; - - RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n"); - - if (pfirmware->firmware_status == FW_STATUS_0_INIT) { - /* it is called by reset */ - rst_opt = OPT_SYSTEM_RESET; - starting_state = FW_INIT_STEP0_BOOT; - /* TODO: system reset */ - - } else if (pfirmware->firmware_status == FW_STATUS_5_READY) { - /* it is called by Initialize */ - rst_opt = OPT_FIRMWARE_RESET; - starting_state = FW_INIT_STEP2_DATA; - } else { - RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n"); - } - - /* - * Download boot, main, and data image for System reset. - * Download data image for firmware reset - */ - for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { - /* - * Open image file, and map file to continuous memory if open file success. - * or read image file from array. Default load from IMG file - */ - if (rst_opt == OPT_SYSTEM_RESET) { - rc = request_firmware(&fw_entry, fw_name[init_step], &priv->udev->dev); - if (rc < 0) { - RT_TRACE(COMP_ERR, "request firmware fail!\n"); - goto download_firmware_fail; - } - - if (fw_entry->size > sizeof(pfirmware->firmware_buf)) { - RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); - goto download_firmware_fail; - } - - if (init_step != FW_INIT_STEP1_MAIN) { - memcpy(pfirmware->firmware_buf, fw_entry->data, fw_entry->size); - mapped_file = pfirmware->firmware_buf; - file_length = fw_entry->size; - } else { - memset(pfirmware->firmware_buf, 0, 128); - memcpy(&pfirmware->firmware_buf[128], fw_entry->data, fw_entry->size); - mapped_file = pfirmware->firmware_buf; - file_length = fw_entry->size + 128; - } - pfirmware->firmware_buf_size = file_length; - } else if (rst_opt == OPT_FIRMWARE_RESET) { - /* we only need to download data.img here */ - mapped_file = pfirmware->firmware_buf; - file_length = pfirmware->firmware_buf_size; - } - - /* Download image file */ - /* The firmware download process is just as following, - * 1. that is each packet will be segmented and inserted to the wait queue. - * 2. each packet segment will be put in the skb_buff packet. - * 3. each skb_buff packet data content will already include the firmware info - * and Tx descriptor info - */ - rt_status = fw_download_code(dev, mapped_file, file_length); - if (rst_opt == OPT_SYSTEM_RESET) - release_firmware(fw_entry); - - if (!rt_status) - goto download_firmware_fail; - - switch (init_step) { - case FW_INIT_STEP0_BOOT: - /* Download boot - * initialize command descriptor. - * will set polling bit when firmware code is also configured - */ - pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE; - /* mdelay(1000); */ - /* - * To initialize IMEM, CPU move code from 0x80000080, - * hence, we send 0x80 byte packet - */ - break; - - case FW_INIT_STEP1_MAIN: - /* Download firmware code. Wait until Boot Ready and Turn on CPU */ - pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE; - - /* Check Put Code OK and Turn On CPU */ - rt_status = CPUcheck_maincodeok_turnonCPU(dev); - if (!rt_status) { - RT_TRACE(COMP_ERR, "CPUcheck_maincodeok_turnonCPU fail!\n"); - goto download_firmware_fail; - } - - pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU; - break; - - case FW_INIT_STEP2_DATA: - /* download initial data code */ - pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE; - mdelay(1); - - rt_status = CPUcheck_firmware_ready(dev); - if (!rt_status) { - RT_TRACE(COMP_ERR, "CPUcheck_firmware_ready fail(%d)!\n", rt_status); - goto download_firmware_fail; - } - - /* wait until data code is initialized ready.*/ - pfirmware->firmware_status = FW_STATUS_5_READY; - break; - } - } - - RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n"); - return rt_status; - -download_firmware_fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = false; - return rt_status; -} - -MODULE_FIRMWARE("RTL8192U/boot.img"); -MODULE_FIRMWARE("RTL8192U/main.img"); -MODULE_FIRMWARE("RTL8192U/data.img"); diff --git a/drivers/staging/rtl8192u/r819xU_firmware.h b/drivers/staging/rtl8192u/r819xU_firmware.h deleted file mode 100644 index b84344c1e62b..000000000000 --- a/drivers/staging/rtl8192u/r819xU_firmware.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __INC_FIRMWARE_H -#define __INC_FIRMWARE_H - -#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) \ - (4 * ((v) / 4) - 8 - USB_HWDESC_HEADER_LEN) - -enum firmware_init_step_e { - FW_INIT_STEP0_BOOT = 0, - FW_INIT_STEP1_MAIN = 1, - FW_INIT_STEP2_DATA = 2, -}; - -enum opt_rst_type_e { - OPT_SYSTEM_RESET = 0, - OPT_FIRMWARE_RESET = 1, -}; - -#endif diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.c b/drivers/staging/rtl8192u/r819xU_firmware_img.c deleted file mode 100644 index 0af062036688..000000000000 --- a/drivers/staging/rtl8192u/r819xU_firmware_img.c +++ /dev/null @@ -1,549 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/*Created on 2008/ 7/16, 5:31*/ -#include -#include "r819xU_firmware_img.h" - -u32 Rtl8192UsbPHY_REGArray[] = { - 0x0, }; - -u32 Rtl8192UsbPHY_REG_1T2RArray[] = { - 0x800, 0x00000000, - 0x804, 0x00000001, - 0x808, 0x0000fc00, - 0x80c, 0x0000001c, - 0x810, 0x801010aa, - 0x814, 0x008514d0, - 0x818, 0x00000040, - 0x81c, 0x00000000, - 0x820, 0x00000004, - 0x824, 0x00690000, - 0x828, 0x00000004, - 0x82c, 0x00e90000, - 0x830, 0x00000004, - 0x834, 0x00690000, - 0x838, 0x00000004, - 0x83c, 0x00e90000, - 0x840, 0x00000000, - 0x844, 0x00000000, - 0x848, 0x00000000, - 0x84c, 0x00000000, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x65a965a9, - 0x85c, 0x65a965a9, - 0x860, 0x001f0010, - 0x864, 0x007f0010, - 0x868, 0x001f0010, - 0x86c, 0x007f0010, - 0x870, 0x0f100f70, - 0x874, 0x0f100f70, - 0x878, 0x00000000, - 0x87c, 0x00000000, - 0x880, 0x6870e36c, - 0x884, 0xe3573600, - 0x888, 0x4260c340, - 0x88c, 0x0000ff00, - 0x890, 0x00000000, - 0x894, 0xfffffffe, - 0x898, 0x4c42382f, - 0x89c, 0x00656056, - 0x8b0, 0x00000000, - 0x8e0, 0x00000000, - 0x8e4, 0x00000000, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x31121311, - 0xa00, 0x00d0c7d8, - 0xa04, 0x811f0008, - 0xa08, 0x80cd8300, - 0xa0c, 0x2e62740f, - 0xa10, 0x95009b78, - 0xa14, 0x11145008, - 0xa18, 0x00881117, - 0xa1c, 0x89140fa0, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00000000, - 0xc00, 0x00000040, - 0xc04, 0x00005433, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08000000, - 0xc1c, 0x40000100, - 0xc20, 0x08000000, - 0xc24, 0x40000100, - 0xc28, 0x08000000, - 0xc2c, 0x40000100, - 0xc30, 0x6de9ac44, - 0xc34, 0x465c52cd, - 0xc38, 0x497f5994, - 0xc3c, 0x0a969764, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020000, - 0xc4c, 0x00000300, - 0xc50, 0x69543420, - 0xc54, 0x433c0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x69543420, - 0xc64, 0x433c0094, - 0xc68, 0x69543420, - 0xc6c, 0x433c0094, - 0xc70, 0x2c7f000d, - 0xc74, 0x0186175b, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20000000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x40000100, - 0xc94, 0x00000000, - 0xc98, 0x40000100, - 0xc9c, 0x00000000, - 0xca0, 0x00492492, - 0xca4, 0x00000000, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x00492492, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xd00, 0x00000750, - 0xd04, 0x00000403, - 0xd08, 0x0000907f, - 0xd0c, 0x00000001, - 0xd10, 0xa0633333, - 0xd14, 0x33333c63, - 0xd18, 0x6a8f5b6b, - 0xd1c, 0x00000000, - 0xd20, 0x00000000, - 0xd24, 0x00000000, - 0xd28, 0x00000000, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x00000000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x024dbd02, - 0xd58, 0x00000000, - 0xd5c, 0x04032064, - 0xe00, 0x161a1a1a, - 0xe04, 0x12121416, - 0xe08, 0x00001800, - 0xe0c, 0x00000000, - 0xe10, 0x161a1a1a, - 0xe14, 0x12121416, - 0xe18, 0x161a1a1a, - 0xe1c, 0x12121416, -}; - -u32 Rtl8192UsbRadioA_Array[] = { - 0x019, 0x00000003, - 0x000, 0x000000bf, - 0x001, 0x00000ee0, - 0x002, 0x0000004c, - 0x003, 0x000007f1, - 0x004, 0x00000975, - 0x005, 0x00000c58, - 0x006, 0x00000ae6, - 0x007, 0x000000ca, - 0x008, 0x00000e1c, - 0x009, 0x000007f0, - 0x00a, 0x000009d0, - 0x00b, 0x000001ba, - 0x00c, 0x00000240, - 0x00e, 0x00000020, - 0x00f, 0x00000990, - 0x012, 0x00000806, - 0x014, 0x000005ab, - 0x015, 0x00000f80, - 0x016, 0x00000020, - 0x017, 0x00000597, - 0x018, 0x0000050a, - 0x01a, 0x00000f80, - 0x01b, 0x00000f5e, - 0x01c, 0x00000008, - 0x01d, 0x00000607, - 0x01e, 0x000006cc, - 0x01f, 0x00000000, - 0x020, 0x000001a5, - 0x01f, 0x00000001, - 0x020, 0x00000165, - 0x01f, 0x00000002, - 0x020, 0x000000c6, - 0x01f, 0x00000003, - 0x020, 0x00000086, - 0x01f, 0x00000004, - 0x020, 0x00000046, - 0x01f, 0x00000005, - 0x020, 0x000001e6, - 0x01f, 0x00000006, - 0x020, 0x000001a6, - 0x01f, 0x00000007, - 0x020, 0x00000166, - 0x01f, 0x00000008, - 0x020, 0x000000c7, - 0x01f, 0x00000009, - 0x020, 0x00000087, - 0x01f, 0x0000000a, - 0x020, 0x000000f7, - 0x01f, 0x0000000b, - 0x020, 0x000000d7, - 0x01f, 0x0000000c, - 0x020, 0x000000b7, - 0x01f, 0x0000000d, - 0x020, 0x00000097, - 0x01f, 0x0000000e, - 0x020, 0x00000077, - 0x01f, 0x0000000f, - 0x020, 0x00000057, - 0x01f, 0x00000010, - 0x020, 0x00000037, - 0x01f, 0x00000011, - 0x020, 0x000000fb, - 0x01f, 0x00000012, - 0x020, 0x000000db, - 0x01f, 0x00000013, - 0x020, 0x000000bb, - 0x01f, 0x00000014, - 0x020, 0x000000ff, - 0x01f, 0x00000015, - 0x020, 0x000000e3, - 0x01f, 0x00000016, - 0x020, 0x000000c3, - 0x01f, 0x00000017, - 0x020, 0x000000a3, - 0x01f, 0x00000018, - 0x020, 0x00000083, - 0x01f, 0x00000019, - 0x020, 0x00000063, - 0x01f, 0x0000001a, - 0x020, 0x00000043, - 0x01f, 0x0000001b, - 0x020, 0x00000023, - 0x01f, 0x0000001c, - 0x020, 0x00000003, - 0x01f, 0x0000001d, - 0x020, 0x000001e3, - 0x01f, 0x0000001e, - 0x020, 0x000001c3, - 0x01f, 0x0000001f, - 0x020, 0x000001a3, - 0x01f, 0x00000020, - 0x020, 0x00000183, - 0x01f, 0x00000021, - 0x020, 0x00000163, - 0x01f, 0x00000022, - 0x020, 0x00000143, - 0x01f, 0x00000023, - 0x020, 0x00000123, - 0x01f, 0x00000024, - 0x020, 0x00000103, - 0x023, 0x00000203, - 0x024, 0x00000200, - 0x00b, 0x000001ba, - 0x02c, 0x000003d7, - 0x02d, 0x00000ff0, - 0x000, 0x00000037, - 0x004, 0x00000160, - 0x007, 0x00000080, - 0x002, 0x0000088d, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x016, 0x00000200, - 0x016, 0x00000380, - 0x016, 0x00000020, - 0x016, 0x000001a0, - 0x000, 0x000000bf, - 0x00d, 0x0000001f, - 0x00d, 0x00000c9f, - 0x002, 0x0000004d, - 0x000, 0x00000cbf, - 0x004, 0x00000975, - 0x007, 0x00000700, -}; - -u32 Rtl8192UsbRadioB_Array[] = { - 0x019, 0x00000003, - 0x000, 0x000000bf, - 0x001, 0x000006e0, - 0x002, 0x0000004c, - 0x003, 0x000007f1, - 0x004, 0x00000975, - 0x005, 0x00000c58, - 0x006, 0x00000ae6, - 0x007, 0x000000ca, - 0x008, 0x00000e1c, - 0x000, 0x000000b7, - 0x00a, 0x00000850, - 0x000, 0x000000bf, - 0x00b, 0x000001ba, - 0x00c, 0x00000240, - 0x00e, 0x00000020, - 0x015, 0x00000f80, - 0x016, 0x00000020, - 0x017, 0x00000597, - 0x018, 0x0000050a, - 0x01a, 0x00000e00, - 0x01b, 0x00000f5e, - 0x01d, 0x00000607, - 0x01e, 0x000006cc, - 0x00b, 0x000001ba, - 0x023, 0x00000203, - 0x024, 0x00000200, - 0x000, 0x00000037, - 0x004, 0x00000160, - 0x016, 0x00000200, - 0x016, 0x00000380, - 0x016, 0x00000020, - 0x016, 0x000001a0, - 0x00d, 0x00000ccc, - 0x000, 0x000000bf, - 0x002, 0x0000004d, - 0x000, 0x00000cbf, - 0x004, 0x00000975, - 0x007, 0x00000700, -}; - -u32 Rtl8192UsbRadioC_Array[] = { - 0x0, }; - -u32 Rtl8192UsbRadioD_Array[] = { - 0x0, }; - -u32 Rtl8192UsbMACPHY_Array[] = { - 0x03c, 0xffff0000, 0x00000f0f, - 0x340, 0xffffffff, 0x161a1a1a, - 0x344, 0xffffffff, 0x12121416, - 0x348, 0x0000ffff, 0x00001818, - 0x12c, 0xffffffff, 0x04000802, - 0x318, 0x00000fff, 0x00000100, -}; - -u32 Rtl8192UsbMACPHY_Array_PG[] = { - 0x03c, 0xffff0000, 0x00000f0f, - 0xe00, 0xffffffff, 0x06090909, - 0xe04, 0xffffffff, 0x00030306, - 0xe08, 0x0000ff00, 0x00000000, - 0xe10, 0xffffffff, 0x0a0c0d0f, - 0xe14, 0xffffffff, 0x06070809, - 0xe18, 0xffffffff, 0x0a0c0d0f, - 0xe1c, 0xffffffff, 0x06070809, - 0x12c, 0xffffffff, 0x04000802, - 0x318, 0x00000fff, 0x00000800, -}; - -u32 Rtl8192UsbAGCTAB_Array[] = { - 0xc78, 0x7d000001, - 0xc78, 0x7d010001, - 0xc78, 0x7d020001, - 0xc78, 0x7d030001, - 0xc78, 0x7d040001, - 0xc78, 0x7d050001, - 0xc78, 0x7c060001, - 0xc78, 0x7b070001, - 0xc78, 0x7a080001, - 0xc78, 0x79090001, - 0xc78, 0x780a0001, - 0xc78, 0x770b0001, - 0xc78, 0x760c0001, - 0xc78, 0x750d0001, - 0xc78, 0x740e0001, - 0xc78, 0x730f0001, - 0xc78, 0x72100001, - 0xc78, 0x71110001, - 0xc78, 0x70120001, - 0xc78, 0x6f130001, - 0xc78, 0x6e140001, - 0xc78, 0x6d150001, - 0xc78, 0x6c160001, - 0xc78, 0x6b170001, - 0xc78, 0x6a180001, - 0xc78, 0x69190001, - 0xc78, 0x681a0001, - 0xc78, 0x671b0001, - 0xc78, 0x661c0001, - 0xc78, 0x651d0001, - 0xc78, 0x641e0001, - 0xc78, 0x491f0001, - 0xc78, 0x48200001, - 0xc78, 0x47210001, - 0xc78, 0x46220001, - 0xc78, 0x45230001, - 0xc78, 0x44240001, - 0xc78, 0x43250001, - 0xc78, 0x28260001, - 0xc78, 0x27270001, - 0xc78, 0x26280001, - 0xc78, 0x25290001, - 0xc78, 0x242a0001, - 0xc78, 0x232b0001, - 0xc78, 0x222c0001, - 0xc78, 0x212d0001, - 0xc78, 0x202e0001, - 0xc78, 0x0a2f0001, - 0xc78, 0x08300001, - 0xc78, 0x06310001, - 0xc78, 0x05320001, - 0xc78, 0x04330001, - 0xc78, 0x03340001, - 0xc78, 0x02350001, - 0xc78, 0x01360001, - 0xc78, 0x00370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7d400001, - 0xc78, 0x7d410001, - 0xc78, 0x7d420001, - 0xc78, 0x7d430001, - 0xc78, 0x7d440001, - 0xc78, 0x7d450001, - 0xc78, 0x7c460001, - 0xc78, 0x7b470001, - 0xc78, 0x7a480001, - 0xc78, 0x79490001, - 0xc78, 0x784a0001, - 0xc78, 0x774b0001, - 0xc78, 0x764c0001, - 0xc78, 0x754d0001, - 0xc78, 0x744e0001, - 0xc78, 0x734f0001, - 0xc78, 0x72500001, - 0xc78, 0x71510001, - 0xc78, 0x70520001, - 0xc78, 0x6f530001, - 0xc78, 0x6e540001, - 0xc78, 0x6d550001, - 0xc78, 0x6c560001, - 0xc78, 0x6b570001, - 0xc78, 0x6a580001, - 0xc78, 0x69590001, - 0xc78, 0x685a0001, - 0xc78, 0x675b0001, - 0xc78, 0x665c0001, - 0xc78, 0x655d0001, - 0xc78, 0x645e0001, - 0xc78, 0x495f0001, - 0xc78, 0x48600001, - 0xc78, 0x47610001, - 0xc78, 0x46620001, - 0xc78, 0x45630001, - 0xc78, 0x44640001, - 0xc78, 0x43650001, - 0xc78, 0x28660001, - 0xc78, 0x27670001, - 0xc78, 0x26680001, - 0xc78, 0x25690001, - 0xc78, 0x246a0001, - 0xc78, 0x236b0001, - 0xc78, 0x226c0001, - 0xc78, 0x216d0001, - 0xc78, 0x206e0001, - 0xc78, 0x0a6f0001, - 0xc78, 0x08700001, - 0xc78, 0x06710001, - 0xc78, 0x05720001, - 0xc78, 0x04730001, - 0xc78, 0x03740001, - 0xc78, 0x02750001, - 0xc78, 0x01760001, - 0xc78, 0x00770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x2e00001e, - 0xc78, 0x2e01001e, - 0xc78, 0x2e02001e, - 0xc78, 0x2e03001e, - 0xc78, 0x2e04001e, - 0xc78, 0x2e05001e, - 0xc78, 0x3006001e, - 0xc78, 0x3407001e, - 0xc78, 0x3908001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3f0a001e, - 0xc78, 0x420b001e, - 0xc78, 0x440c001e, - 0xc78, 0x450d001e, - 0xc78, 0x460e001e, - 0xc78, 0x460f001e, - 0xc78, 0x4710001e, - 0xc78, 0x4811001e, - 0xc78, 0x4912001e, - 0xc78, 0x4a13001e, - 0xc78, 0x4b14001e, - 0xc78, 0x4b15001e, - 0xc78, 0x4c16001e, - 0xc78, 0x4d17001e, - 0xc78, 0x4e18001e, - 0xc78, 0x4f19001e, - 0xc78, 0x4f1a001e, - 0xc78, 0x501b001e, - 0xc78, 0x511c001e, - 0xc78, 0x521d001e, - 0xc78, 0x521e001e, - 0xc78, 0x531f001e, - 0xc78, 0x5320001e, - 0xc78, 0x5421001e, - 0xc78, 0x5522001e, - 0xc78, 0x5523001e, - 0xc78, 0x5624001e, - 0xc78, 0x5725001e, - 0xc78, 0x5726001e, - 0xc78, 0x5827001e, - 0xc78, 0x5828001e, - 0xc78, 0x5929001e, - 0xc78, 0x592a001e, - 0xc78, 0x5a2b001e, - 0xc78, 0x5b2c001e, - 0xc78, 0x5c2d001e, - 0xc78, 0x5c2e001e, - 0xc78, 0x5d2f001e, - 0xc78, 0x5e30001e, - 0xc78, 0x5f31001e, - 0xc78, 0x6032001e, - 0xc78, 0x6033001e, - 0xc78, 0x6134001e, - 0xc78, 0x6235001e, - 0xc78, 0x6336001e, - 0xc78, 0x6437001e, - 0xc78, 0x6438001e, - 0xc78, 0x6539001e, - 0xc78, 0x663a001e, - 0xc78, 0x673b001e, - 0xc78, 0x673c001e, - 0xc78, 0x683d001e, - 0xc78, 0x693e001e, - 0xc78, 0x6a3f001e, -}; diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.h b/drivers/staging/rtl8192u/r819xU_firmware_img.h deleted file mode 100644 index 61585a72465e..000000000000 --- a/drivers/staging/rtl8192u/r819xU_firmware_img.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef IMG_H -#define IMG_H - -#define MACPHY_Array_PGLength 30 -#define PHY_REG_1T2RArrayLength 296 -#define AGCTAB_ArrayLength 384 -#define MACPHY_ArrayLength 18 - -#define RadioA_ArrayLength 246 -#define RadioB_ArrayLength 78 -#define RadioC_ArrayLength 1 -#define RadioD_ArrayLength 1 -#define PHY_REGArrayLength 1 - -extern u32 Rtl8192UsbPHY_REGArray[]; -extern u32 Rtl8192UsbPHY_REG_1T2RArray[]; -extern u32 Rtl8192UsbRadioA_Array[]; -extern u32 Rtl8192UsbRadioB_Array[]; -extern u32 Rtl8192UsbRadioC_Array[]; -extern u32 Rtl8192UsbRadioD_Array[]; -extern u32 Rtl8192UsbMACPHY_Array[]; -extern u32 Rtl8192UsbMACPHY_Array_PG[]; -extern u32 Rtl8192UsbAGCTAB_Array[]; - -#endif diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c deleted file mode 100644 index e6836eacc7aa..000000000000 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ /dev/null @@ -1,1646 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "r8192U.h" -#include "r8192U_hw.h" -#include "r819xU_phy.h" -#include "r819xU_phyreg.h" -#include "r8190_rtl8256.h" -#include "r8192U_dm.h" -#include "r819xU_firmware_img.h" - -#include "ieee80211/dot11d.h" -#include - -static u32 RF_CHANNEL_TABLE_ZEBRA[] = { - 0, - 0x085c, /* 2412 1 */ - 0x08dc, /* 2417 2 */ - 0x095c, /* 2422 3 */ - 0x09dc, /* 2427 4 */ - 0x0a5c, /* 2432 5 */ - 0x0adc, /* 2437 6 */ - 0x0b5c, /* 2442 7 */ - 0x0bdc, /* 2447 8 */ - 0x0c5c, /* 2452 9 */ - 0x0cdc, /* 2457 10 */ - 0x0d5c, /* 2462 11 */ - 0x0ddc, /* 2467 12 */ - 0x0e5c, /* 2472 13 */ - 0x0f72, /* 2484 */ -}; - -#define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array - -/****************************************************************************** - * function: This function checks different RF type to execute legal judgement. - * If RF Path is illegal, we will return false. - * input: net_device *dev - * u32 e_rfpath - * output: none - * return: 0(illegal, false), 1(legal, true) - *****************************************************************************/ -u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 e_rfpath) -{ - u8 ret = 1; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->rf_type == RF_2T4R) { - ret = 0; - } else if (priv->rf_type == RF_1T2R) { - if (e_rfpath == RF90_PATH_A || e_rfpath == RF90_PATH_B) - ret = 1; - else if (e_rfpath == RF90_PATH_C || e_rfpath == RF90_PATH_D) - ret = 0; - } - return ret; -} - -/****************************************************************************** - * function: This function sets specific bits to BB register - * input: net_device *dev - * u32 reg_addr //target addr to be modified - * u32 bitmask //taget bit pos to be modified - * u32 data //value to be write - * output: none - * return: none - * notice: - ******************************************************************************/ -void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask, - u32 data) -{ - u32 reg, bitshift; - - if (bitmask != bMaskDWord) { - read_nic_dword(dev, reg_addr, ®); - bitshift = ffs(bitmask) - 1; - reg &= ~bitmask; - reg |= data << bitshift; - write_nic_dword(dev, reg_addr, reg); - } else { - write_nic_dword(dev, reg_addr, data); - } -} - -/****************************************************************************** - * function: This function reads specific bits from BB register - * input: net_device *dev - * u32 reg_addr //target addr to be readback - * u32 bitmask //taget bit pos to be readback - * output: none - * return: u32 data //the readback register value - * notice: - ******************************************************************************/ -u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask) -{ - u32 reg, bitshift; - - read_nic_dword(dev, reg_addr, ®); - bitshift = ffs(bitmask) - 1; - - return (reg & bitmask) >> bitshift; -} - -static u32 phy_FwRFSerialRead(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 offset); - -static void phy_FwRFSerialWrite(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 offset, - u32 data); - -/****************************************************************************** - * function: This function reads register from RF chip - * input: net_device *dev - * rf90_radio_path_e e_rfpath //radio path of A/B/C/D - * u32 offset //target address to be read - * output: none - * return: u32 readback value - * notice: There are three types of serial operations: - * (1) Software serial write. - * (2)Hardware LSSI-Low Speed Serial Interface. - * (3)Hardware HSSI-High speed serial write. - * Driver here need to implement (1) and (2) - * ---need more spec for this information. - ******************************************************************************/ -static u32 rtl8192_phy_RFSerialRead(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, u32 offset) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 ret = 0; - u32 new_offset = 0; - BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[e_rfpath]; - - rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0); - /* Make sure RF register offset is correct */ - offset &= 0x3f; - - /* Switch page for 8256 RF IC */ - if (priv->rf_chip == RF_8256) { - if (offset >= 31) { - priv->RfReg0Value[e_rfpath] |= 0x140; - /* Switch to Reg_Mode2 for Reg 31-45 */ - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - priv->RfReg0Value[e_rfpath]<<16); - /* Modify offset */ - new_offset = offset - 30; - } else if (offset >= 16) { - priv->RfReg0Value[e_rfpath] |= 0x100; - priv->RfReg0Value[e_rfpath] &= (~0x40); - /* Switch to Reg_Mode1 for Reg16-30 */ - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - priv->RfReg0Value[e_rfpath]<<16); - - new_offset = offset - 15; - } else { - new_offset = offset; - } - } else { - RT_TRACE((COMP_PHY|COMP_ERR), - "check RF type here, need to be 8256\n"); - new_offset = offset; - } - /* Put desired read addr to LSSI control Register */ - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, - new_offset); - /* Issue a posedge trigger */ - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - - /* TODO: we should not delay such a long time. Ask for help from SD3 */ - usleep_range(1000, 1000); - - ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, - bLSSIReadBackData); - - /* Switch back to Reg_Mode0 */ - if (priv->rf_chip == RF_8256) { - priv->RfReg0Value[e_rfpath] &= 0xebf; - - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, - priv->RfReg0Value[e_rfpath] << 16); - } - - return ret; -} - -/****************************************************************************** - * function: This function writes data to RF register - * input: net_device *dev - * rf90_radio_path_e e_rfpath //radio path of A/B/C/D - * u32 offset //target address to be written - * u32 data //the new register data to be written - * output: none - * return: none - * notice: For RF8256 only. - * =========================================================================== - * Reg Mode RegCTL[1] RegCTL[0] Note - * (Reg00[12]) (Reg00[10]) - * =========================================================================== - * Reg_Mode0 0 x Reg 0 ~ 15(0x0 ~ 0xf) - * --------------------------------------------------------------------------- - * Reg_Mode1 1 0 Reg 16 ~ 30(0x1 ~ 0xf) - * --------------------------------------------------------------------------- - * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) - * --------------------------------------------------------------------------- - *****************************************************************************/ -static void rtl8192_phy_RFSerialWrite(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 offset, - u32 data) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 DataAndAddr = 0, new_offset = 0; - BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[e_rfpath]; - - offset &= 0x3f; - if (priv->rf_chip == RF_8256) { - if (offset >= 31) { - priv->RfReg0Value[e_rfpath] |= 0x140; - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - priv->RfReg0Value[e_rfpath] << 16); - new_offset = offset - 30; - } else if (offset >= 16) { - priv->RfReg0Value[e_rfpath] |= 0x100; - priv->RfReg0Value[e_rfpath] &= (~0x40); - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - priv->RfReg0Value[e_rfpath]<<16); - new_offset = offset - 15; - } else { - new_offset = offset; - } - } else { - RT_TRACE((COMP_PHY|COMP_ERR), - "check RF type here, need to be 8256\n"); - new_offset = offset; - } - - /* Put write addr in [5:0] and write data in [31:16] */ - DataAndAddr = (data<<16) | (new_offset&0x3f); - - /* Write operation */ - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); - - if (offset == 0x0) - priv->RfReg0Value[e_rfpath] = data; - - /* Switch back to Reg_Mode0 */ - if (priv->rf_chip == RF_8256) { - if (offset != 0) { - priv->RfReg0Value[e_rfpath] &= 0xebf; - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, - bMaskDWord, - priv->RfReg0Value[e_rfpath] << 16); - } - } -} - -/****************************************************************************** - * function: This function set specific bits to RF register - * input: net_device dev - * rf90_radio_path_e e_rfpath //radio path of A/B/C/D - * u32 reg_addr //target addr to be modified - * u32 bitmask //taget bit pos to be modified - * u32 data //value to be written - * output: none - * return: none - * notice: - *****************************************************************************/ -void rtl8192_phy_SetRFReg(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 reg_addr, u32 bitmask, u32 data) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 reg, bitshift; - - if (!rtl8192_phy_CheckIsLegalRFPath(dev, e_rfpath)) - return; - - if (priv->Rf_Mode == RF_OP_By_FW) { - if (bitmask != bMask12Bits) { - /* RF data is 12 bits only */ - reg = phy_FwRFSerialRead(dev, e_rfpath, reg_addr); - bitshift = ffs(bitmask) - 1; - reg &= ~bitmask; - reg |= data << bitshift; - - phy_FwRFSerialWrite(dev, e_rfpath, reg_addr, reg); - } else { - phy_FwRFSerialWrite(dev, e_rfpath, reg_addr, data); - } - - udelay(200); - - } else { - if (bitmask != bMask12Bits) { - /* RF data is 12 bits only */ - reg = rtl8192_phy_RFSerialRead(dev, e_rfpath, reg_addr); - bitshift = ffs(bitmask) - 1; - reg &= ~bitmask; - reg |= data << bitshift; - - rtl8192_phy_RFSerialWrite(dev, e_rfpath, reg_addr, reg); - } else { - rtl8192_phy_RFSerialWrite(dev, e_rfpath, reg_addr, data); - } - } -} - -/****************************************************************************** - * function: This function reads specific bits from RF register - * input: net_device *dev - * u32 reg_addr //target addr to be readback - * u32 bitmask //taget bit pos to be readback - * output: none - * return: u32 data //the readback register value - * notice: - *****************************************************************************/ -u32 rtl8192_phy_QueryRFReg(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 reg_addr, u32 bitmask) -{ - u32 reg, bitshift; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (!rtl8192_phy_CheckIsLegalRFPath(dev, e_rfpath)) - return 0; - if (priv->Rf_Mode == RF_OP_By_FW) { - reg = phy_FwRFSerialRead(dev, e_rfpath, reg_addr); - udelay(200); - } else { - reg = rtl8192_phy_RFSerialRead(dev, e_rfpath, reg_addr); - } - bitshift = ffs(bitmask) - 1; - reg = (reg & bitmask) >> bitshift; - return reg; -} - -/****************************************************************************** - * function: We support firmware to execute RF-R/W. - * input: net_device *dev - * rf90_radio_path_e e_rfpath - * u32 offset - * output: none - * return: u32 - * notice: - ****************************************************************************/ -static u32 phy_FwRFSerialRead(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 offset) -{ - u32 reg = 0; - u32 data = 0; - u8 time = 0; - u32 tmp; - - /* Firmware RF Write control. - * We can not execute the scheme in the initial step. - * Otherwise, RF-R/W will waste much time. - * This is only for site survey. - */ - /* 1. Read operation need not insert data. bit 0-11 */ - /* 2. Write RF register address. bit 12-19 */ - data |= ((offset&0xFF)<<12); - /* 3. Write RF path. bit 20-21 */ - data |= ((e_rfpath&0x3)<<20); - /* 4. Set RF read indicator. bit 22=0 */ - /* 5. Trigger Fw to operate the command. bit 31 */ - data |= 0x80000000; - /* 6. We can not execute read operation if bit 31 is 1. */ - read_nic_dword(dev, QPNR, &tmp); - while (tmp & 0x80000000) { - /* If FW can not finish RF-R/W for more than ?? times. - * We must reset FW. - */ - if (time++ < 100) { - udelay(10); - read_nic_dword(dev, QPNR, &tmp); - } else { - break; - } - } - /* 7. Execute read operation. */ - write_nic_dword(dev, QPNR, data); - /* 8. Check if firmware send back RF content. */ - read_nic_dword(dev, QPNR, &tmp); - while (tmp & 0x80000000) { - /* If FW can not finish RF-R/W for more than ?? times. - * We must reset FW. - */ - if (time++ < 100) { - udelay(10); - read_nic_dword(dev, QPNR, &tmp); - } else { - return 0; - } - } - read_nic_dword(dev, RF_DATA, ®); - - return reg; -} - -/****************************************************************************** - * function: We support firmware to execute RF-R/W. - * input: net_device *dev - * rf90_radio_path_e e_rfpath - * u32 offset - * u32 data - * output: none - * return: none - * notice: - ****************************************************************************/ -static void phy_FwRFSerialWrite(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 offset, u32 data) -{ - u8 time = 0; - u32 tmp; - - /* Firmware RF Write control. - * We can not execute the scheme in the initial step. - * Otherwise, RF-R/W will waste much time. - * This is only for site survey. - */ - - /* 1. Set driver write bit and 12 bit data. bit 0-11 */ - /* 2. Write RF register address. bit 12-19 */ - data |= ((offset&0xFF)<<12); - /* 3. Write RF path. bit 20-21 */ - data |= ((e_rfpath&0x3)<<20); - /* 4. Set RF write indicator. bit 22=1 */ - data |= 0x400000; - /* 5. Trigger Fw to operate the command. bit 31=1 */ - data |= 0x80000000; - - /* 6. Write operation. We can not write if bit 31 is 1. */ - read_nic_dword(dev, QPNR, &tmp); - while (tmp & 0x80000000) { - /* If FW can not finish RF-R/W for more than ?? times. - * We must reset FW. - */ - if (time++ < 100) { - udelay(10); - read_nic_dword(dev, QPNR, &tmp); - } else { - break; - } - } - /* 7. No matter check bit. We always force the write. - * Because FW will not accept the command. - */ - write_nic_dword(dev, QPNR, data); - /* According to test, we must delay 20us to wait firmware - * to finish RF write operation. - */ - /* We support delay in firmware side now. */ -} - -/****************************************************************************** - * function: This function reads BB parameters from header file we generate, - * and do register read/write - * input: net_device *dev - * output: none - * return: none - * notice: BB parameters may change all the time, so please make - * sure it has been synced with the newest. - *****************************************************************************/ -void rtl8192_phy_configmac(struct net_device *dev) -{ - u32 dwArrayLen = 0, i; - u32 *pdwArray = NULL; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->btxpowerdata_readfromEEPORM) { - RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n"); - dwArrayLen = MACPHY_Array_PGLength; - pdwArray = Rtl8192UsbMACPHY_Array_PG; - - } else { - RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n"); - dwArrayLen = MACPHY_ArrayLength; - pdwArray = rtl819XMACPHY_Array; - } - for (i = 0; i < dwArrayLen; i = i+3) { - if (pdwArray[i] == 0x318) - pdwArray[i+2] = 0x00000800; - - RT_TRACE(COMP_DBG, - "Rtl8190MACPHY_Array[0]=%x Rtl8190MACPHY_Array[1]=%x Rtl8190MACPHY_Array[2]=%x\n", - pdwArray[i], pdwArray[i+1], pdwArray[i+2]); - rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], - pdwArray[i+2]); - } -} - -/****************************************************************************** - * function: This function does dirty work - * input: net_device *dev - * u8 ConfigType - * output: none - * return: none - * notice: BB parameters may change all the time, so please make - * sure it has been synced with the newest. - *****************************************************************************/ -static void rtl8192_phyConfigBB(struct net_device *dev, - enum baseband_config_type ConfigType) -{ - u32 i; - - if (ConfigType == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) { - rtl8192_setBBreg(dev, Rtl8192UsbPHY_REG_1T2RArray[i], - bMaskDWord, - Rtl8192UsbPHY_REG_1T2RArray[i+1]); - RT_TRACE(COMP_DBG, - "i: %x, Rtl819xUsbPHY_REGArray[0]=%x Rtl819xUsbPHY_REGArray[1]=%x\n", - i, Rtl8192UsbPHY_REG_1T2RArray[i], - Rtl8192UsbPHY_REG_1T2RArray[i+1]); - } - } else if (ConfigType == BASEBAND_CONFIG_AGC_TAB) { - for (i = 0; i < AGCTAB_ArrayLength; i += 2) { - rtl8192_setBBreg(dev, Rtl8192UsbAGCTAB_Array[i], - bMaskDWord, Rtl8192UsbAGCTAB_Array[i+1]); - RT_TRACE(COMP_DBG, - "i: %x, Rtl8192UsbAGCTAB_Array[0]=%x Rtl8192UsbAGCTAB_Array[1]=%x\n", - i, Rtl8192UsbAGCTAB_Array[i], - Rtl8192UsbAGCTAB_Array[i+1]); - } - } -} - -/****************************************************************************** - * function: This function initializes Register definition offset for - * Radio Path A/B/C/D - * input: net_device *dev - * output: none - * return: none - * notice: Initialization value here is constant and it should never - * be changed - *****************************************************************************/ -static void rtl8192_InitBBRFRegDef(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - /* RF Interface Software Control */ - /* 16 LSBs if read 32-bit from 0x870 */ - priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; - /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ - priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; - /* 16 LSBs if read 32-bit from 0x874 */ - priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW; - /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ - priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW; - - /* RF Interface Readback Value */ - /* 16 LSBs if read 32-bit from 0x8E0 */ - priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; - /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ - priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB; - /* 16 LSBs if read 32-bit from 0x8E4 */ - priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB; - /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ - priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB; - - /* RF Interface Output (and Enable) */ - /* 16 LSBs if read 32-bit from 0x860 */ - priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; - /* 16 LSBs if read 32-bit from 0x864 */ - priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; - /* 16 LSBs if read 32-bit from 0x868 */ - priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE; - /* 16 LSBs if read 32-bit from 0x86C */ - priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE; - - /* RF Interface (Output and) Enable */ - /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ - priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; - /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ - priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; - /* 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) */ - priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE; - /* 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) */ - priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE; - - /* Addr of LSSI. Write RF register by driver */ - priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; - priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; - priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; - priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter; - - /* RF parameter */ - /* BB Band Select */ - priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; - priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; - priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; - priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; - - /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ - priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; - priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; - priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; - priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; - - /* Tranceiver A~D HSSI Parameter-1 */ - /* wire control parameter1 */ - priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; - priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; - priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; - priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; - - /* Tranceiver A~D HSSI Parameter-2 */ - /* wire control parameter2 */ - priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; - priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; - priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; - priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; - - /* RF Switch Control */ - /* TR/Ant switch control */ - priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; - priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; - priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; - priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; - - /* AGC control 1 */ - priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; - priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; - priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; - priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; - - /* AGC control 2 */ - priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; - priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; - priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; - priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; - - /* RX AFE control 1 */ - priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; - priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; - priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; - priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; - - /* RX AFE control 1 */ - priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE; - priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; - priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; - priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; - - /* Tx AFE control 1 */ - priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; - priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; - priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; - priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; - - /* Tx AFE control 2 */ - priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE; - priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; - priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; - priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; - - /* Tranceiver LSSI Readback */ - priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; -} - -/****************************************************************************** - * function: This function is to write register and then readback to make - * sure whether BB and RF is OK - * input: net_device *dev - * hw90_block_e CheckBlock - * rf90_radio_path_e e_rfpath //only used when checkblock is - * //HW90_BLOCK_RF - * output: none - * return: return whether BB and RF is ok (0:OK, 1:Fail) - * notice: This function may be removed in the ASIC - ******************************************************************************/ -u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, enum hw90_block_e CheckBlock, - enum rf90_radio_path_e e_rfpath) -{ - u8 ret = 0; - u32 i, CheckTimes = 4, reg = 0; - u32 WriteAddr[4]; - u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; - - /* Initialize register address offset to be checked */ - WriteAddr[HW90_BLOCK_MAC] = 0x100; - WriteAddr[HW90_BLOCK_PHY0] = 0x900; - WriteAddr[HW90_BLOCK_PHY1] = 0x800; - WriteAddr[HW90_BLOCK_RF] = 0x3; - RT_TRACE(COMP_PHY, "%s(), CheckBlock: %d\n", __func__, CheckBlock); - for (i = 0; i < CheckTimes; i++) { - /* Write data to register and readback */ - switch (CheckBlock) { - case HW90_BLOCK_MAC: - RT_TRACE(COMP_ERR, - "PHY_CheckBBRFOK(): Never Write 0x100 here!\n"); - break; - - case HW90_BLOCK_PHY0: - case HW90_BLOCK_PHY1: - write_nic_dword(dev, WriteAddr[CheckBlock], - WriteData[i]); - read_nic_dword(dev, WriteAddr[CheckBlock], ®); - break; - - case HW90_BLOCK_RF: - WriteData[i] &= 0xfff; - rtl8192_phy_SetRFReg(dev, e_rfpath, - WriteAddr[HW90_BLOCK_RF], - bMask12Bits, WriteData[i]); - /* TODO: we should not delay for such a long time. - * Ask SD3 - */ - usleep_range(1000, 1000); - reg = rtl8192_phy_QueryRFReg(dev, e_rfpath, - WriteAddr[HW90_BLOCK_RF], - bMask12Bits); - usleep_range(1000, 1000); - break; - - default: - ret = 1; - break; - } - - /* Check whether readback data is correct */ - if (reg != WriteData[i]) { - RT_TRACE((COMP_PHY|COMP_ERR), - "error reg: %x, WriteData: %x\n", - reg, WriteData[i]); - ret = 1; - break; - } - } - - return ret; -} - -/****************************************************************************** - * function: This function initializes BB&RF - * input: net_device *dev - * output: none - * return: none - * notice: Initialization value may change all the time, so please make - * sure it has been synced with the newest. - ******************************************************************************/ -static void rtl8192_BB_Config_ParaFile(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 reg_u8 = 0, eCheckItem = 0, status = 0; - u32 reg_u32 = 0; - - /************************************** - * <1> Initialize BaseBand - *************************************/ - - /* --set BB Global Reset-- */ - read_nic_byte(dev, BB_GLOBAL_RESET, ®_u8); - write_nic_byte(dev, BB_GLOBAL_RESET, (reg_u8|BB_GLOBAL_RESET_BIT)); - mdelay(50); - /* ---set BB reset Active--- */ - read_nic_dword(dev, CPU_GEN, ®_u32); - write_nic_dword(dev, CPU_GEN, (reg_u32&(~CPU_GEN_BB_RST))); - - /* ----Ckeck FPGAPHY0 and PHY1 board is OK---- */ - /* TODO: this function should be removed on ASIC */ - for (eCheckItem = (enum hw90_block_e)HW90_BLOCK_PHY0; - eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) { - /* don't care RF path */ - status = rtl8192_phy_checkBBAndRF(dev, (enum hw90_block_e)eCheckItem, - (enum rf90_radio_path_e)0); - if (status != 0) { - RT_TRACE((COMP_ERR | COMP_PHY), - "phy_rf8256_config(): Check PHY%d Fail!!\n", - eCheckItem-1); - return; - } - } - /* ---- Set CCK and OFDM Block "OFF"---- */ - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); - /* ----BB Register Initilazation---- */ - /* ==m==>Set PHY REG From Header<==m== */ - rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_PHY_REG); - - /* ----Set BB reset de-Active---- */ - read_nic_dword(dev, CPU_GEN, ®_u32); - write_nic_dword(dev, CPU_GEN, (reg_u32|CPU_GEN_BB_RST)); - - /* ----BB AGC table Initialization---- */ - /* ==m==>Set PHY REG From Header<==m== */ - rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_AGC_TAB); - - /* ----Enable XSTAL ---- */ - write_nic_byte_E(dev, 0x5e, 0x00); - if (priv->card_8192_version == VERSION_819XU_A) { - /* Antenna gain offset from B/C/D to A */ - reg_u32 = priv->AntennaTxPwDiff[1]<<4 | - priv->AntennaTxPwDiff[0]; - rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC), - reg_u32); - - /* XSTALLCap */ - reg_u32 = priv->CrystalCap & 0xf; - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap, - reg_u32); - } - - /* Check if the CCK HighPower is turned ON. - * This is used to calculate PWDB. - */ - priv->bCckHighPower = (u8)rtl8192_QueryBBReg(dev, - rFPGA0_XA_HSSIParameter2, - 0x200); -} - -/****************************************************************************** - * function: This function initializes BB&RF - * input: net_device *dev - * output: none - * return: none - * notice: Initialization value may change all the time, so please make - * sure it has been synced with the newest. - *****************************************************************************/ -void rtl8192_BBConfig(struct net_device *dev) -{ - rtl8192_InitBBRFRegDef(dev); - /* config BB&RF. As hardCode based initialization has not been well - * implemented, so use file first. - * FIXME: should implement it for hardcode? - */ - rtl8192_BB_Config_ParaFile(dev); -} - -/****************************************************************************** - * function: This function obtains the initialization value of Tx power Level - * offset - * input: net_device *dev - * output: none - * return: none - *****************************************************************************/ -void rtl8192_phy_getTxPower(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 tmp; - - read_nic_dword(dev, rTxAGC_Rate18_06, - &priv->MCSTxPowerLevelOriginalOffset[0]); - read_nic_dword(dev, rTxAGC_Rate54_24, - &priv->MCSTxPowerLevelOriginalOffset[1]); - read_nic_dword(dev, rTxAGC_Mcs03_Mcs00, - &priv->MCSTxPowerLevelOriginalOffset[2]); - read_nic_dword(dev, rTxAGC_Mcs07_Mcs04, - &priv->MCSTxPowerLevelOriginalOffset[3]); - read_nic_dword(dev, rTxAGC_Mcs11_Mcs08, - &priv->MCSTxPowerLevelOriginalOffset[4]); - read_nic_dword(dev, rTxAGC_Mcs15_Mcs12, - &priv->MCSTxPowerLevelOriginalOffset[5]); - - /* Read rx initial gain */ - read_nic_byte(dev, rOFDM0_XAAGCCore1, &priv->DefaultInitialGain[0]); - read_nic_byte(dev, rOFDM0_XBAGCCore1, &priv->DefaultInitialGain[1]); - read_nic_byte(dev, rOFDM0_XCAGCCore1, &priv->DefaultInitialGain[2]); - read_nic_byte(dev, rOFDM0_XDAGCCore1, &priv->DefaultInitialGain[3]); - RT_TRACE(COMP_INIT, - "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", - priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], - priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); - - /* Read framesync */ - read_nic_byte(dev, rOFDM0_RxDetector3, &priv->framesync); - read_nic_byte(dev, rOFDM0_RxDetector2, &tmp); - priv->framesyncC34 = tmp; - RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n", - rOFDM0_RxDetector3, priv->framesync); - - /* Read SIFS (save the value read fome MACPHY_REG.txt) */ - read_nic_word(dev, SIFS, &priv->SifsTime); -} - -/****************************************************************************** - * function: This function sets the initialization value of Tx power Level - * offset - * input: net_device *dev - * u8 channel - * output: none - * return: none - ******************************************************************************/ -void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; - u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - - switch (priv->rf_chip) { - case RF_8256: - /* need further implement */ - phy_set_rf8256_cck_tx_power(dev, powerlevel); - phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G); - break; - default: - RT_TRACE((COMP_PHY|COMP_ERR), - "error RF chipID(8225 or 8258) in function %s()\n", - __func__); - break; - } -} - -/****************************************************************************** - * function: This function checks Rf chip to do RF config - * input: net_device *dev - * output: none - * return: only 8256 is supported - ******************************************************************************/ -void rtl8192_phy_RFConfig(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - switch (priv->rf_chip) { - case RF_8256: - phy_rf8256_config(dev); - break; - default: - RT_TRACE(COMP_ERR, "error chip id\n"); - break; - } -} - -/****************************************************************************** - * function: This function updates Initial gain - * input: net_device *dev - * output: none - * return: As Windows has not implemented this, wait for complement - ******************************************************************************/ -void rtl8192_phy_updateInitGain(struct net_device *dev) -{ -} - -/****************************************************************************** - * function: This function read RF parameters from general head file, - * and do RF 3-wire - * input: net_device *dev - * rf90_radio_path_e e_rfpath - * output: none - * return: return code show if RF configuration is successful(0:pass, 1:fail) - * notice: Delay may be required for RF configuration - *****************************************************************************/ -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, - enum rf90_radio_path_e e_rfpath) -{ - int i; - - switch (e_rfpath) { - case RF90_PATH_A: - for (i = 0; i < RadioA_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioA_Array[i] == 0xfe) { - mdelay(100); - continue; - } - rtl8192_phy_SetRFReg(dev, e_rfpath, - Rtl8192UsbRadioA_Array[i], - bMask12Bits, - Rtl8192UsbRadioA_Array[i+1]); - mdelay(1); - } - break; - case RF90_PATH_B: - for (i = 0; i < RadioB_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioB_Array[i] == 0xfe) { - mdelay(100); - continue; - } - rtl8192_phy_SetRFReg(dev, e_rfpath, - Rtl8192UsbRadioB_Array[i], - bMask12Bits, - Rtl8192UsbRadioB_Array[i+1]); - mdelay(1); - } - break; - case RF90_PATH_C: - for (i = 0; i < RadioC_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioC_Array[i] == 0xfe) { - mdelay(100); - continue; - } - rtl8192_phy_SetRFReg(dev, e_rfpath, - Rtl8192UsbRadioC_Array[i], - bMask12Bits, - Rtl8192UsbRadioC_Array[i+1]); - mdelay(1); - } - break; - case RF90_PATH_D: - for (i = 0; i < RadioD_ArrayLength; i = i+2) { - if (Rtl8192UsbRadioD_Array[i] == 0xfe) { - mdelay(100); - continue; - } - rtl8192_phy_SetRFReg(dev, e_rfpath, - Rtl8192UsbRadioD_Array[i], - bMask12Bits, - Rtl8192UsbRadioD_Array[i+1]); - mdelay(1); - } - break; - default: - break; - } - - return 0; -} - -/****************************************************************************** - * function: This function sets Tx Power of the channel - * input: net_device *dev - * u8 channel - * output: none - * return: none - * notice: - ******************************************************************************/ -static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; - u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - - switch (priv->rf_chip) { - case RF_8225: - break; - - case RF_8256: - phy_set_rf8256_cck_tx_power(dev, powerlevel); - phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G); - break; - - case RF_8258: - break; - default: - RT_TRACE(COMP_ERR, "unknown rf chip ID in %s()\n", __func__); - break; - } -} - -/****************************************************************************** - * function: This function sets command table variable (struct sw_chnl_cmd). - * input: sw_chnl_cmd *CmdTable //table to be set - * u32 CmdTableIdx //variable index in table to be set - * u32 CmdTableSz //table size - * switch_chan_cmd_id CmdID //command ID to set - * u32 Para1 - * u32 Para2 - * u32 msDelay - * output: - * return: true if finished, false otherwise - * notice: - ******************************************************************************/ -static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, u32 CmdTableIdx, - u32 CmdTableSz, enum switch_chan_cmd_id CmdID, - u32 Para1, u32 Para2, u32 msDelay) -{ - struct sw_chnl_cmd *pCmd; - - if (!CmdTable) { - RT_TRACE(COMP_ERR, "%s(): CmdTable cannot be NULL\n", __func__); - return false; - } - if (CmdTableIdx >= CmdTableSz) { - RT_TRACE(COMP_ERR, "%s(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n", - __func__, CmdTableIdx, CmdTableSz); - return false; - } - - pCmd = CmdTable + CmdTableIdx; - pCmd->cmd_id = CmdID; - pCmd->para_1 = Para1; - pCmd->para_2 = Para2; - pCmd->ms_delay = msDelay; - - return true; -} - -/****************************************************************************** - * function: This function sets channel step by step - * input: net_device *dev - * u8 channel - * u8 *stage //3 stages - * u8 *step - * u32 *delay //whether need to delay - * output: store new stage, step and delay for next step - * (combine with function above) - * return: true if finished, false otherwise - * notice: Wait for simpler function to replace it - *****************************************************************************/ -static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, - u8 *stage, u8 *step, u32 *delay) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct sw_chnl_cmd *pre_cmd; - u32 pre_cmd_cnt = 0; - struct sw_chnl_cmd *post_cmd; - u32 post_cmd_cnt = 0; - struct sw_chnl_cmd *rf_cmd; - u32 rf_cmd_cnt = 0; - struct sw_chnl_cmd *current_cmd = NULL; - u8 e_rfpath; - bool ret; - - pre_cmd = kcalloc(MAX_PRECMD_CNT, sizeof(*pre_cmd), GFP_KERNEL); - if (!pre_cmd) - return false; - - post_cmd = kcalloc(MAX_POSTCMD_CNT, sizeof(*post_cmd), GFP_KERNEL); - if (!post_cmd) { - kfree(pre_cmd); - return false; - } - - rf_cmd = kcalloc(MAX_RFDEPENDCMD_CNT, sizeof(*rf_cmd), GFP_KERNEL); - if (!rf_cmd) { - kfree(pre_cmd); - kfree(post_cmd); - return false; - } - - RT_TRACE(COMP_CH, "%s() stage: %d, step: %d, channel: %d\n", - __func__, *stage, *step, channel); - if (!is_legal_channel(priv->ieee80211, channel)) { - RT_TRACE(COMP_ERR, "set to illegal channel: %d\n", channel); - /* return true to tell upper caller function this channel - * setting is finished! Or it will in while loop. - */ - ret = true; - goto out; - } - /* FIXME: need to check whether channel is legal or not here */ - - /* <1> Fill up pre common command. */ - rtl8192_phy_SetSwChnlCmdArray(pre_cmd, pre_cmd_cnt++, - MAX_PRECMD_CNT, CMD_ID_SET_TX_PWR_LEVEL, - 0, 0, 0); - rtl8192_phy_SetSwChnlCmdArray(pre_cmd, pre_cmd_cnt++, - MAX_PRECMD_CNT, CMD_ID_END, 0, 0, 0); - - /* <2> Fill up post common command. */ - rtl8192_phy_SetSwChnlCmdArray(post_cmd, post_cmd_cnt++, - MAX_POSTCMD_CNT, CMD_ID_END, 0, 0, 0); - - /* <3> Fill up RF dependent command. */ - switch (priv->rf_chip) { - case RF_8225: - if (!(channel >= 1 && channel <= 14)) { - RT_TRACE(COMP_ERR, - "illegal channel for Zebra 8225: %d\n", - channel); - ret = true; - goto out; - } - rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++, - MAX_RFDEPENDCMD_CNT, - CMD_ID_RF_WRITE_REG, - rZebra1_Channel, - RF_CHANNEL_TABLE_ZEBRA[channel], - 10); - rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++, - MAX_RFDEPENDCMD_CNT, - CMD_ID_END, 0, 0, 0); - break; - - case RF_8256: - /* TEST!! This is not the table for 8256!! */ - if (!(channel >= 1 && channel <= 14)) { - RT_TRACE(COMP_ERR, - "illegal channel for Zebra 8256: %d\n", - channel); - ret = true; - goto out; - } - rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++, - MAX_RFDEPENDCMD_CNT, - CMD_ID_RF_WRITE_REG, - rZebra1_Channel, channel, 10); - rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++, - MAX_RFDEPENDCMD_CNT, - CMD_ID_END, 0, 0, 0); - break; - - case RF_8258: - break; - - default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); - ret = true; - goto out; - } - - do { - switch (*stage) { - case 0: - current_cmd = &pre_cmd[*step]; - break; - case 1: - current_cmd = &rf_cmd[*step]; - break; - case 2: - current_cmd = &post_cmd[*step]; - break; - } - - if (current_cmd->cmd_id == CMD_ID_END) { - if ((*stage) == 2) { - *delay = current_cmd->ms_delay; - ret = true; - goto out; - } - (*stage)++; - (*step) = 0; - continue; - } - - switch (current_cmd->cmd_id) { - case CMD_ID_SET_TX_PWR_LEVEL: - if (priv->card_8192_version == VERSION_819XU_A) - /* consider it later! */ - rtl8192_SetTxPowerLevel(dev, channel); - break; - case CMD_ID_WRITE_PORT_ULONG: - write_nic_dword(dev, current_cmd->para_1, - current_cmd->para_2); - break; - case CMD_ID_WRITE_PORT_USHORT: - write_nic_word(dev, current_cmd->para_1, - (u16)current_cmd->para_2); - break; - case CMD_ID_WRITE_PORT_UCHAR: - write_nic_byte(dev, current_cmd->para_1, - (u8)current_cmd->para_2); - break; - case CMD_ID_RF_WRITE_REG: - for (e_rfpath = 0; e_rfpath < RF90_PATH_MAX; e_rfpath++) { - rtl8192_phy_SetRFReg(dev, - (enum rf90_radio_path_e)e_rfpath, - current_cmd->para_1, - bZebra1_ChannelNum, - current_cmd->para_2); - } - break; - default: - break; - } - - break; - } while (true); - - *delay = current_cmd->ms_delay; - (*step)++; - ret = false; - -out: - kfree(pre_cmd); - kfree(post_cmd); - kfree(rf_cmd); - - return ret; -} - -/****************************************************************************** - * function: This function does actually set channel work - * input: net_device *dev - * u8 channel - * output: none - * return: none - * notice: We should not call this function directly - *****************************************************************************/ -static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 delay = 0; - - while (!rtl8192_phy_SwChnlStepByStep(dev, channel, &priv->SwChnlStage, - &priv->SwChnlStep, &delay)) { - if (!priv->up) - break; - } -} - -/****************************************************************************** - * function: Callback routine of the work item for switch channel. - * input: net_device *dev - * - * output: none - * return: none - *****************************************************************************/ -void rtl8192_SwChnl_WorkItem(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", - priv->chan); - - rtl8192_phy_FinishSwChnlNow(dev, priv->chan); - - RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n"); -} - -/****************************************************************************** - * function: This function scheduled actual work item to set channel - * input: net_device *dev - * u8 channel //channel to set - * output: none - * return: return code show if workitem is scheduled (1:pass, 0:fail) - * notice: Delay may be required for RF configuration - ******************************************************************************/ -u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_CH, "%s(), SwChnlInProgress: %d\n", __func__, - priv->SwChnlInProgress); - if (!priv->up) - return false; - if (priv->SwChnlInProgress) - return false; - - /* -------------------------------------------- */ - switch (priv->ieee80211->mode) { - case WIRELESS_MODE_A: - case WIRELESS_MODE_N_5G: - if (channel <= 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14\n"); - return false; - } - break; - case WIRELESS_MODE_B: - if (channel > 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14\n"); - return false; - } - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - if (channel > 14) { - RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14\n"); - return false; - } - break; - } - /* -------------------------------------------- */ - - priv->SwChnlInProgress = true; - if (channel == 0) - channel = 1; - - priv->chan = channel; - - priv->SwChnlStage = 0; - priv->SwChnlStep = 0; - if (priv->up) - rtl8192_SwChnl_WorkItem(dev); - - priv->SwChnlInProgress = false; - return true; -} - -/****************************************************************************** - * function: Callback routine of the work item for set bandwidth mode. - * input: net_device *dev - * output: none - * return: none - * notice: I doubt whether SetBWModeInProgress flag is necessary as we can - * test whether current work in the queue or not.//do I? - *****************************************************************************/ -void rtl8192_SetBWModeWorkItem(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 regBwOpMode; - - RT_TRACE(COMP_SWBW, "%s() Switch to %s bandwidth\n", __func__, - priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"); - - if (priv->rf_chip == RF_PSEUDO_11N) { - priv->SetBWModeInProgress = false; - return; - } - - /* <1> Set MAC register */ - read_nic_byte(dev, BW_OPMODE, ®BwOpMode); - - switch (priv->CurrentChannelBW) { - case HT_CHANNEL_WIDTH_20: - regBwOpMode |= BW_OPMODE_20MHZ; - /* We have not verify whether this register works */ - write_nic_byte(dev, BW_OPMODE, regBwOpMode); - break; - - case HT_CHANNEL_WIDTH_20_40: - regBwOpMode &= ~BW_OPMODE_20MHZ; - /* We have not verify whether this register works */ - write_nic_byte(dev, BW_OPMODE, regBwOpMode); - break; - - default: - RT_TRACE(COMP_ERR, - "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n", - priv->CurrentChannelBW); - break; - } - - /* <2> Set PHY related register */ - switch (priv->CurrentChannelBW) { - case HT_CHANNEL_WIDTH_20: - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, - 0x00100000, 1); - - /* Correct the tx power for CCK rate in 20M. */ - priv->cck_present_attenuation = - priv->cck_present_attenuation_20Mdefault + - priv->cck_present_attenuation_difference; - - if (priv->cck_present_attenuation > 22) - priv->cck_present_attenuation = 22; - if (priv->cck_present_attenuation < 0) - priv->cck_present_attenuation = 0; - RT_TRACE(COMP_INIT, - "20M, pHalData->CCKPresentAttentuation = %d\n", - priv->cck_present_attenuation); - - if (priv->chan == 14 && !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->chan != 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else { - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - - break; - case HT_CHANNEL_WIDTH_20_40: - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); - rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, - priv->nCur40MhzPrimeSC >> 1); - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); - rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, - priv->nCur40MhzPrimeSC); - priv->cck_present_attenuation = - priv->cck_present_attenuation_40Mdefault + - priv->cck_present_attenuation_difference; - - if (priv->cck_present_attenuation > 22) - priv->cck_present_attenuation = 22; - if (priv->cck_present_attenuation < 0) - priv->cck_present_attenuation = 0; - - RT_TRACE(COMP_INIT, - "40M, pHalData->CCKPresentAttentuation = %d\n", - priv->cck_present_attenuation); - if (priv->chan == 14 && !priv->bcck_in_ch14) { - priv->bcck_in_ch14 = true; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else if (priv->chan != 14 && priv->bcck_in_ch14) { - priv->bcck_in_ch14 = false; - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } else { - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); - } - - break; - default: - RT_TRACE(COMP_ERR, - "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n", - priv->CurrentChannelBW); - break; - } - /* Skip over setting of J-mode in BB register here. - * Default value is "None J mode". - */ - - /* <3> Set RF related register */ - switch (priv->rf_chip) { - case RF_8225: - break; - - case RF_8256: - phy_set_rf8256_bandwidth(dev, priv->CurrentChannelBW); - break; - - case RF_8258: - break; - - case RF_PSEUDO_11N: - break; - - default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); - break; - } - priv->SetBWModeInProgress = false; - - RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d\n", - atomic_read(&priv->ieee80211->atm_swbw)); -} - -/****************************************************************************** - * function: This function schedules bandwidth switch work. - * input: struct net_deviceq *dev - * HT_CHANNEL_WIDTH bandwidth //20M or 40M - * HT_EXTCHNL_OFFSET offset //Upper, Lower, or Don't care - * output: none - * return: none - * notice: I doubt whether SetBWModeInProgress flag is necessary as we can - * test whether current work in the queue or not.//do I? - *****************************************************************************/ -void rtl8192_SetBWMode(struct net_device *dev, - enum ht_channel_width bandwidth, - enum ht_extension_chan_offset offset) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->SetBWModeInProgress) - return; - priv->SetBWModeInProgress = true; - - priv->CurrentChannelBW = bandwidth; - - if (offset == HT_EXTCHNL_OFFSET_LOWER) - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; - else if (offset == HT_EXTCHNL_OFFSET_UPPER) - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; - else - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - - rtl8192_SetBWModeWorkItem(dev); -} - -void InitialGain819xUsb(struct net_device *dev, u8 Operation) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->InitialGainOperateType = Operation; - - if (priv->up) - queue_delayed_work(priv->priv_wq, &priv->initialgain_operate_wq, 0); -} - -void InitialGainOperateWorkItemCallBack(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct r8192_priv *priv = container_of(dwork, struct r8192_priv, - initialgain_operate_wq); - struct net_device *dev = priv->ieee80211->dev; -#define SCAN_RX_INITIAL_GAIN 0x17 -#define POWER_DETECTION_TH 0x08 - u32 bitmask; - u8 initial_gain; - u8 Operation; - - Operation = priv->InitialGainOperateType; - - switch (Operation) { - case IG_Backup: - RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n"); - initial_gain = SCAN_RX_INITIAL_GAIN; - bitmask = bMaskByte0; - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - /* FW DIG OFF */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); - priv->initgain_backup.xaagccore1 = - (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bitmask); - priv->initgain_backup.xbagccore1 = - (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bitmask); - priv->initgain_backup.xcagccore1 = - (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bitmask); - priv->initgain_backup.xdagccore1 = - (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bitmask); - bitmask = bMaskByte2; - priv->initgain_backup.cca = - (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bitmask); - - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n", - priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n", - priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n", - priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n", - priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n", - priv->initgain_backup.cca); - - RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x\n", - initial_gain); - write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); - RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x\n", - POWER_DETECTION_TH); - write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH); - break; - case IG_Restore: - RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n"); - bitmask = 0x7f; /* Bit0 ~ Bit6 */ - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - /* FW DIG OFF */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); - - rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bitmask, - (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bitmask, - (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bitmask, - (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bitmask, - (u32)priv->initgain_backup.xdagccore1); - bitmask = bMaskByte2; - rtl8192_setBBreg(dev, rCCK0_CCA, bitmask, - (u32)priv->initgain_backup.cca); - - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n", - priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n", - priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n", - priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n", - priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n", - priv->initgain_backup.cca); - - rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel); - - if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - /* FW DIG ON */ - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); - break; - default: - RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n"); - break; - } -} diff --git a/drivers/staging/rtl8192u/r819xU_phy.h b/drivers/staging/rtl8192u/r819xU_phy.h deleted file mode 100644 index bafaa6a90c50..000000000000 --- a/drivers/staging/rtl8192u/r819xU_phy.h +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _R819XU_PHY_H -#define _R819XU_PHY_H - -/* Channel switch: The size of command tables for switch channel */ -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -enum baseband_config_type { - BASEBAND_CONFIG_PHY_REG = 0, //Radio Path A - BASEBAND_CONFIG_AGC_TAB = 1, //Radio Path B -}; - -enum switch_chan_cmd_id { - CMD_ID_END, - CMD_ID_SET_TX_PWR_LEVEL, - CMD_ID_WRITE_PORT_ULONG, - CMD_ID_WRITE_PORT_USHORT, - CMD_ID_WRITE_PORT_UCHAR, - CMD_ID_RF_WRITE_REG, -}; - -/* -----------------------Define structure---------------------- */ -/* 1. Switch channel related */ -struct sw_chnl_cmd { - enum switch_chan_cmd_id cmd_id; - u32 para_1; - u32 para_2; - u32 ms_delay; -} __packed; - -enum hw90_block_e { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, /* Never use this */ -}; - -enum rf90_radio_path_e { - RF90_PATH_A = 0, /* Radio Path A */ - RF90_PATH_B = 1, /* Radio Path B */ - RF90_PATH_C = 2, /* Radio Path C */ - RF90_PATH_D = 3, /* Radio Path D */ - RF90_PATH_MAX /* Max RF number 92 support */ -}; - -u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 e_rfpath); -void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, - u32 bitmask, u32 data); -u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask); -void rtl8192_phy_SetRFReg(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 reg_addr, u32 bitmask, u32 data); -u32 rtl8192_phy_QueryRFReg(struct net_device *dev, - enum rf90_radio_path_e e_rfpath, - u32 reg_addr, u32 bitmask); -void rtl8192_phy_configmac(struct net_device *dev); -u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, - enum hw90_block_e CheckBlock, - enum rf90_radio_path_e e_rfpath); -void rtl8192_BBConfig(struct net_device *dev); -void rtl8192_phy_getTxPower(struct net_device *dev); -void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel); -void rtl8192_phy_RFConfig(struct net_device *dev); -void rtl8192_phy_updateInitGain(struct net_device *dev); -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, - enum rf90_radio_path_e e_rfpath); - -u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); -void rtl8192_SetBWMode(struct net_device *dev, - enum ht_channel_width bandwidth, - enum ht_extension_chan_offset offset); -void rtl8192_SwChnl_WorkItem(struct net_device *dev); -void rtl8192_SetBWModeWorkItem(struct net_device *dev); -void InitialGain819xUsb(struct net_device *dev, u8 Operation); - -void InitialGainOperateWorkItemCallBack(struct work_struct *work); - -#endif diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h deleted file mode 100644 index c9669821b278..000000000000 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ /dev/null @@ -1,143 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _R819XU_PHYREG_H -#define _R819XU_PHYREG_H - -#define RF_DATA 0x1d4 /* FW will write RF data in the register.*/ - -/* page8 */ -#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC */ -#define rFPGA0_TxGainStage 0x80c -#define rFPGA0_XA_HSSIParameter1 0x820 -#define rFPGA0_XA_HSSIParameter2 0x824 -#define rFPGA0_XB_HSSIParameter1 0x828 -#define rFPGA0_XB_HSSIParameter2 0x82c -#define rFPGA0_XC_HSSIParameter1 0x830 -#define rFPGA0_XC_HSSIParameter2 0x834 -#define rFPGA0_XD_HSSIParameter1 0x838 -#define rFPGA0_XD_HSSIParameter2 0x83c -#define rFPGA0_XA_LSSIParameter 0x840 -#define rFPGA0_XB_LSSIParameter 0x844 -#define rFPGA0_XC_LSSIParameter 0x848 -#define rFPGA0_XD_LSSIParameter 0x84c -#define rFPGA0_XAB_SwitchControl 0x858 -#define rFPGA0_XCD_SwitchControl 0x85c -#define rFPGA0_XA_RFInterfaceOE 0x860 -#define rFPGA0_XB_RFInterfaceOE 0x864 -#define rFPGA0_XC_RFInterfaceOE 0x868 -#define rFPGA0_XD_RFInterfaceOE 0x86c -#define rFPGA0_XAB_RFInterfaceSW 0x870 -#define rFPGA0_XCD_RFInterfaceSW 0x874 -#define rFPGA0_XAB_RFParameter 0x878 -#define rFPGA0_XCD_RFParameter 0x87c -#define rFPGA0_AnalogParameter1 0x880 -#define rFPGA0_AnalogParameter4 0x88c -#define rFPGA0_XA_LSSIReadBack 0x8a0 -#define rFPGA0_XB_LSSIReadBack 0x8a4 -#define rFPGA0_XC_LSSIReadBack 0x8a8 -#define rFPGA0_XD_LSSIReadBack 0x8ac -#define rFPGA0_XAB_RFInterfaceRB 0x8e0 -#define rFPGA0_XCD_RFInterfaceRB 0x8e4 - -/* page 9 */ -#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC */ - -/* page a */ -#define rCCK0_System 0xa00 -#define rCCK0_AFESetting 0xa04 -#define rCCK0_CCA 0xa08 -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ - -/* page c */ -#define rOFDM0_TRxPathEnable 0xc04 -#define rOFDM0_XARxAFE 0xc10 /* RxIQ DC offset, Rx digital filter, DC notch filter */ -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ -#define rOFDM0_XBRxAFE 0xc18 -#define rOFDM0_XBRxIQImbalance 0xc1c -#define rOFDM0_XCRxAFE 0xc20 -#define rOFDM0_XCRxIQImbalance 0xc24 -#define rOFDM0_XDRxAFE 0xc28 -#define rOFDM0_XDRxIQImbalance 0xc2c -#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD */ -#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync.*/ -#define rOFDM0_RxDetector3 0xc38 /* Frame Sync.*/ -#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ -#define rOFDM0_XAAGCCore1 0xc50 -#define rOFDM0_XAAGCCore2 0xc54 -#define rOFDM0_XBAGCCore1 0xc58 -#define rOFDM0_XBAGCCore2 0xc5c -#define rOFDM0_XCAGCCore1 0xc60 -#define rOFDM0_XCAGCCore2 0xc64 -#define rOFDM0_XDAGCCore1 0xc68 -#define rOFDM0_XDAGCCore2 0xc6c -#define rOFDM0_XATxIQImbalance 0xc80 -#define rOFDM0_XATxAFE 0xc84 -#define rOFDM0_XBTxIQImbalance 0xc88 -#define rOFDM0_XBTxAFE 0xc8c -#define rOFDM0_XCTxIQImbalance 0xc90 -#define rOFDM0_XCTxAFE 0xc94 -#define rOFDM0_XDTxIQImbalance 0xc98 -#define rOFDM0_XDTxAFE 0xc9c - -/* page d */ -#define rOFDM1_LSTF 0xd00 -#define rOFDM1_TRxPathEnable 0xd04 - -/* page e */ -#define rTxAGC_Rate18_06 0xe00 -#define rTxAGC_Rate54_24 0xe04 -#define rTxAGC_CCK_Mcs32 0xe08 -#define rTxAGC_Mcs03_Mcs00 0xe10 -#define rTxAGC_Mcs07_Mcs04 0xe14 -#define rTxAGC_Mcs11_Mcs08 0xe18 -#define rTxAGC_Mcs15_Mcs12 0xe1c - -/* RF - * Zebra1 - */ -#define rZebra1_Channel 0x7 - -/* Zebra4 */ -#define rGlobalCtrl 0 - -/* Bit Mask - * page-8 - */ -#define bRFMOD 0x1 -#define bCCKEn 0x1000000 -#define bOFDMEn 0x2000000 -#define bXBTxAGC 0xf00 -#define bXCTxAGC 0xf000 -#define b3WireDataLength 0x800 -#define b3WireAddressLength 0x400 -#define bRFSI_RFENV 0x10 -#define bLSSIReadAddress 0x3f000000 /* LSSI "Read" Address */ -#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ -#define bLSSIReadBackData 0xfff -#define bXtalCap 0x0f000000 - -/* page-a */ -#define bCCKSideBand 0x10 - -/* page e */ -#define bTxAGCRateCCK 0x7f00 - -/* RF - * Zebra1 - */ -#define bZebra1_ChannelNum 0xf80 - -/* RTL8258 */ -/* for PutRegsetting & GetRegSetting BitMask */ -#define bMaskByte0 0xff -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -/* for PutRFRegsetting & GetRFRegSetting BitMask */ -#define bMask12Bits 0xfff - -#endif /* __INC_HAL8190PCIPHYREG_H */ diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c index a3bff27af523..7764896a04ea 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c @@ -153,7 +153,7 @@ static u32 phy_RFSerialRead_8723B( * @Data: The new register Data in the target bit position * of the target to be read * - * .. Note:: Threre are three types of serial operations: + * .. Note:: There are three types of serial operations: * 1. Software serial write * 2. Hardware LSSI-Low Speed Serial Interface * 3. Hardware HSSI-High speed @@ -280,7 +280,7 @@ void PHY_SetRFReg_8723B( /*----------------------------------------------------------------------------- - * PHY_MACConfig8192C - Condig MAC by header file or parameter file. + * PHY_MACConfig8192C - Config MAC by header file or parameter file. * * Revised History: * When Who Remark @@ -325,7 +325,7 @@ static void phy_InitBBRFRegisterDefinition(struct adapter *Adapter) pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */ - /* Tranceiver Readback LSSI/HSPI mode */ + /* Transceiver Readback LSSI/HSPI mode */ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 08543a3936da..86d32e3b3282 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -117,7 +117,7 @@ static int slave_configure(struct scsi_device *sdev) } while (0) /* queue a command */ -/* This is always called with scsi_lock(host) held */ +/* This is always called with spin_lock_irq(host->host_lock) held */ static int queuecommand_lck(struct scsi_cmnd *srb) { void (*done)(struct scsi_cmnd *) = scsi_done; @@ -159,18 +159,18 @@ static int command_abort(struct scsi_cmnd *srb) struct rtsx_dev *dev = host_to_rtsx(host); struct rtsx_chip *chip = dev->chip; - scsi_lock(host); + spin_lock_irq(host->host_lock); /* Is this command still active? */ if (chip->srb != srb) { - scsi_unlock(host); + spin_unlock_irq(host->host_lock); dev_info(&dev->pci->dev, "-- nothing to abort\n"); return FAILED; } rtsx_set_stat(chip, RTSX_STAT_ABORT); - scsi_unlock(host); + spin_unlock_irq(host->host_lock); /* Wait for the aborted command to finish */ wait_for_completion(&dev->notify); @@ -366,7 +366,7 @@ static int rtsx_control_thread(void *__dev) } /* lock access to the state */ - scsi_lock(host); + spin_lock_irq(host->host_lock); /* has the command aborted ? */ if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { @@ -374,7 +374,7 @@ static int rtsx_control_thread(void *__dev) goto skip_for_abort; } - scsi_unlock(host); + spin_unlock_irq(host->host_lock); /* reject the command if the direction indicator * is UNKNOWN @@ -402,7 +402,7 @@ static int rtsx_control_thread(void *__dev) } /* lock access to the state */ - scsi_lock(host); + spin_lock_irq(host->host_lock); /* did the command already complete because of a disconnect? */ if (!chip->srb) @@ -424,7 +424,7 @@ skip_for_abort: /* finished working on this command */ chip->srb = NULL; - scsi_unlock(host); + spin_unlock_irq(host->host_lock); /* unlock the device pointers */ mutex_unlock(&dev->dev_mutex); @@ -603,9 +603,9 @@ static void quiesce_and_remove_host(struct rtsx_dev *dev) * interrupt a SCSI-scan or device-reset delay */ mutex_lock(&dev->dev_mutex); - scsi_lock(host); + spin_lock_irq(host->host_lock); rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); - scsi_unlock(host); + spin_unlock_irq(host->host_lock); mutex_unlock(&dev->dev_mutex); wake_up(&dev->delay_wait); wait_for_completion(&dev->scanning_done); @@ -621,10 +621,10 @@ static void quiesce_and_remove_host(struct rtsx_dev *dev) mutex_lock(&dev->dev_mutex); if (chip->srb) { chip->srb->result = DID_NO_CONNECT << 16; - scsi_lock(host); + spin_lock_irq(host->host_lock); scsi_done(dev->chip->srb); chip->srb = NULL; - scsi_unlock(host); + spin_unlock_irq(host->host_lock); } mutex_unlock(&dev->dev_mutex); diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h index 2e101da83220..ec6f5b07390b 100644 --- a/drivers/staging/rts5208/rtsx.h +++ b/drivers/staging/rts5208/rtsx.h @@ -39,25 +39,6 @@ /* * macros for easy use */ -#define rtsx_writel(chip, reg, value) \ - iowrite32(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readl(chip, reg) \ - ioread32((chip)->rtsx->remap_addr + reg) -#define rtsx_writew(chip, reg, value) \ - iowrite16(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readw(chip, reg) \ - ioread16((chip)->rtsx->remap_addr + reg) -#define rtsx_writeb(chip, reg, value) \ - iowrite8(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readb(chip, reg) \ - ioread8((chip)->rtsx->remap_addr + reg) - -#define rtsx_read_config_byte(chip, where, val) \ - pci_read_config_byte((chip)->rtsx->pci, where, val) - -#define rtsx_write_config_byte(chip, where, val) \ - pci_write_config_byte((chip)->rtsx->pci, where, val) - #define wait_timeout_x(task_state, msecs) \ do { \ set_current_state((task_state)); \ @@ -127,13 +108,6 @@ static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) return (struct rtsx_dev *)host->hostdata; } -/* - * The scsi_lock() and scsi_unlock() macros protect the sm_state and the - * single queue element srb for write access - */ -#define scsi_unlock(host) spin_unlock_irq(host->host_lock) -#define scsi_lock(host) spin_lock_irq(host->host_lock) - #define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) #define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) @@ -147,4 +121,44 @@ enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; #include "rtsx_sys.h" #include "general.h" +static inline void rtsx_writel(struct rtsx_chip *chip, u32 reg, u32 value) +{ + iowrite32(value, chip->rtsx->remap_addr + reg); +} + +static inline u32 rtsx_readl(struct rtsx_chip *chip, u32 reg) +{ + return ioread32(chip->rtsx->remap_addr + reg); +} + +static inline void rtsx_writew(struct rtsx_chip *chip, u32 reg, u16 value) +{ + iowrite16(value, chip->rtsx->remap_addr + reg); +} + +static inline u16 rtsx_readw(struct rtsx_chip *chip, u32 reg) +{ + return ioread16(chip->rtsx->remap_addr + reg); +} + +static inline void rtsx_writeb(struct rtsx_chip *chip, u32 reg, u8 value) +{ + iowrite8(value, chip->rtsx->remap_addr + reg); +} + +static inline u8 rtsx_readb(struct rtsx_chip *chip, u32 reg) +{ + return ioread8((chip)->rtsx->remap_addr + reg); +} + +static inline int rtsx_read_config_byte(struct rtsx_chip *chip, int where, u8 *val) +{ + return pci_read_config_byte(chip->rtsx->pci, where, val); +} + +static inline int rtsx_write_config_byte(struct rtsx_chip *chip, int where, u8 val) +{ + return pci_write_config_byte(chip->rtsx->pci, where, val); +} + #endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c index e00a6cb31947..3b25892af713 100644 --- a/drivers/staging/sm750fb/ddk750_mode.c +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -14,13 +14,13 @@ * in bit 29:27 of Display Control register. */ static unsigned long -displayControlAdjust_SM750LE(struct mode_parameter *pModeParam, - unsigned long dispControl) +display_control_adjust_SM750LE(struct mode_parameter *mode_param, + unsigned long disp_control) { unsigned long x, y; - x = pModeParam->horizontal_display_end; - y = pModeParam->vertical_display_end; + x = mode_param->horizontal_display_end; + y = mode_param->vertical_display_end; /* * SM750LE has to set up the top-left and bottom-right @@ -36,49 +36,48 @@ displayControlAdjust_SM750LE(struct mode_parameter *pModeParam, ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK)); /* - * Assume common fields in dispControl have been properly set before + * Assume common fields in disp_control have been properly set before * calling this function. - * This function only sets the extra fields in dispControl. + * This function only sets the extra fields in disp_control. */ /* Clear bit 29:27 of display control register */ - dispControl &= ~CRT_DISPLAY_CTRL_CLK_MASK; + disp_control &= ~CRT_DISPLAY_CTRL_CLK_MASK; /* Set bit 29:27 of display control register for the right clock */ /* Note that SM750LE only need to supported 7 resolutions. */ if (x == 800 && y == 600) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL41; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL41; else if (x == 1024 && y == 768) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL65; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL65; else if (x == 1152 && y == 864) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL80; else if (x == 1280 && y == 768) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL80; else if (x == 1280 && y == 720) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL74; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL74; else if (x == 1280 && y == 960) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL108; else if (x == 1280 && y == 1024) - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL108; else /* default to VGA clock */ - dispControl |= CRT_DISPLAY_CTRL_CLK_PLL25; + disp_control |= CRT_DISPLAY_CTRL_CLK_PLL25; /* Set bit 25:24 of display controller */ - dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT); + disp_control |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT); /* Set bit 14 of display controller */ - dispControl |= DISPLAY_CTRL_CLOCK_PHASE; + disp_control |= DISPLAY_CTRL_CLOCK_PHASE; - poke32(CRT_DISPLAY_CTRL, dispControl); + poke32(CRT_DISPLAY_CTRL, disp_control); - return dispControl; + return disp_control; } /* only timing related registers will be programed */ -static int programModeRegisters(struct mode_parameter *pModeParam, - struct pll_value *pll) +static void program_mode_registers(struct mode_parameter *mode_param, + struct pll_value *pll) { - int ret = 0; int cnt = 0; unsigned int tmp, reg; @@ -86,46 +85,46 @@ static int programModeRegisters(struct mode_parameter *pModeParam, /* programe secondary pixel clock */ poke32(CRT_PLL_CTRL, sm750_format_pll_reg(pll)); - tmp = ((pModeParam->horizontal_total - 1) << + tmp = ((mode_param->horizontal_total - 1) << CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) & CRT_HORIZONTAL_TOTAL_TOTAL_MASK; - tmp |= (pModeParam->horizontal_display_end - 1) & + tmp |= (mode_param->horizontal_display_end - 1) & CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK; poke32(CRT_HORIZONTAL_TOTAL, tmp); - tmp = (pModeParam->horizontal_sync_width << + tmp = (mode_param->horizontal_sync_width << CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) & CRT_HORIZONTAL_SYNC_WIDTH_MASK; - tmp |= (pModeParam->horizontal_sync_start - 1) & + tmp |= (mode_param->horizontal_sync_start - 1) & CRT_HORIZONTAL_SYNC_START_MASK; poke32(CRT_HORIZONTAL_SYNC, tmp); - tmp = ((pModeParam->vertical_total - 1) << + tmp = ((mode_param->vertical_total - 1) << CRT_VERTICAL_TOTAL_TOTAL_SHIFT) & CRT_VERTICAL_TOTAL_TOTAL_MASK; - tmp |= (pModeParam->vertical_display_end - 1) & + tmp |= (mode_param->vertical_display_end - 1) & CRT_VERTICAL_TOTAL_DISPLAY_END_MASK; poke32(CRT_VERTICAL_TOTAL, tmp); - tmp = ((pModeParam->vertical_sync_height << + tmp = ((mode_param->vertical_sync_height << CRT_VERTICAL_SYNC_HEIGHT_SHIFT)) & CRT_VERTICAL_SYNC_HEIGHT_MASK; - tmp |= (pModeParam->vertical_sync_start - 1) & + tmp |= (mode_param->vertical_sync_start - 1) & CRT_VERTICAL_SYNC_START_MASK; poke32(CRT_VERTICAL_SYNC, tmp); tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE; - if (pModeParam->vertical_sync_polarity) + if (mode_param->vertical_sync_polarity) tmp |= DISPLAY_CTRL_VSYNC_PHASE; - if (pModeParam->horizontal_sync_polarity) + if (mode_param->horizontal_sync_polarity) tmp |= DISPLAY_CTRL_HSYNC_PHASE; if (sm750_get_chip_type() == SM750LE) { - displayControlAdjust_SM750LE(pModeParam, tmp); + display_control_adjust_SM750LE(mode_param, tmp); } else { reg = peek32(CRT_DISPLAY_CTRL) & ~(DISPLAY_CTRL_VSYNC_PHASE | @@ -140,40 +139,40 @@ static int programModeRegisters(struct mode_parameter *pModeParam, poke32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll)); - reg = ((pModeParam->horizontal_total - 1) << + reg = ((mode_param->horizontal_total - 1) << PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) & PANEL_HORIZONTAL_TOTAL_TOTAL_MASK; - reg |= ((pModeParam->horizontal_display_end - 1) & + reg |= ((mode_param->horizontal_display_end - 1) & PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK); poke32(PANEL_HORIZONTAL_TOTAL, reg); poke32(PANEL_HORIZONTAL_SYNC, - ((pModeParam->horizontal_sync_width << + ((mode_param->horizontal_sync_width << PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) & PANEL_HORIZONTAL_SYNC_WIDTH_MASK) | - ((pModeParam->horizontal_sync_start - 1) & + ((mode_param->horizontal_sync_start - 1) & PANEL_HORIZONTAL_SYNC_START_MASK)); poke32(PANEL_VERTICAL_TOTAL, - (((pModeParam->vertical_total - 1) << + (((mode_param->vertical_total - 1) << PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) & PANEL_VERTICAL_TOTAL_TOTAL_MASK) | - ((pModeParam->vertical_display_end - 1) & + ((mode_param->vertical_display_end - 1) & PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK)); poke32(PANEL_VERTICAL_SYNC, - ((pModeParam->vertical_sync_height << + ((mode_param->vertical_sync_height << PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) & PANEL_VERTICAL_SYNC_HEIGHT_MASK) | - ((pModeParam->vertical_sync_start - 1) & + ((mode_param->vertical_sync_start - 1) & PANEL_VERTICAL_SYNC_START_MASK)); tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE; - if (pModeParam->vertical_sync_polarity) + if (mode_param->vertical_sync_polarity) tmp |= DISPLAY_CTRL_VSYNC_PHASE; - if (pModeParam->horizontal_sync_polarity) + if (mode_param->horizontal_sync_polarity) tmp |= DISPLAY_CTRL_HSYNC_PHASE; - if (pModeParam->clock_phase_polarity) + if (mode_param->clock_phase_polarity) tmp |= DISPLAY_CTRL_CLOCK_PHASE; reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK | @@ -201,13 +200,10 @@ static int programModeRegisters(struct mode_parameter *pModeParam, break; poke32(PANEL_DISPLAY_CTRL, tmp | reg); } - } else { - ret = -1; } - return ret; } -int ddk750_setModeTiming(struct mode_parameter *parm, enum clock_type clock) +int ddk750_set_mode_timing(struct mode_parameter *parm, enum clock_type clock) { struct pll_value pll; @@ -220,6 +216,6 @@ int ddk750_setModeTiming(struct mode_parameter *parm, enum clock_type clock) outb_p(0x88, 0x3d4); outb_p(0x06, 0x3d5); } - programModeRegisters(parm, &pll); + program_mode_registers(parm, &pll); return 0; } diff --git a/drivers/staging/sm750fb/ddk750_mode.h b/drivers/staging/sm750fb/ddk750_mode.h index 2df78a0937b2..1b70885f85e5 100644 --- a/drivers/staging/sm750fb/ddk750_mode.h +++ b/drivers/staging/sm750fb/ddk750_mode.h @@ -33,5 +33,5 @@ struct mode_parameter { enum spolarity clock_phase_polarity; }; -int ddk750_setModeTiming(struct mode_parameter *parm, enum clock_type clock); +int ddk750_set_mode_timing(struct mode_parameter *parm, enum clock_type clock); #endif diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index 71247eaf26ee..4bc89218c11c 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -305,7 +305,7 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, clock = SECONDARY_PLL; pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock); - ret = ddk750_setModeTiming(&modparm, clock); + ret = ddk750_set_mode_timing(&modparm, clock); if (ret) { pr_err("Set mode timing failed\n"); goto exit; diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile index 44794bdf6173..e8b897a7b9a6 100644 --- a/drivers/staging/vc04_services/Makefile +++ b/drivers/staging/vc04_services/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_BCM2835_VCHIQ) += vchiq.o vchiq-objs := \ interface/vchiq_arm/vchiq_core.o \ interface/vchiq_arm/vchiq_arm.o \ + interface/vchiq_arm/vchiq_bus.o \ interface/vchiq_arm/vchiq_debugfs.o \ interface/vchiq_arm/vchiq_connected.o \ diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c index 00bc898b0189..b74cb104e9de 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright 2011 Broadcom Corporation. All rights reserved. */ -#include - +#include #include #include #include +#include "../interface/vchiq_arm/vchiq_bus.h" #include "bcm2835.h" static bool enable_hdmi; @@ -268,11 +268,17 @@ static int snd_add_child_devices(struct device *device, u32 numchans) return 0; } -static int snd_bcm2835_alsa_probe(struct platform_device *pdev) +static int snd_bcm2835_alsa_probe(struct vchiq_device *device) { - struct device *dev = &pdev->dev; + struct device *dev = &device->dev; int err; + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(dev, "dma_set_mask_and_coherent failed: %d\n", err); + return err; + } + if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { num_channels = MAX_SUBSTREAMS; dev_warn(dev, "Illegal num_channels value, will use %u\n", @@ -292,32 +298,38 @@ static int snd_bcm2835_alsa_probe(struct platform_device *pdev) #ifdef CONFIG_PM -static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, +static int snd_bcm2835_alsa_suspend(struct vchiq_device *device, pm_message_t state) { return 0; } -static int snd_bcm2835_alsa_resume(struct platform_device *pdev) +static int snd_bcm2835_alsa_resume(struct vchiq_device *device) { return 0; } #endif -static struct platform_driver bcm2835_alsa_driver = { +static struct vchiq_device_id device_id_table[] = { + { .name = "bcm2835-audio" }, + {} +}; +MODULE_DEVICE_TABLE(vchiq, device_id_table); + +static struct vchiq_driver bcm2835_alsa_driver = { .probe = snd_bcm2835_alsa_probe, #ifdef CONFIG_PM .suspend = snd_bcm2835_alsa_suspend, .resume = snd_bcm2835_alsa_resume, #endif + .id_table = device_id_table, .driver = { - .name = "bcm2835_audio", + .name = "bcm2835-audio", }, }; -module_platform_driver(bcm2835_alsa_driver); +module_vchiq_driver(bcm2835_alsa_driver); MODULE_AUTHOR("Dom Cobley"); MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h index 0a81383c475a..49ec5b496edb 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h @@ -84,7 +84,6 @@ struct bcm2835_alsa_stream { int idx; }; -int snd_bcm2835_new_ctl(struct bcm2835_chip *chip); int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name, int idx, enum snd_bcm2835_route route, u32 numchannels, bool spdif); diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index 346d00df815a..e6e89784d84b 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -11,6 +11,7 @@ * Luke Diamand @ Broadcom */ +#include #include #include #include @@ -24,8 +25,8 @@ #include #include #include -#include +#include "../interface/vchiq_arm/vchiq_bus.h" #include "../vchiq-mmal/mmal-common.h" #include "../vchiq-mmal/mmal-encodings.h" #include "../vchiq-mmal/mmal-vchiq.h" @@ -854,7 +855,7 @@ static int vidioc_enum_input(struct file *file, void *priv, return -EINVAL; inp->type = V4L2_INPUT_TYPE_CAMERA; - sprintf((char *)inp->name, "Camera %u", inp->index); + snprintf((char *)inp->name, sizeof(inp->name), "Camera %u", inp->index); return 0; } @@ -1841,7 +1842,7 @@ static struct v4l2_format default_v4l2_format = { .fmt.pix.sizeimage = 1024 * 768, }; -static int bcm2835_mmal_probe(struct platform_device *pdev) +static int bcm2835_mmal_probe(struct vchiq_device *device) { int ret; struct bcm2835_mmal_dev *dev; @@ -1852,6 +1853,12 @@ static int bcm2835_mmal_probe(struct platform_device *pdev) unsigned int resolutions[MAX_BCM2835_CAMERAS][2]; int i; + ret = dma_set_mask_and_coherent(&device->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&device->dev, "dma_set_mask_and_coherent failed: %d\n", ret); + return ret; + } + ret = vchiq_mmal_init(&instance); if (ret < 0) return ret; @@ -1896,7 +1903,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev) &camera_instance); ret = v4l2_device_register(NULL, &dev->v4l2_dev); if (ret) { - dev_err(&pdev->dev, "%s: could not register V4L2 device: %d\n", + dev_err(&device->dev, "%s: could not register V4L2 device: %d\n", __func__, ret); goto free_dev; } @@ -1976,7 +1983,7 @@ cleanup_mmal: return ret; } -static void bcm2835_mmal_remove(struct platform_device *pdev) +static void bcm2835_mmal_remove(struct vchiq_device *device) { int camera; struct vchiq_mmal_instance *instance = gdev[0]->instance; @@ -1988,17 +1995,23 @@ static void bcm2835_mmal_remove(struct platform_device *pdev) vchiq_mmal_finalise(instance); } -static struct platform_driver bcm2835_camera_driver = { +static const struct vchiq_device_id device_id_table[] = { + { .name = "bcm2835-camera" }, + {} +}; +MODULE_DEVICE_TABLE(vchiq, device_id_table); + +static struct vchiq_driver bcm2835_camera_driver = { .probe = bcm2835_mmal_probe, - .remove_new = bcm2835_mmal_remove, + .remove = bcm2835_mmal_remove, + .id_table = device_id_table, .driver = { .name = "bcm2835-camera", }, }; -module_platform_driver(bcm2835_camera_driver) +module_vchiq_driver(bcm2835_camera_driver) MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture"); MODULE_AUTHOR("Vincent Sanders"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:bcm2835-camera"); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index aa2313f3bcab..9fb8f657cc78 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include "vchiq_core.h" #include "vchiq_ioctl.h" #include "vchiq_arm.h" +#include "vchiq_bus.h" #include "vchiq_debugfs.h" #include "vchiq_connected.h" #include "vchiq_pagelist.h" @@ -58,15 +60,16 @@ #define KEEPALIVE_VER 1 #define KEEPALIVE_VER_MIN KEEPALIVE_VER -/* Run time control of log level, based on KERN_XXX level. */ -int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT; -int vchiq_susp_log_level = VCHIQ_LOG_ERROR; - DEFINE_SPINLOCK(msg_queue_spinlock); struct vchiq_state g_state; -static struct platform_device *bcm2835_camera; -static struct platform_device *bcm2835_audio; +/* + * The devices implemented in the VCHIQ firmware are not discoverable, + * so we need to maintain a list of them in order to register them with + * the interface. + */ +static struct vchiq_device *bcm2835_audio; +static struct vchiq_device *bcm2835_camera; struct vchiq_drvdata { const unsigned int cache_line_size; @@ -252,7 +255,8 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr, GFP_KERNEL); - vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist); + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, + "%s - %pK", __func__, pagelist); if (!pagelist) return NULL; @@ -307,9 +311,9 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, type == PAGELIST_READ, pages); if (actual_pages != num_pages) { - vchiq_log_info(vchiq_arm_log_level, - "%s - only %d/%d pages locked", - __func__, actual_pages, num_pages); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s - only %d/%d pages locked", + __func__, actual_pages, num_pages); /* This is probably due to the process being killed */ if (actual_pages > 0) @@ -403,8 +407,8 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel struct page **pages = pagelistinfo->pages; unsigned int num_pages = pagelistinfo->num_pages; - vchiq_log_trace(vchiq_arm_log_level, "%s - %pK, %d", - __func__, pagelistinfo->pagelist, actual); + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, + "%s - %pK, %d", __func__, pagelistinfo->pagelist, actual); /* * NOTE: dma_unmap_sg must be called before the @@ -499,7 +503,7 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0); - vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); + vchiq_slot_zero = vchiq_init_slots(dev, slot_mem, slot_mem_size); if (!vchiq_slot_zero) return -ENOMEM; @@ -552,8 +556,8 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state return -ENXIO; } - vchiq_log_info(vchiq_arm_log_level, "vchiq_init - done (slots %pK, phys %pad)", - vchiq_slot_zero, &slot_phys); + vchiq_log_debug(&pdev->dev, VCHIQ_ARM, "vchiq_init - done (slots %pK, phys %pad)", + vchiq_slot_zero, &slot_phys); vchiq_call_connected_callbacks(); @@ -683,17 +687,18 @@ int vchiq_initialise(struct vchiq_instance **instance_out) usleep_range(500, 600); } if (i == VCHIQ_INIT_RETRIES) { - vchiq_log_error(vchiq_core_log_level, "%s: videocore not initialized\n", __func__); + vchiq_log_error(state->dev, VCHIQ_CORE, "%s: videocore not initialized\n", + __func__); ret = -ENOTCONN; goto failed; } else if (i > 0) { - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(state->dev, VCHIQ_CORE, "%s: videocore initialized after %d retries\n", __func__, i); } instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "%s: error allocating vchiq instance\n", __func__); ret = -ENOMEM; goto failed; @@ -709,7 +714,8 @@ int vchiq_initialise(struct vchiq_instance **instance_out) ret = 0; failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, ret); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, ret); return ret; } @@ -722,8 +728,9 @@ void free_bulk_waiter(struct vchiq_instance *instance) list_for_each_entry_safe(waiter, next, &instance->bulk_waiter_list, list) { list_del(&waiter->list); - vchiq_log_info(vchiq_arm_log_level, "bulk_waiter - cleaned up %pK for pid %d", - waiter, waiter->pid); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "bulk_waiter - cleaned up %pK for pid %d", + waiter, waiter->pid); kfree(waiter); } } @@ -741,7 +748,8 @@ int vchiq_shutdown(struct vchiq_instance *instance) mutex_unlock(&state->mutex); - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); free_bulk_waiter(instance); kfree(instance); @@ -761,7 +769,8 @@ int vchiq_connect(struct vchiq_instance *instance) struct vchiq_state *state = instance->state; if (mutex_lock_killable(&state->mutex)) { - vchiq_log_trace(vchiq_core_log_level, "%s: call to mutex_lock failed", __func__); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s: call to mutex_lock failed", __func__); status = -EAGAIN; goto failed; } @@ -773,7 +782,8 @@ int vchiq_connect(struct vchiq_instance *instance) mutex_unlock(&state->mutex); failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -804,7 +814,8 @@ vchiq_add_service(struct vchiq_instance *instance, status = -EINVAL; } - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -835,7 +846,8 @@ vchiq_open_service(struct vchiq_instance *instance, } failed: - vchiq_log_trace(vchiq_core_log_level, "%s(%p): returning %d", __func__, instance, status); + vchiq_log_trace(state->dev, VCHIQ_CORE, + "%s(%p): returning %d", __func__, instance, status); return status; } @@ -959,7 +971,8 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl } else { waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); if (!waiter) { - vchiq_log_error(vchiq_core_log_level, "%s - out of memory", __func__); + vchiq_log_error(service->state->dev, VCHIQ_CORE, + "%s - out of memory", __func__); return -ENOMEM; } } @@ -982,8 +995,9 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl mutex_lock(&instance->bulk_waiter_list_mutex); list_add(&waiter->list, &instance->bulk_waiter_list); mutex_unlock(&instance->bulk_waiter_list_mutex); - vchiq_log_info(vchiq_arm_log_level, "saved bulk_waiter %pK for pid %d", waiter, - current->pid); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "saved bulk_waiter %pK for pid %d", waiter, + current->pid); } return status; @@ -1003,13 +1017,16 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) { /* Out of space - wait for the client */ DEBUG_TRACE(SERVICE_CALLBACK_LINE); - vchiq_log_trace(vchiq_arm_log_level, "%s - completion queue full", __func__); + vchiq_log_trace(instance->state->dev, VCHIQ_CORE, + "%s - completion queue full", __func__); DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); if (wait_for_completion_interruptible(&instance->remove_event)) { - vchiq_log_info(vchiq_arm_log_level, "service_callback interrupted"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "service_callback interrupted"); return -EAGAIN; } else if (instance->closing) { - vchiq_log_info(vchiq_arm_log_level, "service_callback closing"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "service_callback closing"); return 0; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -1089,7 +1106,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, vchiq_service_get(service); rcu_read_unlock(); - vchiq_log_trace(vchiq_arm_log_level, + vchiq_log_trace(service->state->dev, VCHIQ_ARM, "%s - service %lx(%d,%p), reason %d, header %lx, instance %lx, bulk_userdata %lx", __func__, (unsigned long)user_service, service->localport, user_service->userdata, reason, (unsigned long)header, @@ -1102,7 +1119,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, spin_unlock(&msg_queue_spinlock); DEBUG_TRACE(SERVICE_CALLBACK_LINE); DEBUG_COUNT(MSG_QUEUE_FULL_COUNT); - vchiq_log_trace(vchiq_arm_log_level, "%s - msg queue full", __func__); + vchiq_log_trace(service->state->dev, VCHIQ_ARM, + "%s - msg queue full", __func__); /* * If there is no MESSAGE_AVAILABLE in the completion * queue, add one @@ -1111,8 +1129,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, instance->completion_remove) < 0) { int status; - vchiq_log_info(vchiq_arm_log_level, - "Inserting extra MESSAGE_AVAILABLE"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "Inserting extra MESSAGE_AVAILABLE"); DEBUG_TRACE(SERVICE_CALLBACK_LINE); status = add_completion(instance, reason, NULL, user_service, bulk_userdata); @@ -1125,12 +1143,14 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, DEBUG_TRACE(SERVICE_CALLBACK_LINE); if (wait_for_completion_interruptible(&user_service->remove_event)) { - vchiq_log_info(vchiq_arm_log_level, "%s interrupted", __func__); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s interrupted", __func__); DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_service_put(service); return -EAGAIN; } else if (instance->closing) { - vchiq_log_info(vchiq_arm_log_level, "%s closing", __func__); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "%s closing", __func__); DEBUG_TRACE(SERVICE_CALLBACK_LINE); vchiq_service_put(service); return -EINVAL; @@ -1326,7 +1346,8 @@ vchiq_keepalive_vchiq_callback(struct vchiq_instance *instance, struct vchiq_header *header, unsigned int service_user, void *bulk_user) { - vchiq_log_error(vchiq_susp_log_level, "%s callback reason %d", __func__, reason); + vchiq_log_error(instance->state->dev, VCHIQ_SUSPEND, + "%s callback reason %d", __func__, reason); return 0; } @@ -1350,22 +1371,22 @@ vchiq_keepalive_thread_func(void *v) ret = vchiq_initialise(&instance); if (ret) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_initialise failed %d", __func__, - ret); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_initialise failed %d", __func__, ret); goto exit; } status = vchiq_connect(instance); if (status) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_connect failed %d", __func__, - status); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_connect failed %d", __func__, status); goto shutdown; } status = vchiq_add_service(instance, ¶ms, &ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, "%s vchiq_open_service failed %d", __func__, - status); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s vchiq_open_service failed %d", __func__, status); goto shutdown; } @@ -1373,7 +1394,8 @@ vchiq_keepalive_thread_func(void *v) long rc = 0, uc = 0; if (wait_for_completion_interruptible(&arm_state->ka_evt)) { - vchiq_log_error(vchiq_susp_log_level, "%s interrupted", __func__); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, + "%s interrupted", __func__); flush_signals(current); continue; } @@ -1393,14 +1415,14 @@ vchiq_keepalive_thread_func(void *v) atomic_inc(&arm_state->ka_use_ack_count); status = vchiq_use_service(instance, ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s vchiq_use_service error %d", __func__, status); } } while (rc--) { status = vchiq_release_service(instance, ka_handle); if (status) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s vchiq_release_service error %d", __func__, status); } @@ -1419,7 +1441,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, { struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); int ret = 0; - char entity[16]; + char entity[64]; int *entity_uc; int local_uc; @@ -1429,15 +1451,15 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, } if (use_type == USE_TYPE_VCHIQ) { - sprintf(entity, "VCHIQ: "); + snprintf(entity, sizeof(entity), "VCHIQ: "); entity_uc = &arm_state->peer_use_count; } else if (service) { - sprintf(entity, "%c%c%c%c:%03d", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->client_id); + snprintf(entity, sizeof(entity), "%p4cc:%03d", + &service->base.fourcc, + service->client_id); entity_uc = &service->service_use_count; } else { - vchiq_log_error(vchiq_susp_log_level, "%s null service ptr", __func__); + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "%s null service ptr", __func__); ret = -EINVAL; goto out; } @@ -1446,8 +1468,8 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, local_uc = ++arm_state->videocore_use_count; ++(*entity_uc); - vchiq_log_trace(vchiq_susp_log_level, "%s %s count %d, state count %d", __func__, entity, - *entity_uc, local_uc); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s %s count %d, state count %d", + __func__, entity, *entity_uc, local_uc); write_unlock_bh(&arm_state->susp_res_lock); @@ -1466,7 +1488,7 @@ vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, } out: - vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s exit %d", __func__, ret); return ret; } @@ -1475,7 +1497,7 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) { struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); int ret = 0; - char entity[16]; + char entity[64]; int *entity_uc; if (!arm_state) { @@ -1484,12 +1506,12 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) } if (service) { - sprintf(entity, "%c%c%c%c:%03d", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->client_id); + snprintf(entity, sizeof(entity), "%p4cc:%03d", + &service->base.fourcc, + service->client_id); entity_uc = &service->service_use_count; } else { - sprintf(entity, "PEER: "); + snprintf(entity, sizeof(entity), "PEER: "); entity_uc = &arm_state->peer_use_count; } @@ -1504,14 +1526,14 @@ vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service) --arm_state->videocore_use_count; --(*entity_uc); - vchiq_log_trace(vchiq_susp_log_level, "%s %s count %d, state count %d", __func__, entity, - *entity_uc, arm_state->videocore_use_count); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s %s count %d, state count %d", + __func__, entity, *entity_uc, arm_state->videocore_use_count); unlock: write_unlock_bh(&arm_state->susp_res_lock); out: - vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret); + vchiq_log_trace(state->dev, VCHIQ_SUSPEND, "%s exit %d", __func__, ret); return ret; } @@ -1685,17 +1707,19 @@ vchiq_dump_service_use_state(struct vchiq_state *state) read_unlock_bh(&arm_state->susp_res_lock); if (only_nonzero) - vchiq_log_warning(vchiq_susp_log_level, "Too many active services (%d). Only dumping up to first %d services with non-zero use-count", + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, + "Too many active services (%d). Only dumping up to first %d services with non-zero use-count", active_services, found); for (i = 0; i < found; i++) { - vchiq_log_warning(vchiq_susp_log_level, "----- %c%c%c%c:%d service count %d %s", - VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc), + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, + "%p4cc:%d service count %d %s", + &service_data[i].fourcc, service_data[i].clientid, service_data[i].use_count, service_data[i].use_count ? nz : ""); } - vchiq_log_warning(vchiq_susp_log_level, "----- VCHIQ use count %d", peer_count); - vchiq_log_warning(vchiq_susp_log_level, "--- Overall vchiq instance use count %d", + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, "VCHIQ use count %d", peer_count); + vchiq_log_warning(state->dev, VCHIQ_SUSPEND, "Overall vchiq instance use count %d", vc_use_count); kfree(service_data); @@ -1718,9 +1742,9 @@ vchiq_check_service(struct vchiq_service *service) read_unlock_bh(&arm_state->susp_res_lock); if (ret) { - vchiq_log_error(vchiq_susp_log_level, - "%s ERROR - %c%c%c%c:%d service count %d, state count %d", __func__, - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id, + vchiq_log_error(service->state->dev, VCHIQ_SUSPEND, + "%s ERROR - %p4cc:%d service count %d, state count %d", __func__, + &service->base.fourcc, service->client_id, service->service_use_count, arm_state->videocore_use_count); vchiq_dump_service_use_state(service->state); } @@ -1735,8 +1759,8 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state); char threadname[16]; - vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id, - get_conn_state_name(oldstate), get_conn_state_name(newstate)); + vchiq_log_debug(state->dev, VCHIQ_SUSPEND, "%d: %s->%s", state->id, + get_conn_state_name(oldstate), get_conn_state_name(newstate)); if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED) return; @@ -1754,7 +1778,7 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, (void *)state, threadname); if (IS_ERR(arm_state->ka_thread)) { - vchiq_log_error(vchiq_susp_log_level, + vchiq_log_error(state->dev, VCHIQ_SUSPEND, "vchiq: FATAL: couldn't create thread %s", threadname); } else { @@ -1769,28 +1793,6 @@ static const struct of_device_id vchiq_of_match[] = { }; MODULE_DEVICE_TABLE(of, vchiq_of_match); -static struct platform_device * -vchiq_register_child(struct platform_device *pdev, const char *name) -{ - struct platform_device_info pdevinfo; - struct platform_device *child; - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - - pdevinfo.parent = &pdev->dev; - pdevinfo.name = name; - pdevinfo.id = PLATFORM_DEVID_NONE; - pdevinfo.dma_mask = DMA_BIT_MASK(32); - - child = platform_device_register_full(&pdevinfo); - if (IS_ERR(child)) { - dev_warn(&pdev->dev, "%s not registered\n", name); - child = NULL; - } - - return child; -} - static int vchiq_probe(struct platform_device *pdev) { struct device_node *fw_node; @@ -1823,9 +1825,9 @@ static int vchiq_probe(struct platform_device *pdev) vchiq_debugfs_init(); - vchiq_log_info(vchiq_arm_log_level, - "vchiq: platform initialised - version %d (min %d)", - VCHIQ_VERSION, VCHIQ_VERSION_MIN); + vchiq_log_debug(&pdev->dev, VCHIQ_ARM, + "vchiq: platform initialised - version %d (min %d)", + VCHIQ_VERSION, VCHIQ_VERSION_MIN); /* * Simply exit on error since the function handles cleanup in @@ -1833,26 +1835,26 @@ static int vchiq_probe(struct platform_device *pdev) */ err = vchiq_register_chrdev(&pdev->dev); if (err) { - vchiq_log_warning(vchiq_arm_log_level, + vchiq_log_warning(&pdev->dev, VCHIQ_ARM, "Failed to initialize vchiq cdev"); goto error_exit; } - bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); - bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); + bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio"); + bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera"); return 0; failed_platform_init: - vchiq_log_warning(vchiq_arm_log_level, "could not initialize vchiq platform"); + vchiq_log_warning(&pdev->dev, VCHIQ_ARM, "could not initialize vchiq platform"); error_exit: return err; } static void vchiq_remove(struct platform_device *pdev) { - platform_device_unregister(bcm2835_audio); - platform_device_unregister(bcm2835_camera); + vchiq_device_unregister(bcm2835_audio); + vchiq_device_unregister(bcm2835_camera); vchiq_debugfs_deinit(); vchiq_deregister_chrdev(); } @@ -1870,9 +1872,17 @@ static int __init vchiq_driver_init(void) { int ret; + ret = bus_register(&vchiq_bus_type); + if (ret) { + pr_err("Failed to register %s\n", vchiq_bus_type.name); + return ret; + } + ret = platform_driver_register(&vchiq_driver); - if (ret) + if (ret) { pr_err("Failed to register vchiq driver\n"); + bus_unregister(&vchiq_bus_type); + } return ret; } @@ -1880,6 +1890,7 @@ module_init(vchiq_driver_init); static void __exit vchiq_driver_exit(void) { + bus_unregister(&vchiq_bus_type); platform_driver_unregister(&vchiq_driver); } module_exit(vchiq_driver_exit); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 2fb31f9b527f..7cdc3d70bd2c 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -76,9 +76,6 @@ struct dump_context { loff_t offset; }; -extern int vchiq_arm_log_level; -extern int vchiq_susp_log_level; - extern spinlock_t msg_queue_spinlock; extern struct vchiq_state g_state; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c new file mode 100644 index 000000000000..933027e0011e --- /dev/null +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * vchiq_device.c - VCHIQ generic device and bus-type + * + * Copyright (c) 2023 Ideas On Board Oy + */ + +#include +#include +#include +#include +#include + +#include "vchiq_bus.h" + +static int vchiq_bus_type_match(struct device *dev, struct device_driver *drv) +{ + if (dev->bus == &vchiq_bus_type && + strcmp(dev_name(dev), drv->name) == 0) + return true; + + return false; +} + +static int vchiq_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) +{ + const struct vchiq_device *device = container_of_const(dev, struct vchiq_device, dev); + + return add_uevent_var(env, "MODALIAS=vchiq:%s", dev_name(&device->dev)); +} + +static int vchiq_bus_probe(struct device *dev) +{ + struct vchiq_device *device = to_vchiq_device(dev); + struct vchiq_driver *driver = to_vchiq_driver(dev->driver); + + return driver->probe(device); +} + +struct bus_type vchiq_bus_type = { + .name = "vchiq-bus", + .match = vchiq_bus_type_match, + .uevent = vchiq_bus_uevent, + .probe = vchiq_bus_probe, +}; + +static void vchiq_device_release(struct device *dev) +{ + struct vchiq_device *device = to_vchiq_device(dev); + + kfree(device); +} + +struct vchiq_device * +vchiq_device_register(struct device *parent, const char *name) +{ + struct vchiq_device *device; + int ret; + + device = kzalloc(sizeof(*device), GFP_KERNEL); + if (!device) + return NULL; + + device->dev.init_name = name; + device->dev.parent = parent; + device->dev.bus = &vchiq_bus_type; + device->dev.dma_mask = &device->dev.coherent_dma_mask; + device->dev.release = vchiq_device_release; + + of_dma_configure(&device->dev, parent->of_node, true); + + ret = device_register(&device->dev); + if (ret) { + dev_err(parent, "Cannot register %s: %d\n", name, ret); + put_device(&device->dev); + return NULL; + } + + return device; +} + +void vchiq_device_unregister(struct vchiq_device *vchiq_dev) +{ + device_unregister(&vchiq_dev->dev); +} + +int vchiq_driver_register(struct vchiq_driver *vchiq_drv) +{ + vchiq_drv->driver.bus = &vchiq_bus_type; + + return driver_register(&vchiq_drv->driver); +} +EXPORT_SYMBOL_GPL(vchiq_driver_register); + +void vchiq_driver_unregister(struct vchiq_driver *vchiq_drv) +{ + driver_unregister(&vchiq_drv->driver); +} +EXPORT_SYMBOL_GPL(vchiq_driver_unregister); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h new file mode 100644 index 000000000000..caa6fdf25bb1 --- /dev/null +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023 Ideas On Board Oy + */ + +#ifndef _VCHIQ_DEVICE_H +#define _VCHIQ_DEVICE_H + +#include +#include + +struct vchiq_device { + struct device dev; +}; + +struct vchiq_driver { + int (*probe)(struct vchiq_device *device); + void (*remove)(struct vchiq_device *device); + int (*resume)(struct vchiq_device *device); + int (*suspend)(struct vchiq_device *device, + pm_message_t state); + + const struct vchiq_device_id *id_table; + struct device_driver driver; +}; + +static inline struct vchiq_device *to_vchiq_device(struct device *d) +{ + return container_of(d, struct vchiq_device, dev); +} + +static inline struct vchiq_driver *to_vchiq_driver(struct device_driver *d) +{ + return container_of(d, struct vchiq_driver, driver); +} + +extern struct bus_type vchiq_bus_type; + +struct vchiq_device * +vchiq_device_register(struct device *parent, const char *name); +void vchiq_device_unregister(struct vchiq_device *dev); + +int vchiq_driver_register(struct vchiq_driver *vchiq_drv); +void vchiq_driver_unregister(struct vchiq_driver *vchiq_drv); + +/** + * module_vchiq_driver() - Helper macro for registering a vchiq driver + * @__vchiq_driver: vchiq driver struct + * + * Helper macro for vchiq drivers which do not do anything special in + * module init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_vchiq_driver(__vchiq_driver) \ + module_driver(__vchiq_driver, vchiq_driver_register, vchiq_driver_unregister) + +#endif /* _VCHIQ_DEVICE_H */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c index bdb0ab617d8b..b3928bd8c9c6 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c @@ -39,7 +39,7 @@ void vchiq_add_connected_callback(void (*callback)(void)) callback(); } else { if (g_num_deferred_callbacks >= MAX_CALLBACKS) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(NULL, VCHIQ_CORE, "There already %d callback registered - please increase MAX_CALLBACKS", g_num_deferred_callbacks); } else { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 596894338cb4..39b857da2d42 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -103,11 +103,6 @@ static_assert((unsigned int)VCHIQ_PORT_MAX < #define BULK_INDEX(x) ((x) & (VCHIQ_NUM_SERVICE_BULKS - 1)) -#define SRVTRACE_LEVEL(srv) \ - (((srv) && (srv)->trace) ? VCHIQ_LOG_TRACE : vchiq_core_msg_log_level) -#define SRVTRACE_ENABLED(srv, lev) \ - (((srv) && (srv)->trace) || (vchiq_core_msg_log_level >= (lev))) - #define NO_CLOSE_RECVD 0 #define CLOSE_RECVD 1 @@ -154,11 +149,6 @@ static inline void check_sizes(void) BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_MAX_SERVICES); } -/* Run time control of log level, based on KERN_XXX level. */ -int vchiq_core_log_level = VCHIQ_LOG_DEFAULT; -int vchiq_core_msg_log_level = VCHIQ_LOG_DEFAULT; -int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT; - DEFINE_SPINLOCK(bulk_waiter_spinlock); static DEFINE_SPINLOCK(quota_spinlock); @@ -227,10 +217,10 @@ static const char *msg_type_str(unsigned int msg_type) static inline void set_service_state(struct vchiq_service *service, int newstate) { - vchiq_log_info(vchiq_core_log_level, "%d: srv:%d %s->%s", - service->state->id, service->localport, - srvstate_names[service->srvstate], - srvstate_names[newstate]); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, "%d: srv:%d %s->%s", + service->state->id, service->localport, + srvstate_names[service->srvstate], + srvstate_names[newstate]); service->srvstate = newstate; } @@ -255,8 +245,8 @@ find_service_by_handle(struct vchiq_instance *instance, unsigned int handle) return service; } rcu_read_unlock(); - vchiq_log_info(vchiq_core_log_level, - "Invalid service handle 0x%x", handle); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, + "Invalid service handle 0x%x", handle); return NULL; } @@ -276,8 +266,8 @@ find_service_by_port(struct vchiq_state *state, unsigned int localport) } rcu_read_unlock(); } - vchiq_log_info(vchiq_core_log_level, - "Invalid port %u", localport); + vchiq_log_debug(state->dev, VCHIQ_CORE, + "Invalid port %u", localport); return NULL; } @@ -297,8 +287,8 @@ find_service_for_instance(struct vchiq_instance *instance, unsigned int handle) return service; } rcu_read_unlock(); - vchiq_log_info(vchiq_core_log_level, - "Invalid service handle 0x%x", handle); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, + "Invalid service handle 0x%x", handle); return NULL; } @@ -320,8 +310,8 @@ find_closed_service_for_instance(struct vchiq_instance *instance, unsigned int h return service; } rcu_read_unlock(); - vchiq_log_info(vchiq_core_log_level, - "Invalid service handle 0x%x", handle); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, + "Invalid service handle 0x%x", handle); return service; } @@ -469,13 +459,13 @@ make_service_callback(struct vchiq_service *service, enum vchiq_reason reason, { int status; - vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %pK, %pK)", + vchiq_log_trace(service->state->dev, VCHIQ_CORE, "%d: callback:%d (%s, %pK, %pK)", service->state->id, service->localport, reason_names[reason], header, bulk_userdata); status = service->base.callback(service->instance, reason, header, service->handle, bulk_userdata); if (status && (status != -EAGAIN)) { - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(service->state->dev, VCHIQ_CORE, "%d: ignoring ERROR from callback to service %x", service->state->id, service->handle); status = 0; @@ -492,8 +482,8 @@ vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newstate) { enum vchiq_connstate oldstate = state->conn_state; - vchiq_log_info(vchiq_core_log_level, "%d: %s->%s", state->id, conn_state_names[oldstate], - conn_state_names[newstate]); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: %s->%s", state->id, conn_state_names[oldstate], + conn_state_names[newstate]); state->conn_state = newstate; vchiq_platform_conn_state_changed(state, oldstate, newstate); } @@ -751,7 +741,7 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found, */ complete("a->quota_event); } else if (count == 0) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "service %d message_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)", port, quota->message_use_count, header, msgid, header->msgid, header->size); @@ -773,10 +763,10 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found, * it has dropped below its quota */ complete("a->quota_event); - vchiq_log_trace(vchiq_core_log_level, "%d: pfq:%d %x@%pK - slot_use->%d", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: pfq:%d %x@%pK - slot_use->%d", state->id, port, header->size, header, count - 1); } else { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "service %d slot_use_count=%d (header %pK, msgid %x, header->msgid %x, header->size %x)", port, count, header, msgid, header->msgid, header->size); WARN(1, "bad slot use count\n"); @@ -819,7 +809,7 @@ process_free_queue(struct vchiq_state *state, u32 *service_found, */ rmb(); - vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%pK %x %x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: pfq %d=%pK %x %x", state->id, slot_index, data, local->slot_queue_recycle, slot_queue_available); @@ -841,7 +831,7 @@ process_free_queue(struct vchiq_state *state, u32 *service_found, pos += calc_stride(header->size); if (pos > VCHIQ_SLOT_SIZE) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "pfq - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x", pos, header, msgid, header->msgid, header->size); WARN(1, "invalid slot position\n"); @@ -990,7 +980,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, ((tx_end_index != quota->previous_tx_index) && (quota->slot_use_count == quota->slot_quota))) { spin_unlock("a_spinlock); - vchiq_log_trace(vchiq_core_log_level, + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: qm:%d %s,%zx - quota stall (msg %d, slot %d)", state->id, service->localport, msg_type_str(type), size, quota->message_use_count, quota->slot_use_count); @@ -1033,9 +1023,9 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, int tx_end_index; int slot_use_count; - vchiq_log_info(vchiq_core_log_level, "%d: qm %s@%pK,%zx (%d->%d)", state->id, - msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size, - VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid)); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: qm %s@%pK,%zx (%d->%d)", state->id, + msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size, + VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid)); WARN_ON(flags & (QMFLAGS_NO_MUTEX_LOCK | QMFLAGS_NO_MUTEX_UNLOCK)); @@ -1050,11 +1040,9 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, return -EINVAL; } - if (SRVTRACE_ENABLED(service, - VCHIQ_LOG_INFO)) - vchiq_log_dump_mem("Sent", 0, - header->data, - min_t(size_t, 16, callback_result)); + vchiq_log_dump_mem(state->dev, "Sent", 0, + header->data, + min_t(size_t, 16, callback_result)); spin_lock("a_spinlock); quota->message_use_count++; @@ -1085,7 +1073,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, spin_unlock("a_spinlock); if (slot_use_count) - vchiq_log_trace(vchiq_core_log_level, + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: qm:%d %s,%zx - slot_use->%d (hdr %p)", state->id, service->localport, msg_type_str(VCHIQ_MSG_TYPE(msgid)), size, slot_use_count, header); @@ -1093,9 +1081,9 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); } else { - vchiq_log_info(vchiq_core_log_level, "%d: qm %s@%pK,%zx (%d->%d)", state->id, - msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size, - VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid)); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: qm %s@%pK,%zx (%d->%d)", state->id, + msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size, + VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid)); if (size != 0) { /* * It is assumed for now that this code path @@ -1123,11 +1111,11 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, ? service->base.fourcc : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_info(SRVTRACE_LEVEL(service), - "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%zu", - msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), - VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), VCHIQ_MSG_SRCPORT(msgid), - VCHIQ_MSG_DSTPORT(msgid), size); + vchiq_log_debug(state->dev, VCHIQ_CORE_MSG, + "Sent Msg %s(%u) to %p4cc s:%u d:%d len:%zu", + msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), + &svc_fourcc, VCHIQ_MSG_SRCPORT(msgid), + VCHIQ_MSG_DSTPORT(msgid), size); } /* Make sure the new header is visible to the peer. */ @@ -1159,6 +1147,7 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, struct vchiq_shared_state *local; struct vchiq_header *header; ssize_t callback_result; + int svc_fourcc; local = state->local; @@ -1178,15 +1167,15 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, int oldmsgid = header->msgid; if (oldmsgid != VCHIQ_MSGID_PADDING) - vchiq_log_error(vchiq_core_log_level, "%d: qms - msgid %x, not PADDING", + vchiq_log_error(state->dev, VCHIQ_CORE, "%d: qms - msgid %x, not PADDING", state->id, oldmsgid); } - vchiq_log_info(vchiq_sync_log_level, - "%d: qms %s@%pK,%x (%d->%d)", state->id, - msg_type_str(VCHIQ_MSG_TYPE(msgid)), - header, size, VCHIQ_MSG_SRCPORT(msgid), - VCHIQ_MSG_DSTPORT(msgid)); + vchiq_log_debug(state->dev, VCHIQ_SYNC, + "%d: qms %s@%pK,%x (%d->%d)", state->id, + msg_type_str(VCHIQ_MSG_TYPE(msgid)), + header, size, VCHIQ_MSG_SRCPORT(msgid), + VCHIQ_MSG_DSTPORT(msgid)); callback_result = copy_message_data(copy_callback, context, @@ -1199,11 +1188,9 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, } if (service) { - if (SRVTRACE_ENABLED(service, - VCHIQ_LOG_INFO)) - vchiq_log_dump_mem("Sent", 0, - header->data, - min_t(size_t, 16, callback_result)); + vchiq_log_dump_mem(state->dev, "Sent", 0, + header->data, + min_t(size_t, 16, callback_result)); VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); @@ -1214,19 +1201,15 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, header->size = size; header->msgid = msgid; - if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) { - int svc_fourcc; - svc_fourcc = service - ? service->base.fourcc - : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); + svc_fourcc = service ? service->base.fourcc + : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_trace(vchiq_sync_log_level, - "Sent Sync Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d", - msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), - VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), VCHIQ_MSG_SRCPORT(msgid), - VCHIQ_MSG_DSTPORT(msgid), size); - } + vchiq_log_trace(state->dev, VCHIQ_SYNC, + "Sent Sync Msg %s(%u) to %p4cc s:%u d:%d len:%d", + msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid), + &svc_fourcc, VCHIQ_MSG_SRCPORT(msgid), + VCHIQ_MSG_DSTPORT(msgid), size); remote_event_signal(&state->remote->sync_trigger); @@ -1278,9 +1261,9 @@ release_slot(struct vchiq_state *state, struct vchiq_slot_info *slot_info, VCHIQ_SLOT_QUEUE_MASK] = SLOT_INDEX_FROM_INFO(state, slot_info); state->remote->slot_queue_recycle = slot_queue_recycle + 1; - vchiq_log_info(vchiq_core_log_level, "%d: %s %d - recycle->%x", state->id, __func__, - SLOT_INDEX_FROM_INFO(state, slot_info), - state->remote->slot_queue_recycle); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: %s %d - recycle->%x", + state->id, __func__, SLOT_INDEX_FROM_INFO(state, slot_info), + state->remote->slot_queue_recycle); /* * A write barrier is necessary, but remote_event_signal @@ -1315,8 +1298,10 @@ notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue, { int status = 0; - vchiq_log_trace(vchiq_core_log_level, "%d: nb:%d %cx - p=%x rn=%x r=%x", service->state->id, - service->localport, (queue == &service->bulk_tx) ? 't' : 'r', + vchiq_log_trace(service->state->dev, VCHIQ_CORE, + "%d: nb:%d %cx - p=%x rn=%x r=%x", + service->state->id, service->localport, + (queue == &service->bulk_tx) ? 't' : 'r', queue->process, queue->remote_notify, queue->remove); queue->remote_notify = queue->process; @@ -1397,9 +1382,8 @@ poll_services_of_group(struct vchiq_state *state, int group) service_flags = atomic_xchg(&service->poll_flags, 0); if (service_flags & BIT(VCHIQ_POLL_REMOVE)) { - vchiq_log_info(vchiq_core_log_level, "%d: ps - remove %d<->%d", - state->id, service->localport, - service->remoteport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: ps - remove %d<->%d", + state->id, service->localport, service->remoteport); /* * Make it look like a client, because @@ -1411,8 +1395,8 @@ poll_services_of_group(struct vchiq_state *state, int group) if (vchiq_close_service_internal(service, NO_CLOSE_RECVD)) request_poll(state, service, VCHIQ_POLL_REMOVE); } else if (service_flags & BIT(VCHIQ_POLL_TERMINATE)) { - vchiq_log_info(vchiq_core_log_level, "%d: ps - terminate %d<->%d", - state->id, service->localport, service->remoteport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: ps - terminate %d<->%d", + state->id, service->localport, service->remoteport); if (vchiq_close_service_internal(service, NO_CLOSE_RECVD)) request_poll(state, service, VCHIQ_POLL_TERMINATE); } @@ -1441,9 +1425,11 @@ abort_outstanding_bulks(struct vchiq_service *service, { int is_tx = (queue == &service->bulk_tx); - vchiq_log_trace(vchiq_core_log_level, "%d: aob:%d %cx - li=%x ri=%x p=%x", - service->state->id, service->localport, is_tx ? 't' : 'r', - queue->local_insert, queue->remote_insert, queue->process); + vchiq_log_trace(service->state->dev, VCHIQ_CORE, + "%d: aob:%d %cx - li=%x ri=%x p=%x", + service->state->id, service->localport, + is_tx ? 't' : 'r', queue->local_insert, + queue->remote_insert, queue->process); WARN_ON((int)(queue->local_insert - queue->process) < 0); WARN_ON((int)(queue->remote_insert - queue->process) < 0); @@ -1462,11 +1448,11 @@ abort_outstanding_bulks(struct vchiq_service *service, if (queue->process != queue->local_insert) { vchiq_complete_bulk(service->instance, bulk); - vchiq_log_info(SRVTRACE_LEVEL(service), - "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d", - is_tx ? "Send Bulk to" : "Recv Bulk from", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->remoteport, bulk->size, bulk->remote_size); + vchiq_log_debug(service->state->dev, VCHIQ_CORE_MSG, + "%s %p4cc d:%d ABORTED - tx len:%d, rx len:%d", + is_tx ? "Send Bulk to" : "Recv Bulk from", + &service->base.fourcc, + service->remoteport, bulk->size, bulk->remote_size); } else { /* fabricate a matching dummy bulk */ bulk->data = 0; @@ -1499,8 +1485,8 @@ parse_open(struct vchiq_state *state, struct vchiq_header *header) payload = (struct vchiq_open_payload *)header->data; fourcc = payload->fourcc; - vchiq_log_info(vchiq_core_log_level, "%d: prs OPEN@%pK (%d->'%c%c%c%c')", - state->id, header, localport, VCHIQ_FOURCC_AS_4CHARS(fourcc)); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: prs OPEN@%pK (%d->'%p4cc')", + state->id, header, localport, &fourcc); service = get_listening_service(state, fourcc); if (!service) @@ -1512,11 +1498,9 @@ parse_open(struct vchiq_state *state, struct vchiq_header *header) if ((service->version < version_min) || (version < service->version_min)) { /* Version mismatch */ - vchiq_loud_error_header(); - vchiq_loud_error("%d: service %d (%c%c%c%c) version mismatch - local (%d, min %d) vs. remote (%d, min %d)", - state->id, service->localport, VCHIQ_FOURCC_AS_4CHARS(fourcc), - service->version, service->version_min, version, version_min); - vchiq_loud_error_footer(); + dev_err(state->dev, "%d: service %d (%p4cc) version mismatch - local (%d, min %d) vs. remote (%d, min %d)", + state->id, service->localport, &fourcc, + service->version, service->version_min, version, version_min); vchiq_service_put(service); service = NULL; goto fail_open; @@ -1587,6 +1571,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) struct vchiq_service *service = NULL; unsigned int localport, remoteport; int msgid, size, type, ret = -EINVAL; + int svc_fourcc; DEBUG_INITIALISE(state->local); @@ -1624,14 +1609,14 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) vchiq_service_put(service); service = get_connected_service(state, remoteport); if (service) - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(state->dev, VCHIQ_CORE, "%d: prs %s@%pK (%d->%d) - found connected service %d", state->id, msg_type_str(type), header, remoteport, localport, service->localport); } if (!service) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "%d: prs %s@%pK (%d->%d) - invalid/closed service %d", state->id, msg_type_str(type), header, remoteport, localport, localport); @@ -1642,23 +1627,20 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) break; } - if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) { - int svc_fourcc; - svc_fourcc = service - ? service->base.fourcc - : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_info(SRVTRACE_LEVEL(service), - "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d len:%d", - msg_type_str(type), type, VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, min(16, size)); - } + svc_fourcc = service ? service->base.fourcc + : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); + + vchiq_log_debug(state->dev, VCHIQ_CORE_MSG, + "Rcvd Msg %s(%u) from %p4cc s:%d d:%d len:%d", + msg_type_str(type), type, &svc_fourcc, + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem(state->dev, "Rcvd", 0, header->data, min(16, size)); if (((unsigned long)header & VCHIQ_SLOT_MASK) + calc_stride(size) > VCHIQ_SLOT_SIZE) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "header %pK (msgid %x) - size %x too big for slot", header, (unsigned int)msgid, (unsigned int)size); WARN(1, "oversized for slot\n"); @@ -1677,36 +1659,37 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) header->data; service->peer_version = payload->version; } - vchiq_log_info(vchiq_core_log_level, "%d: prs OPENACK@%pK,%x (%d->%d) v:%d", - state->id, header, size, remoteport, localport, - service->peer_version); + vchiq_log_debug(state->dev, VCHIQ_CORE, + "%d: prs OPENACK@%pK,%x (%d->%d) v:%d", + state->id, header, size, remoteport, localport, + service->peer_version); if (service->srvstate == VCHIQ_SRVSTATE_OPENING) { service->remoteport = remoteport; set_service_state(service, VCHIQ_SRVSTATE_OPEN); complete(&service->remove_event); } else { - vchiq_log_error(vchiq_core_log_level, "OPENACK received in state %s", + vchiq_log_error(state->dev, VCHIQ_CORE, "OPENACK received in state %s", srvstate_names[service->srvstate]); } break; case VCHIQ_MSG_CLOSE: WARN_ON(size); /* There should be no data */ - vchiq_log_info(vchiq_core_log_level, "%d: prs CLOSE@%pK (%d->%d)", - state->id, header, remoteport, localport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: prs CLOSE@%pK (%d->%d)", + state->id, header, remoteport, localport); mark_service_closing_internal(service, 1); if (vchiq_close_service_internal(service, CLOSE_RECVD) == -EAGAIN) goto bail_not_ready; - vchiq_log_info(vchiq_core_log_level, "Close Service %c%c%c%c s:%u d:%d", - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->localport, service->remoteport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "Close Service %p4cc s:%u d:%d", + &service->base.fourcc, + service->localport, service->remoteport); break; case VCHIQ_MSG_DATA: - vchiq_log_info(vchiq_core_log_level, "%d: prs DATA@%pK,%x (%d->%d)", - state->id, header, size, remoteport, localport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: prs DATA@%pK,%x (%d->%d)", + state->id, header, size, remoteport, localport); if ((service->remoteport == remoteport) && (service->srvstate == VCHIQ_SRVSTATE_OPEN)) { @@ -1725,7 +1708,8 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) } break; case VCHIQ_MSG_CONNECT: - vchiq_log_info(vchiq_core_log_level, "%d: prs CONNECT@%pK", state->id, header); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: prs CONNECT@%pK", + state->id, header); state->version_common = ((struct vchiq_slot_zero *) state->slot_data)->version; complete(&state->connect); @@ -1756,7 +1740,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) } if ((int)(queue->remote_insert - queue->local_insert) >= 0) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "%d: prs %s@%pK (%d->%d) unexpected (ri=%d,li=%d)", state->id, msg_type_str(type), header, remoteport, localport, queue->remote_insert, @@ -1777,11 +1761,12 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) bulk->actual = *(int *)header->data; queue->remote_insert++; - vchiq_log_info(vchiq_core_log_level, "%d: prs %s@%pK (%d->%d) %x@%pad", - state->id, msg_type_str(type), header, remoteport, localport, - bulk->actual, &bulk->data); + vchiq_log_debug(state->dev, VCHIQ_CORE, + "%d: prs %s@%pK (%d->%d) %x@%pad", + state->id, msg_type_str(type), header, remoteport, + localport, bulk->actual, &bulk->data); - vchiq_log_trace(vchiq_core_log_level, "%d: prs:%d %cx li=%x ri=%x p=%x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: prs:%d %cx li=%x ri=%x p=%x", state->id, localport, (type == VCHIQ_MSG_BULK_RX_DONE) ? 'r' : 't', queue->local_insert, queue->remote_insert, queue->process); @@ -1797,16 +1782,16 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) } break; case VCHIQ_MSG_PADDING: - vchiq_log_trace(vchiq_core_log_level, "%d: prs PADDING@%pK,%x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: prs PADDING@%pK,%x", state->id, header, size); break; case VCHIQ_MSG_PAUSE: /* If initiated, signal the application thread */ - vchiq_log_trace(vchiq_core_log_level, "%d: prs PAUSE@%pK,%x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: prs PAUSE@%pK,%x", state->id, header, size); if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) { - vchiq_log_error(vchiq_core_log_level, "%d: PAUSE received in state PAUSED", - state->id); + vchiq_log_error(state->dev, VCHIQ_CORE, + "%d: PAUSE received in state PAUSED", state->id); break; } if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) { @@ -1819,7 +1804,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED); break; case VCHIQ_MSG_RESUME: - vchiq_log_trace(vchiq_core_log_level, "%d: prs RESUME@%pK,%x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: prs RESUME@%pK,%x", state->id, header, size); /* Release the slot mutex */ mutex_unlock(&state->slot_mutex); @@ -1836,7 +1821,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) break; default: - vchiq_log_error(vchiq_core_log_level, "%d: prs invalid msgid %x@%pK,%x", + vchiq_log_error(state->dev, VCHIQ_CORE, "%d: prs invalid msgid %x@%pK,%x", state->id, msgid, header, size); WARN(1, "invalid message\n"); break; @@ -1947,7 +1932,7 @@ handle_poll(struct vchiq_state *state) * since the PAUSE should have flushed * through outstanding messages. */ - vchiq_log_error(vchiq_core_log_level, "Failed to send RESUME message"); + vchiq_log_error(state->dev, VCHIQ_CORE, "Failed to send RESUME message"); } break; default: @@ -2025,6 +2010,7 @@ sync_func(void *v) struct vchiq_header *header = (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state, state->remote->slot_sync); + int svc_fourcc; while (1) { struct vchiq_service *service; @@ -2046,7 +2032,7 @@ sync_func(void *v) service = find_service_by_port(state, localport); if (!service) { - vchiq_log_error(vchiq_sync_log_level, + vchiq_log_error(state->dev, VCHIQ_SYNC, "%d: sf %s@%pK (%d->%d) - invalid/closed service %d", state->id, msg_type_str(type), header, remoteport, localport, localport); @@ -2054,19 +2040,15 @@ sync_func(void *v) continue; } - if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) { - int svc_fourcc; + svc_fourcc = service ? service->base.fourcc + : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - svc_fourcc = service - ? service->base.fourcc - : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); - vchiq_log_trace(vchiq_sync_log_level, - "Rcvd Msg %s from %c%c%c%c s:%d d:%d len:%d", - msg_type_str(type), VCHIQ_FOURCC_AS_4CHARS(svc_fourcc), - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, min(16, size)); - } + vchiq_log_trace(state->dev, VCHIQ_SYNC, + "Rcvd Msg %s from %p4cc s:%d d:%d len:%d", + msg_type_str(type), &svc_fourcc, + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem(state->dev, "Rcvd", 0, header->data, min(16, size)); switch (type) { case VCHIQ_MSG_OPENACK: @@ -2076,9 +2058,9 @@ sync_func(void *v) header->data; service->peer_version = payload->version; } - vchiq_log_info(vchiq_sync_log_level, "%d: sf OPENACK@%pK,%x (%d->%d) v:%d", - state->id, header, size, remoteport, localport, - service->peer_version); + vchiq_log_debug(state->dev, VCHIQ_SYNC, "%d: sf OPENACK@%pK,%x (%d->%d) v:%d", + state->id, header, size, remoteport, localport, + service->peer_version); if (service->srvstate == VCHIQ_SRVSTATE_OPENING) { service->remoteport = remoteport; set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC); @@ -2089,21 +2071,21 @@ sync_func(void *v) break; case VCHIQ_MSG_DATA: - vchiq_log_trace(vchiq_sync_log_level, "%d: sf DATA@%pK,%x (%d->%d)", + vchiq_log_trace(state->dev, VCHIQ_SYNC, "%d: sf DATA@%pK,%x (%d->%d)", state->id, header, size, remoteport, localport); if ((service->remoteport == remoteport) && (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC)) { if (make_service_callback(service, VCHIQ_MESSAGE_AVAILABLE, header, NULL) == -EAGAIN) - vchiq_log_error(vchiq_sync_log_level, + vchiq_log_error(state->dev, VCHIQ_SYNC, "synchronous callback to service %d returns -EAGAIN", localport); } break; default: - vchiq_log_error(vchiq_sync_log_level, "%d: sf unexpected msgid %x@%pK,%x", + vchiq_log_error(state->dev, VCHIQ_SYNC, "%d: sf unexpected msgid %x@%pK,%x", state->id, msgid, header, size); release_message_sync(state, header); break; @@ -2122,7 +2104,7 @@ get_conn_state_name(enum vchiq_connstate conn_state) } struct vchiq_slot_zero * -vchiq_init_slots(void *mem_base, int mem_size) +vchiq_init_slots(struct device *dev, void *mem_base, int mem_size) { int mem_align = (int)((VCHIQ_SLOT_SIZE - (long)mem_base) & VCHIQ_SLOT_MASK); @@ -2137,7 +2119,7 @@ vchiq_init_slots(void *mem_base, int mem_size) num_slots -= first_data_slot; if (num_slots < 4) { - vchiq_log_error(vchiq_core_log_level, "%s - insufficient memory %x bytes", + vchiq_log_error(dev, VCHIQ_CORE, "%s - insufficient memory %x bytes", __func__, mem_size); return NULL; } @@ -2174,12 +2156,11 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s remote = &slot_zero->master; if (local->initialised) { - vchiq_loud_error_header(); if (remote->initialised) - vchiq_loud_error("local state has already been initialised"); + dev_err(dev, "local state has already been initialised\n"); else - vchiq_loud_error("master/slave mismatch two slaves"); - vchiq_loud_error_footer(); + dev_err(dev, "master/slave mismatch two slaves\n"); + return -EINVAL; } @@ -2257,9 +2238,7 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s state->slot_handler_thread = kthread_create(&slot_handler_func, (void *)state, threadname); if (IS_ERR(state->slot_handler_thread)) { - vchiq_loud_error_header(); - vchiq_loud_error("couldn't create thread %s", threadname); - vchiq_loud_error_footer(); + dev_err(state->dev, "couldn't create thread %s\n", threadname); return PTR_ERR(state->slot_handler_thread); } set_user_nice(state->slot_handler_thread, -19); @@ -2267,9 +2246,7 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s snprintf(threadname, sizeof(threadname), "vchiq-recy/%d", state->id); state->recycle_thread = kthread_create(&recycle_func, (void *)state, threadname); if (IS_ERR(state->recycle_thread)) { - vchiq_loud_error_header(); - vchiq_loud_error("couldn't create thread %s", threadname); - vchiq_loud_error_footer(); + dev_err(state->dev, "couldn't create thread %s\n", threadname); ret = PTR_ERR(state->recycle_thread); goto fail_free_handler_thread; } @@ -2278,9 +2255,7 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s snprintf(threadname, sizeof(threadname), "vchiq-sync/%d", state->id); state->sync_thread = kthread_create(&sync_func, (void *)state, threadname); if (IS_ERR(state->sync_thread)) { - vchiq_loud_error_header(); - vchiq_loud_error("couldn't create thread %s", threadname); - vchiq_loud_error_footer(); + dev_err(state->dev, "couldn't create thread %s\n", threadname); ret = PTR_ERR(state->sync_thread); goto fail_free_recycle_thread; } @@ -2353,10 +2328,11 @@ struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned in } EXPORT_SYMBOL(vchiq_msg_hold); -static int vchiq_validate_params(const struct vchiq_service_params_kernel *params) +static int vchiq_validate_params(struct vchiq_state *state, + const struct vchiq_service_params_kernel *params) { if (!params->callback || !params->fourcc) { - vchiq_loud_error("Can't add service, invalid params\n"); + dev_err(state->dev, "Can't add service, invalid params\n"); return -EINVAL; } @@ -2376,7 +2352,7 @@ vchiq_add_service_internal(struct vchiq_state *state, int ret; int i; - ret = vchiq_validate_params(params); + ret = vchiq_validate_params(state, params); if (ret) return NULL; @@ -2486,9 +2462,9 @@ vchiq_add_service_internal(struct vchiq_state *state, /* Bring this service online */ set_service_state(service, srvstate); - vchiq_log_info(vchiq_core_msg_log_level, "%s Service %c%c%c%c SrcPort:%d", - (srvstate == VCHIQ_SRVSTATE_OPENING) ? "Open" : "Add", - VCHIQ_FOURCC_AS_4CHARS(params->fourcc), service->localport); + vchiq_log_debug(state->dev, VCHIQ_CORE_MSG, "%s Service %p4cc SrcPort:%d", + (srvstate == VCHIQ_SRVSTATE_OPENING) ? "Open" : "Add", + ¶ms->fourcc, service->localport); /* Don't unlock the service - leave it with a ref_count of 1. */ @@ -2525,7 +2501,7 @@ vchiq_open_service_internal(struct vchiq_service *service, int client_id) } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) && (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) { if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(service->state->dev, VCHIQ_CORE, "%d: osi - srvstate = %s (ref %u)", service->state->id, srvstate_names[service->srvstate], @@ -2584,12 +2560,13 @@ release_service_messages(struct vchiq_service *service) int port = VCHIQ_MSG_DSTPORT(msgid); if ((port == service->localport) && (msgid & VCHIQ_MSGID_CLAIMED)) { - vchiq_log_info(vchiq_core_log_level, " fsi - hdr %pK", header); + vchiq_log_debug(state->dev, VCHIQ_CORE, + " fsi - hdr %pK", header); release_slot(state, slot_info, header, NULL); } pos += calc_stride(header->size); if (pos > VCHIQ_SLOT_SIZE) { - vchiq_log_error(vchiq_core_log_level, + vchiq_log_error(state->dev, VCHIQ_CORE, "fsi - pos %x: header %pK, msgid %x, header->msgid %x, header->size %x", pos, header, msgid, header->msgid, header->size); WARN(1, "invalid slot position\n"); @@ -2645,8 +2622,8 @@ close_service_complete(struct vchiq_service *service, int failstate) case VCHIQ_SRVSTATE_LISTENING: break; default: - vchiq_log_error(vchiq_core_log_level, "%s(%x) called in state %s", __func__, - service->handle, srvstate_names[service->srvstate]); + vchiq_log_error(service->state->dev, VCHIQ_CORE, "%s(%x) called in state %s", + __func__, service->handle, srvstate_names[service->srvstate]); WARN(1, "%s in unexpected state\n", __func__); return -EINVAL; } @@ -2692,8 +2669,8 @@ vchiq_close_service_internal(struct vchiq_service *service, int close_recvd) int close_id = MAKE_CLOSE(service->localport, VCHIQ_MSG_DSTPORT(service->remoteport)); - vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)", service->state->id, - service->localport, close_recvd, srvstate_names[service->srvstate]); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: csi:%d,%d (%s)", service->state->id, + service->localport, close_recvd, srvstate_names[service->srvstate]); switch (service->srvstate) { case VCHIQ_SRVSTATE_CLOSED: @@ -2701,7 +2678,7 @@ vchiq_close_service_internal(struct vchiq_service *service, int close_recvd) case VCHIQ_SRVSTATE_LISTENING: case VCHIQ_SRVSTATE_CLOSEWAIT: if (close_recvd) { - vchiq_log_error(vchiq_core_log_level, "%s(1) called in state %s", + vchiq_log_error(state->dev, VCHIQ_CORE, "%s(1) called in state %s", __func__, srvstate_names[service->srvstate]); } else if (is_server) { if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) { @@ -2789,7 +2766,7 @@ vchiq_close_service_internal(struct vchiq_service *service, int close_recvd) break; default: - vchiq_log_error(vchiq_core_log_level, "%s(%d) called in state %s", __func__, + vchiq_log_error(state->dev, VCHIQ_CORE, "%s(%d) called in state %s", __func__, close_recvd, srvstate_names[service->srvstate]); break; } @@ -2803,8 +2780,8 @@ vchiq_terminate_service_internal(struct vchiq_service *service) { struct vchiq_state *state = service->state; - vchiq_log_info(vchiq_core_log_level, "%d: tsi - (%d<->%d)", state->id, - service->localport, service->remoteport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: tsi - (%d<->%d)", state->id, + service->localport, service->remoteport); mark_service_closing(service); @@ -2818,7 +2795,8 @@ vchiq_free_service_internal(struct vchiq_service *service) { struct vchiq_state *state = service->state; - vchiq_log_info(vchiq_core_log_level, "%d: fsi - (%d)", state->id, service->localport); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: fsi - (%d)", + state->id, service->localport); switch (service->srvstate) { case VCHIQ_SRVSTATE_OPENING: @@ -2828,7 +2806,7 @@ vchiq_free_service_internal(struct vchiq_service *service) case VCHIQ_SRVSTATE_CLOSEWAIT: break; default: - vchiq_log_error(vchiq_core_log_level, "%d: fsi - (%d) in state %s", state->id, + vchiq_log_error(state->dev, VCHIQ_CORE, "%d: fsi - (%d) in state %s", state->id, service->localport, srvstate_names[service->srvstate]); return; } @@ -2898,8 +2876,8 @@ vchiq_close_service(struct vchiq_instance *instance, unsigned int handle) if (!service) return -EINVAL; - vchiq_log_info(vchiq_core_log_level, "%d: close_service:%d", - service->state->id, service->localport); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, "%d: close_service:%d", + service->state->id, service->localport); if ((service->srvstate == VCHIQ_SRVSTATE_FREE) || (service->srvstate == VCHIQ_SRVSTATE_LISTENING) || @@ -2929,7 +2907,7 @@ vchiq_close_service(struct vchiq_instance *instance, unsigned int handle) (service->srvstate == VCHIQ_SRVSTATE_OPEN)) break; - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(service->state->dev, VCHIQ_CORE, "%d: close_service:%d - waiting in state %s", service->state->id, service->localport, srvstate_names[service->srvstate]); @@ -2956,8 +2934,8 @@ vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle) if (!service) return -EINVAL; - vchiq_log_info(vchiq_core_log_level, "%d: remove_service:%d", - service->state->id, service->localport); + vchiq_log_debug(service->state->dev, VCHIQ_CORE, "%d: remove_service:%d", + service->state->id, service->localport); if (service->srvstate == VCHIQ_SRVSTATE_FREE) { vchiq_service_put(service); @@ -2990,7 +2968,7 @@ vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle) (service->srvstate == VCHIQ_SRVSTATE_OPEN)) break; - vchiq_log_warning(vchiq_core_log_level, + vchiq_log_warning(service->state->dev, VCHIQ_CORE, "%d: remove_service:%d - waiting in state %s", service->state->id, service->localport, srvstate_names[service->srvstate]); @@ -3100,9 +3078,9 @@ int vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, */ wmb(); - vchiq_log_info(vchiq_core_log_level, "%d: bt (%d->%d) %cx %x@%pad %pK", - state->id, service->localport, service->remoteport, - dir_char, size, &bulk->data, userdata); + vchiq_log_debug(state->dev, VCHIQ_CORE, "%d: bt (%d->%d) %cx %x@%pad %pK", + state->id, service->localport, service->remoteport, + dir_char, size, &bulk->data, userdata); /* * The slot mutex must be held when the service is being closed, so @@ -3137,7 +3115,7 @@ int vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, mutex_unlock(&state->slot_mutex); mutex_unlock(&service->bulk_mutex); - vchiq_log_trace(vchiq_core_log_level, "%d: bt:%d %cx li=%x ri=%x p=%x", + vchiq_log_trace(state->dev, VCHIQ_CORE, "%d: bt:%d %cx li=%x ri=%x p=%x", state->id, service->localport, dir_char, queue->local_insert, queue->remote_insert, queue->process); @@ -3565,8 +3543,8 @@ int vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) } len += scnprintf(buf + len, sizeof(buf) - len, - " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)", - VCHIQ_FOURCC_AS_4CHARS(fourcc), remoteport, + " '%p4cc' remote %s (msg use %d/%d, slot use %d/%d)", + &fourcc, remoteport, quota->message_use_count, quota->message_quota, quota->slot_use_count, quota->slot_quota); @@ -3628,26 +3606,6 @@ int vchiq_dump_service_state(void *dump_context, struct vchiq_service *service) return err; } -void -vchiq_loud_error_header(void) -{ - vchiq_log_error(vchiq_core_log_level, - "============================================================================"); - vchiq_log_error(vchiq_core_log_level, - "============================================================================"); - vchiq_log_error(vchiq_core_log_level, "====="); -} - -void -vchiq_loud_error_footer(void) -{ - vchiq_log_error(vchiq_core_log_level, "====="); - vchiq_log_error(vchiq_core_log_level, - "============================================================================"); - vchiq_log_error(vchiq_core_log_level, - "============================================================================"); -} - int vchiq_send_remote_use(struct vchiq_state *state) { if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) @@ -3665,7 +3623,8 @@ int vchiq_send_remote_use_active(struct vchiq_state *state) NULL, NULL, 0, 0); } -void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_t num_bytes) +void vchiq_log_dump_mem(struct device *dev, const char *label, u32 addr, + const void *void_mem, size_t num_bytes) { const u8 *mem = void_mem; size_t offset; @@ -3694,9 +3653,9 @@ void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_ *s++ = '\0'; if (label && (*label != '\0')) - vchiq_log_trace(VCHIQ_LOG_TRACE, "%s: %08x: %s", label, addr, line_buf); + vchiq_log_trace(dev, VCHIQ_CORE, "%s: %08x: %s", label, addr, line_buf); else - vchiq_log_trace(VCHIQ_LOG_TRACE, "%08x: %s", addr, line_buf); + vchiq_log_trace(dev, VCHIQ_CORE, "%s: %08x: %s", label, addr, line_buf); addr += 16; mem += 16; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h index ec1a3caefaea..161358db457c 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -30,50 +31,49 @@ #define VCHIQ_SLOT_SIZE 4096 #define VCHIQ_MAX_MSG_SIZE (VCHIQ_SLOT_SIZE - sizeof(struct vchiq_header)) -/* Run time control of log level, based on KERN_XXX level. */ -#define VCHIQ_LOG_DEFAULT 4 -#define VCHIQ_LOG_ERROR 3 -#define VCHIQ_LOG_WARNING 4 -#define VCHIQ_LOG_INFO 6 -#define VCHIQ_LOG_TRACE 7 +enum vchiq_log_category { + VCHIQ_ARM, + VCHIQ_CORE, + VCHIQ_CORE_MSG, + VCHIQ_SYNC, + VCHIQ_SUSPEND, +}; -#define VCHIQ_LOG_PREFIX KERN_INFO "vchiq: " +static inline const char *log_category_str(enum vchiq_log_category c) +{ + static const char * const strings[] = { + "vchiq_arm", + "vchiq_core", + "vchiq_core_msg", + "vchiq_sync", + "vchiq_suspend", + }; + + return strings[c]; +}; #ifndef vchiq_log_error -#define vchiq_log_error(cat, fmt, ...) \ - do { if (cat >= VCHIQ_LOG_ERROR) \ - printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) +#define vchiq_log_error(dev, cat, fmt, ...) \ + do { dev_dbg(dev, "%s error: " fmt, log_category_str(cat), ##__VA_ARGS__); } while (0) #endif #ifndef vchiq_log_warning -#define vchiq_log_warning(cat, fmt, ...) \ - do { if (cat >= VCHIQ_LOG_WARNING) \ - printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) +#define vchiq_log_warning(dev, cat, fmt, ...) \ + do { dev_dbg(dev, "%s warning: " fmt, log_category_str(cat), ##__VA_ARGS__); } while (0) #endif -#ifndef vchiq_log_info -#define vchiq_log_info(cat, fmt, ...) \ - do { if (cat >= VCHIQ_LOG_INFO) \ - printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) +#ifndef vchiq_log_debug +#define vchiq_log_debug(dev, cat, fmt, ...) \ + do { dev_dbg(dev, "%s debug: " fmt, log_category_str(cat), ##__VA_ARGS__); } while (0) #endif #ifndef vchiq_log_trace -#define vchiq_log_trace(cat, fmt, ...) \ - do { if (cat >= VCHIQ_LOG_TRACE) \ - printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0) +#define vchiq_log_trace(dev, cat, fmt, ...) \ + do { dev_dbg(dev, "%s trace: " fmt, log_category_str(cat), ##__VA_ARGS__); } while (0) #endif -#define vchiq_loud_error(...) \ - vchiq_log_error(vchiq_core_log_level, "===== " __VA_ARGS__) - #define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1) #define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1) #define VCHIQ_SLOT_ZERO_SLOTS DIV_ROUND_UP(sizeof(struct vchiq_slot_zero), \ VCHIQ_SLOT_SIZE) -#define VCHIQ_FOURCC_AS_4CHARS(fourcc) \ - ((fourcc) >> 24) & 0xff, \ - ((fourcc) >> 16) & 0xff, \ - ((fourcc) >> 8) & 0xff, \ - (fourcc) & 0xff - #define BITSET_SIZE(b) ((b + 31) >> 5) #define BITSET_WORD(b) (b >> 5) #define BITSET_BIT(b) (1 << (b & 31)) @@ -463,15 +463,11 @@ struct vchiq_config { extern spinlock_t bulk_waiter_spinlock; -extern int vchiq_core_log_level; -extern int vchiq_core_msg_log_level; -extern int vchiq_sync_log_level; - extern const char * get_conn_state_name(enum vchiq_connstate conn_state); extern struct vchiq_slot_zero * -vchiq_init_slots(void *mem_base, int mem_size); +vchiq_init_slots(struct device *dev, void *mem_base, int mem_size); extern int vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, struct device *dev); @@ -600,7 +596,8 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, void vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newstate); -void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_t num_bytes); +void vchiq_log_dump_mem(struct device *dev, const char *label, u32 addr, + const void *void_mem, size_t num_bytes); int vchiq_remove_service(struct vchiq_instance *instance, unsigned int service); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c index dc667afd1f8c..58db78a9c8d4 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c @@ -13,102 +13,10 @@ #define DEBUGFS_WRITE_BUF_SIZE 256 -#define VCHIQ_LOG_ERROR_STR "error" -#define VCHIQ_LOG_WARNING_STR "warning" -#define VCHIQ_LOG_INFO_STR "info" -#define VCHIQ_LOG_TRACE_STR "trace" - /* Global 'vchiq' debugfs and clients entry used by all instances */ static struct dentry *vchiq_dbg_dir; static struct dentry *vchiq_dbg_clients; -/* Log category debugfs entries */ -struct vchiq_debugfs_log_entry { - const char *name; - void *plevel; -}; - -static struct vchiq_debugfs_log_entry vchiq_debugfs_log_entries[] = { - { "core", &vchiq_core_log_level }, - { "msg", &vchiq_core_msg_log_level }, - { "sync", &vchiq_sync_log_level }, - { "susp", &vchiq_susp_log_level }, - { "arm", &vchiq_arm_log_level }, -}; - -static int debugfs_log_show(struct seq_file *f, void *offset) -{ - int *levp = f->private; - char *log_value = NULL; - - switch (*levp) { - case VCHIQ_LOG_ERROR: - log_value = VCHIQ_LOG_ERROR_STR; - break; - case VCHIQ_LOG_WARNING: - log_value = VCHIQ_LOG_WARNING_STR; - break; - case VCHIQ_LOG_INFO: - log_value = VCHIQ_LOG_INFO_STR; - break; - case VCHIQ_LOG_TRACE: - log_value = VCHIQ_LOG_TRACE_STR; - break; - default: - break; - } - - seq_printf(f, "%s\n", log_value ? log_value : "(null)"); - - return 0; -} - -static int debugfs_log_open(struct inode *inode, struct file *file) -{ - return single_open(file, debugfs_log_show, inode->i_private); -} - -static ssize_t debugfs_log_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct seq_file *f = (struct seq_file *)file->private_data; - int *levp = f->private; - char kbuf[DEBUGFS_WRITE_BUF_SIZE + 1]; - - memset(kbuf, 0, DEBUGFS_WRITE_BUF_SIZE + 1); - if (count >= DEBUGFS_WRITE_BUF_SIZE) - count = DEBUGFS_WRITE_BUF_SIZE; - - if (copy_from_user(kbuf, buffer, count)) - return -EFAULT; - kbuf[count - 1] = 0; - - if (strncmp("error", kbuf, strlen("error")) == 0) - *levp = VCHIQ_LOG_ERROR; - else if (strncmp("warning", kbuf, strlen("warning")) == 0) - *levp = VCHIQ_LOG_WARNING; - else if (strncmp("info", kbuf, strlen("info")) == 0) - *levp = VCHIQ_LOG_INFO; - else if (strncmp("trace", kbuf, strlen("trace")) == 0) - *levp = VCHIQ_LOG_TRACE; - else - *levp = VCHIQ_LOG_DEFAULT; - - *ppos += count; - - return count; -} - -static const struct file_operations debugfs_log_fops = { - .owner = THIS_MODULE, - .open = debugfs_log_open, - .write = debugfs_log_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int debugfs_usecount_show(struct seq_file *f, void *offset) { struct vchiq_instance *instance = f->private; @@ -205,19 +113,8 @@ void vchiq_debugfs_remove_instance(struct vchiq_instance *instance) void vchiq_debugfs_init(void) { - struct dentry *dir; - int i; - vchiq_dbg_dir = debugfs_create_dir("vchiq", NULL); vchiq_dbg_clients = debugfs_create_dir("clients", vchiq_dbg_dir); - - /* create an entry under /vchiq/log for each log category */ - dir = debugfs_create_dir("log", vchiq_dbg_dir); - - for (i = 0; i < ARRAY_SIZE(vchiq_debugfs_log_entries); i++) - debugfs_create_file(vchiq_debugfs_log_entries[i].name, 0644, - dir, vchiq_debugfs_log_entries[i].plevel, - &debugfs_log_fops); } /* remove all the debugfs entries */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c index 841e1a535642..0bc93f48c14c 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c @@ -47,9 +47,9 @@ user_service_free(void *userdata) static void close_delivered(struct user_service *user_service) { - vchiq_log_info(vchiq_arm_log_level, - "%s(handle=%x)", - __func__, user_service->service->handle); + vchiq_log_debug(user_service->service->state->dev, VCHIQ_ARM, + "%s(handle=%x)", + __func__, user_service->service->handle); if (user_service->close_pending) { /* Allow the underlying service to be culled */ @@ -235,8 +235,8 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, spin_unlock(&msg_queue_spinlock); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); if (wait_for_completion_interruptible(&user_service->insert_event)) { - vchiq_log_info(vchiq_arm_log_level, - "DEQUEUE_MESSAGE interrupted"); + vchiq_log_debug(service->state->dev, VCHIQ_ARM, + "DEQUEUE_MESSAGE interrupted"); ret = -EINTR; break; } @@ -271,7 +271,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, ret = -EFAULT; } } else { - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(service->state->dev, VCHIQ_ARM, "header %pK: bufsize %x < size %x", header, args->bufsize, header->size); WARN(1, "invalid size\n"); @@ -318,13 +318,13 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, } mutex_unlock(&instance->bulk_waiter_list_mutex); if (!waiter) { - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(service->state->dev, VCHIQ_ARM, "no bulk_waiter found for pid %d", current->pid); ret = -ESRCH; goto out; } - vchiq_log_info(vchiq_arm_log_level, - "found bulk_waiter %pK for pid %d", waiter, current->pid); + vchiq_log_debug(service->state->dev, VCHIQ_ARM, + "found bulk_waiter %pK for pid %d", waiter, current->pid); userdata = &waiter->bulk_waiter; } else { userdata = args->userdata; @@ -355,8 +355,8 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, mutex_lock(&instance->bulk_waiter_list_mutex); list_add(&waiter->list, &instance->bulk_waiter_list); mutex_unlock(&instance->bulk_waiter_list_mutex); - vchiq_log_info(vchiq_arm_log_level, - "saved bulk_waiter %pK for pid %d", waiter, current->pid); + vchiq_log_debug(service->state->dev, VCHIQ_ARM, + "saved bulk_waiter %pK for pid %d", waiter, current->pid); ret = put_user(mode_waiting, mode); } @@ -455,8 +455,8 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance, mutex_lock(&instance->completion_mutex); if (rc) { DEBUG_TRACE(AWAIT_COMPLETION_LINE); - vchiq_log_info(vchiq_arm_log_level, - "AWAIT_COMPLETION interrupted"); + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, + "AWAIT_COMPLETION interrupted"); ret = -EINTR; goto out; } @@ -501,7 +501,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance, msglen = header->size + sizeof(struct vchiq_header); /* This must be a VCHIQ-style service */ if (args->msgbufsize < msglen) { - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(service->state->dev, VCHIQ_ARM, "header %pK: msgbufsize %x < msglen %x", header, args->msgbufsize, msglen); WARN(1, "invalid message size\n"); @@ -582,7 +582,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) long ret = 0; int i, rc; - vchiq_log_trace(vchiq_arm_log_level, + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, "%s - instance %pK, cmd %s, arg %lx", __func__, instance, ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ? ioctl_names[_IOC_NR(cmd)] : "", arg); @@ -618,7 +618,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } rc = mutex_lock_killable(&instance->state->mutex); if (rc) { - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(instance->state->dev, VCHIQ_ARM, "vchiq: connect: could not lock mutex for state %d: %d", instance->state->id, rc); ret = -EINTR; @@ -630,7 +630,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (!status) instance->connected = 1; else - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(instance->state->dev, VCHIQ_ARM, "vchiq: could not connect: %d", status); break; @@ -700,14 +700,13 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) vchiq_use_service_internal(service) : vchiq_release_service_internal(service); if (ret) { - vchiq_log_error(vchiq_susp_log_level, - "%s: cmd %s returned error %ld for service %c%c%c%c:%03d", + vchiq_log_error(instance->state->dev, VCHIQ_SUSPEND, + "%s: cmd %s returned error %ld for service %p4cc:%03d", __func__, (cmd == VCHIQ_IOC_USE_SERVICE) ? "VCHIQ_IOC_USE_SERVICE" : "VCHIQ_IOC_RELEASE_SERVICE", - ret, - VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), - service->client_id); + ret, &service->base.fourcc, + service->client_id); } } else { ret = -EINVAL; @@ -868,16 +867,17 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = -EINTR; } - if (!status && (ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK)) - vchiq_log_info(vchiq_arm_log_level, - " ioctl instance %pK, cmd %s -> status %d, %ld", - instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? - ioctl_names[_IOC_NR(cmd)] : "", status, ret); - else - vchiq_log_trace(vchiq_arm_log_level, + if (!status && (ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK)) { + vchiq_log_debug(instance->state->dev, VCHIQ_ARM, " ioctl instance %pK, cmd %s -> status %d, %ld", instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? ioctl_names[_IOC_NR(cmd)] : "", status, ret); + } else { + vchiq_log_trace(instance->state->dev, VCHIQ_ARM, + " ioctl instance %pK, cmd %s -> status %d, %ld", + instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? + ioctl_names[_IOC_NR(cmd)] : "", status, ret); + } return ret; } @@ -1170,10 +1170,10 @@ static int vchiq_open(struct inode *inode, struct file *file) struct vchiq_state *state = vchiq_get_state(); struct vchiq_instance *instance; - vchiq_log_info(vchiq_arm_log_level, "vchiq_open"); + vchiq_log_debug(state->dev, VCHIQ_ARM, "vchiq_open"); if (!state) { - vchiq_log_error(vchiq_arm_log_level, + vchiq_log_error(state->dev, VCHIQ_ARM, "vchiq has no connection to VideoCore"); return -ENOTCONN; } @@ -1206,8 +1206,8 @@ static int vchiq_release(struct inode *inode, struct file *file) int ret = 0; int i; - vchiq_log_info(vchiq_arm_log_level, "%s: instance=%lx", __func__, - (unsigned long)instance); + vchiq_log_debug(state->dev, VCHIQ_ARM, "%s: instance=%lx", __func__, + (unsigned long)instance); if (!state) { ret = -EPERM; diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c index d0366dd3f2b1..5c416c31ec57 100644 --- a/drivers/staging/vme_user/vme.c +++ b/drivers/staging/vme_user/vme.c @@ -62,7 +62,6 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource) return list_entry(resource->entry, struct vme_lm_resource, list)->parent; default: - printk(KERN_ERR "Unknown resource type\n"); return NULL; } } @@ -81,27 +80,12 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource) void *vme_alloc_consistent(struct vme_resource *resource, size_t size, dma_addr_t *dma) { - struct vme_bridge *bridge; - - if (!resource) { - printk(KERN_ERR "No resource\n"); - return NULL; - } - - bridge = find_bridge(resource); - if (!bridge) { - printk(KERN_ERR "Can't find bridge\n"); - return NULL; - } - - if (!bridge->parent) { - printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); - return NULL; - } + struct vme_bridge *bridge = find_bridge(resource); if (!bridge->alloc_consistent) { - printk(KERN_ERR "alloc_consistent not supported by bridge %s\n", - bridge->name); + dev_err(bridge->parent, + "alloc_consistent not supported by bridge %s\n", + bridge->name); return NULL; } @@ -121,27 +105,12 @@ EXPORT_SYMBOL(vme_alloc_consistent); void vme_free_consistent(struct vme_resource *resource, size_t size, void *vaddr, dma_addr_t dma) { - struct vme_bridge *bridge; - - if (!resource) { - printk(KERN_ERR "No resource\n"); - return; - } - - bridge = find_bridge(resource); - if (!bridge) { - printk(KERN_ERR "Can't find bridge\n"); - return; - } - - if (!bridge->parent) { - printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name); - return; - } + struct vme_bridge *bridge = find_bridge(resource); if (!bridge->free_consistent) { - printk(KERN_ERR "free_consistent not supported by bridge %s\n", - bridge->name); + dev_err(bridge->parent, + "free_consistent not supported by bridge %s\n", + bridge->name); return; } @@ -161,6 +130,7 @@ EXPORT_SYMBOL(vme_free_consistent); */ size_t vme_get_size(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); int enabled, retval; unsigned long long base, size; dma_addr_t buf_base; @@ -184,14 +154,14 @@ size_t vme_get_size(struct vme_resource *resource) case VME_DMA: return 0; default: - printk(KERN_ERR "Unknown resource type\n"); + dev_err(bridge->parent, "Unknown resource type\n"); return 0; } } EXPORT_SYMBOL(vme_get_size); -int vme_check_window(u32 aspace, unsigned long long vme_base, - unsigned long long size) +int vme_check_window(struct vme_bridge *bridge, u32 aspace, + unsigned long long vme_base, unsigned long long size) { int retval = 0; @@ -225,7 +195,7 @@ int vme_check_window(u32 aspace, unsigned long long vme_base, /* User Defined */ break; default: - printk(KERN_ERR "Invalid address space\n"); + dev_err(bridge->parent, "Invalid address space\n"); retval = -EINVAL; break; } @@ -282,24 +252,21 @@ struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, u32 cycle) { struct vme_bridge *bridge; - struct list_head *slave_pos = NULL; struct vme_slave_resource *allocated_image = NULL; struct vme_slave_resource *slave_image = NULL; struct vme_resource *resource = NULL; bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); goto err_bus; } /* Loop through slave resources */ - list_for_each(slave_pos, &bridge->slave_resources) { - slave_image = list_entry(slave_pos, - struct vme_slave_resource, list); - + list_for_each_entry(slave_image, &bridge->slave_resources, list) { if (!slave_image) { - printk(KERN_ERR "Registered NULL Slave resource\n"); + dev_err(bridge->parent, + "Registered NULL Slave resource\n"); continue; } @@ -366,24 +333,24 @@ int vme_slave_set(struct vme_resource *resource, int enabled, int retval; if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); + dev_err(bridge->parent, "Not a slave resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_slave_resource, list); if (!bridge->slave_set) { - printk(KERN_ERR "Function not supported\n"); + dev_err(bridge->parent, "Function not supported\n"); return -ENOSYS; } if (!(((image->address_attr & aspace) == aspace) && ((image->cycle_attr & cycle) == cycle))) { - printk(KERN_ERR "Invalid attributes\n"); + dev_err(bridge->parent, "Invalid attributes\n"); return -EINVAL; } - retval = vme_check_window(aspace, vme_base, size); + retval = vme_check_window(bridge, aspace, vme_base, size); if (retval) return retval; @@ -415,14 +382,14 @@ int vme_slave_get(struct vme_resource *resource, int *enabled, struct vme_slave_resource *image; if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); + dev_err(bridge->parent, "Not a slave resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_slave_resource, list); if (!bridge->slave_get) { - printk(KERN_ERR "vme_slave_get not supported\n"); + dev_err(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -439,24 +406,25 @@ EXPORT_SYMBOL(vme_slave_get); */ void vme_slave_free(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_slave_resource *slave_image; if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); + dev_err(bridge->parent, "Not a slave resource\n"); return; } slave_image = list_entry(resource->entry, struct vme_slave_resource, list); if (!slave_image) { - printk(KERN_ERR "Can't find slave resource\n"); + dev_err(bridge->parent, "Can't find slave resource\n"); return; } /* Unlock image */ mutex_lock(&slave_image->mtx); if (slave_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); + dev_err(bridge->parent, "Image is already free\n"); slave_image->locked = 0; mutex_unlock(&slave_image->mtx); @@ -482,24 +450,21 @@ struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, u32 cycle, u32 dwidth) { struct vme_bridge *bridge; - struct list_head *master_pos = NULL; struct vme_master_resource *allocated_image = NULL; struct vme_master_resource *master_image = NULL; struct vme_resource *resource = NULL; bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); goto err_bus; } /* Loop through master resources */ - list_for_each(master_pos, &bridge->master_resources) { - master_image = list_entry(master_pos, - struct vme_master_resource, list); - + list_for_each_entry(master_image, &bridge->master_resources, list) { if (!master_image) { - printk(KERN_WARNING "Registered NULL master resource\n"); + dev_warn(bridge->parent, + "Registered NULL master resource\n"); continue; } @@ -519,7 +484,7 @@ struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, /* Check to see if we found a resource */ if (!allocated_image) { - printk(KERN_ERR "Can't find a suitable resource\n"); + dev_err(&vdev->dev, "Can't find a suitable resource\n"); goto err_image; } @@ -569,25 +534,25 @@ int vme_master_set(struct vme_resource *resource, int enabled, int retval; if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_master_resource, list); if (!bridge->master_set) { - printk(KERN_WARNING "vme_master_set not supported\n"); + dev_warn(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } if (!(((image->address_attr & aspace) == aspace) && ((image->cycle_attr & cycle) == cycle) && ((image->width_attr & dwidth) == dwidth))) { - printk(KERN_WARNING "Invalid attributes\n"); + dev_warn(bridge->parent, "Invalid attributes\n"); return -EINVAL; } - retval = vme_check_window(aspace, vme_base, size); + retval = vme_check_window(bridge, aspace, vme_base, size); if (retval) return retval; @@ -619,14 +584,14 @@ int vme_master_get(struct vme_resource *resource, int *enabled, struct vme_master_resource *image; if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } image = list_entry(resource->entry, struct vme_master_resource, list); if (!bridge->master_get) { - printk(KERN_WARNING "%s not supported\n", __func__); + dev_warn(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -658,12 +623,13 @@ ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, size_t length; if (!bridge->master_read) { - printk(KERN_WARNING "Reading from resource not supported\n"); + dev_warn(bridge->parent, + "Reading from resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } @@ -672,7 +638,7 @@ ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, length = vme_get_size(resource); if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); + dev_warn(bridge->parent, "Invalid Offset\n"); return -EFAULT; } @@ -706,12 +672,12 @@ ssize_t vme_master_write(struct vme_resource *resource, void *buf, size_t length; if (!bridge->master_write) { - printk(KERN_WARNING "Writing to resource not supported\n"); + dev_warn(bridge->parent, "Writing to resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } @@ -720,7 +686,7 @@ ssize_t vme_master_write(struct vme_resource *resource, void *buf, length = vme_get_size(resource); if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); + dev_warn(bridge->parent, "Invalid Offset\n"); return -EFAULT; } @@ -757,12 +723,12 @@ unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, struct vme_master_resource *image; if (!bridge->master_rmw) { - printk(KERN_WARNING "Writing to resource not supported\n"); + dev_warn(bridge->parent, "Writing to resource not supported\n"); return -EINVAL; } if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } @@ -785,12 +751,13 @@ EXPORT_SYMBOL(vme_master_rmw); */ int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_master_resource *image; phys_addr_t phys_addr; unsigned long vma_size; if (resource->type != VME_MASTER) { - pr_err("Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return -EINVAL; } @@ -799,7 +766,7 @@ int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma) vma_size = vma->vm_end - vma->vm_start; if (phys_addr + vma_size > image->bus_resource.end + 1) { - pr_err("Map size cannot exceed the window size\n"); + dev_err(bridge->parent, "Map size cannot exceed the window size\n"); return -EFAULT; } @@ -817,24 +784,25 @@ EXPORT_SYMBOL(vme_master_mmap); */ void vme_master_free(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_master_resource *master_image; if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); + dev_err(bridge->parent, "Not a master resource\n"); return; } master_image = list_entry(resource->entry, struct vme_master_resource, list); if (!master_image) { - printk(KERN_ERR "Can't find master resource\n"); + dev_err(bridge->parent, "Can't find master resource\n"); return; } /* Unlock image */ spin_lock(&master_image->lock); if (master_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); + dev_err(bridge->parent, "Image is already free\n"); master_image->locked = 0; spin_unlock(&master_image->lock); @@ -857,26 +825,24 @@ EXPORT_SYMBOL(vme_master_free); struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) { struct vme_bridge *bridge; - struct list_head *dma_pos = NULL; struct vme_dma_resource *allocated_ctrlr = NULL; struct vme_dma_resource *dma_ctrlr = NULL; struct vme_resource *resource = NULL; /* XXX Not checking resource attributes */ - printk(KERN_ERR "No VME resource Attribute tests done\n"); + dev_err(&vdev->dev, "No VME resource Attribute tests done\n"); bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); goto err_bus; } /* Loop through DMA resources */ - list_for_each(dma_pos, &bridge->dma_resources) { - dma_ctrlr = list_entry(dma_pos, - struct vme_dma_resource, list); + list_for_each_entry(dma_ctrlr, &bridge->dma_resources, list) { if (!dma_ctrlr) { - printk(KERN_ERR "Registered NULL DMA resource\n"); + dev_err(bridge->parent, + "Registered NULL DMA resource\n"); continue; } @@ -928,10 +894,11 @@ EXPORT_SYMBOL(vme_dma_request); */ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_dma_list *dma_list; if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); + dev_err(bridge->parent, "Not a DMA resource\n"); return NULL; } @@ -1109,12 +1076,13 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, int retval; if (!bridge->dma_list_add) { - printk(KERN_WARNING "Link List DMA generation not supported\n"); + dev_warn(bridge->parent, + "Link List DMA generation not supported\n"); return -EINVAL; } if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List already submitted\n"); + dev_err(bridge->parent, "Link List already submitted\n"); return -EINVAL; } @@ -1142,7 +1110,8 @@ int vme_dma_list_exec(struct vme_dma_list *list) int retval; if (!bridge->dma_list_exec) { - printk(KERN_ERR "Link List DMA execution not supported\n"); + dev_err(bridge->parent, + "Link List DMA execution not supported\n"); return -EINVAL; } @@ -1171,12 +1140,13 @@ int vme_dma_list_free(struct vme_dma_list *list) int retval; if (!bridge->dma_list_empty) { - printk(KERN_WARNING "Emptying of Link Lists not supported\n"); + dev_warn(bridge->parent, + "Emptying of Link Lists not supported\n"); return -EINVAL; } if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List in use\n"); + dev_err(bridge->parent, "Link List in use\n"); return -EBUSY; } @@ -1186,7 +1156,7 @@ int vme_dma_list_free(struct vme_dma_list *list) */ retval = bridge->dma_list_empty(list); if (retval) { - printk(KERN_ERR "Unable to empty link-list entries\n"); + dev_err(bridge->parent, "Unable to empty link-list entries\n"); mutex_unlock(&list->mtx); return retval; } @@ -1208,22 +1178,24 @@ EXPORT_SYMBOL(vme_dma_list_free); */ int vme_dma_free(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_dma_resource *ctrlr; if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); + dev_err(bridge->parent, "Not a DMA resource\n"); return -EINVAL; } ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); if (!mutex_trylock(&ctrlr->mtx)) { - printk(KERN_ERR "Resource busy, can't free\n"); + dev_err(bridge->parent, "Resource busy, can't free\n"); return -EBUSY; } if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) { - printk(KERN_WARNING "Resource still processing transfers\n"); + dev_warn(bridge->parent, + "Resource still processing transfers\n"); mutex_unlock(&ctrlr->mtx); return -EBUSY; } @@ -1241,14 +1213,11 @@ EXPORT_SYMBOL(vme_dma_free); void vme_bus_error_handler(struct vme_bridge *bridge, unsigned long long address, int am) { - struct list_head *handler_pos = NULL; struct vme_error_handler *handler; int handler_triggered = 0; u32 aspace = vme_get_aspace(am); - list_for_each(handler_pos, &bridge->vme_error_handlers) { - handler = list_entry(handler_pos, struct vme_error_handler, - list); + list_for_each_entry(handler, &bridge->vme_error_handlers, list) { if ((aspace == handler->aspace) && (address >= handler->start) && (address < handler->end)) { @@ -1304,8 +1273,9 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) if (call) call(level, statid, priv_data); else - printk(KERN_WARNING "Spurious VME interrupt, level:%x, vector:%x\n", - level, statid); + dev_warn(bridge->parent, + "Spurious VME interrupt, level:%x, vector:%x\n", level, + statid); } EXPORT_SYMBOL(vme_irq_handler); @@ -1333,17 +1303,18 @@ int vme_irq_request(struct vme_dev *vdev, int level, int statid, bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); return -EINVAL; } if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); + dev_err(bridge->parent, "Invalid interrupt level\n"); return -EINVAL; } if (!bridge->irq_set) { - printk(KERN_ERR "Configuring interrupts not supported\n"); + dev_err(bridge->parent, + "Configuring interrupts not supported\n"); return -EINVAL; } @@ -1351,7 +1322,7 @@ int vme_irq_request(struct vme_dev *vdev, int level, int statid, if (bridge->irq[level - 1].callback[statid].func) { mutex_unlock(&bridge->irq_mtx); - printk(KERN_WARNING "VME Interrupt already taken\n"); + dev_warn(bridge->parent, "VME Interrupt already taken\n"); return -EBUSY; } @@ -1382,17 +1353,18 @@ void vme_irq_free(struct vme_dev *vdev, int level, int statid) bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); return; } if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); + dev_err(bridge->parent, "Invalid interrupt level\n"); return; } if (!bridge->irq_set) { - printk(KERN_ERR "Configuring interrupts not supported\n"); + dev_err(bridge->parent, + "Configuring interrupts not supported\n"); return; } @@ -1429,17 +1401,18 @@ int vme_irq_generate(struct vme_dev *vdev, int level, int statid) bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); return -EINVAL; } if ((level < 1) || (level > 7)) { - printk(KERN_WARNING "Invalid interrupt level\n"); + dev_warn(bridge->parent, "Invalid interrupt level\n"); return -EINVAL; } if (!bridge->irq_generate) { - printk(KERN_WARNING "Interrupt generation not supported\n"); + dev_warn(bridge->parent, + "Interrupt generation not supported\n"); return -EINVAL; } @@ -1460,23 +1433,21 @@ EXPORT_SYMBOL(vme_irq_generate); struct vme_resource *vme_lm_request(struct vme_dev *vdev) { struct vme_bridge *bridge; - struct list_head *lm_pos = NULL; struct vme_lm_resource *allocated_lm = NULL; struct vme_lm_resource *lm = NULL; struct vme_resource *resource = NULL; bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); goto err_bus; } /* Loop through LM resources */ - list_for_each(lm_pos, &bridge->lm_resources) { - lm = list_entry(lm_pos, - struct vme_lm_resource, list); + list_for_each_entry(lm, &bridge->lm_resources, list) { if (!lm) { - printk(KERN_ERR "Registered NULL Location Monitor resource\n"); + dev_err(bridge->parent, + "Registered NULL Location Monitor resource\n"); continue; } @@ -1528,10 +1499,11 @@ EXPORT_SYMBOL(vme_lm_request); */ int vme_lm_count(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return -EINVAL; } @@ -1562,14 +1534,14 @@ int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return -EINVAL; } lm = list_entry(resource->entry, struct vme_lm_resource, list); if (!bridge->lm_set) { - printk(KERN_ERR "vme_lm_set not supported\n"); + dev_err(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -1598,14 +1570,14 @@ int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base, struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return -EINVAL; } lm = list_entry(resource->entry, struct vme_lm_resource, list); if (!bridge->lm_get) { - printk(KERN_ERR "vme_lm_get not supported\n"); + dev_err(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -1620,7 +1592,7 @@ EXPORT_SYMBOL(vme_lm_get); * @callback: Pointer to callback function called when triggered. * @data: Generic pointer that will be passed to the callback function. * - * Attach a callback to the specificed offset into the location monitors + * Attach a callback to the specified offset into the location monitors * monitored addresses. A generic pointer is provided to allow data to be * passed to the callback when called. * @@ -1635,14 +1607,14 @@ int vme_lm_attach(struct vme_resource *resource, int monitor, struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return -EINVAL; } lm = list_entry(resource->entry, struct vme_lm_resource, list); if (!bridge->lm_attach) { - printk(KERN_ERR "vme_lm_attach not supported\n"); + dev_err(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -1655,7 +1627,7 @@ EXPORT_SYMBOL(vme_lm_attach); * @resource: Pointer to VME location monitor resource. * @monitor: Offset to which callback should be removed. * - * Remove the callback associated with the specificed offset into the + * Remove the callback associated with the specified offset into the * location monitors monitored addresses. * * Return: Zero on success, -EINVAL when provided with an invalid location @@ -1668,14 +1640,14 @@ int vme_lm_detach(struct vme_resource *resource, int monitor) struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return -EINVAL; } lm = list_entry(resource->entry, struct vme_lm_resource, list); if (!bridge->lm_detach) { - printk(KERN_ERR "vme_lm_detach not supported\n"); + dev_err(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -1697,10 +1669,11 @@ EXPORT_SYMBOL(vme_lm_detach); */ void vme_lm_free(struct vme_resource *resource) { + struct vme_bridge *bridge = find_bridge(resource); struct vme_lm_resource *lm; if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); + dev_err(bridge->parent, "Not a Location Monitor resource\n"); return; } @@ -1737,12 +1710,12 @@ int vme_slot_num(struct vme_dev *vdev) bridge = vdev->bridge; if (!bridge) { - printk(KERN_ERR "Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); return -EINVAL; } if (!bridge->slot_get) { - printk(KERN_WARNING "vme_slot_num not supported\n"); + dev_warn(bridge->parent, "%s not supported\n", __func__); return -EINVAL; } @@ -1765,7 +1738,7 @@ int vme_bus_num(struct vme_dev *vdev) bridge = vdev->bridge; if (!bridge) { - pr_err("Can't find VME bus\n"); + dev_err(&vdev->dev, "Can't find VME bus\n"); return -EINVAL; } @@ -1866,8 +1839,9 @@ static int __vme_register_driver_bus(struct vme_driver *drv, if (vdev->dev.platform_data) { list_add_tail(&vdev->drv_list, &drv->devices); list_add_tail(&vdev->bridge_list, &bridge->devices); - } else + } else { device_unregister(&vdev->dev); + } } return 0; diff --git a/drivers/staging/vme_user/vme.h b/drivers/staging/vme_user/vme.h index faa9816046a9..06504dccd5ff 100644 --- a/drivers/staging/vme_user/vme.h +++ b/drivers/staging/vme_user/vme.h @@ -87,7 +87,7 @@ extern struct bus_type vme_bus_type; #define VME_NUM_STATUSID 256 /* VME_MAX_BRIDGES comes from the type of vme_bus_numbers */ -#define VME_MAX_BRIDGES (sizeof(unsigned int)*8) +#define VME_MAX_BRIDGES (sizeof(unsigned int) * 8) #define VME_MAX_SLOTS 32 #define VME_SLOT_CURRENT -1 @@ -133,8 +133,8 @@ void vme_free_consistent(struct vme_resource *, size_t, void *, dma_addr_t); size_t vme_get_size(struct vme_resource *); -int vme_check_window(u32 aspace, unsigned long long vme_base, - unsigned long long size); +int vme_check_window(struct vme_bridge *bridge, u32 aspace, + unsigned long long vme_base, unsigned long long size); struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32); int vme_slave_set(struct vme_resource *, int, unsigned long long, diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index 7c53a8a7b79b..7f84d1c86f29 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -95,7 +95,7 @@ static void fake_VIRQ_tasklet(unsigned long data) struct vme_bridge *fake_bridge; struct fake_driver *bridge; - fake_bridge = (struct vme_bridge *) data; + fake_bridge = (struct vme_bridge *)data; bridge = fake_bridge->driver_priv; vme_irq_handler(fake_bridge, bridge->int_level, bridge->int_statid); @@ -105,7 +105,7 @@ static void fake_VIRQ_tasklet(unsigned long data) * Configure VME interrupt */ static void fake_irq_set(struct vme_bridge *fake_bridge, int level, - int state, int sync) + int state, int sync) { /* Nothing to do */ } @@ -125,7 +125,7 @@ static dma_addr_t fake_ptr_to_pci(void *addr) * interrupt to be acked. */ static int fake_irq_generate(struct vme_bridge *fake_bridge, int level, - int statid) + int statid) { struct fake_driver *bridge; @@ -152,8 +152,8 @@ static int fake_irq_generate(struct vme_bridge *fake_bridge, int level, * Initialize a slave window with the requested attributes. */ static int fake_slave_set(struct vme_slave_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t buf_base, u32 aspace, u32 cycle) + unsigned long long vme_base, unsigned long long size, + dma_addr_t buf_base, u32 aspace, u32 cycle) { unsigned int i, granularity = 0; unsigned long long vme_bound; @@ -221,8 +221,8 @@ static int fake_slave_set(struct vme_slave_resource *image, int enabled, * Get slave window configuration. */ static int fake_slave_get(struct vme_slave_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *buf_base, u32 *aspace, u32 *cycle) + unsigned long long *vme_base, unsigned long long *size, + dma_addr_t *buf_base, u32 *aspace, u32 *cycle) { unsigned int i; struct fake_driver *bridge; @@ -249,8 +249,8 @@ static int fake_slave_get(struct vme_slave_resource *image, int *enabled, * Set the attributes of an outbound window. */ static int fake_master_set(struct vme_master_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - u32 aspace, u32 cycle, u32 dwidth) + unsigned long long vme_base, unsigned long long size, + u32 aspace, u32 cycle, u32 dwidth) { int retval = 0; unsigned int i; @@ -335,8 +335,8 @@ err_window: * Set the attributes of an outbound window. */ static int __fake_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - u32 *aspace, u32 *cycle, u32 *dwidth) + unsigned long long *vme_base, unsigned long long *size, + u32 *aspace, u32 *cycle, u32 *dwidth) { unsigned int i; struct fake_driver *bridge; @@ -356,15 +356,15 @@ static int __fake_master_get(struct vme_master_resource *image, int *enabled, } static int fake_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - u32 *aspace, u32 *cycle, u32 *dwidth) + unsigned long long *vme_base, unsigned long long *size, + u32 *aspace, u32 *cycle, u32 *dwidth) { int retval; spin_lock(&image->lock); retval = __fake_master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); + cycle, dwidth); spin_unlock(&image->lock); @@ -403,8 +403,7 @@ static void fake_lm_check(struct fake_driver *bridge, unsigned long long addr, if (((lm_base + (8 * i)) <= addr) && ((lm_base + (8 * i) + 8) > addr)) { if (bridge->lm_callback[i]) - bridge->lm_callback[i]( - bridge->lm_data[i]); + bridge->lm_callback[i](bridge->lm_data[i]); } } } @@ -511,7 +510,7 @@ static noinline_for_stack u32 fake_vmeread32(struct fake_driver *bridge, } static ssize_t fake_master_read(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) + size_t count, loff_t offset) { int retval; u32 aspace, cycle, dwidth; @@ -585,7 +584,6 @@ static ssize_t fake_master_read(struct vme_master_resource *image, void *buf, aspace, cycle); done += 1; } - } if ((dwidth == VME_D16) || (dwidth == VME_D32)) { @@ -700,7 +698,7 @@ static noinline_for_stack void fake_vmewrite32(struct fake_driver *bridge, } static ssize_t fake_master_write(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) + size_t count, loff_t offset) { int retval = 0; u32 aspace, cycle, dwidth; @@ -739,7 +737,7 @@ static ssize_t fake_master_write(struct vme_master_resource *image, void *buf, if ((addr + done) & 0x2) { if ((count - done) < 2) { fake_vmewrite8(bridge, (u8 *)(buf + done), - addr + done, aspace, cycle); + addr + done, aspace, cycle); done += 1; goto out; } else { @@ -768,10 +766,9 @@ static ssize_t fake_master_write(struct vme_master_resource *image, void *buf, count32 = (count - done); while (done < count32) { fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done, - aspace, cycle); + aspace, cycle); done += 1; } - } if ((dwidth == VME_D16) || (dwidth == VME_D32)) { @@ -784,7 +781,7 @@ static ssize_t fake_master_write(struct vme_master_resource *image, void *buf, if ((count - done) & 0x1) { fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done, aspace, - cycle); + cycle); done += 1; } @@ -802,8 +799,8 @@ out: * Requires a previously configured master window, returns final value. */ static unsigned int fake_master_rmw(struct vme_master_resource *image, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset) + unsigned int mask, unsigned int compare, + unsigned int swap, loff_t offset) { u32 tmp, base; u32 aspace, cycle; @@ -848,7 +845,7 @@ static unsigned int fake_master_rmw(struct vme_master_resource *image, * callback is attached and disabled when the last callback is removed. */ static int fake_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, - u32 aspace, u32 cycle) + u32 aspace, u32 cycle) { int i; struct vme_bridge *fake_bridge; @@ -894,7 +891,8 @@ static int fake_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, * or disabled. */ static int fake_lm_get(struct vme_lm_resource *lm, - unsigned long long *lm_base, u32 *aspace, u32 *cycle) + unsigned long long *lm_base, + u32 *aspace, u32 *cycle) { struct fake_driver *bridge; @@ -917,7 +915,7 @@ static int fake_lm_get(struct vme_lm_resource *lm, * Callback will be passed the monitor triggered. */ static int fake_lm_attach(struct vme_lm_resource *lm, int monitor, - void (*callback)(void *), void *data) + void (*callback)(void *), void *data) { struct vme_bridge *fake_bridge; struct fake_driver *bridge; @@ -995,7 +993,7 @@ static int fake_slot_get(struct vme_bridge *fake_bridge) } static void *fake_alloc_consistent(struct device *parent, size_t size, - dma_addr_t *dma) + dma_addr_t *dma) { void *alloc = kmalloc(size, GFP_KERNEL); @@ -1006,12 +1004,9 @@ static void *fake_alloc_consistent(struct device *parent, size_t size, } static void fake_free_consistent(struct device *parent, size_t size, - void *vaddr, dma_addr_t dma) + void *vaddr, dma_addr_t dma) { kfree(vaddr); -/* - dma_free_coherent(parent, size, vaddr, dma); -*/ } /* @@ -1094,9 +1089,9 @@ static int __init fake_init(void) mutex_init(&fake_device->vme_int); mutex_init(&fake_bridge->irq_mtx); tasklet_init(&fake_device->int_tasklet, fake_VIRQ_tasklet, - (unsigned long) fake_bridge); + (unsigned long)fake_bridge); - strcpy(fake_bridge->name, driver_name); + strscpy(fake_bridge->name, driver_name, sizeof(fake_bridge->name)); /* Add master windows to list */ INIT_LIST_HEAD(&fake_bridge->master_resources); @@ -1118,10 +1113,10 @@ static int __init fake_init(void) VME_PROG | VME_DATA; master_image->width_attr = VME_D16 | VME_D32; memset(&master_image->bus_resource, 0, - sizeof(struct resource)); + sizeof(struct resource)); master_image->kern_base = NULL; list_add_tail(&master_image->list, - &fake_bridge->master_resources); + &fake_bridge->master_resources); } /* Add slave windows to list */ @@ -1144,7 +1139,7 @@ static int __init fake_init(void) VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | VME_PROG | VME_DATA; list_add_tail(&slave_image->list, - &fake_bridge->slave_resources); + &fake_bridge->slave_resources); } /* Add location monitor to list */ @@ -1179,7 +1174,7 @@ static int __init fake_init(void) fake_bridge->free_consistent = fake_free_consistent; pr_info("Board is%s the VME system controller\n", - (geoid == 1) ? "" : " not"); + (geoid == 1) ? "" : " not"); pr_info("VME geographical address is set to %d\n", geoid); @@ -1220,7 +1215,7 @@ err_master: /* resources are stored in link list */ list_for_each_safe(pos, n, &fake_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, - list); + list); list_del(pos); kfree(master_image); } @@ -1275,7 +1270,7 @@ static void __exit fake_exit(void) /* resources are stored in link list */ list_for_each_safe(pos, tmplist, &fake_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, - list); + list); list_del(pos); kfree(master_image); } diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c index 2f5eafd50934..2ec9c2904404 100644 --- a/drivers/staging/vme_user/vme_tsi148.c +++ b/drivers/staging/vme_user/vme_tsi148.c @@ -2118,8 +2118,9 @@ static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) if (!geoid) { slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT); slot = slot & TSI148_LCSR_VSTAT_GA_M; - } else + } else { slot = geoid; + } return (int)slot; } @@ -2196,9 +2197,9 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar); crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); - if (crat & TSI148_LCSR_CRAT_EN) + if (crat & TSI148_LCSR_CRAT_EN) { dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n"); - else { + } else { dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n"); iowrite32be(crat | TSI148_LCSR_CRAT_EN, bridge->base + TSI148_LCSR_CRAT); @@ -2309,7 +2310,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(&tsi148_device->vme_rmw); tsi148_bridge->parent = &pdev->dev; - strcpy(tsi148_bridge->name, driver_name); + strscpy(tsi148_bridge->name, driver_name, VMENAMSIZ); /* Setup IRQ */ retval = tsi148_irq_init(tsi148_bridge); diff --git a/drivers/staging/vme_user/vme_tsi148.h b/drivers/staging/vme_user/vme_tsi148.h index 63f726e1811a..4dd224d0b86e 100644 --- a/drivers/staging/vme_user/vme_tsi148.h +++ b/drivers/staging/vme_user/vme_tsi148.h @@ -96,13 +96,9 @@ struct tsi148_dma_entry { #define TSI148_PCFS_MISC0 0xC #define TSI148_PCFS_MBARL 0x10 #define TSI148_PCFS_MBARU 0x14 - #define TSI148_PCFS_SUBID 0x28 - #define TSI148_PCFS_CAPP 0x34 - #define TSI148_PCFS_MISC1 0x3C - #define TSI148_PCFS_XCAPP 0x40 #define TSI148_PCFS_XSTAT 0x44 @@ -210,7 +206,7 @@ static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1, /* * VMEbus interrupt ack - * offset 200 + * offset 0x200 */ #define TSI148_LCSR_VIACK1 0x204 #define TSI148_LCSR_VIACK2 0x208 @@ -227,7 +223,7 @@ static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, /* * RMW - * offset 220 + * offset 0x220 */ #define TSI148_LCSR_RMWAU 0x220 #define TSI148_LCSR_RMWAL 0x224 @@ -237,7 +233,7 @@ static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, /* * VMEbus control - * offset 234 + * offset 0x234 */ #define TSI148_LCSR_VMCTRL 0x234 #define TSI148_LCSR_VCTRL 0x238 @@ -245,38 +241,38 @@ static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, /* * PCI status - * offset 240 + * offset 0x240 */ #define TSI148_LCSR_PSTAT 0x240 /* * VME filter. - * offset 250 + * offset 0x250 */ #define TSI148_LCSR_VMEFL 0x250 - /* - * VME exception. - * offset 260 +/* + * VME exception. + * offset 0x260 */ #define TSI148_LCSR_VEAU 0x260 #define TSI148_LCSR_VEAL 0x264 #define TSI148_LCSR_VEAT 0x268 - /* - * PCI error - * offset 270 - */ +/* + * PCI error + * offset 0x270 + */ #define TSI148_LCSR_EDPAU 0x270 #define TSI148_LCSR_EDPAL 0x274 #define TSI148_LCSR_EDPXA 0x278 #define TSI148_LCSR_EDPXS 0x27C #define TSI148_LCSR_EDPAT 0x280 - /* - * Inbound Translations - * offset 300 - */ +/* + * Inbound Translations + * offset 0x300 + */ #define TSI148_LCSR_IT0_ITSAU 0x300 #define TSI148_LCSR_IT0_ITSAL 0x304 #define TSI148_LCSR_IT0_ITEAU 0x308 @@ -363,53 +359,53 @@ static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, #define TSI148_LCSR_OFFSET_ITOFL 0x14 #define TSI148_LCSR_OFFSET_ITAT 0x18 - /* - * Inbound Translation GCSR - * offset 400 - */ +/* + * Inbound Translation GCSR + * offset 0x400 + */ #define TSI148_LCSR_GBAU 0x400 #define TSI148_LCSR_GBAL 0x404 #define TSI148_LCSR_GCSRAT 0x408 - /* - * Inbound Translation CRG - * offset 40C - */ +/* + * Inbound Translation CRG + * offset 0x40C + */ #define TSI148_LCSR_CBAU 0x40C #define TSI148_LCSR_CBAL 0x410 #define TSI148_LCSR_CSRAT 0x414 - /* - * Inbound Translation CR/CSR - * CRG - * offset 418 - */ +/* + * Inbound Translation CR/CSR + * CRG + * offset 0x418 + */ #define TSI148_LCSR_CROU 0x418 #define TSI148_LCSR_CROL 0x41C #define TSI148_LCSR_CRAT 0x420 - /* - * Inbound Translation Location Monitor - * offset 424 - */ +/* + * Inbound Translation Location Monitor + * offset 0x424 + */ #define TSI148_LCSR_LMBAU 0x424 #define TSI148_LCSR_LMBAL 0x428 #define TSI148_LCSR_LMAT 0x42C - /* - * VMEbus Interrupt Control. - * offset 430 - */ +/* + * VMEbus Interrupt Control. + * offset 0x430 + */ #define TSI148_LCSR_BCU 0x430 #define TSI148_LCSR_BCL 0x434 #define TSI148_LCSR_BPGTR 0x438 #define TSI148_LCSR_BPCTR 0x43C #define TSI148_LCSR_VICR 0x440 - /* - * Local Bus Interrupt Control. - * offset 448 - */ +/* + * Local Bus Interrupt Control. + * offset 0x448 + */ #define TSI148_LCSR_INTEN 0x448 #define TSI148_LCSR_INTEO 0x44C #define TSI148_LCSR_INTS 0x450 @@ -417,10 +413,10 @@ static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, #define TSI148_LCSR_INTM1 0x458 #define TSI148_LCSR_INTM2 0x45C - /* - * DMA Controllers - * offset 500 - */ +/* + * DMA Controllers + * offset 0x500 + */ #define TSI148_LCSR_DCTL0 0x500 #define TSI148_LCSR_DSTA0 0x504 #define TSI148_LCSR_DCSAU0 0x508 @@ -484,27 +480,27 @@ static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0, #define TSI148_LCSR_OFFSET_DCNT 0x40 #define TSI148_LCSR_OFFSET_DDBS 0x44 - /* - * GCSR Register Group - */ +/* + * GCSR Register Group + */ - /* - * GCSR CRG - * offset 00 600 - DEVI/VENI - * offset 04 604 - CTRL/GA/REVID - * offset 08 608 - Semaphore3/2/1/0 - * offset 0C 60C - Seamphore7/6/5/4 - */ +/* + * GCSR CRG + * offset 0x00 0x600 - DEVI/VENI + * offset 0x04 0x604 - CTRL/GA/REVID + * offset 0x08 0x608 - Semaphore3/2/1/0 + * offset 0x0C 0x60C - Seamphore7/6/5/4 + */ #define TSI148_GCSR_ID 0x600 #define TSI148_GCSR_CSR 0x604 #define TSI148_GCSR_SEMA0 0x608 #define TSI148_GCSR_SEMA1 0x60C - /* - * Mail Box - * GCSR CRG - * offset 10 610 - Mailbox0 - */ +/* + * Mail Box + * GCSR CRG + * offset 0x10 0x610 - Mailbox0 + */ #define TSI148_GCSR_MBOX0 0x610 #define TSI148_GCSR_MBOX1 0x614 #define TSI148_GCSR_MBOX2 0x618 @@ -515,27 +511,27 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, TSI148_GCSR_MBOX2, TSI148_GCSR_MBOX3 }; - /* - * CR/CSR - */ +/* + * CR/CSR + */ - /* - * CR/CSR CRG - * offset 7FFF4 FF4 - CSRBCR - * offset 7FFF8 FF8 - CSRBSR - * offset 7FFFC FFC - CBAR - */ +/* + * CR/CSR CRG + * offset 0x7FFF4 0xFF4 - CSRBCR + * offset 0x7FFF8 0xFF8 - CSRBSR + * offset 0x7FFFC 0xFFC - CBAR + */ #define TSI148_CSRBCR 0xFF4 #define TSI148_CSRBSR 0xFF8 #define TSI148_CBAR 0xFFC - /* - * TSI148 Register Bit Definitions - */ +/* + * TSI148 Register Bit Definitions + */ - /* - * PFCS Register Set - */ +/* + * PFCS Register Set + */ #define TSI148_PCFS_CMMD_SERR BIT(8) /* SERR_L out pin ssys err */ #define TSI148_PCFS_CMMD_PERR BIT(6) /* PERR_L out pin parity */ #define TSI148_PCFS_CMMD_MSTR BIT(2) /* PCI bus master */ @@ -547,7 +543,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_PCFS_STAT_RCVMA BIT(13) /* Received Master Abort */ #define TSI148_PCFS_STAT_RCVTA BIT(12) /* Received Target Abort */ #define TSI148_PCFS_STAT_SIGTA BIT(11) /* Signalled Target Abort */ -#define TSI148_PCFS_STAT_SELTIM (3<<9) /* DELSEL Timing */ +#define TSI148_PCFS_STAT_SELTIM (3 << 9) /* DELSEL Timing */ #define TSI148_PCFS_STAT_DPAR BIT(8) /* Data Parity Err Reported */ #define TSI148_PCFS_STAT_FAST BIT(7) /* Fast back-to-back Cap */ #define TSI148_PCFS_STAT_P66M BIT(5) /* 66 MHz Capable */ @@ -556,49 +552,49 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Revision ID/Class Code Registers (CRG +$008) */ -#define TSI148_PCFS_CLAS_M (0xFF<<24) /* Class ID */ -#define TSI148_PCFS_SUBCLAS_M (0xFF<<16) /* Sub-Class ID */ -#define TSI148_PCFS_PROGIF_M (0xFF<<8) /* Sub-Class ID */ -#define TSI148_PCFS_REVID_M (0xFF<<0) /* Rev ID */ +#define TSI148_PCFS_CLAS_M (0xFF << 24) /* Class ID */ +#define TSI148_PCFS_SUBCLAS_M (0xFF << 16) /* Sub-Class ID */ +#define TSI148_PCFS_PROGIF_M (0xFF << 8) /* Sub-Class ID */ +#define TSI148_PCFS_REVID_M (0xFF << 0) /* Rev ID */ /* * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C) */ -#define TSI148_PCFS_HEAD_M (0xFF<<16) /* Master Lat Timer */ -#define TSI148_PCFS_MLAT_M (0xFF<<8) /* Master Lat Timer */ -#define TSI148_PCFS_CLSZ_M (0xFF<<0) /* Cache Line Size */ +#define TSI148_PCFS_HEAD_M (0xFF << 16) /* Master Lat Timer */ +#define TSI148_PCFS_MLAT_M (0xFF << 8) /* Master Lat Timer */ +#define TSI148_PCFS_CLSZ_M (0xFF << 0) /* Cache Line Size */ /* * Memory Base Address Lower Reg (CRG + $010) */ -#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ +#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF << 12) /* Base Addr Lower Mask */ #define TSI148_PCFS_MBARL_PRE BIT(3) /* Prefetch */ -#define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */ +#define TSI148_PCFS_MBARL_MTYPE_M (3 << 1) /* Memory Type Mask */ #define TSI148_PCFS_MBARL_IOMEM BIT(0) /* I/O Space Indicator */ /* * Message Signaled Interrupt Capabilities Register (CRG + $040) */ #define TSI148_PCFS_MSICAP_64BAC BIT(7) /* 64-bit Address Capable */ -#define TSI148_PCFS_MSICAP_MME_M (7<<4) /* Multiple Msg Enable Mask */ -#define TSI148_PCFS_MSICAP_MMC_M (7<<1) /* Multiple Msg Capable Mask */ +#define TSI148_PCFS_MSICAP_MME_M (7 << 4) /* Multiple Msg Enable Mask */ +#define TSI148_PCFS_MSICAP_MMC_M (7 << 1) /* Multiple Msg Capable Mask */ #define TSI148_PCFS_MSICAP_MSIEN BIT(0) /* Msg signaled INT Enable */ /* * Message Address Lower Register (CRG +$044) */ -#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF<<2) /* Mask */ +#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF << 2) /* Mask */ /* * Message Data Register (CRG + 4C) */ -#define TSI148_PCFS_MSIMD_M (0xFFFF<<0) /* Mask */ +#define TSI148_PCFS_MSIMD_M (0xFFFF << 0) /* Mask */ /* * PCI-X Capabilities Register (CRG + $050) */ -#define TSI148_PCFS_PCIXCAP_MOST_M (7<<4) /* Max outstanding Split Tran */ -#define TSI148_PCFS_PCIXCAP_MMRBC_M (3<<2) /* Max Mem Read byte cnt */ +#define TSI148_PCFS_PCIXCAP_MOST_M (7 << 4) /* Max outstanding Split Tran */ +#define TSI148_PCFS_PCIXCAP_MMRBC_M (3 << 2) /* Max Mem Read byte cnt */ #define TSI148_PCFS_PCIXCAP_ERO BIT(1) /* Enable Relaxed Ordering */ #define TSI148_PCFS_PCIXCAP_DPERE BIT(0) /* Data Parity Recover Enable */ @@ -606,18 +602,17 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, * PCI-X Status Register (CRG +$054) */ #define TSI148_PCFS_PCIXSTAT_RSCEM BIT(29) /* Received Split Comp Error */ -#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ -#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans - */ -#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */ +#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7 << 26) /* max Cumulative Read Size */ +#define TSI148_PCFS_PCIXSTAT_DMOST_M (7 << 23) /* max outstanding Split Trans */ +#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3 << 21) /* max mem read byte count */ #define TSI148_PCFS_PCIXSTAT_DC BIT(20) /* Device Complexity */ #define TSI148_PCFS_PCIXSTAT_USC BIT(19) /* Unexpected Split comp */ #define TSI148_PCFS_PCIXSTAT_SCD BIT(18) /* Split completion discard */ #define TSI148_PCFS_PCIXSTAT_133C BIT(17) /* 133MHz capable */ #define TSI148_PCFS_PCIXSTAT_64D BIT(16) /* 64 bit device */ -#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF<<8) /* Bus number */ -#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F<<3) /* Device number */ -#define TSI148_PCFS_PCIXSTAT_FN_M (7<<0) /* Function Number */ +#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF << 8) /* Bus number */ +#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F << 3) /* Device number */ +#define TSI148_PCFS_PCIXSTAT_FN_M (7 << 0) /* Function Number */ /* * LCSR Registers @@ -626,22 +621,22 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Outbound Translation Starting Address Lower */ -#define TSI148_LCSR_OTSAL_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_OTSAL_M (0xFFFF << 16) /* Mask */ /* * Outbound Translation Ending Address Lower */ -#define TSI148_LCSR_OTEAL_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_OTEAL_M (0xFFFF << 16) /* Mask */ /* * Outbound Translation Offset Lower */ -#define TSI148_LCSR_OTOFFL_M (0xFFFF<<16) /* Mask */ +#define TSI148_LCSR_OTOFFL_M (0xFFFF << 16) /* Mask */ /* * Outbound Translation 2eSST Broadcast Select */ -#define TSI148_LCSR_OTBS_M (0xFFFFF<<0) /* Mask */ +#define TSI148_LCSR_OTBS_M (0xFFFFF << 0) /* Mask */ /* * Outbound Translation Attribute @@ -649,42 +644,42 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_OTAT_EN BIT(31) /* Window Enable */ #define TSI148_LCSR_OTAT_MRPFD BIT(18) /* Prefetch Disable */ -#define TSI148_LCSR_OTAT_PFS_M (3<<16) /* Prefetch Size Mask */ -#define TSI148_LCSR_OTAT_PFS_2 (0<<16) /* 2 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_M (3 << 16) /* Prefetch Size Mask */ +#define TSI148_LCSR_OTAT_PFS_2 (0 << 16) /* 2 Cache Lines P Size */ #define TSI148_LCSR_OTAT_PFS_4 BIT(16) /* 4 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_8 (2<<16) /* 8 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_16 (3<<16) /* 16 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_8 (2 << 16) /* 8 Cache Lines P Size */ +#define TSI148_LCSR_OTAT_PFS_16 (3 << 16) /* 16 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_2eSSTM_M (7<<11) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_OTAT_2eSSTM_160 (0<<11) /* 160MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_OTAT_2eSSTM_M (7 << 11) /* 2eSST Xfer Rate Mask */ +#define TSI148_LCSR_OTAT_2eSSTM_160 (0 << 11) /* 160MB/s 2eSST Xfer Rate */ #define TSI148_LCSR_OTAT_2eSSTM_267 BIT(11) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_2eSSTM_320 (2<<11) /* 320MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_OTAT_2eSSTM_320 (2 << 11) /* 320MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_TM_M (7<<8) /* Xfer Protocol Mask */ -#define TSI148_LCSR_OTAT_TM_SCT (0<<8) /* SCT Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_M (7 << 8) /* Xfer Protocol Mask */ +#define TSI148_LCSR_OTAT_TM_SCT (0 << 8) /* SCT Xfer Protocol */ #define TSI148_LCSR_OTAT_TM_BLT BIT(8) /* BLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_MBLT (2<<8) /* MBLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eVME (3<<8) /* 2eVME Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSST (4<<8) /* 2eSST Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSSTB (5<<8) /* 2eSST Bcast Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_MBLT (2 << 8) /* MBLT Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eVME (3 << 8) /* 2eVME Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eSST (4 << 8) /* 2eSST Xfer Protocol */ +#define TSI148_LCSR_OTAT_TM_2eSSTB (5 << 8) /* 2eSST Bcast Xfer Protocol */ -#define TSI148_LCSR_OTAT_DBW_M (3<<6) /* Max Data Width */ -#define TSI148_LCSR_OTAT_DBW_16 (0<<6) /* 16-bit Data Width */ +#define TSI148_LCSR_OTAT_DBW_M (3 << 6) /* Max Data Width */ +#define TSI148_LCSR_OTAT_DBW_16 (0 << 6) /* 16-bit Data Width */ #define TSI148_LCSR_OTAT_DBW_32 BIT(6) /* 32-bit Data Width */ #define TSI148_LCSR_OTAT_SUP BIT(5) /* Supervisory Access */ #define TSI148_LCSR_OTAT_PGM BIT(4) /* Program Access */ -#define TSI148_LCSR_OTAT_AMODE_M (0xf<<0) /* Address Mode Mask */ -#define TSI148_LCSR_OTAT_AMODE_A16 (0<<0) /* A16 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_M (0xf << 0) /* Address Mode Mask */ +#define TSI148_LCSR_OTAT_AMODE_A16 (0 << 0) /* A16 Address Space */ #define TSI148_LCSR_OTAT_AMODE_A24 BIT(0) /* A24 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A32 (2<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A64 (4<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_CRCSR (5<<0) /* CR/CSR Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER1 (8<<0) /* User1 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER2 (9<<0) /* User2 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER3 (10<<0) /* User3 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER4 (11<<0) /* User4 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_A32 (2 << 0) /* A32 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_A64 (4 << 0) /* A32 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_CRCSR (5 << 0) /* CR/CSR Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER1 (8 << 0) /* User1 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER2 (9 << 0) /* User2 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER3 (10 << 0) /* User3 Address Space */ +#define TSI148_LCSR_OTAT_AMODE_USER4 (11 << 0) /* User4 Address Space */ /* * VME Master Control Register CRG+$234 @@ -696,46 +691,46 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VMCTRL_RMWEN BIT(20) /* RMW Enable */ -#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask +#define TSI148_LCSR_VMCTRL_ATO_M (7 << 16) /* Master Access Time-out Mask */ -#define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */ +#define TSI148_LCSR_VMCTRL_ATO_32 (0 << 16) /* 32 us */ #define TSI148_LCSR_VMCTRL_ATO_128 BIT(16) /* 128 us */ -#define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */ -#define TSI148_LCSR_VMCTRL_ATO_2M (3<<16) /* 2 ms */ -#define TSI148_LCSR_VMCTRL_ATO_8M (4<<16) /* 8 ms */ -#define TSI148_LCSR_VMCTRL_ATO_32M (5<<16) /* 32 ms */ -#define TSI148_LCSR_VMCTRL_ATO_128M (6<<16) /* 128 ms */ -#define TSI148_LCSR_VMCTRL_ATO_DIS (7<<16) /* Disabled */ +#define TSI148_LCSR_VMCTRL_ATO_512 (2 << 16) /* 512 us */ +#define TSI148_LCSR_VMCTRL_ATO_2M (3 << 16) /* 2 ms */ +#define TSI148_LCSR_VMCTRL_ATO_8M (4 << 16) /* 8 ms */ +#define TSI148_LCSR_VMCTRL_ATO_32M (5 << 16) /* 32 ms */ +#define TSI148_LCSR_VMCTRL_ATO_128M (6 << 16) /* 128 ms */ +#define TSI148_LCSR_VMCTRL_ATO_DIS (7 << 16) /* Disabled */ -#define TSI148_LCSR_VMCTRL_VTOFF_M (7<<12) /* VMEbus Master Time off */ -#define TSI148_LCSR_VMCTRL_VTOFF_0 (0<<12) /* 0us */ +#define TSI148_LCSR_VMCTRL_VTOFF_M (7 << 12) /* VMEbus Master Time off */ +#define TSI148_LCSR_VMCTRL_VTOFF_0 (0 << 12) /* 0us */ #define TSI148_LCSR_VMCTRL_VTOFF_1 BIT(12) /* 1us */ -#define TSI148_LCSR_VMCTRL_VTOFF_2 (2<<12) /* 2us */ -#define TSI148_LCSR_VMCTRL_VTOFF_4 (3<<12) /* 4us */ -#define TSI148_LCSR_VMCTRL_VTOFF_8 (4<<12) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTOFF_16 (5<<12) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTOFF_32 (6<<12) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTOFF_64 (7<<12) /* 64us */ +#define TSI148_LCSR_VMCTRL_VTOFF_2 (2 << 12) /* 2us */ +#define TSI148_LCSR_VMCTRL_VTOFF_4 (3 << 12) /* 4us */ +#define TSI148_LCSR_VMCTRL_VTOFF_8 (4 << 12) /* 8us */ +#define TSI148_LCSR_VMCTRL_VTOFF_16 (5 << 12) /* 16us */ +#define TSI148_LCSR_VMCTRL_VTOFF_32 (6 << 12) /* 32us */ +#define TSI148_LCSR_VMCTRL_VTOFF_64 (7 << 12) /* 64us */ -#define TSI148_LCSR_VMCTRL_VTON_M (7<<8) /* VMEbus Master Time On */ -#define TSI148_LCSR_VMCTRL_VTON_4 (0<<8) /* 8us */ +#define TSI148_LCSR_VMCTRL_VTON_M (7 << 8) /* VMEbus Master Time On */ +#define TSI148_LCSR_VMCTRL_VTON_4 (0 << 8) /* 8us */ #define TSI148_LCSR_VMCTRL_VTON_8 BIT(8) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTON_16 (2<<8) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTON_32 (3<<8) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTON_64 (4<<8) /* 64us */ -#define TSI148_LCSR_VMCTRL_VTON_128 (5<<8) /* 128us */ -#define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */ -#define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */ +#define TSI148_LCSR_VMCTRL_VTON_16 (2 << 8) /* 16us */ +#define TSI148_LCSR_VMCTRL_VTON_32 (3 << 8) /* 32us */ +#define TSI148_LCSR_VMCTRL_VTON_64 (4 << 8) /* 64us */ +#define TSI148_LCSR_VMCTRL_VTON_128 (5 << 8) /* 128us */ +#define TSI148_LCSR_VMCTRL_VTON_256 (6 << 8) /* 256us */ +#define TSI148_LCSR_VMCTRL_VTON_512 (7 << 8) /* 512us */ -#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask +#define TSI148_LCSR_VMCTRL_VREL_M (3 << 3) /* VMEbus Master Rel Mode Mask */ -#define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */ +#define TSI148_LCSR_VMCTRL_VREL_T_D (0 << 3) /* Time on or Done */ #define TSI148_LCSR_VMCTRL_VREL_T_R_D BIT(3) /* Time on and REQ or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */ +#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2 << 3) /* Time on and BCLR or Done */ +#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3 << 3) /* Time on or Done and REQ */ #define TSI148_LCSR_VMCTRL_VFAIR BIT(2) /* VMEbus Master Fair Mode */ -#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask +#define TSI148_LCSR_VMCTRL_VREQL_M (3 << 0) /* VMEbus Master Req Level Mask */ /* @@ -743,20 +738,20 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, */ #define TSI148_LCSR_VCTRL_LRE BIT(31) /* Late Retry Enable */ -#define TSI148_LCSR_VCTRL_DLT_M (0xF<<24) /* Deadlock Timer */ -#define TSI148_LCSR_VCTRL_DLT_OFF (0<<24) /* Deadlock Timer Off */ +#define TSI148_LCSR_VCTRL_DLT_M (0xF << 24) /* Deadlock Timer */ +#define TSI148_LCSR_VCTRL_DLT_OFF (0 << 24) /* Deadlock Timer Off */ #define TSI148_LCSR_VCTRL_DLT_16 BIT(24) /* 16 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32 (2<<24) /* 32 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_64 (3<<24) /* 64 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_128 (4<<24) /* 128 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_256 (5<<24) /* 256 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_512 (6<<24) /* 512 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_1024 (7<<24) /* 1024 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_2048 (8<<24) /* 2048 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_4096 (9<<24) /* 4096 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_8192 (0xA<<24) /* 8192 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_32 (2 << 24) /* 32 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_64 (3 << 24) /* 64 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_128 (4 << 24) /* 128 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_256 (5 << 24) /* 256 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_512 (6 << 24) /* 512 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_1024 (7 << 24) /* 1024 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_2048 (8 << 24) /* 2048 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_4096 (9 << 24) /* 4096 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_8192 (0xA << 24) /* 8192 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_16384 (0xB << 24) /* 16384 VCLKS */ +#define TSI148_LCSR_VCTRL_DLT_32768 (0xC << 24) /* 32768 VCLKS */ #define TSI148_LCSR_VCTRL_NERBB BIT(20) /* No Early Release of Bus Busy */ @@ -765,21 +760,20 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VCTRL_LRESET BIT(16) /* Local Reset */ #define TSI148_LCSR_VCTRL_SFAILAI BIT(15) /* SYSFAIL Auto Slot ID */ -#define TSI148_LCSR_VCTRL_BID_M (0x1F<<8) /* Broadcast ID Mask */ +#define TSI148_LCSR_VCTRL_BID_M (0x1F << 8) /* Broadcast ID Mask */ #define TSI148_LCSR_VCTRL_ATOEN BIT(7) /* Arbiter Time-out Enable */ #define TSI148_LCSR_VCTRL_ROBIN BIT(6) /* VMEbus Round Robin */ -#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask - */ -#define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */ +#define TSI148_LCSR_VCTRL_GTO_M (7 << 0) /* VMEbus Global Time-out Mask*/ +#define TSI148_LCSR_VCTRL_GTO_8 (0 << 0) /* 8 us */ #define TSI148_LCSR_VCTRL_GTO_16 BIT(0) /* 16 us */ -#define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */ -#define TSI148_LCSR_VCTRL_GTO_64 (3<<0) /* 64 us */ -#define TSI148_LCSR_VCTRL_GTO_128 (4<<0) /* 128 us */ -#define TSI148_LCSR_VCTRL_GTO_256 (5<<0) /* 256 us */ -#define TSI148_LCSR_VCTRL_GTO_512 (6<<0) /* 512 us */ -#define TSI148_LCSR_VCTRL_GTO_DIS (7<<0) /* Disabled */ +#define TSI148_LCSR_VCTRL_GTO_32 (2 << 0) /* 32 us */ +#define TSI148_LCSR_VCTRL_GTO_64 (3 << 0) /* 64 us */ +#define TSI148_LCSR_VCTRL_GTO_128 (4 << 0) /* 128 us */ +#define TSI148_LCSR_VCTRL_GTO_256 (5 << 0) /* 256 us */ +#define TSI148_LCSR_VCTRL_GTO_512 (6 << 0) /* 512 us */ +#define TSI148_LCSR_VCTRL_GTO_DIS (7 << 0) /* Disabled */ /* * VMEbus Status Register CRG + $23C @@ -792,7 +786,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VSTAT_ACFAILS BIT(9) /* AC fail status */ #define TSI148_LCSR_VSTAT_SCONS BIT(8) /* System Cont Status */ #define TSI148_LCSR_VSTAT_GAP BIT(5) /* Geographic Addr Parity */ -#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ +#define TSI148_LCSR_VSTAT_GA_M (0x1F << 0) /* Geographic Addr Mask */ /* * PCI Configuration Status Register CRG+$240 @@ -819,8 +813,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VEAT_IACK BIT(16) /* IACK_ signal state */ #define TSI148_LCSR_VEAT_DS1 BIT(15) /* DS1_ signal state */ #define TSI148_LCSR_VEAT_DS0 BIT(14) /* DS0_ signal state */ -#define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */ -#define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */ +#define TSI148_LCSR_VEAT_AM_M (0x3F << 8) /* Address Mode Mask */ +#define TSI148_LCSR_VEAT_XAM_M (0xFF << 0) /* Master AMode Mask */ /* * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280 @@ -830,23 +824,23 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Inbound Translation Starting Address Lower */ -#define TSI148_LCSR_ITSAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITSAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITSAL16_M (0x0000FFF<<4) /* Mask */ +#define TSI148_LCSR_ITSAL6432_M (0xFFFF << 16) /* Mask */ +#define TSI148_LCSR_ITSAL24_M (0x00FFF << 12) /* Mask */ +#define TSI148_LCSR_ITSAL16_M (0x0000FFF << 4) /* Mask */ /* * Inbound Translation Ending Address Lower */ -#define TSI148_LCSR_ITEAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITEAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITEAL16_M (0x0000FFF<<4) /* Mask */ +#define TSI148_LCSR_ITEAL6432_M (0xFFFF << 16) /* Mask */ +#define TSI148_LCSR_ITEAL24_M (0x00FFF << 12) /* Mask */ +#define TSI148_LCSR_ITEAL16_M (0x0000FFF << 4) /* Mask */ /* * Inbound Translation Offset Lower */ -#define TSI148_LCSR_ITOFFL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITOFFL24_M (0xFFFFF<<12) /* Mask */ -#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF<<4) /* Mask */ +#define TSI148_LCSR_ITOFFL6432_M (0xFFFF << 16) /* Mask */ +#define TSI148_LCSR_ITOFFL24_M (0xFFFFF << 12) /* Mask */ +#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF << 4) /* Mask */ /* * Inbound Translation Attribute @@ -854,16 +848,16 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_ITAT_EN BIT(31) /* Window Enable */ #define TSI148_LCSR_ITAT_TH BIT(18) /* Prefetch Threshold */ -#define TSI148_LCSR_ITAT_VFS_M (3<<16) /* Virtual FIFO Size Mask */ -#define TSI148_LCSR_ITAT_VFS_64 (0<<16) /* 64 bytes Virtual FIFO Size */ +#define TSI148_LCSR_ITAT_VFS_M (3 << 16) /* Virtual FIFO Size Mask */ +#define TSI148_LCSR_ITAT_VFS_64 (0 << 16) /* 64 bytes Virtual FIFO Size */ #define TSI148_LCSR_ITAT_VFS_128 BIT(16) /* 128 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_256 (2<<16) /* 256 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_512 (3<<16) /* 512 bytes Virtual FIFO Sz */ +#define TSI148_LCSR_ITAT_VFS_256 (2 << 16) /* 256 bytes Virtual FIFO Sz */ +#define TSI148_LCSR_ITAT_VFS_512 (3 << 16) /* 512 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_2eSSTM_M (7<<12) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_ITAT_2eSSTM_160 (0<<12) /* 160MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_ITAT_2eSSTM_M (7 << 12) /* 2eSST Xfer Rate Mask */ +#define TSI148_LCSR_ITAT_2eSSTM_160 (0 << 12) /* 160MB/s 2eSST Xfer Rate */ #define TSI148_LCSR_ITAT_2eSSTM_267 BIT(12) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_ITAT_2eSSTM_320 (2<<12) /* 320MB/s 2eSST Xfer Rate */ +#define TSI148_LCSR_ITAT_2eSSTM_320 (2 << 12) /* 320MB/s 2eSST Xfer Rate */ #define TSI148_LCSR_ITAT_2eSSTB BIT(11) /* 2eSST Bcast Xfer Protocol */ #define TSI148_LCSR_ITAT_2eSST BIT(10) /* 2eSST Xfer Protocol */ @@ -871,11 +865,11 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_ITAT_MBLT BIT(8) /* MBLT Xfer Protocol */ #define TSI148_LCSR_ITAT_BLT BIT(7) /* BLT Xfer Protocol */ -#define TSI148_LCSR_ITAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_ITAT_AS_A16 (0<<4) /* A16 Address Space */ +#define TSI148_LCSR_ITAT_AS_M (7 << 4) /* Address Space Mask */ +#define TSI148_LCSR_ITAT_AS_A16 (0 << 4) /* A16 Address Space */ #define TSI148_LCSR_ITAT_AS_A24 BIT(4) /* A24 Address Space */ -#define TSI148_LCSR_ITAT_AS_A32 (2<<4) /* A32 Address Space */ -#define TSI148_LCSR_ITAT_AS_A64 (4<<4) /* A64 Address Space */ +#define TSI148_LCSR_ITAT_AS_A32 (2 << 4) /* A32 Address Space */ +#define TSI148_LCSR_ITAT_AS_A64 (4 << 4) /* A64 Address Space */ #define TSI148_LCSR_ITAT_SUPR BIT(3) /* Supervisor Access */ #define TSI148_LCSR_ITAT_NPRIV BIT(2) /* Non-Priv (User) Access */ @@ -885,18 +879,18 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * GCSR Base Address Lower Address CRG +$404 */ -#define TSI148_LCSR_GBAL_M (0x7FFFFFF<<5) /* Mask */ +#define TSI148_LCSR_GBAL_M (0x7FFFFFF << 5) /* Mask */ /* * GCSR Attribute Register CRG + $408 */ #define TSI148_LCSR_GCSRAT_EN BIT(7) /* Enable access to GCSR */ -#define TSI148_LCSR_GCSRAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_GCSRAT_AS_A16 (0<<4) /* Address Space 16 */ +#define TSI148_LCSR_GCSRAT_AS_M (7 << 4) /* Address Space Mask */ +#define TSI148_LCSR_GCSRAT_AS_A16 (0 << 4) /* Address Space 16 */ #define TSI148_LCSR_GCSRAT_AS_A24 BIT(4) /* Address Space 24 */ -#define TSI148_LCSR_GCSRAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_GCSRAT_AS_A64 (4<<4) /* Address Space 64 */ +#define TSI148_LCSR_GCSRAT_AS_A32 (2 << 4) /* Address Space 32 */ +#define TSI148_LCSR_GCSRAT_AS_A64 (4 << 4) /* Address Space 64 */ #define TSI148_LCSR_GCSRAT_SUPR BIT(3) /* Sup set -GCSR decoder */ #define TSI148_LCSR_GCSRAT_NPRIV BIT(2) /* Non-Privliged set - CGSR */ @@ -906,18 +900,18 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * CRG Base Address Lower Address CRG + $410 */ -#define TSI148_LCSR_CBAL_M (0xFFFFF<<12) +#define TSI148_LCSR_CBAL_M (0xFFFFF << 12) /* * CRG Attribute Register CRG + $414 */ #define TSI148_LCSR_CRGAT_EN BIT(7) /* Enable PRG Access */ -#define TSI148_LCSR_CRGAT_AS_M (7<<4) /* Address Space */ -#define TSI148_LCSR_CRGAT_AS_A16 (0<<4) /* Address Space 16 */ +#define TSI148_LCSR_CRGAT_AS_M (7 << 4) /* Address Space */ +#define TSI148_LCSR_CRGAT_AS_A16 (0 << 4) /* Address Space 16 */ #define TSI148_LCSR_CRGAT_AS_A24 BIT(4) /* Address Space 24 */ -#define TSI148_LCSR_CRGAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_CRGAT_AS_A64 (4<<4) /* Address Space 64 */ +#define TSI148_LCSR_CRGAT_AS_A32 (2 << 4) /* Address Space 32 */ +#define TSI148_LCSR_CRGAT_AS_A64 (4 << 4) /* Address Space 64 */ #define TSI148_LCSR_CRGAT_SUPR BIT(3) /* Supervisor Access */ #define TSI148_LCSR_CRGAT_NPRIV BIT(2) /* Non-Privliged(User) Access */ @@ -927,7 +921,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * CR/CSR Offset Lower Register CRG + $41C */ -#define TSI148_LCSR_CROL_M (0x1FFF<<19) /* Mask */ +#define TSI148_LCSR_CROL_M (0x1FFF << 19) /* Mask */ /* * CR/CSR Attribute register CRG + $420 @@ -937,18 +931,18 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Location Monitor base address lower register CRG + $428 */ -#define TSI148_LCSR_LMBAL_M (0x7FFFFFF<<5) /* Mask */ +#define TSI148_LCSR_LMBAL_M (0x7FFFFFF << 5) /* Mask */ /* * Location Monitor Attribute Register CRG + $42C */ #define TSI148_LCSR_LMAT_EN BIT(7) /* Enable Location Monitor */ -#define TSI148_LCSR_LMAT_AS_M (7<<4) /* Address Space MASK */ -#define TSI148_LCSR_LMAT_AS_A16 (0<<4) /* A16 */ +#define TSI148_LCSR_LMAT_AS_M (7 << 4) /* Address Space MASK */ +#define TSI148_LCSR_LMAT_AS_A16 (0 << 4) /* A16 */ #define TSI148_LCSR_LMAT_AS_A24 BIT(4) /* A24 */ -#define TSI148_LCSR_LMAT_AS_A32 (2<<4) /* A32 */ -#define TSI148_LCSR_LMAT_AS_A64 (4<<4) /* A64 */ +#define TSI148_LCSR_LMAT_AS_A32 (2 << 4) /* A32 */ +#define TSI148_LCSR_LMAT_AS_A64 (4 << 4) /* A64 */ #define TSI148_LCSR_LMAT_SUPR BIT(3) /* Supervisor Access */ #define TSI148_LCSR_LMAT_NPRIV BIT(2) /* Non-Priv (User) Access */ @@ -958,58 +952,58 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Broadcast Pulse Generator Timer Register CRG + $438 */ -#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF<<0) /* Mask */ +#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF << 0) /* Mask */ /* * Broadcast Programmable Clock Timer Register CRG + $43C */ -#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF<<0) /* Mask */ +#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF << 0) /* Mask */ /* * VMEbus Interrupt Control Register CRG + $43C */ -#define TSI148_LCSR_VICR_CNTS_M (3<<22) /* Cntr Source MASK */ +#define TSI148_LCSR_VICR_CNTS_M (3 << 22) /* Cntr Source MASK */ #define TSI148_LCSR_VICR_CNTS_DIS BIT(22) /* Cntr Disable */ -#define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */ -#define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */ +#define TSI148_LCSR_VICR_CNTS_IRQ1 (2 << 22) /* IRQ1 to Cntr */ +#define TSI148_LCSR_VICR_CNTS_IRQ2 (3 << 22) /* IRQ2 to Cntr */ -#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */ +#define TSI148_LCSR_VICR_EDGIS_M (3 << 20) /* Edge interrupt MASK */ #define TSI148_LCSR_VICR_EDGIS_DIS BIT(20) /* Edge interrupt Disable */ -#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */ -#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */ +#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2 << 20) /* IRQ1 to Edge */ +#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3 << 20) /* IRQ2 to Edge */ -#define TSI148_LCSR_VICR_IRQIF_M (3<<18) /* IRQ1* Function MASK */ +#define TSI148_LCSR_VICR_IRQIF_M (3 << 18) /* IRQ1* Function MASK */ #define TSI148_LCSR_VICR_IRQIF_NORM BIT(18) /* Normal */ -#define TSI148_LCSR_VICR_IRQIF_PULSE (2<<18) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQIF_PROG (3<<18) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQIF_1U (4<<18) /* 1us Clock */ +#define TSI148_LCSR_VICR_IRQIF_PULSE (2 << 18) /* Pulse Generator */ +#define TSI148_LCSR_VICR_IRQIF_PROG (3 << 18) /* Programmable Clock */ +#define TSI148_LCSR_VICR_IRQIF_1U (4 << 18) /* 1us Clock */ -#define TSI148_LCSR_VICR_IRQ2F_M (3<<16) /* IRQ2* Function MASK */ +#define TSI148_LCSR_VICR_IRQ2F_M (3 << 16) /* IRQ2* Function MASK */ #define TSI148_LCSR_VICR_IRQ2F_NORM BIT(16) /* Normal */ -#define TSI148_LCSR_VICR_IRQ2F_PULSE (2<<16) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQ2F_PROG (3<<16) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQ2F_1U (4<<16) /* 1us Clock */ +#define TSI148_LCSR_VICR_IRQ2F_PULSE (2 << 16) /* Pulse Generator */ +#define TSI148_LCSR_VICR_IRQ2F_PROG (3 << 16) /* Programmable Clock */ +#define TSI148_LCSR_VICR_IRQ2F_1U (4 << 16) /* 1us Clock */ #define TSI148_LCSR_VICR_BIP BIT(15) /* Broadcast Interrupt Pulse */ #define TSI148_LCSR_VICR_IRQC BIT(12) /* VMEbus IRQ Clear */ #define TSI148_LCSR_VICR_IRQS BIT(11) /* VMEbus IRQ Status */ -#define TSI148_LCSR_VICR_IRQL_M (7<<8) /* VMEbus SW IRQ Level Mask */ +#define TSI148_LCSR_VICR_IRQL_M (7 << 8) /* VMEbus SW IRQ Level Mask */ #define TSI148_LCSR_VICR_IRQL_1 BIT(8) /* VMEbus SW IRQ Level 1 */ -#define TSI148_LCSR_VICR_IRQL_2 (2<<8) /* VMEbus SW IRQ Level 2 */ -#define TSI148_LCSR_VICR_IRQL_3 (3<<8) /* VMEbus SW IRQ Level 3 */ -#define TSI148_LCSR_VICR_IRQL_4 (4<<8) /* VMEbus SW IRQ Level 4 */ -#define TSI148_LCSR_VICR_IRQL_5 (5<<8) /* VMEbus SW IRQ Level 5 */ -#define TSI148_LCSR_VICR_IRQL_6 (6<<8) /* VMEbus SW IRQ Level 6 */ -#define TSI148_LCSR_VICR_IRQL_7 (7<<8) /* VMEbus SW IRQ Level 7 */ +#define TSI148_LCSR_VICR_IRQL_2 (2 << 8) /* VMEbus SW IRQ Level 2 */ +#define TSI148_LCSR_VICR_IRQL_3 (3 << 8) /* VMEbus SW IRQ Level 3 */ +#define TSI148_LCSR_VICR_IRQL_4 (4 << 8) /* VMEbus SW IRQ Level 4 */ +#define TSI148_LCSR_VICR_IRQL_5 (5 << 8) /* VMEbus SW IRQ Level 5 */ +#define TSI148_LCSR_VICR_IRQL_6 (6 << 8) /* VMEbus SW IRQ Level 6 */ +#define TSI148_LCSR_VICR_IRQL_7 (7 << 8) /* VMEbus SW IRQ Level 7 */ static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1, TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3, TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5, TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 }; -#define TSI148_LCSR_VICR_STID_M (0xFF<<0) /* Status/ID Mask */ +#define TSI148_LCSR_VICR_STID_M (0xFF << 0) /* Status/ID Mask */ /* * Interrupt Enable Register CRG + $440 @@ -1161,33 +1155,33 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, /* * Interrupt Map Register 1 CRG + $458 */ -#define TSI148_LCSR_INTM1_DMA1M_M (3<<18) /* DMA 1 */ -#define TSI148_LCSR_INTM1_DMA0M_M (3<<16) /* DMA 0 */ -#define TSI148_LCSR_INTM1_LM3M_M (3<<14) /* Location Monitor 3 */ -#define TSI148_LCSR_INTM1_LM2M_M (3<<12) /* Location Monitor 2 */ -#define TSI148_LCSR_INTM1_LM1M_M (3<<10) /* Location Monitor 1 */ -#define TSI148_LCSR_INTM1_LM0M_M (3<<8) /* Location Monitor 0 */ -#define TSI148_LCSR_INTM1_MB3M_M (3<<6) /* Mail Box 3 */ -#define TSI148_LCSR_INTM1_MB2M_M (3<<4) /* Mail Box 2 */ -#define TSI148_LCSR_INTM1_MB1M_M (3<<2) /* Mail Box 1 */ -#define TSI148_LCSR_INTM1_MB0M_M (3<<0) /* Mail Box 0 */ +#define TSI148_LCSR_INTM1_DMA1M_M (3 << 18) /* DMA 1 */ +#define TSI148_LCSR_INTM1_DMA0M_M (3 << 16) /* DMA 0 */ +#define TSI148_LCSR_INTM1_LM3M_M (3 << 14) /* Location Monitor 3 */ +#define TSI148_LCSR_INTM1_LM2M_M (3 << 12) /* Location Monitor 2 */ +#define TSI148_LCSR_INTM1_LM1M_M (3 << 10) /* Location Monitor 1 */ +#define TSI148_LCSR_INTM1_LM0M_M (3 << 8) /* Location Monitor 0 */ +#define TSI148_LCSR_INTM1_MB3M_M (3 << 6) /* Mail Box 3 */ +#define TSI148_LCSR_INTM1_MB2M_M (3 << 4) /* Mail Box 2 */ +#define TSI148_LCSR_INTM1_MB1M_M (3 << 2) /* Mail Box 1 */ +#define TSI148_LCSR_INTM1_MB0M_M (3 << 0) /* Mail Box 0 */ /* * Interrupt Map Register 2 CRG + $45C */ -#define TSI148_LCSR_INTM2_PERRM_M (3<<26) /* PCI Bus Error */ -#define TSI148_LCSR_INTM2_VERRM_M (3<<24) /* VMEbus Error */ -#define TSI148_LCSR_INTM2_VIEM_M (3<<22) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTM2_IACKM_M (3<<20) /* IACK */ -#define TSI148_LCSR_INTM2_SYSFLM_M (3<<18) /* System Fail */ -#define TSI148_LCSR_INTM2_ACFLM_M (3<<16) /* AC Fail */ -#define TSI148_LCSR_INTM2_IRQ7M_M (3<<14) /* IRQ7 */ -#define TSI148_LCSR_INTM2_IRQ6M_M (3<<12) /* IRQ6 */ -#define TSI148_LCSR_INTM2_IRQ5M_M (3<<10) /* IRQ5 */ -#define TSI148_LCSR_INTM2_IRQ4M_M (3<<8) /* IRQ4 */ -#define TSI148_LCSR_INTM2_IRQ3M_M (3<<6) /* IRQ3 */ -#define TSI148_LCSR_INTM2_IRQ2M_M (3<<4) /* IRQ2 */ -#define TSI148_LCSR_INTM2_IRQ1M_M (3<<2) /* IRQ1 */ +#define TSI148_LCSR_INTM2_PERRM_M (3 << 26) /* PCI Bus Error */ +#define TSI148_LCSR_INTM2_VERRM_M (3 << 24) /* VMEbus Error */ +#define TSI148_LCSR_INTM2_VIEM_M (3 << 22) /* VMEbus IRQ Edge */ +#define TSI148_LCSR_INTM2_IACKM_M (3 << 20) /* IACK */ +#define TSI148_LCSR_INTM2_SYSFLM_M (3 << 18) /* System Fail */ +#define TSI148_LCSR_INTM2_ACFLM_M (3 << 16) /* AC Fail */ +#define TSI148_LCSR_INTM2_IRQ7M_M (3 << 14) /* IRQ7 */ +#define TSI148_LCSR_INTM2_IRQ6M_M (3 << 12) /* IRQ6 */ +#define TSI148_LCSR_INTM2_IRQ5M_M (3 << 10) /* IRQ5 */ +#define TSI148_LCSR_INTM2_IRQ4M_M (3 << 8) /* IRQ4 */ +#define TSI148_LCSR_INTM2_IRQ3M_M (3 << 6) /* IRQ3 */ +#define TSI148_LCSR_INTM2_IRQ2M_M (3 << 4) /* IRQ2 */ +#define TSI148_LCSR_INTM2_IRQ1M_M (3 << 2) /* IRQ1 */ /* * DMA Control (0-1) Registers CRG + $500 @@ -1198,45 +1192,45 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, #define TSI148_LCSR_DCTL_MOD BIT(23) /* Mode */ -#define TSI148_LCSR_DCTL_VBKS_M (7<<12) /* VMEbus block Size MASK */ -#define TSI148_LCSR_DCTL_VBKS_32 (0<<12) /* VMEbus block Size 32 */ +#define TSI148_LCSR_DCTL_VBKS_M (7 << 12) /* VMEbus block Size MASK */ +#define TSI148_LCSR_DCTL_VBKS_32 (0 << 12) /* VMEbus block Size 32 */ #define TSI148_LCSR_DCTL_VBKS_64 BIT(12) /* VMEbus block Size 64 */ -#define TSI148_LCSR_DCTL_VBKS_128 (2<<12) /* VMEbus block Size 128 */ -#define TSI148_LCSR_DCTL_VBKS_256 (3<<12) /* VMEbus block Size 256 */ -#define TSI148_LCSR_DCTL_VBKS_512 (4<<12) /* VMEbus block Size 512 */ -#define TSI148_LCSR_DCTL_VBKS_1024 (5<<12) /* VMEbus block Size 1024 */ -#define TSI148_LCSR_DCTL_VBKS_2048 (6<<12) /* VMEbus block Size 2048 */ -#define TSI148_LCSR_DCTL_VBKS_4096 (7<<12) /* VMEbus block Size 4096 */ +#define TSI148_LCSR_DCTL_VBKS_128 (2 << 12) /* VMEbus block Size 128 */ +#define TSI148_LCSR_DCTL_VBKS_256 (3 << 12) /* VMEbus block Size 256 */ +#define TSI148_LCSR_DCTL_VBKS_512 (4 << 12) /* VMEbus block Size 512 */ +#define TSI148_LCSR_DCTL_VBKS_1024 (5 << 12) /* VMEbus block Size 1024 */ +#define TSI148_LCSR_DCTL_VBKS_2048 (6 << 12) /* VMEbus block Size 2048 */ +#define TSI148_LCSR_DCTL_VBKS_4096 (7 << 12) /* VMEbus block Size 4096 */ -#define TSI148_LCSR_DCTL_VBOT_M (7<<8) /* VMEbus back-off MASK */ -#define TSI148_LCSR_DCTL_VBOT_0 (0<<8) /* VMEbus back-off 0us */ +#define TSI148_LCSR_DCTL_VBOT_M (7 << 8) /* VMEbus back-off MASK */ +#define TSI148_LCSR_DCTL_VBOT_0 (0 << 8) /* VMEbus back-off 0us */ #define TSI148_LCSR_DCTL_VBOT_1 BIT(8) /* VMEbus back-off 1us */ -#define TSI148_LCSR_DCTL_VBOT_2 (2<<8) /* VMEbus back-off 2us */ -#define TSI148_LCSR_DCTL_VBOT_4 (3<<8) /* VMEbus back-off 4us */ -#define TSI148_LCSR_DCTL_VBOT_8 (4<<8) /* VMEbus back-off 8us */ -#define TSI148_LCSR_DCTL_VBOT_16 (5<<8) /* VMEbus back-off 16us */ -#define TSI148_LCSR_DCTL_VBOT_32 (6<<8) /* VMEbus back-off 32us */ -#define TSI148_LCSR_DCTL_VBOT_64 (7<<8) /* VMEbus back-off 64us */ +#define TSI148_LCSR_DCTL_VBOT_2 (2 << 8) /* VMEbus back-off 2us */ +#define TSI148_LCSR_DCTL_VBOT_4 (3 << 8) /* VMEbus back-off 4us */ +#define TSI148_LCSR_DCTL_VBOT_8 (4 << 8) /* VMEbus back-off 8us */ +#define TSI148_LCSR_DCTL_VBOT_16 (5 << 8) /* VMEbus back-off 16us */ +#define TSI148_LCSR_DCTL_VBOT_32 (6 << 8) /* VMEbus back-off 32us */ +#define TSI148_LCSR_DCTL_VBOT_64 (7 << 8) /* VMEbus back-off 64us */ -#define TSI148_LCSR_DCTL_PBKS_M (7<<4) /* PCI block size MASK */ -#define TSI148_LCSR_DCTL_PBKS_32 (0<<4) /* PCI block size 32 bytes */ +#define TSI148_LCSR_DCTL_PBKS_M (7 << 4) /* PCI block size MASK */ +#define TSI148_LCSR_DCTL_PBKS_32 (0 << 4) /* PCI block size 32 bytes */ #define TSI148_LCSR_DCTL_PBKS_64 BIT(4) /* PCI block size 64 bytes */ -#define TSI148_LCSR_DCTL_PBKS_128 (2<<4) /* PCI block size 128 bytes */ -#define TSI148_LCSR_DCTL_PBKS_256 (3<<4) /* PCI block size 256 bytes */ -#define TSI148_LCSR_DCTL_PBKS_512 (4<<4) /* PCI block size 512 bytes */ -#define TSI148_LCSR_DCTL_PBKS_1024 (5<<4) /* PCI block size 1024 bytes */ -#define TSI148_LCSR_DCTL_PBKS_2048 (6<<4) /* PCI block size 2048 bytes */ -#define TSI148_LCSR_DCTL_PBKS_4096 (7<<4) /* PCI block size 4096 bytes */ +#define TSI148_LCSR_DCTL_PBKS_128 (2 << 4) /* PCI block size 128 bytes */ +#define TSI148_LCSR_DCTL_PBKS_256 (3 << 4) /* PCI block size 256 bytes */ +#define TSI148_LCSR_DCTL_PBKS_512 (4 << 4) /* PCI block size 512 bytes */ +#define TSI148_LCSR_DCTL_PBKS_1024 (5 << 4) /* PCI block size 1024 bytes */ +#define TSI148_LCSR_DCTL_PBKS_2048 (6 << 4) /* PCI block size 2048 bytes */ +#define TSI148_LCSR_DCTL_PBKS_4096 (7 << 4) /* PCI block size 4096 bytes */ -#define TSI148_LCSR_DCTL_PBOT_M (7<<0) /* PCI back off MASK */ -#define TSI148_LCSR_DCTL_PBOT_0 (0<<0) /* PCI back off 0us */ +#define TSI148_LCSR_DCTL_PBOT_M (7 << 0) /* PCI back off MASK */ +#define TSI148_LCSR_DCTL_PBOT_0 (0 << 0) /* PCI back off 0us */ #define TSI148_LCSR_DCTL_PBOT_1 BIT(0) /* PCI back off 1us */ -#define TSI148_LCSR_DCTL_PBOT_2 (2<<0) /* PCI back off 2us */ -#define TSI148_LCSR_DCTL_PBOT_4 (3<<0) /* PCI back off 3us */ -#define TSI148_LCSR_DCTL_PBOT_8 (4<<0) /* PCI back off 4us */ -#define TSI148_LCSR_DCTL_PBOT_16 (5<<0) /* PCI back off 8us */ -#define TSI148_LCSR_DCTL_PBOT_32 (6<<0) /* PCI back off 16us */ -#define TSI148_LCSR_DCTL_PBOT_64 (7<<0) /* PCI back off 32us */ +#define TSI148_LCSR_DCTL_PBOT_2 (2 << 0) /* PCI back off 2us */ +#define TSI148_LCSR_DCTL_PBOT_4 (3 << 0) /* PCI back off 3us */ +#define TSI148_LCSR_DCTL_PBOT_8 (4 << 0) /* PCI back off 4us */ +#define TSI148_LCSR_DCTL_PBOT_16 (5 << 0) /* PCI back off 8us */ +#define TSI148_LCSR_DCTL_PBOT_32 (6 << 0) /* PCI back off 16us */ +#define TSI148_LCSR_DCTL_PBOT_64 (7 << 0) /* PCI back off 32us */ /* * DMA Status Registers (0-1) CRG + $504 @@ -1253,97 +1247,97 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, /* * DMA Current Link Address Lower (0-1) */ -#define TSI148_LCSR_DCLAL_M (0x3FFFFFF<<6) /* Mask */ +#define TSI148_LCSR_DCLAL_M (0x3FFFFFF << 6) /* Mask */ /* * DMA Source Attribute (0-1) Reg */ -#define TSI148_LCSR_DSAT_TYP_M (3<<28) /* Source Bus Type */ -#define TSI148_LCSR_DSAT_TYP_PCI (0<<28) /* PCI Bus */ +#define TSI148_LCSR_DSAT_TYP_M (3 << 28) /* Source Bus Type */ +#define TSI148_LCSR_DSAT_TYP_PCI (0 << 28) /* PCI Bus */ #define TSI148_LCSR_DSAT_TYP_VME BIT(28) /* VMEbus */ -#define TSI148_LCSR_DSAT_TYP_PAT (2<<28) /* Data Pattern */ +#define TSI148_LCSR_DSAT_TYP_PAT (2 << 28) /* Data Pattern */ #define TSI148_LCSR_DSAT_PSZ BIT(25) /* Pattern Size */ #define TSI148_LCSR_DSAT_NIN BIT(24) /* No Increment */ -#define TSI148_LCSR_DSAT_2eSSTM_M (3<<11) /* 2eSST Trans Rate Mask */ -#define TSI148_LCSR_DSAT_2eSSTM_160 (0<<11) /* 160 MB/s */ +#define TSI148_LCSR_DSAT_2eSSTM_M (3 << 11) /* 2eSST Trans Rate Mask */ +#define TSI148_LCSR_DSAT_2eSSTM_160 (0 << 11) /* 160 MB/s */ #define TSI148_LCSR_DSAT_2eSSTM_267 BIT(11) /* 267 MB/s */ -#define TSI148_LCSR_DSAT_2eSSTM_320 (2<<11) /* 320 MB/s */ +#define TSI148_LCSR_DSAT_2eSSTM_320 (2 << 11) /* 320 MB/s */ -#define TSI148_LCSR_DSAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DSAT_TM_SCT (0<<8) /* SCT */ +#define TSI148_LCSR_DSAT_TM_M (7 << 8) /* Bus Transfer Protocol Mask */ +#define TSI148_LCSR_DSAT_TM_SCT (0 << 8) /* SCT */ #define TSI148_LCSR_DSAT_TM_BLT BIT(8) /* BLT */ -#define TSI148_LCSR_DSAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DSAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DSAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DSAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ +#define TSI148_LCSR_DSAT_TM_MBLT (2 << 8) /* MBLT */ +#define TSI148_LCSR_DSAT_TM_2eVME (3 << 8) /* 2eVME */ +#define TSI148_LCSR_DSAT_TM_2eSST (4 << 8) /* 2eSST */ +#define TSI148_LCSR_DSAT_TM_2eSSTB (5 << 8) /* 2eSST Broadcast */ -#define TSI148_LCSR_DSAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DSAT_DBW_16 (0<<6) /* 16 Bits */ +#define TSI148_LCSR_DSAT_DBW_M (3 << 6) /* Max Data Width MASK */ +#define TSI148_LCSR_DSAT_DBW_16 (0 << 6) /* 16 Bits */ #define TSI148_LCSR_DSAT_DBW_32 BIT(6) /* 32 Bits */ #define TSI148_LCSR_DSAT_SUP BIT(5) /* Supervisory Mode */ #define TSI148_LCSR_DSAT_PGM BIT(4) /* Program Mode */ -#define TSI148_LCSR_DSAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DSAT_AMODE_A16 (0<<0) /* A16 */ +#define TSI148_LCSR_DSAT_AMODE_M (0xf << 0) /* Address Space Mask */ +#define TSI148_LCSR_DSAT_AMODE_A16 (0 << 0) /* A16 */ #define TSI148_LCSR_DSAT_AMODE_A24 BIT(0) /* A24 */ -#define TSI148_LCSR_DSAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DSAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DSAT_AMODE_CRCSR (5<<0) /* CR/CSR */ -#define TSI148_LCSR_DSAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DSAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb<<0) /* User4 */ +#define TSI148_LCSR_DSAT_AMODE_A32 (2 << 0) /* A32 */ +#define TSI148_LCSR_DSAT_AMODE_A64 (4 << 0) /* A64 */ +#define TSI148_LCSR_DSAT_AMODE_CRCSR (5 << 0) /* CR/CSR */ +#define TSI148_LCSR_DSAT_AMODE_USER1 (8 << 0) /* User1 */ +#define TSI148_LCSR_DSAT_AMODE_USER2 (9 << 0) /* User2 */ +#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa << 0) /* User3 */ +#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb << 0) /* User4 */ /* * DMA Destination Attribute Registers (0-1) */ -#define TSI148_LCSR_DDAT_TYP_PCI (0<<28) /* Destination PCI Bus */ +#define TSI148_LCSR_DDAT_TYP_PCI (0 << 28) /* Destination PCI Bus */ #define TSI148_LCSR_DDAT_TYP_VME BIT(28) /* Destination VMEbus */ -#define TSI148_LCSR_DDAT_2eSSTM_M (3<<11) /* 2eSST Transfer Rate Mask */ -#define TSI148_LCSR_DDAT_2eSSTM_160 (0<<11) /* 160 MB/s */ +#define TSI148_LCSR_DDAT_2eSSTM_M (3 << 11) /* 2eSST Transfer Rate Mask */ +#define TSI148_LCSR_DDAT_2eSSTM_160 (0 << 11) /* 160 MB/s */ #define TSI148_LCSR_DDAT_2eSSTM_267 BIT(11) /* 267 MB/s */ -#define TSI148_LCSR_DDAT_2eSSTM_320 (2<<11) /* 320 MB/s */ +#define TSI148_LCSR_DDAT_2eSSTM_320 (2 << 11) /* 320 MB/s */ -#define TSI148_LCSR_DDAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DDAT_TM_SCT (0<<8) /* SCT */ +#define TSI148_LCSR_DDAT_TM_M (7 << 8) /* Bus Transfer Protocol Mask */ +#define TSI148_LCSR_DDAT_TM_SCT (0 << 8) /* SCT */ #define TSI148_LCSR_DDAT_TM_BLT BIT(8) /* BLT */ -#define TSI148_LCSR_DDAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DDAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DDAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DDAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ +#define TSI148_LCSR_DDAT_TM_MBLT (2 << 8) /* MBLT */ +#define TSI148_LCSR_DDAT_TM_2eVME (3 << 8) /* 2eVME */ +#define TSI148_LCSR_DDAT_TM_2eSST (4 << 8) /* 2eSST */ +#define TSI148_LCSR_DDAT_TM_2eSSTB (5 << 8) /* 2eSST Broadcast */ -#define TSI148_LCSR_DDAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DDAT_DBW_16 (0<<6) /* 16 Bits */ +#define TSI148_LCSR_DDAT_DBW_M (3 << 6) /* Max Data Width MASK */ +#define TSI148_LCSR_DDAT_DBW_16 (0 << 6) /* 16 Bits */ #define TSI148_LCSR_DDAT_DBW_32 BIT(6) /* 32 Bits */ #define TSI148_LCSR_DDAT_SUP BIT(5) /* Supervisory/User Access */ #define TSI148_LCSR_DDAT_PGM BIT(4) /* Program/Data Access */ -#define TSI148_LCSR_DDAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DDAT_AMODE_A16 (0<<0) /* A16 */ +#define TSI148_LCSR_DDAT_AMODE_M (0xf << 0) /* Address Space Mask */ +#define TSI148_LCSR_DDAT_AMODE_A16 (0 << 0) /* A16 */ #define TSI148_LCSR_DDAT_AMODE_A24 BIT(0) /* A24 */ -#define TSI148_LCSR_DDAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DDAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DDAT_AMODE_CRCSR (5<<0) /* CRC/SR */ -#define TSI148_LCSR_DDAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DDAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb<<0) /* User4 */ +#define TSI148_LCSR_DDAT_AMODE_A32 (2 << 0) /* A32 */ +#define TSI148_LCSR_DDAT_AMODE_A64 (4 << 0) /* A64 */ +#define TSI148_LCSR_DDAT_AMODE_CRCSR (5 << 0) /* CRC/SR */ +#define TSI148_LCSR_DDAT_AMODE_USER1 (8 << 0) /* User1 */ +#define TSI148_LCSR_DDAT_AMODE_USER2 (9 << 0) /* User2 */ +#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa << 0) /* User3 */ +#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb << 0) /* User4 */ /* * DMA Next Link Address Lower */ -#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */ +#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF << 6) /* Address Mask */ #define TSI148_LCSR_DNLAL_LLA BIT(0) /* Last Link Address Indicator */ /* * DMA 2eSST Broadcast Select */ -#define TSI148_LCSR_DBS_M (0x1FFFFF<<0) /* Mask */ +#define TSI148_LCSR_DBS_M (0x1FFFFF << 0) /* Mask */ /* * GCSR Register Group @@ -1368,7 +1362,7 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, #define TSI148_GCSR_GCTRL_MBI0S BIT(0) /* Mail box 0 Int Status */ #define TSI148_GCSR_GAP BIT(5) /* Geographic Addr Parity */ -#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ +#define TSI148_GCSR_GA_M (0x1F << 0) /* Geographic Address Mask */ /* * CR/CSR Register Group @@ -1395,6 +1389,6 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, /* * CR/CSR Base Address Register CRG + FFC */ -#define TSI148_CRCSR_CBAR_M (0x1F<<3) /* Mask */ +#define TSI148_CRCSR_CBAR_M (0x1F << 3) /* Mask */ #endif /* TSI148_H */ diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user/vme_user.c index b9367b575d00..36183f923768 100644 --- a/drivers/staging/vme_user/vme_user.c +++ b/drivers/staging/vme_user/vme_user.c @@ -37,7 +37,7 @@ #include "vme.h" #include "vme_user.h" -static const char driver_name[] = "vme_user"; +#define DRIVER_NAME "vme_user" static int bus[VME_USER_BUS_MAX]; static unsigned int bus_num; @@ -101,9 +101,11 @@ struct image_desc { static struct image_desc image[VME_DEVS]; static struct cdev *vme_user_cdev; /* Character device */ -static struct class *vme_user_sysfs_class; /* Sysfs class */ static struct vme_dev *vme_user_bridge; /* Pointer to user device */ +static const struct class vme_user_sysfs_class = { + .name = DRIVER_NAME, +}; static const int type[VME_DEVS] = { MASTER_MINOR, MASTER_MINOR, MASTER_MINOR, MASTER_MINOR, SLAVE_MINOR, SLAVE_MINOR, @@ -540,8 +542,7 @@ static int vme_user_probe(struct vme_dev *vdev) } /* Assign major and minor numbers for the driver */ - err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS, - driver_name); + err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS, DRIVER_NAME); if (err) { dev_warn(&vdev->dev, "Error getting Major Number %d for driver.\n", VME_MAJOR); @@ -614,10 +615,9 @@ static int vme_user_probe(struct vme_dev *vdev) } /* Create sysfs entries - on udev systems this creates the dev files */ - vme_user_sysfs_class = class_create(driver_name); - if (IS_ERR(vme_user_sysfs_class)) { + err = class_register(&vme_user_sysfs_class); + if (err) { dev_err(&vdev->dev, "Error creating vme_user class.\n"); - err = PTR_ERR(vme_user_sysfs_class); goto err_master; } @@ -641,7 +641,7 @@ static int vme_user_probe(struct vme_dev *vdev) } num = (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i; - image[i].device = device_create(vme_user_sysfs_class, NULL, + image[i].device = device_create(&vme_user_sysfs_class, NULL, MKDEV(VME_MAJOR, i), NULL, name, num); if (IS_ERR(image[i].device)) { @@ -656,9 +656,9 @@ static int vme_user_probe(struct vme_dev *vdev) err_sysfs: while (i > 0) { i--; - device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); + device_destroy(&vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); } - class_destroy(vme_user_sysfs_class); + class_unregister(&vme_user_sysfs_class); /* Ensure counter set correctly to unalloc all master windows */ i = MASTER_MAX + 1; @@ -696,9 +696,9 @@ static void vme_user_remove(struct vme_dev *dev) /* Remove sysfs Entries */ for (i = 0; i < VME_DEVS; i++) { mutex_destroy(&image[i].mutex); - device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); + device_destroy(&vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); } - class_destroy(vme_user_sysfs_class); + class_unregister(&vme_user_sysfs_class); for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) { kfree(image[i].kern_buf); @@ -720,7 +720,7 @@ static void vme_user_remove(struct vme_dev *dev) } static struct vme_driver vme_user_driver = { - .name = driver_name, + .name = DRIVER_NAME, .match = vme_user_match, .probe = vme_user_probe, .remove = vme_user_remove, diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 696d4dd03aa2..f7824396c5ff 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -761,7 +761,7 @@ static const unsigned char vt3253b0_rfmd[CB_VT3253B0_INIT_FOR_RFMD][2] = { #define CB_VT3253B0_AGC_FOR_RFMD2959 195 /* For RFMD2959 */ static -unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { +unsigned char vt3253b0_agc4_rfmd2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { {0xF0, 0x00}, {0xF1, 0x3E}, {0xF0, 0x80}, @@ -962,7 +962,7 @@ unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = { #define CB_VT3253B0_INIT_FOR_AIROHA2230 256 /* For AIROHA */ static -unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { +unsigned char vt3253b0_airoha2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { {0x00, 0x31}, {0x01, 0x00}, {0x02, 0x00}, @@ -1223,7 +1223,7 @@ unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = { #define CB_VT3253B0_INIT_FOR_UW2451 256 /* For UW2451 */ -static unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = { +static unsigned char vt3253b0_uw2451[CB_VT3253B0_INIT_FOR_UW2451][2] = { {0x00, 0x31}, {0x01, 0x00}, {0x02, 0x00}, @@ -1484,7 +1484,7 @@ static unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = { #define CB_VT3253B0_AGC 193 /* For AIROHA */ -static unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = { +static unsigned char vt3253b0_agc[CB_VT3253B0_AGC][2] = { {0xF0, 0x00}, {0xF1, 0x00}, {0xF0, 0x80}, @@ -1979,7 +1979,7 @@ bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr, * In: * iobase - I/O base address * byRevId - Revision ID - * byRFType - RF type + * rf_type - RF type * Out: * none * @@ -1992,10 +1992,10 @@ bool bb_vt3253_init(struct vnt_private *priv) bool result = true; int ii; void __iomem *iobase = priv->port_offset; - unsigned char by_rf_type = priv->byRFType; + unsigned char rf_type = priv->rf_type; unsigned char by_local_id = priv->local_id; - if (by_rf_type == RF_RFMD2959) { + if (rf_type == RF_RFMD2959) { if (by_local_id <= REV_ID_VT3253_A1) { for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) result &= bb_write_embedded(priv, @@ -2010,74 +2010,74 @@ bool bb_vt3253_init(struct vnt_private *priv) for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AGC4_RFMD2959[ii][0], - byVT3253B0_AGC4_RFMD2959[ii][1]); + vt3253b0_agc4_rfmd2959[ii][0], + vt3253b0_agc4_rfmd2959[ii][1]); iowrite32(0x23, iobase + MAC_REG_ITRTMSET); vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0)); } - priv->abyBBVGA[0] = 0x18; - priv->abyBBVGA[1] = 0x0A; - priv->abyBBVGA[2] = 0x0; - priv->abyBBVGA[3] = 0x0; + priv->bbvga[0] = 0x18; + priv->bbvga[1] = 0x0A; + priv->bbvga[2] = 0x0; + priv->bbvga[3] = 0x0; priv->dbm_threshold[0] = -70; priv->dbm_threshold[1] = -50; priv->dbm_threshold[2] = 0; priv->dbm_threshold[3] = 0; - } else if ((by_rf_type == RF_AIROHA) || (by_rf_type == RF_AL2230S)) { + } else if ((rf_type == RF_AIROHA) || (rf_type == RF_AL2230S)) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AIROHA2230[ii][0], - byVT3253B0_AIROHA2230[ii][1]); + vt3253b0_airoha2230[ii][0], + vt3253b0_airoha2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + vt3253b0_agc[ii][0], vt3253b0_agc[ii][1]); - priv->abyBBVGA[0] = 0x1C; - priv->abyBBVGA[1] = 0x10; - priv->abyBBVGA[2] = 0x0; - priv->abyBBVGA[3] = 0x0; + priv->bbvga[0] = 0x1C; + priv->bbvga[1] = 0x10; + priv->bbvga[2] = 0x0; + priv->bbvga[3] = 0x0; priv->dbm_threshold[0] = -70; priv->dbm_threshold[1] = -48; priv->dbm_threshold[2] = 0; priv->dbm_threshold[3] = 0; - } else if (by_rf_type == RF_UW2451) { + } else if (rf_type == RF_UW2451) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) result &= bb_write_embedded(priv, - byVT3253B0_UW2451[ii][0], - byVT3253B0_UW2451[ii][1]); + vt3253b0_uw2451[ii][0], + vt3253b0_uw2451[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AGC[ii][0], - byVT3253B0_AGC[ii][1]); + vt3253b0_agc[ii][0], + vt3253b0_agc[ii][1]); iowrite8(0x23, iobase + MAC_REG_ITRTMSET); vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0)); - priv->abyBBVGA[0] = 0x14; - priv->abyBBVGA[1] = 0x0A; - priv->abyBBVGA[2] = 0x0; - priv->abyBBVGA[3] = 0x0; + priv->bbvga[0] = 0x14; + priv->bbvga[1] = 0x0A; + priv->bbvga[2] = 0x0; + priv->bbvga[3] = 0x0; priv->dbm_threshold[0] = -60; priv->dbm_threshold[1] = -50; priv->dbm_threshold[2] = 0; priv->dbm_threshold[3] = 0; - } else if (by_rf_type == RF_VT3226) { + } else if (rf_type == RF_VT3226) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AIROHA2230[ii][0], - byVT3253B0_AIROHA2230[ii][1]); + vt3253b0_airoha2230[ii][0], + vt3253b0_airoha2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) result &= bb_write_embedded(priv, - byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + vt3253b0_agc[ii][0], vt3253b0_agc[ii][1]); - priv->abyBBVGA[0] = 0x1C; - priv->abyBBVGA[1] = 0x10; - priv->abyBBVGA[2] = 0x0; - priv->abyBBVGA[3] = 0x0; + priv->bbvga[0] = 0x1C; + priv->bbvga[1] = 0x10; + priv->bbvga[2] = 0x0; + priv->bbvga[3] = 0x0; priv->dbm_threshold[0] = -70; priv->dbm_threshold[1] = -48; priv->dbm_threshold[2] = 0; @@ -2087,8 +2087,8 @@ bool bb_vt3253_init(struct vnt_private *priv) /* {{ RobertYu: 20050104 */ } else { /* No VGA Table now */ - priv->bUpdateBBVGA = false; - priv->abyBBVGA[0] = 0x1C; + priv->update_bbvga = false; + priv->bbvga[0] = 0x1C; } if (by_local_id > REV_ID_VT3253_A1) { @@ -2126,7 +2126,7 @@ bb_set_short_slot_time(struct vnt_private *priv) /* patch for 3253B0 Baseband with Cardbus module */ bb_read_embedded(priv, 0xE7, &by_bb_vga); - if (by_bb_vga == priv->abyBBVGA[0]) + if (by_bb_vga == priv->bbvga[0]) by_bb_rx_conf |= 0x20; /* 0010 0000 */ bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */ @@ -2140,13 +2140,13 @@ void bb_set_vga_gain_offset(struct vnt_private *priv, unsigned char by_data) bb_read_embedded(priv, 0x0A, &by_bb_rx_conf); /* CR10 */ /* patch for 3253B0 Baseband with Cardbus module */ - if (by_data == priv->abyBBVGA[0]) + if (by_data == priv->bbvga[0]) by_bb_rx_conf |= 0x20; /* 0010 0000 */ else if (priv->short_slot_time) by_bb_rx_conf &= 0xDF; /* 1101 1111 */ else by_bb_rx_conf |= 0x20; /* 0010 0000 */ - priv->byBBVGACurrent = by_data; + priv->bbvga_current = by_data; bb_write_embedded(priv, 0x0A, by_bb_rx_conf); /* CR10 */ } diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index c680925b9c92..350ab8f3778a 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -6,7 +6,7 @@ * Purpose: Provide functions to setup NIC operation mode * Functions: * s_vSafeResetTx - Rest Tx - * CARDvSetRSPINF - Set RSPINF + * card_set_rspinf - Set RSPINF * CARDvUpdateBasicTopRate - Update BasicTopRate * CARDbAddBasicRate - Add to BasicRateSet * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet @@ -50,7 +50,7 @@ /*--------------------- Static Variables --------------------------*/ -static const unsigned short cwRXBCNTSFOff[MAX_RATE] = { +static const unsigned short rx_bcn_tsf_off[MAX_RATE] = { 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; /*--------------------- Static Functions --------------------------*/ @@ -75,95 +75,95 @@ static void vt6655_mac_set_bb_type(void __iomem *iobase, u32 mask) * wRate - Tx Rate * byPktType - Tx Packet type * Out: - * pbyTxRate - pointer to RSPINF TxRate field - * pbyRsvTime - pointer to RSPINF RsvTime field + * tx_rate - pointer to RSPINF TxRate field + * rsv_time - pointer to RSPINF RsvTime field * * Return Value: none */ -static void s_vCalculateOFDMRParameter(unsigned char rate, +static void calculate_ofdmr_parameter(unsigned char rate, u8 bb_type, - unsigned char *pbyTxRate, - unsigned char *pbyRsvTime) + unsigned char *tx_rate, + unsigned char *rsv_time) { switch (rate) { case RATE_6M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9B; - *pbyRsvTime = 44; + *tx_rate = 0x9B; + *rsv_time = 44; } else { - *pbyTxRate = 0x8B; - *pbyRsvTime = 50; + *tx_rate = 0x8B; + *rsv_time = 50; } break; case RATE_9M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9F; - *pbyRsvTime = 36; + *tx_rate = 0x9F; + *rsv_time = 36; } else { - *pbyTxRate = 0x8F; - *pbyRsvTime = 42; + *tx_rate = 0x8F; + *rsv_time = 42; } break; case RATE_12M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9A; - *pbyRsvTime = 32; + *tx_rate = 0x9A; + *rsv_time = 32; } else { - *pbyTxRate = 0x8A; - *pbyRsvTime = 38; + *tx_rate = 0x8A; + *rsv_time = 38; } break; case RATE_18M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9E; - *pbyRsvTime = 28; + *tx_rate = 0x9E; + *rsv_time = 28; } else { - *pbyTxRate = 0x8E; - *pbyRsvTime = 34; + *tx_rate = 0x8E; + *rsv_time = 34; } break; case RATE_36M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9D; - *pbyRsvTime = 24; + *tx_rate = 0x9D; + *rsv_time = 24; } else { - *pbyTxRate = 0x8D; - *pbyRsvTime = 30; + *tx_rate = 0x8D; + *rsv_time = 30; } break; case RATE_48M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x98; - *pbyRsvTime = 24; + *tx_rate = 0x98; + *rsv_time = 24; } else { - *pbyTxRate = 0x88; - *pbyRsvTime = 30; + *tx_rate = 0x88; + *rsv_time = 30; } break; case RATE_54M: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x9C; - *pbyRsvTime = 24; + *tx_rate = 0x9C; + *rsv_time = 24; } else { - *pbyTxRate = 0x8C; - *pbyRsvTime = 30; + *tx_rate = 0x8C; + *rsv_time = 30; } break; case RATE_24M: default: if (bb_type == BB_TYPE_11A) { /* 5GHZ */ - *pbyTxRate = 0x99; - *pbyRsvTime = 28; + *tx_rate = 0x99; + *rsv_time = 28; } else { - *pbyTxRate = 0x89; - *pbyRsvTime = 34; + *tx_rate = 0x89; + *rsv_time = 34; } break; } @@ -182,59 +182,59 @@ static void s_vCalculateOFDMRParameter(unsigned char rate, * * Return Value: None. */ -bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) +bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type) { - unsigned char byCWMaxMin = 0; - unsigned char bySlot = 0; - unsigned char bySIFS = 0; - unsigned char byDIFS = 0; + unsigned char cw_max_min = 0; + unsigned char slot = 0; + unsigned char sifs = 0; + unsigned char difs = 0; int i; /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ if (bb_type == BB_TYPE_11A) { vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11A); bb_write_embedded(priv, 0x88, 0x03); - bySlot = C_SLOT_SHORT; - bySIFS = C_SIFS_A; - byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT; - byCWMaxMin = 0xA4; + slot = C_SLOT_SHORT; + sifs = C_SIFS_A; + difs = C_SIFS_A + 2 * C_SLOT_SHORT; + cw_max_min = 0xA4; } else if (bb_type == BB_TYPE_11B) { vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11B); bb_write_embedded(priv, 0x88, 0x02); - bySlot = C_SLOT_LONG; - bySIFS = C_SIFS_BG; - byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG; - byCWMaxMin = 0xA5; + slot = C_SLOT_LONG; + sifs = C_SIFS_BG; + difs = C_SIFS_BG + 2 * C_SLOT_LONG; + cw_max_min = 0xA5; } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11G); bb_write_embedded(priv, 0x88, 0x08); - bySIFS = C_SIFS_BG; + sifs = C_SIFS_BG; if (priv->short_slot_time) { - bySlot = C_SLOT_SHORT; - byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT; + slot = C_SLOT_SHORT; + difs = C_SIFS_BG + 2 * C_SLOT_SHORT; } else { - bySlot = C_SLOT_LONG; - byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG; + slot = C_SLOT_LONG; + difs = C_SIFS_BG + 2 * C_SLOT_LONG; } - byCWMaxMin = 0xa4; + cw_max_min = 0xa4; for (i = RATE_54M; i >= RATE_6M; i--) { if (priv->basic_rates & ((u32)(0x1 << i))) { - byCWMaxMin |= 0x1; + cw_max_min |= 0x1; break; } } } - if (priv->byRFType == RF_RFMD2959) { + if (priv->rf_type == RF_RFMD2959) { /* * bcs TX_PE will reserve 3 us hardware's processing * time here is 2 us. */ - bySIFS -= 3; - byDIFS -= 3; + sifs -= 3; + difs -= 3; /* * TX_PE will reserve 3 us for MAX2829 A mode only, it is for * better TX throughput; MAC will need 2 us to process, so the @@ -242,32 +242,32 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) */ } - if (priv->bySIFS != bySIFS) { - priv->bySIFS = bySIFS; - iowrite8(priv->bySIFS, priv->port_offset + MAC_REG_SIFS); + if (priv->sifs != sifs) { + priv->sifs = sifs; + iowrite8(priv->sifs, priv->port_offset + MAC_REG_SIFS); } - if (priv->byDIFS != byDIFS) { - priv->byDIFS = byDIFS; - iowrite8(priv->byDIFS, priv->port_offset + MAC_REG_DIFS); + if (priv->difs != difs) { + priv->difs = difs; + iowrite8(priv->difs, priv->port_offset + MAC_REG_DIFS); } - if (priv->byEIFS != C_EIFS) { - priv->byEIFS = C_EIFS; - iowrite8(priv->byEIFS, priv->port_offset + MAC_REG_EIFS); + if (priv->eifs != C_EIFS) { + priv->eifs = C_EIFS; + iowrite8(priv->eifs, priv->port_offset + MAC_REG_EIFS); } - if (priv->bySlot != bySlot) { - priv->bySlot = bySlot; - iowrite8(priv->bySlot, priv->port_offset + MAC_REG_SLOT); + if (priv->slot != slot) { + priv->slot = slot; + iowrite8(priv->slot, priv->port_offset + MAC_REG_SLOT); bb_set_short_slot_time(priv); } - if (priv->byCWMaxMin != byCWMaxMin) { - priv->byCWMaxMin = byCWMaxMin; - iowrite8(priv->byCWMaxMin, priv->port_offset + MAC_REG_CWMAXMIN0); + if (priv->cw_max_min != cw_max_min) { + priv->cw_max_min = cw_max_min; + iowrite8(priv->cw_max_min, priv->port_offset + MAC_REG_CWMAXMIN0); } - priv->byPacketType = CARDbyGetPktType(priv); + priv->packet_type = card_get_pkt_type(priv); - CARDvSetRSPINF(priv, bb_type); + card_set_rspinf(priv, bb_type); return true; } @@ -278,8 +278,8 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) * * Parameters: * In: - * priv - The adapter to be sync. - * byRxRate - data rate of receive beacon + * priv - The adapter to be sync. + * rx_rate - data rate of receive beacon * qwBSSTimestamp - Rx BCN's TSF * qwLocalTSF - Local TSF * Out: @@ -287,7 +287,7 @@ bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) * * Return Value: none */ -bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate, +bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, u64 qwBSSTimestamp) { u64 local_tsf; @@ -296,7 +296,7 @@ bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate, local_tsf = vt6655_get_current_tsf(priv); if (qwBSSTimestamp != local_tsf) { - qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, + qwTSFOffset = CARDqGetTSFOffset(rx_rate, qwBSSTimestamp, local_tsf); /* adjust TSF, HW's TSF add TSF Offset reg */ qwTSFOffset = le64_to_cpu(qwTSFOffset); @@ -356,7 +356,7 @@ void CARDbRadioPowerOff(struct vnt_private *priv) if (priv->radio_off) return; - switch (priv->byRFType) { + switch (priv->rf_type) { case RF_RFMD2959: vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV); @@ -536,7 +536,7 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, * * Return Value: None. */ -void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type) +void card_set_rspinf(struct vnt_private *priv, u8 bb_type) { union vnt_phy_field_swap phy; unsigned char byTxRate, byRsvTime; /* For OFDM */ @@ -585,58 +585,58 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type) iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11); /* RSPINF_a_6 */ - s_vCalculateOFDMRParameter(RATE_6M, + calculate_ofdmr_parameter(RATE_6M, bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6); /* RSPINF_a_9 */ - s_vCalculateOFDMRParameter(RATE_9M, + calculate_ofdmr_parameter(RATE_9M, bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9); /* RSPINF_a_12 */ - s_vCalculateOFDMRParameter(RATE_12M, + calculate_ofdmr_parameter(RATE_12M, bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12); /* RSPINF_a_18 */ - s_vCalculateOFDMRParameter(RATE_18M, + calculate_ofdmr_parameter(RATE_18M, bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18); /* RSPINF_a_24 */ - s_vCalculateOFDMRParameter(RATE_24M, + calculate_ofdmr_parameter(RATE_24M, bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24); /* RSPINF_a_36 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, + calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, RATE_36M), bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36); /* RSPINF_a_48 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, + calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, RATE_48M), bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48); /* RSPINF_a_54 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, + calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M), bb_type, &byTxRate, &byRsvTime); iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54); /* RSPINF_a_72 */ - s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, + calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M), bb_type, &byTxRate, @@ -684,7 +684,7 @@ bool CARDbIsOFDMinBasicRate(struct vnt_private *priv) return false; } -unsigned char CARDbyGetPktType(struct vnt_private *priv) +unsigned char card_get_pkt_type(struct vnt_private *priv) { if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) return (unsigned char)priv->byBBType; @@ -708,11 +708,11 @@ unsigned char CARDbyGetPktType(struct vnt_private *priv) * * Return Value: TSF Offset value */ -u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) +u64 CARDqGetTSFOffset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2) { unsigned short wRxBcnTSFOffst; - wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE]; + wRxBcnTSFOffst = rx_bcn_tsf_off[rx_rate % MAX_RATE]; qwTSF2 += (u64)wRxBcnTSFOffst; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 22dc359a6565..19689a291f5b 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -39,7 +39,7 @@ struct vnt_private; -void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type); +void card_set_rspinf(struct vnt_private *priv, u8 bb_type); void CARDvUpdateBasicTopRate(struct vnt_private *priv); bool CARDbIsOFDMinBasicRate(struct vnt_private *priv); void CARDvSetFirstNextTBTT(struct vnt_private *priv, @@ -48,13 +48,13 @@ void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, unsigned short wBeaconInterval); u64 vt6655_get_current_tsf(struct vnt_private *priv); u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval); -u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2); -unsigned char CARDbyGetPktType(struct vnt_private *priv); +u64 CARDqGetTSFOffset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2); +unsigned char card_get_pkt_type(struct vnt_private *priv); void CARDvSafeResetTx(struct vnt_private *priv); void CARDvSafeResetRx(struct vnt_private *priv); void CARDbRadioPowerOff(struct vnt_private *priv); -bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type); -bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate, +bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type); +bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate, u64 qwBSSTimestamp); bool CARDbSetBeaconPeriod(struct vnt_private *priv, unsigned short wBeaconInterval); diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 4122875ebcaa..771c1364b0f0 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -82,15 +82,15 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch) { bool ret = true; - if (priv->byCurrentCh == ch->hw_value) + if (priv->current_ch == ch->hw_value) return ret; /* Set VGA to max sensitivity */ - if (priv->bUpdateBBVGA && - priv->byBBVGACurrent != priv->abyBBVGA[0]) { - priv->byBBVGACurrent = priv->abyBBVGA[0]; + if (priv->update_bbvga && + priv->bbvga_current != priv->bbvga[0]) { + priv->bbvga_current = priv->bbvga[0]; - bb_set_vga_gain_offset(priv, priv->byBBVGACurrent); + bb_set_vga_gain_offset(priv, priv->bbvga_current); } /* clear NAV */ @@ -100,13 +100,13 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch) * it is for better TX throughput */ - priv->byCurrentCh = ch->hw_value; - ret &= RFbSelectChannel(priv, priv->byRFType, + priv->current_ch = ch->hw_value; + ret &= RFbSelectChannel(priv, priv->rf_type, ch->hw_value); /* Init Synthesizer Table */ if (priv->bEnablePSMode) - rf_write_wake_prog_syn(priv, priv->byRFType, ch->hw_value); + rf_write_wake_prog_syn(priv, priv->rf_type, ch->hw_value); bb_software_reset(priv); @@ -117,19 +117,19 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch) /* set HW default power register */ VT6655_MAC_SELECT_PAGE1(priv->port_offset); - RFbSetPower(priv, RATE_1M, priv->byCurrentCh); - iowrite8(priv->byCurPwr, priv->port_offset + MAC_REG_PWRCCK); - RFbSetPower(priv, RATE_6M, priv->byCurrentCh); - iowrite8(priv->byCurPwr, priv->port_offset + MAC_REG_PWROFDM); + RFbSetPower(priv, RATE_1M, priv->current_ch); + iowrite8(priv->cur_pwr, priv->port_offset + MAC_REG_PWRCCK); + RFbSetPower(priv, RATE_6M, priv->current_ch); + iowrite8(priv->cur_pwr, priv->port_offset + MAC_REG_PWROFDM); VT6655_MAC_SELECT_PAGE0(priv->port_offset); spin_unlock_irqrestore(&priv->lock, flags); } if (priv->byBBType == BB_TYPE_11B) - RFbSetPower(priv, RATE_1M, priv->byCurrentCh); + RFbSetPower(priv, RATE_1M, priv->current_ch); else - RFbSetPower(priv, RATE_6M, priv->byCurrentCh); + RFbSetPower(priv, RATE_6M, priv->current_ch); return ret; } diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index c272a4ab2fa0..d9ee0b7401fe 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -153,7 +153,7 @@ struct vnt_private { /* Version control */ unsigned char local_id; - unsigned char byRFType; + unsigned char rf_type; unsigned char max_pwr_level; unsigned char byZoneType; @@ -181,14 +181,14 @@ struct vnt_private { unsigned int uCwMin; /* Current CwMin */ unsigned int uCwMax; /* CwMax is fixed on 1023. */ /* PHY parameter */ - unsigned char bySIFS; - unsigned char byDIFS; - unsigned char byEIFS; - unsigned char bySlot; - unsigned char byCWMaxMin; + unsigned char sifs; + unsigned char difs; + unsigned char eifs; + unsigned char slot; + unsigned char cw_max_min; u8 byBBType; /* 0:11A, 1:11B, 2:11G */ - u8 byPacketType; /* + u8 packet_type; /* * 0:11a,1:11b,2:11gb (only CCK * in BasicRate), 3:11ga (OFDM in * Basic Rate) @@ -239,21 +239,21 @@ struct vnt_private { bool bIsBeaconBufReadySet; unsigned int cbBeaconBufReadySetCnt; bool bFixRate; - u16 byCurrentCh; + u16 current_ch; bool bAES; unsigned char byAutoFBCtrl; /* For Update BaseBand VGA Gain Offset */ - bool bUpdateBBVGA; + bool update_bbvga; unsigned int uBBVGADiffCount; - unsigned char byBBVGANew; - unsigned char byBBVGACurrent; - unsigned char abyBBVGA[BB_VGA_LEVEL]; + unsigned char bbvga_new; + unsigned char bbvga_current; + unsigned char bbvga[BB_VGA_LEVEL]; long dbm_threshold[BB_VGA_LEVEL]; - unsigned char byBBPreEDRSSI; + unsigned char bb_pre_edrssi; unsigned char byBBPreEDIndex; unsigned long dwDiagRefCount; @@ -264,7 +264,7 @@ struct vnt_private { /* For RF Power table */ unsigned char byCCKPwr; unsigned char byOFDMPwrG; - unsigned char byCurPwr; + unsigned char cur_pwr; char byCurPwrdBm; unsigned char abyCCKPwrTbl[CB_MAX_CHANNEL_24G + 1]; unsigned char abyOFDMPwrTbl[CB_MAX_CHANNEL + 1]; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 45e5eccadb44..7d297526e653 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -177,9 +177,9 @@ device_set_options(struct vnt_private *priv) priv->byShortRetryLimit = priv->opts.short_retry; priv->byLongRetryLimit = priv->opts.long_retry; priv->byBBType = priv->opts.bbp_type; - priv->byPacketType = priv->byBBType; + priv->packet_type = priv->byBBType; priv->byAutoFBCtrl = AUTO_FB_0; - priv->bUpdateBBVGA = true; + priv->update_bbvga = true; priv->preamble_type = 0; pr_debug(" byShortRetryLimit= %d\n", (int)priv->byShortRetryLimit); @@ -359,7 +359,7 @@ static void device_init_registers(struct vnt_private *priv) RFbInit(priv); /* Get Desire Power Value */ - priv->byCurPwr = 0xFF; + priv->cur_pwr = 0xFF; priv->byCCKPwr = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_PWR_CCK); priv->byOFDMPwrG = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_PWR_OFDMG); @@ -423,10 +423,10 @@ static void device_init_registers(struct vnt_private *priv) /* initialize BBP registers */ bb_vt3253_init(priv); - if (priv->bUpdateBBVGA) { - priv->byBBVGACurrent = priv->abyBBVGA[0]; - priv->byBBVGANew = priv->byBBVGACurrent; - bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]); + if (priv->update_bbvga) { + priv->bbvga_current = priv->bbvga[0]; + priv->bbvga_new = priv->bbvga_current; + bb_set_vga_gain_offset(priv, priv->bbvga[0]); } bb_set_rx_antenna_mode(priv, priv->byRxAntennaMode); @@ -1040,7 +1040,7 @@ static void vnt_check_bb_vga(struct vnt_private *priv) long dbm; int i; - if (!priv->bUpdateBBVGA) + if (!priv->update_bbvga) return; if (priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) @@ -1053,12 +1053,12 @@ static void vnt_check_bb_vga(struct vnt_private *priv) for (i = 0; i < BB_VGA_LEVEL; i++) { if (dbm < priv->dbm_threshold[i]) { - priv->byBBVGANew = priv->abyBBVGA[i]; + priv->bbvga_new = priv->bbvga[i]; break; } } - if (priv->byBBVGANew == priv->byBBVGACurrent) { + if (priv->bbvga_new == priv->bbvga_current) { priv->uBBVGADiffCount = 1; return; } @@ -1067,23 +1067,23 @@ static void vnt_check_bb_vga(struct vnt_private *priv) if (priv->uBBVGADiffCount == 1) { /* first VGA diff gain */ - bb_set_vga_gain_offset(priv, priv->byBBVGANew); + bb_set_vga_gain_offset(priv, priv->bbvga_new); dev_dbg(&priv->pcid->dev, "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)dbm, priv->byBBVGANew, - priv->byBBVGACurrent, + (int)dbm, priv->bbvga_new, + priv->bbvga_current, (int)priv->uBBVGADiffCount); } if (priv->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) { dev_dbg(&priv->pcid->dev, "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)dbm, priv->byBBVGANew, - priv->byBBVGACurrent, + (int)dbm, priv->bbvga_new, + priv->bbvga_current, (int)priv->uBBVGADiffCount); - bb_set_vga_gain_offset(priv, priv->byBBVGANew); + bb_set_vga_gain_offset(priv, priv->bbvga_new); } } @@ -1442,7 +1442,7 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed) if (priv->byBBType != bb_type) { priv->byBBType = bb_type; - CARDbSetPhyParameter(priv, priv->byBBType); + card_set_phy_parameter(priv, priv->byBBType); } } @@ -1509,8 +1509,8 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, else priv->short_slot_time = false; - CARDbSetPhyParameter(priv, priv->byBBType); - bb_set_vga_gain_offset(priv, priv->abyBBVGA[0]); + card_set_phy_parameter(priv, priv->byBBType); + bb_set_vga_gain_offset(priv, priv->bbvga[0]); } if (changed & BSS_CHANGED_TXPOWER) @@ -1534,7 +1534,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) && priv->op_mode != NL80211_IFTYPE_AP) { if (vif->cfg.assoc && conf->beacon_rate) { - CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, + card_update_tsf(priv, conf->beacon_rate->hw_value, conf->sync_tsf); CARDbSetBeaconPeriod(priv, conf->beacon_int); @@ -1792,10 +1792,10 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) vt6655_mac_read_ether_addr(priv->port_offset, priv->abyCurrentNetAddr); /* Get RFType */ - priv->byRFType = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_RFTYPE); - priv->byRFType &= RF_MASK; + priv->rf_type = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_RFTYPE); + priv->rf_type &= RF_MASK; - dev_dbg(&pcid->dev, "RF Type = %x\n", priv->byRFType); + dev_dbg(&pcid->dev, "RF Type = %x\n", priv->rf_type); device_get_options(priv); device_set_options(priv); diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index c6ed3537f439..7ada188e2048 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -79,7 +79,7 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, RFvRSSITodBm(priv, *rssi, &rx_dbm); - priv->byBBPreEDRSSI = (u8)rx_dbm + 1; + priv->bb_pre_edrssi = (u8)rx_dbm + 1; priv->current_rssi = *rssi; skb_pull(skb, 4); diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 1fadc2fc4412..d319ec21c97b 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -268,7 +268,7 @@ static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byCha * Parameters: * In: * byBBType - * byRFType + * rf_type * Out: * none * @@ -279,7 +279,7 @@ bool RFbInit(struct vnt_private *priv) { bool ret = true; - switch (priv->byRFType) { + switch (priv->rf_type) { case RF_AIROHA: case RF_AL2230S: priv->max_pwr_level = AL2230_PWR_IDX_LEN; @@ -300,7 +300,7 @@ bool RFbInit(struct vnt_private *priv) * * Parameters: * In: - * byRFType + * rf_type * byChannel - Channel number * Out: * none @@ -308,12 +308,12 @@ bool RFbInit(struct vnt_private *priv) * Return Value: true if succeeded; false if failed. * */ -bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, +bool RFbSelectChannel(struct vnt_private *priv, unsigned char rf_type, u16 byChannel) { bool ret = true; - switch (byRFType) { + switch (rf_type) { case RF_AIROHA: case RF_AL2230S: ret = RFbAL2230SelectChannel(priv, byChannel); @@ -438,12 +438,12 @@ bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH) break; } - if (priv->byCurPwr == byPwr) + if (priv->cur_pwr == byPwr) return true; ret = RFbRawSetPower(priv, byPwr, rate); if (ret) - priv->byCurPwr = byPwr; + priv->cur_pwr = byPwr; return ret; } @@ -470,7 +470,7 @@ bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr, if (byPwr >= priv->max_pwr_level) return false; - switch (priv->byRFType) { + switch (priv->rf_type) { case RF_AIROHA: ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]); if (rate <= RATE_11M) @@ -521,7 +521,7 @@ RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm) long a = 0; unsigned char abyAIROHARF[4] = {0, 18, 0, 40}; - switch (priv->byRFType) { + switch (priv->rf_type) { case RF_AIROHA: case RF_AL2230S: a = abyAIROHARF[byIdx]; diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index 9fef81846a9f..6f842ac00526 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -58,7 +58,7 @@ /*--------------------- Export Functions --------------------------*/ bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData); -bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, u16 byChannel); +bool RFbSelectChannel(struct vnt_private *priv, unsigned char rf_type, u16 byChannel); bool RFbInit(struct vnt_private *priv); bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type, u16 channel); bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH); diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 3e8c92675c82..35650f911ebc 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3194,7 +3194,7 @@ static void hfa384x_usbin_txcompl(struct wlandevice *wlandev, /* Was there an error? */ if (HFA384x_TXSTATUS_ISERROR(status)) - prism2sta_ev_txexc(wlandev, status); + netdev_dbg(wlandev->netdev, "TxExc status=0x%x.\n", status); else prism2sta_ev_tx(wlandev, status); } diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 048e1c3fe19b..8336435eccc2 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -312,8 +312,8 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, payload_length - 4); if (foo) { /* de-wep failed, drop skb. */ - pr_debug("Host de-WEP failed, dropping frame (%d).\n", - foo); + netdev_dbg(netdev, "Host de-WEP failed, dropping frame (%d).\n", + foo); wlandev->rx.decrypt_err++; return 2; } @@ -340,7 +340,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) && ((!ether_addr_equal_unaligned(daddr, e_hdr->daddr)) || (!ether_addr_equal_unaligned(saddr, e_hdr->saddr)))) { - pr_debug("802.3 ENCAP len: %d\n", payload_length); + netdev_dbg(netdev, "802.3 ENCAP len: %d\n", payload_length); /* 802.3 Encapsulated */ /* Test for an overlength frame */ if (payload_length > (netdev->mtu + ETH_HLEN)) { @@ -367,7 +367,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, (p80211_stt_findproto(be16_to_cpu(e_snap->type)))) || (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) != 0))) { - pr_debug("SNAP+RFC1042 len: %d\n", payload_length); + netdev_dbg(netdev, "SNAP+RFC1042 len: %d\n", payload_length); /* it's a SNAP + RFC1042 frame && protocol is in STT */ /* build 802.3 + RFC1042 */ @@ -397,7 +397,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa) && (e_llc->ctl == 0x03)) { - pr_debug("802.1h/RFC1042 len: %d\n", payload_length); + netdev_dbg(netdev, "802.1h/RFC1042 len: %d\n", payload_length); /* it's an 802.1h frame || (an RFC1042 && protocol not in STT) * build a DIXII + RFC894 */ @@ -433,7 +433,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, /* chop off the 802.11 CRC */ skb_trim(skb, skb->len - WLAN_CRC_LEN); } else { - pr_debug("NON-ENCAP len: %d\n", payload_length); + netdev_dbg(netdev, "NON-ENCAP len: %d\n", payload_length); /* any NON-ENCAP */ /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ /* build an 802.3 frame */ diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index f5186380b629..485f2c697f5f 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -114,9 +114,6 @@ struct p80211_frmrx { u32 decrypt_err; }; -/* called by /proc/net/wireless */ -struct iw_statistics *p80211wext_get_wireless_stats(struct net_device *dev); - /* WEP stuff */ #define NUM_WEPKEYS 4 #define MAX_KEYLEN 32 diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 5d03b2b9aab4..3ccd11041646 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -725,7 +725,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, if (j == -1) { /* plug the filename */ memset(dest, 0, s3plug[i].len); - strncpy(dest, PRISM2_USB_FWFILE, s3plug[i].len - 1); + strscpy(dest, PRISM2_USB_FWFILE, s3plug[i].len); } else { /* plug a PDR */ memcpy(dest, &pda->rec[j]->data, s3plug[i].len); } diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h index 083a055ee986..17222516e85e 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ b/drivers/staging/wlan-ng/prism2mgmt.h @@ -45,9 +45,7 @@ extern int prism2_reset_settletime; u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate); -void prism2sta_ev_info(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status); +void prism2sta_ev_info(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf); void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status); void prism2sta_ev_alloc(struct wlandevice *wlandev); @@ -78,14 +76,6 @@ void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr, void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr, struct p80211pstrd *pstr); -/* functions to convert Group Addresses */ -void prism2mgmt_get_grpaddr(u32 did, struct p80211pstrd *pstr, - struct hfa384x *priv); -int prism2mgmt_set_grpaddr(u32 did, - u8 *prism2buf, struct p80211pstrd *pstr, - struct hfa384x *priv); -int prism2mgmt_get_grpaddr_index(u32 did); - void prism2sta_processing_defer(struct work_struct *data); void prism2sta_commsqual_defer(struct work_struct *data); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 57180bb71699..cb6c7a9fb8f3 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -90,9 +90,6 @@ static int prism2sta_getcardinfo(struct wlandevice *wlandev); static int prism2sta_globalsetup(struct wlandevice *wlandev); static int prism2sta_setmulticast(struct wlandevice *wlandev, struct net_device *dev); - -static void prism2sta_inf_handover(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); static void prism2sta_inf_tallies(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf); static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, @@ -268,46 +265,50 @@ static int prism2sta_mlmerequest(struct wlandevice *wlandev, switch (msg->msgcode) { case DIDMSG_DOT11REQ_MIBGET: - pr_debug("Received mibget request\n"); + netdev_dbg(wlandev->netdev, "Received mibget request\n"); result = prism2mgmt_mibset_mibget(wlandev, msg); break; case DIDMSG_DOT11REQ_MIBSET: - pr_debug("Received mibset request\n"); + netdev_dbg(wlandev->netdev, "Received mibset request\n"); result = prism2mgmt_mibset_mibget(wlandev, msg); break; case DIDMSG_DOT11REQ_SCAN: - pr_debug("Received scan request\n"); + netdev_dbg(wlandev->netdev, "Received scan request\n"); result = prism2mgmt_scan(wlandev, msg); break; case DIDMSG_DOT11REQ_SCAN_RESULTS: - pr_debug("Received scan_results request\n"); + netdev_dbg(wlandev->netdev, "Received scan_results request\n"); result = prism2mgmt_scan_results(wlandev, msg); break; case DIDMSG_DOT11REQ_START: - pr_debug("Received mlme start request\n"); + netdev_dbg(wlandev->netdev, "Received mlme start request\n"); result = prism2mgmt_start(wlandev, msg); break; /* * Prism2 specific messages */ case DIDMSG_P2REQ_READPDA: - pr_debug("Received mlme readpda request\n"); + netdev_dbg(wlandev->netdev, "Received mlme readpda request\n"); result = prism2mgmt_readpda(wlandev, msg); break; case DIDMSG_P2REQ_RAMDL_STATE: - pr_debug("Received mlme ramdl_state request\n"); + netdev_dbg(wlandev->netdev, + "Received mlme ramdl_state request\n"); result = prism2mgmt_ramdl_state(wlandev, msg); break; case DIDMSG_P2REQ_RAMDL_WRITE: - pr_debug("Received mlme ramdl_write request\n"); + netdev_dbg(wlandev->netdev, + "Received mlme ramdl_write request\n"); result = prism2mgmt_ramdl_write(wlandev, msg); break; case DIDMSG_P2REQ_FLASHDL_STATE: - pr_debug("Received mlme flashdl_state request\n"); + netdev_dbg(wlandev->netdev, + "Received mlme flashdl_state request\n"); result = prism2mgmt_flashdl_state(wlandev, msg); break; case DIDMSG_P2REQ_FLASHDL_WRITE: - pr_debug("Received mlme flashdl_write request\n"); + netdev_dbg(wlandev->netdev, + "Received mlme flashdl_write request\n"); result = prism2mgmt_flashdl_write(wlandev, msg); break; /* @@ -318,7 +319,7 @@ static int prism2sta_mlmerequest(struct wlandevice *wlandev, case DIDMSG_LNXREQ_IFSTATE: { struct p80211msg_lnxreq_ifstate *ifstatemsg; - pr_debug("Received mlme ifstate request\n"); + netdev_dbg(wlandev->netdev, "Received mlme ifstate request\n"); ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg; result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data); @@ -329,17 +330,18 @@ static int prism2sta_mlmerequest(struct wlandevice *wlandev, break; } case DIDMSG_LNXREQ_WLANSNIFF: - pr_debug("Received mlme wlansniff request\n"); + netdev_dbg(wlandev->netdev, + "Received mlme wlansniff request\n"); result = prism2mgmt_wlansniff(wlandev, msg); break; case DIDMSG_LNXREQ_AUTOJOIN: - pr_debug("Received mlme autojoin request\n"); + netdev_dbg(wlandev->netdev, "Received mlme autojoin request\n"); result = prism2mgmt_autojoin(wlandev, msg); break; case DIDMSG_LNXREQ_COMMSQUALITY: { struct p80211msg_lnxreq_commsquality *qualmsg; - pr_debug("Received commsquality request\n"); + netdev_dbg(wlandev->netdev, "Received commsquality request\n"); qualmsg = (struct p80211msg_lnxreq_commsquality *)msg; @@ -392,8 +394,8 @@ u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate) result = P80211ENUM_resultcode_implementation_failure; - pr_debug("Current MSD state(%d), requesting(%d)\n", - wlandev->msdstate, ifstate); + netdev_dbg(wlandev->netdev, "Current MSD state(%d), requesting(%d)\n", + wlandev->msdstate, ifstate); switch (ifstate) { case P80211ENUM_ifstate_fwload: switch (wlandev->msdstate) { @@ -922,30 +924,6 @@ exit: return result; } -/* - * prism2sta_inf_handover - * - * Handles the receipt of a Handover info frame. Should only be present - * in APs only. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_handover(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - pr_debug("received infoframe:HANDOVER (unhandled)\n"); -} - /* * prism2sta_inf_tallies * @@ -1025,15 +1003,15 @@ static void prism2sta_inf_scanresults(struct wlandevice *wlandev, nbss /= sizeof(struct hfa384x_scan_result_sub); /* Print em */ - pr_debug("rx scanresults, reason=%d, nbss=%d:\n", - inf->info.scanresult.scanreason, nbss); + netdev_dbg(wlandev->netdev, "rx scanresults, reason=%d, nbss=%d:\n", + inf->info.scanresult.scanreason, nbss); for (i = 0; i < nbss; i++) { - pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n", - sr->result[i].chid, - sr->result[i].anl, - sr->result[i].sl, sr->result[i].bcnint); - pr_debug(" capinfo=0x%04x proberesp_rate=%d\n", - sr->result[i].capinfo, sr->result[i].proberesp_rate); + netdev_dbg(wlandev->netdev, "chid=%d anl=%d sl=%d bcnint=%d\n", + sr->result[i].chid, sr->result[i].anl, + sr->result[i].sl, sr->result[i].bcnint); + netdev_dbg(wlandev->netdev, + " capinfo=0x%04x proberesp_rate=%d\n", + sr->result[i].capinfo, sr->result[i].proberesp_rate); } /* issue a join request */ joinreq.channel = sr->result[0].chid; @@ -1071,7 +1049,7 @@ static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, int nbss; nbss = (inf->framelen - 3) / 32; - pr_debug("Received %d hostscan results\n", nbss); + netdev_dbg(wlandev->netdev, "Received %d hostscan results\n", nbss); if (nbss > 32) nbss = 32; @@ -1134,13 +1112,14 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, chinforesult->pnl = result->pnl; chinforesult->active = result->active; - pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", - chan + 1, - (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) - ? "signal" : "noise", - chinforesult->anl, chinforesult->pnl, - (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) - ? 1 : 0); + netdev_dbg(wlandev->netdev, + "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", + chan + 1, + (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) ? + "signal" : "noise", + chinforesult->anl, + chinforesult->pnl, + (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0); n++; } atomic_set(&hw->channel_info.done, 2); @@ -1219,9 +1198,9 @@ void prism2sta_processing_defer(struct work_struct *data) wlandev->bssid, WLAN_BSSID_LEN); if (result) { - pr_debug - ("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); return; } @@ -1229,9 +1208,9 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, &ssid, sizeof(ssid)); if (result) { - pr_debug - ("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); return; } prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, @@ -1242,9 +1221,9 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_PORTSTATUS, &portstatus); if (result) { - pr_debug - ("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_PORTSTATUS, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_PORTSTATUS, result); return; } wlandev->macmode = @@ -1302,8 +1281,9 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTBSSID, wlandev->bssid, WLAN_BSSID_LEN); if (result) { - pr_debug("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); return; } @@ -1311,8 +1291,9 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, &ssid, sizeof(ssid)); if (result) { - pr_debug("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); return; } prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, @@ -1724,7 +1705,8 @@ void prism2sta_ev_info(struct wlandevice *wlandev, /* Dispatch */ switch (inf->infotype) { case HFA384x_IT_HANDOVERADDR: - prism2sta_inf_handover(wlandev, inf); + netdev_dbg(wlandev->netdev, + "received infoframe:HANDOVER (unhandled)\n"); break; case HFA384x_IT_COMMTALLIES: prism2sta_inf_tallies(wlandev, inf); @@ -1766,30 +1748,6 @@ void prism2sta_ev_info(struct wlandevice *wlandev, } } -/* - * prism2sta_ev_txexc - * - * Handles the TxExc event. A Transmit Exception event indicates - * that the MAC's TX process was unsuccessful - so the packet did - * not get transmitted. - * - * Arguments: - * wlandev wlan device structure - * status tx frame status word - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status) -{ - pr_debug("TxExc status=0x%x.\n", status); -} - /* * prism2sta_ev_tx * @@ -1808,7 +1766,7 @@ void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status) */ void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status) { - pr_debug("Tx Complete, status=0x%04x\n", status); + netdev_dbg(wlandev->netdev, "Tx Complete, status=0x%04x\n", status); /* update linux network stats */ wlandev->netdev->stats.tx_packets++; } @@ -1917,10 +1875,10 @@ void prism2sta_commsqual_defer(struct work_struct *data) return; } - pr_debug("commsqual %d %d %d\n", - le16_to_cpu(hw->qual.cq_curr_bss), - le16_to_cpu(hw->qual.asl_curr_bss), - le16_to_cpu(hw->qual.anl_curr_fc)); + netdev_dbg(wlandev->netdev, "commsqual %d %d %d\n", + le16_to_cpu(hw->qual.cq_curr_bss), + le16_to_cpu(hw->qual.asl_curr_bss), + le16_to_cpu(hw->qual.anl_curr_fc)); } /* Get the signal rate */ @@ -1929,8 +1887,8 @@ void prism2sta_commsqual_defer(struct work_struct *data) result = p80211req_dorequest(wlandev, (u8 *)&msg); if (result) { - pr_debug("get signal rate failed, result = %d\n", - result); + netdev_dbg(wlandev->netdev, + "get signal rate failed, result = %d\n", result); return; } @@ -1948,7 +1906,8 @@ void prism2sta_commsqual_defer(struct work_struct *data) hw->txrate = 110; break; default: - pr_debug("Bad ratebit (%d)\n", mibitem->data); + netdev_dbg(wlandev->netdev, "Bad ratebit (%d)\n", + mibitem->data); } /* Lastly, we need to make sure the BSSID didn't change on us */ @@ -1956,8 +1915,9 @@ void prism2sta_commsqual_defer(struct work_struct *data) HFA384x_RID_CURRENTBSSID, wlandev->bssid, WLAN_BSSID_LEN); if (result) { - pr_debug("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); return; } @@ -1965,8 +1925,9 @@ void prism2sta_commsqual_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, &ssid, sizeof(ssid)); if (result) { - pr_debug("getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); + netdev_dbg(wlandev->netdev, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); return; } prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, diff --git a/drivers/thunderbolt/clx.c b/drivers/thunderbolt/clx.c index 13d217ae98e6..787dfd1550e5 100644 --- a/drivers/thunderbolt/clx.c +++ b/drivers/thunderbolt/clx.c @@ -174,6 +174,28 @@ bool tb_port_clx_is_enabled(struct tb_port *port, unsigned int clx) return !!(tb_port_clx(port) & clx); } +/** + * tb_switch_clx_is_supported() - Is CLx supported on this type of router + * @sw: The router to check CLx support for + */ +static bool tb_switch_clx_is_supported(const struct tb_switch *sw) +{ + if (!clx_enabled) + return false; + + if (sw->quirks & QUIRK_NO_CLX) + return false; + + /* + * CLx is not enabled and validated on Intel USB4 platforms + * before Alder Lake. + */ + if (tb_switch_is_tiger_lake(sw)) + return false; + + return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw); +} + /** * tb_switch_clx_init() - Initialize router CL states * @sw: Router @@ -273,28 +295,6 @@ static int tb_switch_mask_clx_objections(struct tb_switch *sw) sw->cap_lp + offset, ARRAY_SIZE(val)); } -/** - * tb_switch_clx_is_supported() - Is CLx supported on this type of router - * @sw: The router to check CLx support for - */ -bool tb_switch_clx_is_supported(const struct tb_switch *sw) -{ - if (!clx_enabled) - return false; - - if (sw->quirks & QUIRK_NO_CLX) - return false; - - /* - * CLx is not enabled and validated on Intel USB4 platforms - * before Alder Lake. - */ - if (tb_switch_is_tiger_lake(sw)) - return false; - - return tb_switch_is_usb4(sw) || tb_switch_is_titan_ridge(sw); -} - static bool validate_mask(unsigned int clx) { /* Previous states need to be enabled */ @@ -405,6 +405,9 @@ int tb_switch_clx_disable(struct tb_switch *sw) if (!clx) return 0; + if (sw->is_unplugged) + return clx; + up = tb_upstream_port(sw); down = tb_switch_downstream_port(sw); diff --git a/drivers/thunderbolt/dma_test.c b/drivers/thunderbolt/dma_test.c index 39476fc48801..9e47a63f28e7 100644 --- a/drivers/thunderbolt/dma_test.c +++ b/drivers/thunderbolt/dma_test.c @@ -101,7 +101,7 @@ struct dma_test { unsigned int packets_sent; unsigned int packets_received; unsigned int link_speed; - unsigned int link_width; + enum tb_link_width link_width; unsigned int crc_errors; unsigned int buffer_overflow_errors; enum dma_test_result result; @@ -465,9 +465,9 @@ DMA_TEST_DEBUGFS_ATTR(packets_to_send, packets_to_send_get, static int dma_test_set_bonding(struct dma_test *dt) { switch (dt->link_width) { - case 2: + case TB_LINK_WIDTH_DUAL: return tb_xdomain_lane_bonding_enable(dt->xd); - case 1: + case TB_LINK_WIDTH_SINGLE: tb_xdomain_lane_bonding_disable(dt->xd); fallthrough; default: @@ -490,12 +490,8 @@ static void dma_test_check_errors(struct dma_test *dt, int ret) if (!dt->error_code) { if (dt->link_speed && dt->xd->link_speed != dt->link_speed) { dt->error_code = DMA_TEST_SPEED_ERROR; - } else if (dt->link_width) { - const struct tb_xdomain *xd = dt->xd; - - if ((dt->link_width == 1 && xd->link_width != TB_LINK_WIDTH_SINGLE) || - (dt->link_width == 2 && xd->link_width < TB_LINK_WIDTH_DUAL)) - dt->error_code = DMA_TEST_WIDTH_ERROR; + } else if (dt->link_width && dt->link_width != dt->xd->link_width) { + dt->error_code = DMA_TEST_WIDTH_ERROR; } else if (dt->packets_to_send != dt->packets_sent || dt->packets_to_receive != dt->packets_received || dt->crc_errors || dt->buffer_overflow_errors) { diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index ee03fd75a472..091a81bbdbdc 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -19,9 +19,9 @@ static void tb_dump_hop(const struct tb_path_hop *hop, const struct tb_regs_hop tb_port_dbg(port, " In HopID: %d => Out port: %d Out HopID: %d\n", hop->in_hop_index, regs->out_port, regs->next_hop); - tb_port_dbg(port, " Weight: %d Priority: %d Credits: %d Drop: %d\n", - regs->weight, regs->priority, - regs->initial_credits, regs->drop_packages); + tb_port_dbg(port, " Weight: %d Priority: %d Credits: %d Drop: %d PM: %d\n", + regs->weight, regs->priority, regs->initial_credits, + regs->drop_packages, regs->pmps); tb_port_dbg(port, " Counter enabled: %d Counter index: %d\n", regs->counter_enable, regs->counter); tb_port_dbg(port, " Flow Control (In/Eg): %d/%d Shared Buffer (In/Eg): %d/%d\n", @@ -535,6 +535,7 @@ int tb_path_activate(struct tb_path *path) hop.next_hop = path->hops[i].next_hop_index; hop.out_port = path->hops[i].out_port->port; hop.initial_credits = path->hops[i].initial_credits; + hop.pmps = path->hops[i].pm_support; hop.unknown1 = 0; hop.enable = 1; diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c index 488138a28ae1..e6bfa63b40ae 100644 --- a/drivers/thunderbolt/quirks.c +++ b/drivers/thunderbolt/quirks.c @@ -31,6 +31,9 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw) { struct tb_port *port; + if (tb_switch_is_icm(sw)) + return; + tb_switch_for_each_port(sw, port) { if (!tb_port_is_usb3_down(port)) continue; diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c index 47becb363ada..d49d6628dbf2 100644 --- a/drivers/thunderbolt/retimer.c +++ b/drivers/thunderbolt/retimer.c @@ -94,6 +94,7 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt) goto err_nvm; rt->nvm = nvm; + dev_dbg(&rt->dev, "NVM version %x.%x\n", nvm->major, nvm->minor); return 0; err_nvm: diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index bd5815f8f23b..1e15ffa79295 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -372,6 +372,7 @@ static int tb_switch_nvm_add(struct tb_switch *sw) ret = tb_nvm_add_active(nvm, nvm_read); if (ret) goto err_nvm; + tb_sw_dbg(sw, "NVM version %x.%x\n", nvm->major, nvm->minor); } if (!sw->no_nvm_upgrade) { @@ -914,6 +915,48 @@ int tb_port_get_link_speed(struct tb_port *port) } } +/** + * tb_port_get_link_generation() - Returns link generation + * @port: Lane adapter + * + * Returns link generation as number or negative errno in case of + * failure. Does not distinguish between Thunderbolt 1 and Thunderbolt 2 + * links so for those always returns 2. + */ +int tb_port_get_link_generation(struct tb_port *port) +{ + int ret; + + ret = tb_port_get_link_speed(port); + if (ret < 0) + return ret; + + switch (ret) { + case 40: + return 4; + case 20: + return 3; + default: + return 2; + } +} + +static const char *width_name(enum tb_link_width width) +{ + switch (width) { + case TB_LINK_WIDTH_SINGLE: + return "symmetric, single lane"; + case TB_LINK_WIDTH_DUAL: + return "symmetric, dual lanes"; + case TB_LINK_WIDTH_ASYM_TX: + return "asymmetric, 3 transmitters, 1 receiver"; + case TB_LINK_WIDTH_ASYM_RX: + return "asymmetric, 3 receivers, 1 transmitter"; + default: + return "unknown"; + } +} + /** * tb_port_get_link_width() - Get current link width * @port: Port to check (USB4 or CIO) @@ -939,8 +982,15 @@ int tb_port_get_link_width(struct tb_port *port) LANE_ADP_CS_1_CURRENT_WIDTH_SHIFT; } -static bool tb_port_is_width_supported(struct tb_port *port, - unsigned int width_mask) +/** + * tb_port_width_supported() - Is the given link width supported + * @port: Port to check + * @width: Widths to check (bitmask) + * + * Can be called to any lane adapter. Checks if given @width is + * supported by the hardware and returns %true if it is. + */ +bool tb_port_width_supported(struct tb_port *port, unsigned int width) { u32 phy, widths; int ret; @@ -948,20 +998,23 @@ static bool tb_port_is_width_supported(struct tb_port *port, if (!port->cap_phy) return false; + if (width & (TB_LINK_WIDTH_ASYM_TX | TB_LINK_WIDTH_ASYM_RX)) { + if (tb_port_get_link_generation(port) < 4 || + !usb4_port_asym_supported(port)) + return false; + } + ret = tb_port_read(port, &phy, TB_CFG_PORT, port->cap_phy + LANE_ADP_CS_0, 1); if (ret) return false; - widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> - LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; - - return widths & width_mask; -} - -static bool is_gen4_link(struct tb_port *port) -{ - return tb_port_get_link_speed(port) > 20; + /* + * The field encoding is the same as &enum tb_link_width (which is + * passed to @width). + */ + widths = FIELD_GET(LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK, phy); + return widths & width; } /** @@ -991,15 +1044,23 @@ int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width) switch (width) { case TB_LINK_WIDTH_SINGLE: /* Gen 4 link cannot be single */ - if (is_gen4_link(port)) + if (tb_port_get_link_generation(port) >= 4) return -EOPNOTSUPP; val |= LANE_ADP_CS_1_TARGET_WIDTH_SINGLE << LANE_ADP_CS_1_TARGET_WIDTH_SHIFT; break; + case TB_LINK_WIDTH_DUAL: + if (tb_port_get_link_generation(port) >= 4) + return usb4_port_asym_set_link_width(port, width); val |= LANE_ADP_CS_1_TARGET_WIDTH_DUAL << LANE_ADP_CS_1_TARGET_WIDTH_SHIFT; break; + + case TB_LINK_WIDTH_ASYM_TX: + case TB_LINK_WIDTH_ASYM_RX: + return usb4_port_asym_set_link_width(port, width); + default: return -EINVAL; } @@ -1124,7 +1185,7 @@ void tb_port_lane_bonding_disable(struct tb_port *port) /** * tb_port_wait_for_link_width() - Wait until link reaches specific width * @port: Port to wait for - * @width_mask: Expected link width mask + * @width: Expected link width (bitmask) * @timeout_msec: Timeout in ms how long to wait * * Should be used after both ends of the link have been bonded (or @@ -1133,14 +1194,15 @@ void tb_port_lane_bonding_disable(struct tb_port *port) * within the given timeout, %0 if it did. Can be passed a mask of * expected widths and succeeds if any of the widths is reached. */ -int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, +int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width, int timeout_msec) { ktime_t timeout = ktime_add_ms(ktime_get(), timeout_msec); int ret; /* Gen 4 link does not support single lane */ - if ((width_mask & TB_LINK_WIDTH_SINGLE) && is_gen4_link(port)) + if ((width & TB_LINK_WIDTH_SINGLE) && + tb_port_get_link_generation(port) >= 4) return -EOPNOTSUPP; do { @@ -1153,7 +1215,7 @@ int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, */ if (ret != -EACCES) return ret; - } else if (ret & width_mask) { + } else if (ret & width) { return 0; } @@ -1332,7 +1394,7 @@ int tb_pci_port_enable(struct tb_port *port, bool enable) * tb_dp_port_hpd_is_active() - Is HPD already active * @port: DP out port to check * - * Checks if the DP OUT adapter port has HDP bit already set. + * Checks if the DP OUT adapter port has HPD bit already set. */ int tb_dp_port_hpd_is_active(struct tb_port *port) { @@ -1344,14 +1406,14 @@ int tb_dp_port_hpd_is_active(struct tb_port *port) if (ret) return ret; - return !!(data & ADP_DP_CS_2_HDP); + return !!(data & ADP_DP_CS_2_HPD); } /** * tb_dp_port_hpd_clear() - Clear HPD from DP IN port * @port: Port to clear HPD * - * If the DP IN port has HDP set, this function can be used to clear it. + * If the DP IN port has HPD set, this function can be used to clear it. */ int tb_dp_port_hpd_clear(struct tb_port *port) { @@ -1363,7 +1425,7 @@ int tb_dp_port_hpd_clear(struct tb_port *port) if (ret) return ret; - data |= ADP_DP_CS_3_HDPC; + data |= ADP_DP_CS_3_HPDC; return tb_port_write(port, &data, TB_CFG_PORT, port->cap_adap + ADP_DP_CS_3, 1); } @@ -2697,6 +2759,38 @@ static int tb_switch_update_link_attributes(struct tb_switch *sw) return 0; } +/* Must be called after tb_switch_update_link_attributes() */ +static void tb_switch_link_init(struct tb_switch *sw) +{ + struct tb_port *up, *down; + bool bonded; + + if (!tb_route(sw) || tb_switch_is_icm(sw)) + return; + + tb_sw_dbg(sw, "current link speed %u.0 Gb/s\n", sw->link_speed); + tb_sw_dbg(sw, "current link width %s\n", width_name(sw->link_width)); + + bonded = sw->link_width >= TB_LINK_WIDTH_DUAL; + + /* + * Gen 4 links come up as bonded so update the port structures + * accordingly. + */ + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + up->bonded = bonded; + if (up->dual_link_port) + up->dual_link_port->bonded = bonded; + tb_port_update_credits(up); + + down->bonded = bonded; + if (down->dual_link_port) + down->dual_link_port->bonded = bonded; + tb_port_update_credits(down); +} + /** * tb_switch_lane_bonding_enable() - Enable lane bonding * @sw: Switch to enable lane bonding @@ -2705,24 +2799,20 @@ static int tb_switch_update_link_attributes(struct tb_switch *sw) * switch. If conditions are correct and both switches support the feature, * lanes are bonded. It is safe to call this to any switch. */ -int tb_switch_lane_bonding_enable(struct tb_switch *sw) +static int tb_switch_lane_bonding_enable(struct tb_switch *sw) { struct tb_port *up, *down; - u64 route = tb_route(sw); - unsigned int width_mask; + unsigned int width; int ret; - if (!route) - return 0; - if (!tb_switch_lane_bonding_possible(sw)) return 0; up = tb_upstream_port(sw); down = tb_switch_downstream_port(sw); - if (!tb_port_is_width_supported(up, TB_LINK_WIDTH_DUAL) || - !tb_port_is_width_supported(down, TB_LINK_WIDTH_DUAL)) + if (!tb_port_width_supported(up, TB_LINK_WIDTH_DUAL) || + !tb_port_width_supported(down, TB_LINK_WIDTH_DUAL)) return 0; /* @@ -2746,21 +2836,10 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw) } /* Any of the widths are all bonded */ - width_mask = TB_LINK_WIDTH_DUAL | TB_LINK_WIDTH_ASYM_TX | - TB_LINK_WIDTH_ASYM_RX; + width = TB_LINK_WIDTH_DUAL | TB_LINK_WIDTH_ASYM_TX | + TB_LINK_WIDTH_ASYM_RX; - ret = tb_port_wait_for_link_width(down, width_mask, 100); - if (ret) { - tb_port_warn(down, "timeout enabling lane bonding\n"); - return ret; - } - - tb_port_update_credits(down); - tb_port_update_credits(up); - tb_switch_update_link_attributes(sw); - - tb_sw_dbg(sw, "lane bonding enabled\n"); - return ret; + return tb_port_wait_for_link_width(down, width, 100); } /** @@ -2770,20 +2849,27 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw) * Disables lane bonding between @sw and parent. This can be called even * if lanes were not bonded originally. */ -void tb_switch_lane_bonding_disable(struct tb_switch *sw) +static int tb_switch_lane_bonding_disable(struct tb_switch *sw) { struct tb_port *up, *down; int ret; - if (!tb_route(sw)) - return; - up = tb_upstream_port(sw); if (!up->bonded) - return; + return 0; + + /* + * If the link is Gen 4 there is no way to switch the link to + * two single lane links so avoid that here. Also don't bother + * if the link is not up anymore (sw is unplugged). + */ + ret = tb_port_get_link_generation(up); + if (ret < 0) + return ret; + if (ret >= 4) + return -EOPNOTSUPP; down = tb_switch_downstream_port(sw); - tb_port_lane_bonding_disable(up); tb_port_lane_bonding_disable(down); @@ -2791,15 +2877,160 @@ void tb_switch_lane_bonding_disable(struct tb_switch *sw) * It is fine if we get other errors as the router might have * been unplugged. */ - ret = tb_port_wait_for_link_width(down, TB_LINK_WIDTH_SINGLE, 100); - if (ret == -ETIMEDOUT) - tb_sw_warn(sw, "timeout disabling lane bonding\n"); + return tb_port_wait_for_link_width(down, TB_LINK_WIDTH_SINGLE, 100); +} + +static int tb_switch_asym_enable(struct tb_switch *sw, enum tb_link_width width) +{ + struct tb_port *up, *down, *port; + enum tb_link_width down_width; + int ret; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + if (width == TB_LINK_WIDTH_ASYM_TX) { + down_width = TB_LINK_WIDTH_ASYM_RX; + port = down; + } else { + down_width = TB_LINK_WIDTH_ASYM_TX; + port = up; + } + + ret = tb_port_set_link_width(up, width); + if (ret) + return ret; + + ret = tb_port_set_link_width(down, down_width); + if (ret) + return ret; + + /* + * Initiate the change in the router that one of its TX lanes is + * changing to RX but do so only if there is an actual change. + */ + if (sw->link_width != width) { + ret = usb4_port_asym_start(port); + if (ret) + return ret; + + ret = tb_port_wait_for_link_width(up, width, 100); + if (ret) + return ret; + } + + sw->link_width = width; + return 0; +} + +static int tb_switch_asym_disable(struct tb_switch *sw) +{ + struct tb_port *up, *down; + int ret; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + ret = tb_port_set_link_width(up, TB_LINK_WIDTH_DUAL); + if (ret) + return ret; + + ret = tb_port_set_link_width(down, TB_LINK_WIDTH_DUAL); + if (ret) + return ret; + + /* + * Initiate the change in the router that has three TX lanes and + * is changing one of its TX lanes to RX but only if there is a + * change in the link width. + */ + if (sw->link_width > TB_LINK_WIDTH_DUAL) { + if (sw->link_width == TB_LINK_WIDTH_ASYM_TX) + ret = usb4_port_asym_start(up); + else + ret = usb4_port_asym_start(down); + if (ret) + return ret; + + ret = tb_port_wait_for_link_width(up, TB_LINK_WIDTH_DUAL, 100); + if (ret) + return ret; + } + + sw->link_width = TB_LINK_WIDTH_DUAL; + return 0; +} + +/** + * tb_switch_set_link_width() - Configure router link width + * @sw: Router to configure + * @width: The new link width + * + * Set device router link width to @width from router upstream port + * perspective. Supports also asymmetric links if the routers boths side + * of the link supports it. + * + * Does nothing for host router. + * + * Returns %0 in case of success, negative errno otherwise. + */ +int tb_switch_set_link_width(struct tb_switch *sw, enum tb_link_width width) +{ + struct tb_port *up, *down; + int ret = 0; + + if (!tb_route(sw)) + return 0; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + switch (width) { + case TB_LINK_WIDTH_SINGLE: + ret = tb_switch_lane_bonding_disable(sw); + break; + + case TB_LINK_WIDTH_DUAL: + if (sw->link_width == TB_LINK_WIDTH_ASYM_TX || + sw->link_width == TB_LINK_WIDTH_ASYM_RX) { + ret = tb_switch_asym_disable(sw); + if (ret) + break; + } + ret = tb_switch_lane_bonding_enable(sw); + break; + + case TB_LINK_WIDTH_ASYM_TX: + case TB_LINK_WIDTH_ASYM_RX: + ret = tb_switch_asym_enable(sw, width); + break; + } + + switch (ret) { + case 0: + break; + + case -ETIMEDOUT: + tb_sw_warn(sw, "timeout changing link width\n"); + return ret; + + case -ENOTCONN: + case -EOPNOTSUPP: + case -ENODEV: + return ret; + + default: + tb_sw_dbg(sw, "failed to change link width: %d\n", ret); + return ret; + } tb_port_update_credits(down); tb_port_update_credits(up); + tb_switch_update_link_attributes(sw); - tb_sw_dbg(sw, "lane bonding disabled\n"); + tb_sw_dbg(sw, "link width set to %s\n", width_name(width)); + return ret; } /** @@ -2959,6 +3190,8 @@ int tb_switch_add(struct tb_switch *sw) if (ret) return ret; + tb_switch_link_init(sw); + ret = tb_switch_clx_init(sw); if (ret) return ret; diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 27bd6ca6f99e..5acdeb766860 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -16,8 +16,31 @@ #include "tb_regs.h" #include "tunnel.h" -#define TB_TIMEOUT 100 /* ms */ -#define MAX_GROUPS 7 /* max Group_ID is 7 */ +#define TB_TIMEOUT 100 /* ms */ + +/* + * Minimum bandwidth (in Mb/s) that is needed in the single transmitter/receiver + * direction. This is 40G - 10% guard band bandwidth. + */ +#define TB_ASYM_MIN (40000 * 90 / 100) + +/* + * Threshold bandwidth (in Mb/s) that is used to switch the links to + * asymmetric and back. This is selected as 45G which means when the + * request is higher than this, we switch the link to asymmetric, and + * when it is less than this we switch it back. The 45G is selected so + * that we still have 27G (of the total 72G) for bulk PCIe traffic when + * switching back to symmetric. + */ +#define TB_ASYM_THRESHOLD 45000 + +#define MAX_GROUPS 7 /* max Group_ID is 7 */ + +static unsigned int asym_threshold = TB_ASYM_THRESHOLD; +module_param_named(asym_threshold, asym_threshold, uint, 0444); +MODULE_PARM_DESC(asym_threshold, + "threshold (Mb/s) when to Gen 4 switch link symmetry. 0 disables. (default: " + __MODULE_STRING(TB_ASYM_THRESHOLD) ")"); /** * struct tb_cm - Simple Thunderbolt connection manager @@ -190,7 +213,7 @@ static void tb_add_dp_resources(struct tb_switch *sw) if (!tb_switch_query_dp_resource(sw, port)) continue; - list_add_tail(&port->list, &tcm->dp_resources); + list_add(&port->list, &tcm->dp_resources); tb_port_dbg(port, "DP IN resource available\n"); } } @@ -255,13 +278,13 @@ static int tb_enable_clx(struct tb_switch *sw) * this in the future to cover the whole topology if it turns * out to be beneficial. */ - while (sw && sw->config.depth > 1) + while (sw && tb_switch_depth(sw) > 1) sw = tb_switch_parent(sw); if (!sw) return 0; - if (sw->config.depth != 1) + if (tb_switch_depth(sw) != 1) return 0; /* @@ -285,14 +308,32 @@ static int tb_enable_clx(struct tb_switch *sw) return ret == -EOPNOTSUPP ? 0 : ret; } -/* Disables CL states up to the host router */ -static void tb_disable_clx(struct tb_switch *sw) +/** + * tb_disable_clx() - Disable CL states up to host router + * @sw: Router to start + * + * Disables CL states from @sw up to the host router. Returns true if + * any CL state were disabled. This can be used to figure out whether + * the link was setup by us or the boot firmware so we don't + * accidentally enable them if they were not enabled during discovery. + */ +static bool tb_disable_clx(struct tb_switch *sw) { + bool disabled = false; + do { - if (tb_switch_clx_disable(sw) < 0) + int ret; + + ret = tb_switch_clx_disable(sw); + if (ret > 0) + disabled = true; + else if (ret < 0) tb_sw_warn(sw, "failed to disable CL states\n"); + sw = tb_switch_parent(sw); } while (sw); + + return disabled; } static int tb_increase_switch_tmu_accuracy(struct device *dev, void *data) @@ -553,7 +594,7 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb, struct tb_switch *sw; /* Pick the router that is deepest in the topology */ - if (dst_port->sw->config.depth > src_port->sw->config.depth) + if (tb_port_path_direction_downstream(src_port, dst_port)) sw = dst_port->sw; else sw = src_port->sw; @@ -572,133 +613,294 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb, return tb_find_tunnel(tb, TB_TUNNEL_USB3, usb3_down, NULL); } -static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, - struct tb_port *dst_port, int *available_up, int *available_down) +/** + * tb_consumed_usb3_pcie_bandwidth() - Consumed USB3/PCIe bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the consumed bandwidth is calculated + * @consumed_up: Consumed upsream bandwidth (Mb/s) + * @consumed_down: Consumed downstream bandwidth (Mb/s) + * + * Calculates consumed USB3 and PCIe bandwidth at @port between path + * from @src_port to @dst_port. Does not take tunnel starting from + * @src_port and ending from @src_port into account. + */ +static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb, + struct tb_port *src_port, + struct tb_port *dst_port, + struct tb_port *port, + int *consumed_up, + int *consumed_down) { - int usb3_consumed_up, usb3_consumed_down, ret; - struct tb_cm *tcm = tb_priv(tb); + int pci_consumed_up, pci_consumed_down; struct tb_tunnel *tunnel; - struct tb_port *port; - tb_dbg(tb, "calculating available bandwidth between %llx:%u <-> %llx:%u\n", - tb_route(src_port->sw), src_port->port, tb_route(dst_port->sw), - dst_port->port); + *consumed_up = *consumed_down = 0; tunnel = tb_find_first_usb3_tunnel(tb, src_port, dst_port); if (tunnel && tunnel->src_port != src_port && tunnel->dst_port != dst_port) { - ret = tb_tunnel_consumed_bandwidth(tunnel, &usb3_consumed_up, - &usb3_consumed_down); + int ret; + + ret = tb_tunnel_consumed_bandwidth(tunnel, consumed_up, + consumed_down); if (ret) return ret; - } else { - usb3_consumed_up = 0; - usb3_consumed_down = 0; } + /* + * If there is anything reserved for PCIe bulk traffic take it + * into account here too. + */ + if (tb_tunnel_reserved_pci(port, &pci_consumed_up, &pci_consumed_down)) { + *consumed_up += pci_consumed_up; + *consumed_down += pci_consumed_down; + } + + return 0; +} + +/** + * tb_consumed_dp_bandwidth() - Consumed DP bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the consumed bandwidth is calculated + * @consumed_up: Consumed upsream bandwidth (Mb/s) + * @consumed_down: Consumed downstream bandwidth (Mb/s) + * + * Calculates consumed DP bandwidth at @port between path from @src_port + * to @dst_port. Does not take tunnel starting from @src_port and ending + * from @src_port into account. + */ +static int tb_consumed_dp_bandwidth(struct tb *tb, + struct tb_port *src_port, + struct tb_port *dst_port, + struct tb_port *port, + int *consumed_up, + int *consumed_down) +{ + struct tb_cm *tcm = tb_priv(tb); + struct tb_tunnel *tunnel; + int ret; + + *consumed_up = *consumed_down = 0; + + /* + * Find all DP tunnels that cross the port and reduce + * their consumed bandwidth from the available. + */ + list_for_each_entry(tunnel, &tcm->tunnel_list, list) { + int dp_consumed_up, dp_consumed_down; + + if (tb_tunnel_is_invalid(tunnel)) + continue; + + if (!tb_tunnel_is_dp(tunnel)) + continue; + + if (!tb_tunnel_port_on_path(tunnel, port)) + continue; + + /* + * Ignore the DP tunnel between src_port and dst_port + * because it is the same tunnel and we may be + * re-calculating estimated bandwidth. + */ + if (tunnel->src_port == src_port && + tunnel->dst_port == dst_port) + continue; + + ret = tb_tunnel_consumed_bandwidth(tunnel, &dp_consumed_up, + &dp_consumed_down); + if (ret) + return ret; + + *consumed_up += dp_consumed_up; + *consumed_down += dp_consumed_down; + } + + return 0; +} + +static bool tb_asym_supported(struct tb_port *src_port, struct tb_port *dst_port, + struct tb_port *port) +{ + bool downstream = tb_port_path_direction_downstream(src_port, dst_port); + enum tb_link_width width; + + if (tb_is_upstream_port(port)) + width = downstream ? TB_LINK_WIDTH_ASYM_RX : TB_LINK_WIDTH_ASYM_TX; + else + width = downstream ? TB_LINK_WIDTH_ASYM_TX : TB_LINK_WIDTH_ASYM_RX; + + return tb_port_width_supported(port, width); +} + +/** + * tb_maximum_bandwidth() - Maximum bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the total bandwidth is calculated + * @max_up: Maximum upstream bandwidth (Mb/s) + * @max_down: Maximum downstream bandwidth (Mb/s) + * @include_asym: Include bandwidth if the link is switched from + * symmetric to asymmetric + * + * Returns maximum possible bandwidth in @max_up and @max_down over a + * single link at @port. If @include_asym is set then includes the + * additional banwdith if the links are transitioned into asymmetric to + * direction from @src_port to @dst_port. + */ +static int tb_maximum_bandwidth(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, struct tb_port *port, + int *max_up, int *max_down, bool include_asym) +{ + bool downstream = tb_port_path_direction_downstream(src_port, dst_port); + int link_speed, link_width, up_bw, down_bw; + + /* + * Can include asymmetric, only if it is actually supported by + * the lane adapter. + */ + if (!tb_asym_supported(src_port, dst_port, port)) + include_asym = false; + + if (tb_is_upstream_port(port)) { + link_speed = port->sw->link_speed; + /* + * sw->link_width is from upstream perspective so we use + * the opposite for downstream of the host router. + */ + if (port->sw->link_width == TB_LINK_WIDTH_ASYM_TX) { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } else if (port->sw->link_width == TB_LINK_WIDTH_ASYM_RX) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else if (include_asym) { + /* + * The link is symmetric at the moment but we + * can switch it to asymmetric as needed. Report + * this bandwidth as available (even though it + * is not yet enabled). + */ + if (downstream) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } + } else { + up_bw = link_speed * port->sw->link_width * 1000; + down_bw = up_bw; + } + } else { + link_speed = tb_port_get_link_speed(port); + if (link_speed < 0) + return link_speed; + + link_width = tb_port_get_link_width(port); + if (link_width < 0) + return link_width; + + if (link_width == TB_LINK_WIDTH_ASYM_TX) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else if (link_width == TB_LINK_WIDTH_ASYM_RX) { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } else if (include_asym) { + /* + * The link is symmetric at the moment but we + * can switch it to asymmetric as needed. Report + * this bandwidth as available (even though it + * is not yet enabled). + */ + if (downstream) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } + } else { + up_bw = link_speed * link_width * 1000; + down_bw = up_bw; + } + } + + /* Leave 10% guard band */ + *max_up = up_bw - up_bw / 10; + *max_down = down_bw - down_bw / 10; + + tb_port_dbg(port, "link maximum bandwidth %d/%d Mb/s\n", *max_up, *max_down); + return 0; +} + +/** + * tb_available_bandwidth() - Available bandwidth for tunneling + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @available_up: Available bandwidth upstream (Mb/s) + * @available_down: Available bandwidth downstream (Mb/s) + * @include_asym: Include bandwidth if the link is switched from + * symmetric to asymmetric + * + * Calculates maximum available bandwidth for protocol tunneling between + * @src_port and @dst_port at the moment. This is minimum of maximum + * link bandwidth across all links reduced by currently consumed + * bandwidth on that link. + * + * If @include_asym is true then includes also bandwidth that can be + * added when the links are transitioned into asymmetric (but does not + * transition the links). + */ +static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int *available_up, + int *available_down, bool include_asym) +{ + struct tb_port *port; + int ret; + /* Maximum possible bandwidth asymmetric Gen 4 link is 120 Gb/s */ *available_up = *available_down = 120000; /* Find the minimum available bandwidth over all links */ tb_for_each_port_on_path(src_port, dst_port, port) { - int link_speed, link_width, up_bw, down_bw; + int max_up, max_down, consumed_up, consumed_down; if (!tb_port_is_null(port)) continue; - if (tb_is_upstream_port(port)) { - link_speed = port->sw->link_speed; - /* - * sw->link_width is from upstream perspective - * so we use the opposite for downstream of the - * host router. - */ - if (port->sw->link_width == TB_LINK_WIDTH_ASYM_TX) { - up_bw = link_speed * 3 * 1000; - down_bw = link_speed * 1 * 1000; - } else if (port->sw->link_width == TB_LINK_WIDTH_ASYM_RX) { - up_bw = link_speed * 1 * 1000; - down_bw = link_speed * 3 * 1000; - } else { - up_bw = link_speed * port->sw->link_width * 1000; - down_bw = up_bw; - } - } else { - link_speed = tb_port_get_link_speed(port); - if (link_speed < 0) - return link_speed; + ret = tb_maximum_bandwidth(tb, src_port, dst_port, port, + &max_up, &max_down, include_asym); + if (ret) + return ret; - link_width = tb_port_get_link_width(port); - if (link_width < 0) - return link_width; + ret = tb_consumed_usb3_pcie_bandwidth(tb, src_port, dst_port, + port, &consumed_up, + &consumed_down); + if (ret) + return ret; + max_up -= consumed_up; + max_down -= consumed_down; - if (link_width == TB_LINK_WIDTH_ASYM_TX) { - up_bw = link_speed * 1 * 1000; - down_bw = link_speed * 3 * 1000; - } else if (link_width == TB_LINK_WIDTH_ASYM_RX) { - up_bw = link_speed * 3 * 1000; - down_bw = link_speed * 1 * 1000; - } else { - up_bw = link_speed * link_width * 1000; - down_bw = up_bw; - } - } + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, port, + &consumed_up, &consumed_down); + if (ret) + return ret; + max_up -= consumed_up; + max_down -= consumed_down; - /* Leave 10% guard band */ - up_bw -= up_bw / 10; - down_bw -= down_bw / 10; - - tb_port_dbg(port, "link total bandwidth %d/%d Mb/s\n", up_bw, - down_bw); - - /* - * Find all DP tunnels that cross the port and reduce - * their consumed bandwidth from the available. - */ - list_for_each_entry(tunnel, &tcm->tunnel_list, list) { - int dp_consumed_up, dp_consumed_down; - - if (tb_tunnel_is_invalid(tunnel)) - continue; - - if (!tb_tunnel_is_dp(tunnel)) - continue; - - if (!tb_tunnel_port_on_path(tunnel, port)) - continue; - - /* - * Ignore the DP tunnel between src_port and - * dst_port because it is the same tunnel and we - * may be re-calculating estimated bandwidth. - */ - if (tunnel->src_port == src_port && - tunnel->dst_port == dst_port) - continue; - - ret = tb_tunnel_consumed_bandwidth(tunnel, - &dp_consumed_up, - &dp_consumed_down); - if (ret) - return ret; - - up_bw -= dp_consumed_up; - down_bw -= dp_consumed_down; - } - - /* - * If USB3 is tunneled from the host router down to the - * branch leading to port we need to take USB3 consumed - * bandwidth into account regardless whether it actually - * crosses the port. - */ - up_bw -= usb3_consumed_up; - down_bw -= usb3_consumed_down; - - if (up_bw < *available_up) - *available_up = up_bw; - if (down_bw < *available_down) - *available_down = down_bw; + if (max_up < *available_up) + *available_up = max_up; + if (max_down < *available_down) + *available_down = max_down; } if (*available_up < 0) @@ -729,21 +931,21 @@ static void tb_reclaim_usb3_bandwidth(struct tb *tb, struct tb_port *src_port, if (!tunnel) return; - tb_dbg(tb, "reclaiming unused bandwidth for USB3\n"); + tb_tunnel_dbg(tunnel, "reclaiming unused bandwidth\n"); /* * Calculate available bandwidth for the first hop USB3 tunnel. * That determines the whole USB3 bandwidth for this branch. */ ret = tb_available_bandwidth(tb, tunnel->src_port, tunnel->dst_port, - &available_up, &available_down); + &available_up, &available_down, false); if (ret) { - tb_warn(tb, "failed to calculate available bandwidth\n"); + tb_tunnel_warn(tunnel, "failed to calculate available bandwidth\n"); return; } - tb_dbg(tb, "available bandwidth for USB3 %d/%d Mb/s\n", - available_up, available_down); + tb_tunnel_dbg(tunnel, "available bandwidth %d/%d Mb/s\n", available_up, + available_down); tb_tunnel_reclaim_available_bandwidth(tunnel, &available_up, &available_down); } @@ -794,8 +996,8 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) return ret; } - ret = tb_available_bandwidth(tb, down, up, &available_up, - &available_down); + ret = tb_available_bandwidth(tb, down, up, &available_up, &available_down, + false); if (ret) goto err_reclaim; @@ -856,6 +1058,225 @@ static int tb_create_usb3_tunnels(struct tb_switch *sw) return 0; } +/** + * tb_configure_asym() - Transition links to asymmetric if needed + * @tb: Domain structure + * @src_port: Source adapter to start the transition + * @dst_port: Destination adapter + * @requested_up: Additional bandwidth (Mb/s) required upstream + * @requested_down: Additional bandwidth (Mb/s) required downstream + * + * Transition links between @src_port and @dst_port into asymmetric, with + * three lanes in the direction from @src_port towards @dst_port and one lane + * in the opposite direction, if the bandwidth requirements + * (requested + currently consumed) on that link exceed @asym_threshold. + * + * Must be called with available >= requested over all links. + */ +static int tb_configure_asym(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int requested_up, + int requested_down) +{ + struct tb_switch *sw; + bool clx, downstream; + struct tb_port *up; + int ret = 0; + + if (!asym_threshold) + return 0; + + /* Disable CL states before doing any transitions */ + downstream = tb_port_path_direction_downstream(src_port, dst_port); + /* Pick up router deepest in the hierarchy */ + if (downstream) + sw = dst_port->sw; + else + sw = src_port->sw; + + clx = tb_disable_clx(sw); + + tb_for_each_upstream_port_on_path(src_port, dst_port, up) { + int consumed_up, consumed_down; + enum tb_link_width width; + + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, up, + &consumed_up, &consumed_down); + if (ret) + break; + + if (downstream) { + /* + * Downstream so make sure upstream is within the 36G + * (40G - guard band 10%), and the requested is above + * what the threshold is. + */ + if (consumed_up + requested_up >= TB_ASYM_MIN) { + ret = -ENOBUFS; + break; + } + /* Does consumed + requested exceed the threshold */ + if (consumed_down + requested_down < asym_threshold) + continue; + + width = TB_LINK_WIDTH_ASYM_RX; + } else { + /* Upstream, the opposite of above */ + if (consumed_down + requested_down >= TB_ASYM_MIN) { + ret = -ENOBUFS; + break; + } + if (consumed_up + requested_up < asym_threshold) + continue; + + width = TB_LINK_WIDTH_ASYM_TX; + } + + if (up->sw->link_width == width) + continue; + + if (!tb_port_width_supported(up, width)) + continue; + + tb_sw_dbg(up->sw, "configuring asymmetric link\n"); + + /* + * Here requested + consumed > threshold so we need to + * transtion the link into asymmetric now. + */ + ret = tb_switch_set_link_width(up->sw, width); + if (ret) { + tb_sw_warn(up->sw, "failed to set link width\n"); + break; + } + } + + /* Re-enable CL states if they were previosly enabled */ + if (clx) + tb_enable_clx(sw); + + return ret; +} + +/** + * tb_configure_sym() - Transition links to symmetric if possible + * @tb: Domain structure + * @src_port: Source adapter to start the transition + * @dst_port: Destination adapter + * @requested_up: New lower bandwidth request upstream (Mb/s) + * @requested_down: New lower bandwidth request downstream (Mb/s) + * + * Goes over each link from @src_port to @dst_port and tries to + * transition the link to symmetric if the currently consumed bandwidth + * allows. + */ +static int tb_configure_sym(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int requested_up, + int requested_down) +{ + struct tb_switch *sw; + bool clx, downstream; + struct tb_port *up; + int ret = 0; + + if (!asym_threshold) + return 0; + + /* Disable CL states before doing any transitions */ + downstream = tb_port_path_direction_downstream(src_port, dst_port); + /* Pick up router deepest in the hierarchy */ + if (downstream) + sw = dst_port->sw; + else + sw = src_port->sw; + + clx = tb_disable_clx(sw); + + tb_for_each_upstream_port_on_path(src_port, dst_port, up) { + int consumed_up, consumed_down; + + /* Already symmetric */ + if (up->sw->link_width <= TB_LINK_WIDTH_DUAL) + continue; + /* Unplugged, no need to switch */ + if (up->sw->is_unplugged) + continue; + + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, up, + &consumed_up, &consumed_down); + if (ret) + break; + + if (downstream) { + /* + * Downstream so we want the consumed_down < threshold. + * Upstream traffic should be less than 36G (40G + * guard band 10%) as the link was configured asymmetric + * already. + */ + if (consumed_down + requested_down >= asym_threshold) + continue; + } else { + if (consumed_up + requested_up >= asym_threshold) + continue; + } + + if (up->sw->link_width == TB_LINK_WIDTH_DUAL) + continue; + + tb_sw_dbg(up->sw, "configuring symmetric link\n"); + + ret = tb_switch_set_link_width(up->sw, TB_LINK_WIDTH_DUAL); + if (ret) { + tb_sw_warn(up->sw, "failed to set link width\n"); + break; + } + } + + /* Re-enable CL states if they were previosly enabled */ + if (clx) + tb_enable_clx(sw); + + return ret; +} + +static void tb_configure_link(struct tb_port *down, struct tb_port *up, + struct tb_switch *sw) +{ + struct tb *tb = sw->tb; + + /* Link the routers using both links if available */ + down->remote = up; + up->remote = down; + if (down->dual_link_port && up->dual_link_port) { + down->dual_link_port->remote = up->dual_link_port; + up->dual_link_port->remote = down->dual_link_port; + } + + /* + * Enable lane bonding if the link is currently two single lane + * links. + */ + if (sw->link_width < TB_LINK_WIDTH_DUAL) + tb_switch_set_link_width(sw, TB_LINK_WIDTH_DUAL); + + /* + * Device router that comes up as symmetric link is + * connected deeper in the hierarchy, we transition the links + * above into symmetric if bandwidth allows. + */ + if (tb_switch_depth(sw) > 1 && + tb_port_get_link_generation(up) >= 4 && + up->sw->link_width == TB_LINK_WIDTH_DUAL) { + struct tb_port *host_port; + + host_port = tb_port_at(tb_route(sw), tb->root_switch); + tb_configure_sym(tb, host_port, up, 0, 0); + } + + /* Set the link configured */ + tb_switch_configure_link(sw); +} + static void tb_scan_port(struct tb_port *port); /* @@ -964,19 +1385,9 @@ static void tb_scan_port(struct tb_port *port) goto out_rpm_put; } - /* Link the switches using both links if available */ upstream_port = tb_upstream_port(sw); - port->remote = upstream_port; - upstream_port->remote = port; - if (port->dual_link_port && upstream_port->dual_link_port) { - port->dual_link_port->remote = upstream_port->dual_link_port; - upstream_port->dual_link_port->remote = port->dual_link_port; - } + tb_configure_link(port, upstream_port, sw); - /* Enable lane bonding if supported */ - tb_switch_lane_bonding_enable(sw); - /* Set the link configured */ - tb_switch_configure_link(sw); /* * CL0s and CL1 are enabled and supported together. * Silently ignore CLx enabling in case CLx is not supported. @@ -1040,6 +1451,11 @@ static void tb_deactivate_and_free_tunnel(struct tb_tunnel *tunnel) * deallocated properly. */ tb_switch_dealloc_dp_resource(src_port->sw, src_port); + /* + * If bandwidth on a link is < asym_threshold + * transition the link to symmetric. + */ + tb_configure_sym(tb, src_port, dst_port, 0, 0); /* Now we can allow the domain to runtime suspend again */ pm_runtime_mark_last_busy(&dst_port->sw->dev); pm_runtime_put_autosuspend(&dst_port->sw->dev); @@ -1092,7 +1508,8 @@ static void tb_free_unplugged_children(struct tb_switch *sw) tb_retimer_remove_all(port); tb_remove_dp_resources(port->remote->sw); tb_switch_unconfigure_link(port->remote->sw); - tb_switch_lane_bonding_disable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + TB_LINK_WIDTH_SINGLE); tb_switch_remove(port->remote->sw); port->remote = NULL; if (port->dual_link_port) @@ -1188,7 +1605,7 @@ tb_recalc_estimated_bandwidth_for_group(struct tb_bandwidth_group *group) ret = tb_release_unused_usb3_bandwidth(tb, first_tunnel->src_port, first_tunnel->dst_port); if (ret) { - tb_port_warn(in, + tb_tunnel_warn(tunnel, "failed to release unused bandwidth\n"); break; } @@ -1196,9 +1613,9 @@ tb_recalc_estimated_bandwidth_for_group(struct tb_bandwidth_group *group) out = tunnel->dst_port; ret = tb_available_bandwidth(tb, in, out, &estimated_up, - &estimated_down); + &estimated_down, true); if (ret) { - tb_port_warn(in, + tb_tunnel_warn(tunnel, "failed to re-calculate estimated bandwidth\n"); break; } @@ -1209,16 +1626,18 @@ tb_recalc_estimated_bandwidth_for_group(struct tb_bandwidth_group *group) * - available bandwidth along the path * - bandwidth allocated for USB 3.x but not used. */ - tb_port_dbg(in, "re-calculated estimated bandwidth %u/%u Mb/s\n", - estimated_up, estimated_down); + tb_tunnel_dbg(tunnel, + "re-calculated estimated bandwidth %u/%u Mb/s\n", + estimated_up, estimated_down); - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) estimated_bw = estimated_down; else estimated_bw = estimated_up; if (usb4_dp_port_set_estimated_bandwidth(in, estimated_bw)) - tb_port_warn(in, "failed to update estimated bandwidth\n"); + tb_tunnel_warn(tunnel, + "failed to update estimated bandwidth\n"); } if (first_tunnel) @@ -1282,18 +1701,14 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) return NULL; } -static void tb_tunnel_dp(struct tb *tb) +static bool tb_tunnel_one_dp(struct tb *tb) { int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); struct tb_port *port, *in, *out; + int consumed_up, consumed_down; struct tb_tunnel *tunnel; - if (!tb_acpi_may_tunnel_dp()) { - tb_dbg(tb, "DP tunneling disabled, not creating tunnel\n"); - return; - } - /* * Find pair of inactive DP IN and DP OUT adapters and then * establish a DP tunnel between them. @@ -1311,22 +1726,21 @@ static void tb_tunnel_dp(struct tb *tb) continue; } - tb_port_dbg(port, "DP IN available\n"); + in = port; + tb_port_dbg(in, "DP IN available\n"); out = tb_find_dp_out(tb, port); - if (out) { - in = port; + if (out) break; - } } if (!in) { tb_dbg(tb, "no suitable DP IN adapter available, not tunneling\n"); - return; + return false; } if (!out) { tb_dbg(tb, "no suitable DP OUT adapter available, not tunneling\n"); - return; + return false; } /* @@ -1369,7 +1783,8 @@ static void tb_tunnel_dp(struct tb *tb) goto err_detach_group; } - ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down); + ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down, + true); if (ret) goto err_reclaim_usb; @@ -1391,6 +1806,13 @@ static void tb_tunnel_dp(struct tb *tb) list_add_tail(&tunnel->list, &tcm->tunnel_list); tb_reclaim_usb3_bandwidth(tb, in, out); + /* + * Transition the links to asymmetric if the consumption exceeds + * the threshold. + */ + if (!tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, &consumed_down)) + tb_configure_asym(tb, in, out, consumed_up, consumed_down); + /* Update the domain with the new bandwidth estimation */ tb_recalc_estimated_bandwidth(tb); @@ -1399,7 +1821,7 @@ static void tb_tunnel_dp(struct tb *tb) * TMU mode to HiFi for CL0s to work. */ tb_increase_tmu_accuracy(tunnel); - return; + return true; err_free: tb_tunnel_free(tunnel); @@ -1414,6 +1836,19 @@ err_rpm_put: pm_runtime_put_autosuspend(&out->sw->dev); pm_runtime_mark_last_busy(&in->sw->dev); pm_runtime_put_autosuspend(&in->sw->dev); + + return false; +} + +static void tb_tunnel_dp(struct tb *tb) +{ + if (!tb_acpi_may_tunnel_dp()) { + tb_dbg(tb, "DP tunneling disabled, not creating tunnel\n"); + return; + } + + while (tb_tunnel_one_dp(tb)) + ; } static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port) @@ -1701,7 +2136,8 @@ static void tb_handle_hotplug(struct work_struct *work) tb_remove_dp_resources(port->remote->sw); tb_switch_tmu_disable(port->remote->sw); tb_switch_unconfigure_link(port->remote->sw); - tb_switch_lane_bonding_disable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + TB_LINK_WIDTH_SINGLE); tb_switch_remove(port->remote->sw); port->remote = NULL; if (port->dual_link_port) @@ -1781,8 +2217,8 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, in = tunnel->src_port; out = tunnel->dst_port; - tb_port_dbg(in, "bandwidth allocated currently %d/%d Mb/s\n", - allocated_up, allocated_down); + tb_tunnel_dbg(tunnel, "bandwidth allocated currently %d/%d Mb/s\n", + allocated_up, allocated_down); /* * If we get rounded up request from graphics side, say HBR2 x 4 @@ -1823,19 +2259,25 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, else if (requested_down_corrected < 0) requested_down_corrected = 0; - tb_port_dbg(in, "corrected bandwidth request %d/%d Mb/s\n", - requested_up_corrected, requested_down_corrected); + tb_tunnel_dbg(tunnel, "corrected bandwidth request %d/%d Mb/s\n", + requested_up_corrected, requested_down_corrected); if ((*requested_up >= 0 && requested_up_corrected > max_up_rounded) || (*requested_down >= 0 && requested_down_corrected > max_down_rounded)) { - tb_port_dbg(in, "bandwidth request too high (%d/%d Mb/s > %d/%d Mb/s)\n", - requested_up_corrected, requested_down_corrected, - max_up_rounded, max_down_rounded); + tb_tunnel_dbg(tunnel, + "bandwidth request too high (%d/%d Mb/s > %d/%d Mb/s)\n", + requested_up_corrected, requested_down_corrected, + max_up_rounded, max_down_rounded); return -ENOBUFS; } if ((*requested_up >= 0 && requested_up_corrected <= allocated_up) || (*requested_down >= 0 && requested_down_corrected <= allocated_down)) { + /* + * If bandwidth on a link is < asym_threshold transition + * the link to symmetric. + */ + tb_configure_sym(tb, in, out, *requested_up, *requested_down); /* * If requested bandwidth is less or equal than what is * currently allocated to that tunnel we simply change @@ -1861,17 +2303,33 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, * are also in the same group but we use the same function here * that we use with the normal bandwidth allocation). */ - ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down); + ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down, + true); if (ret) goto reclaim; - tb_port_dbg(in, "bandwidth available for allocation %d/%d Mb/s\n", - available_up, available_down); + tb_tunnel_dbg(tunnel, "bandwidth available for allocation %d/%d Mb/s\n", + available_up, available_down); if ((*requested_up >= 0 && available_up >= requested_up_corrected) || (*requested_down >= 0 && available_down >= requested_down_corrected)) { + /* + * If bandwidth on a link is >= asym_threshold + * transition the link to asymmetric. + */ + ret = tb_configure_asym(tb, in, out, *requested_up, + *requested_down); + if (ret) { + tb_configure_sym(tb, in, out, 0, 0); + return ret; + } + ret = tb_tunnel_alloc_bandwidth(tunnel, requested_up, requested_down); + if (ret) { + tb_tunnel_warn(tunnel, "failed to allocate bandwidth\n"); + tb_configure_sym(tb, in, out, 0, 0); + } } else { ret = -ENOBUFS; } @@ -1937,7 +2395,7 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) out = tunnel->dst_port; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { requested_up = -1; requested_down = requested_bw; } else { @@ -1948,12 +2406,15 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) ret = tb_alloc_dp_bandwidth(tunnel, &requested_up, &requested_down); if (ret) { if (ret == -ENOBUFS) - tb_port_warn(in, "not enough bandwidth available\n"); + tb_tunnel_warn(tunnel, + "not enough bandwidth available\n"); else - tb_port_warn(in, "failed to change bandwidth allocation\n"); + tb_tunnel_warn(tunnel, + "failed to change bandwidth allocation\n"); } else { - tb_port_dbg(in, "bandwidth allocation changed to %d/%d Mb/s\n", - requested_up, requested_down); + tb_tunnel_dbg(tunnel, + "bandwidth allocation changed to %d/%d Mb/s\n", + requested_up, requested_down); /* Update other clients about the allocation change */ tb_recalc_estimated_bandwidth(tb); @@ -2181,7 +2642,8 @@ static void tb_restore_children(struct tb_switch *sw) continue; if (port->remote) { - tb_switch_lane_bonding_enable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + port->remote->sw->link_width); tb_switch_configure_link(port->remote->sw); tb_restore_children(port->remote->sw); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index d2a55ad2fd3e..e299e53473ae 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -162,11 +162,6 @@ struct tb_switch_tmu { * switches) you need to have domain lock held. * * In USB4 terminology this structure represents a router. - * - * Note @link_width is not the same as whether link is bonded or not. - * For Gen 4 links the link is also bonded when it is asymmetric. The - * correct way to find out whether the link is bonded or not is to look - * @bonded field of the upstream port. */ struct tb_switch { struct device dev; @@ -348,6 +343,7 @@ struct tb_retimer { * the path * @nfc_credits: Number of non-flow controlled buffers allocated for the * @in_port. + * @pm_support: Set path PM packet support bit to 1 (for USB4 v2 routers) * * Hop configuration is always done on the IN port of a switch. * in_port and out_port have to be on the same switch. Packets arriving on @@ -368,6 +364,7 @@ struct tb_path_hop { int next_hop_index; unsigned int initial_credits; unsigned int nfc_credits; + bool pm_support; }; /** @@ -864,6 +861,15 @@ static inline struct tb_port *tb_switch_downstream_port(struct tb_switch *sw) return tb_port_at(tb_route(sw), tb_switch_parent(sw)); } +/** + * tb_switch_depth() - Returns depth of the connected router + * @sw: Router + */ +static inline int tb_switch_depth(const struct tb_switch *sw) +{ + return sw->config.depth; +} + static inline bool tb_switch_is_light_ridge(const struct tb_switch *sw) { return sw->config.vendor_id == PCI_VENDOR_ID_INTEL && @@ -956,8 +962,7 @@ static inline bool tb_switch_is_icm(const struct tb_switch *sw) return !sw->config.enabled; } -int tb_switch_lane_bonding_enable(struct tb_switch *sw); -void tb_switch_lane_bonding_disable(struct tb_switch *sw); +int tb_switch_set_link_width(struct tb_switch *sw, enum tb_link_width width); int tb_switch_configure_link(struct tb_switch *sw); void tb_switch_unconfigure_link(struct tb_switch *sw); @@ -1001,7 +1006,6 @@ static inline bool tb_switch_tmu_is_enabled(const struct tb_switch *sw) bool tb_port_clx_is_enabled(struct tb_port *port, unsigned int clx); int tb_switch_clx_init(struct tb_switch *sw); -bool tb_switch_clx_is_supported(const struct tb_switch *sw); int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx); int tb_switch_clx_disable(struct tb_switch *sw); @@ -1040,6 +1044,21 @@ void tb_port_release_out_hopid(struct tb_port *port, int hopid); struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end, struct tb_port *prev); +/** + * tb_port_path_direction_downstream() - Checks if path directed downstream + * @src: Source adapter + * @dst: Destination adapter + * + * Returns %true only if the specified path from source adapter (@src) + * to destination adapter (@dst) is directed downstream. + */ +static inline bool +tb_port_path_direction_downstream(const struct tb_port *src, + const struct tb_port *dst) +{ + return src->sw->config.depth < dst->sw->config.depth; +} + static inline bool tb_port_use_credit_allocation(const struct tb_port *port) { return tb_port_is_null(port) && port->sw->credit_allocation; @@ -1057,12 +1076,29 @@ static inline bool tb_port_use_credit_allocation(const struct tb_port *port) for ((p) = tb_next_port_on_path((src), (dst), NULL); (p); \ (p) = tb_next_port_on_path((src), (dst), (p))) +/** + * tb_for_each_upstream_port_on_path() - Iterate over each upstreamm port on path + * @src: Source port + * @dst: Destination port + * @p: Port used as iterator + * + * Walks over each upstream lane adapter on path from @src to @dst. + */ +#define tb_for_each_upstream_port_on_path(src, dst, p) \ + for ((p) = tb_next_port_on_path((src), (dst), NULL); (p); \ + (p) = tb_next_port_on_path((src), (dst), (p))) \ + if (!tb_port_is_null((p)) || !tb_is_upstream_port((p))) {\ + continue; \ + } else + int tb_port_get_link_speed(struct tb_port *port); +int tb_port_get_link_generation(struct tb_port *port); int tb_port_get_link_width(struct tb_port *port); +bool tb_port_width_supported(struct tb_port *port, unsigned int width); int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width); int tb_port_lane_bonding_enable(struct tb_port *port); void tb_port_lane_bonding_disable(struct tb_port *port); -int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, +int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width, int timeout_msec); int tb_port_update_credits(struct tb_port *port); @@ -1256,6 +1292,11 @@ int usb4_port_router_online(struct tb_port *port); int usb4_port_enumerate_retimers(struct tb_port *port); bool usb4_port_clx_supported(struct tb_port *port); int usb4_port_margining_caps(struct tb_port *port, u32 *caps); + +bool usb4_port_asym_supported(struct tb_port *port); +int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width); +int usb4_port_asym_start(struct tb_port *port); + int usb4_port_hw_margin(struct tb_port *port, unsigned int lanes, unsigned int ber_level, bool timing, bool right_high, u32 *results); @@ -1283,7 +1324,6 @@ int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index, unsigned int address, void *buf, size_t size); int usb4_usb3_port_max_link_rate(struct tb_port *port); -int usb4_usb3_port_actual_link_rate(struct tb_port *port); int usb4_usb3_port_allocated_bandwidth(struct tb_port *port, int *upstream_bw, int *downstream_bw); int usb4_usb3_port_allocate_bandwidth(struct tb_port *port, int *upstream_bw, diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index cf9f2370878a..87e4795275fe 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -346,10 +346,14 @@ struct tb_regs_port_header { #define LANE_ADP_CS_1 0x01 #define LANE_ADP_CS_1_TARGET_SPEED_MASK GENMASK(3, 0) #define LANE_ADP_CS_1_TARGET_SPEED_GEN3 0xc -#define LANE_ADP_CS_1_TARGET_WIDTH_MASK GENMASK(9, 4) +#define LANE_ADP_CS_1_TARGET_WIDTH_MASK GENMASK(5, 4) #define LANE_ADP_CS_1_TARGET_WIDTH_SHIFT 4 #define LANE_ADP_CS_1_TARGET_WIDTH_SINGLE 0x1 #define LANE_ADP_CS_1_TARGET_WIDTH_DUAL 0x3 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK GENMASK(7, 6) +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_TX 0x1 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_RX 0x2 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_DUAL 0x0 #define LANE_ADP_CS_1_CL0S_ENABLE BIT(10) #define LANE_ADP_CS_1_CL1_ENABLE BIT(11) #define LANE_ADP_CS_1_CL2_ENABLE BIT(12) @@ -382,12 +386,15 @@ struct tb_regs_port_header { #define PORT_CS_18_WOCS BIT(16) #define PORT_CS_18_WODS BIT(17) #define PORT_CS_18_WOU4S BIT(18) +#define PORT_CS_18_CSA BIT(22) +#define PORT_CS_18_TIP BIT(24) #define PORT_CS_19 0x13 #define PORT_CS_19_PC BIT(3) #define PORT_CS_19_PID BIT(4) #define PORT_CS_19_WOC BIT(16) #define PORT_CS_19_WOD BIT(17) #define PORT_CS_19_WOU4 BIT(18) +#define PORT_CS_19_START_ASYM BIT(24) /* Display Port adapter registers */ #define ADP_DP_CS_0 0x00 @@ -400,7 +407,7 @@ struct tb_regs_port_header { #define ADP_DP_CS_1_AUX_RX_HOPID_SHIFT 11 #define ADP_DP_CS_2 0x02 #define ADP_DP_CS_2_NRD_MLC_MASK GENMASK(2, 0) -#define ADP_DP_CS_2_HDP BIT(6) +#define ADP_DP_CS_2_HPD BIT(6) #define ADP_DP_CS_2_NRD_MLR_MASK GENMASK(9, 7) #define ADP_DP_CS_2_NRD_MLR_SHIFT 7 #define ADP_DP_CS_2_CA BIT(10) @@ -417,7 +424,7 @@ struct tb_regs_port_header { #define ADP_DP_CS_2_ESTIMATED_BW_MASK GENMASK(31, 24) #define ADP_DP_CS_2_ESTIMATED_BW_SHIFT 24 #define ADP_DP_CS_3 0x03 -#define ADP_DP_CS_3_HDPC BIT(9) +#define ADP_DP_CS_3_HPDC BIT(9) #define DP_LOCAL_CAP 0x04 #define DP_REMOTE_CAP 0x05 /* For DP IN adapter */ @@ -484,9 +491,6 @@ struct tb_regs_port_header { #define ADP_USB3_CS_3 0x03 #define ADP_USB3_CS_3_SCALE_MASK GENMASK(5, 0) #define ADP_USB3_CS_4 0x04 -#define ADP_USB3_CS_4_ALR_MASK GENMASK(6, 0) -#define ADP_USB3_CS_4_ALR_20G 0x1 -#define ADP_USB3_CS_4_ULV BIT(7) #define ADP_USB3_CS_4_MSLR_MASK GENMASK(18, 12) #define ADP_USB3_CS_4_MSLR_SHIFT 12 #define ADP_USB3_CS_4_MSLR_20G 0x1 @@ -499,7 +503,8 @@ struct tb_regs_hop { * out_port (on the incoming port of the next switch) */ u32 out_port:6; /* next port of the path (on the same switch) */ - u32 initial_credits:8; + u32 initial_credits:7; + u32 pmps:1; u32 unknown1:6; /* set to zero */ bool enable:1; diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index a6810fb36860..7534cd3a81f4 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -21,12 +21,18 @@ #define TB_PCI_PATH_DOWN 0 #define TB_PCI_PATH_UP 1 +#define TB_PCI_PRIORITY 3 +#define TB_PCI_WEIGHT 1 + /* USB3 adapters use always HopID of 8 for both directions */ #define TB_USB3_HOPID 8 #define TB_USB3_PATH_DOWN 0 #define TB_USB3_PATH_UP 1 +#define TB_USB3_PRIORITY 3 +#define TB_USB3_WEIGHT 2 + /* DP adapters use HopID 8 for AUX and 9 for Video */ #define TB_DP_AUX_TX_HOPID 8 #define TB_DP_AUX_RX_HOPID 8 @@ -36,6 +42,12 @@ #define TB_DP_AUX_PATH_OUT 1 #define TB_DP_AUX_PATH_IN 2 +#define TB_DP_VIDEO_PRIORITY 1 +#define TB_DP_VIDEO_WEIGHT 1 + +#define TB_DP_AUX_PRIORITY 2 +#define TB_DP_AUX_WEIGHT 1 + /* Minimum number of credits needed for PCIe path */ #define TB_MIN_PCIE_CREDITS 6U /* @@ -46,6 +58,18 @@ /* Minimum number of credits for DMA path */ #define TB_MIN_DMA_CREDITS 1 +#define TB_DMA_PRIORITY 5 +#define TB_DMA_WEIGHT 1 + +/* + * Reserve additional bandwidth for USB 3.x and PCIe bulk traffic + * according to USB4 v2 Connection Manager guide. This ends up reserving + * 1500 Mb/s for PCIe and 3000 Mb/s for USB 3.x taking weights into + * account. + */ +#define USB4_V2_PCI_MIN_BANDWIDTH (1500 * TB_PCI_WEIGHT) +#define USB4_V2_USB3_MIN_BANDWIDTH (1500 * TB_USB3_WEIGHT) + static unsigned int dma_credits = TB_DMA_CREDITS; module_param(dma_credits, uint, 0444); MODULE_PARM_DESC(dma_credits, "specify custom credits for DMA tunnels (default: " @@ -58,27 +82,6 @@ MODULE_PARM_DESC(bw_alloc_mode, static const char * const tb_tunnel_names[] = { "PCI", "DP", "DMA", "USB3" }; -#define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \ - do { \ - struct tb_tunnel *__tunnel = (tunnel); \ - level(__tunnel->tb, "%llx:%u <-> %llx:%u (%s): " fmt, \ - tb_route(__tunnel->src_port->sw), \ - __tunnel->src_port->port, \ - tb_route(__tunnel->dst_port->sw), \ - __tunnel->dst_port->port, \ - tb_tunnel_names[__tunnel->type], \ - ## arg); \ - } while (0) - -#define tb_tunnel_WARN(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_WARN, tunnel, fmt, ##arg) -#define tb_tunnel_warn(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_warn, tunnel, fmt, ##arg) -#define tb_tunnel_info(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_info, tunnel, fmt, ##arg) -#define tb_tunnel_dbg(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_dbg, tunnel, fmt, ##arg) - static inline unsigned int tb_usable_credits(const struct tb_port *port) { return port->total_credits - port->ctl_credits; @@ -131,6 +134,16 @@ static unsigned int tb_available_credits(const struct tb_port *port, return credits > 0 ? credits : 0; } +static void tb_init_pm_support(struct tb_path_hop *hop) +{ + struct tb_port *out_port = hop->out_port; + struct tb_port *in_port = hop->in_port; + + if (tb_port_is_null(in_port) && tb_port_is_null(out_port) && + usb4_switch_version(in_port->sw) >= 2) + hop->pm_support = true; +} + static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, enum tb_tunnel_type type) { @@ -156,11 +169,11 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable) { + struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw); int ret; /* Only supported of both routers are at least USB4 v2 */ - if (usb4_switch_version(tunnel->src_port->sw) < 2 || - usb4_switch_version(tunnel->dst_port->sw) < 2) + if (tb_port_get_link_generation(port) < 4) return 0; ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable); @@ -234,8 +247,8 @@ static int tb_pci_init_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 3; - path->weight = 1; + path->priority = TB_PCI_PRIORITY; + path->weight = TB_PCI_WEIGHT; path->drop_packages = 0; tb_path_for_each_hop(path, hop) { @@ -376,6 +389,51 @@ err_free: return NULL; } +/** + * tb_tunnel_reserved_pci() - Amount of bandwidth to reserve for PCIe + * @port: Lane 0 adapter + * @reserved_up: Upstream bandwidth in Mb/s to reserve + * @reserved_down: Downstream bandwidth in Mb/s to reserve + * + * Can be called to any connected lane 0 adapter to find out how much + * bandwidth needs to be left in reserve for possible PCIe bulk traffic. + * Returns true if there is something to be reserved and writes the + * amount to @reserved_down/@reserved_up. Otherwise returns false and + * does not touch the parameters. + */ +bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up, + int *reserved_down) +{ + if (WARN_ON_ONCE(!port->remote)) + return false; + + if (!tb_acpi_may_tunnel_pcie()) + return false; + + if (tb_port_get_link_generation(port) < 4) + return false; + + /* Must have PCIe adapters */ + if (tb_is_upstream_port(port)) { + if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_UP)) + return false; + if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_DOWN)) + return false; + } else { + if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_DOWN)) + return false; + if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_UP)) + return false; + } + + *reserved_up = USB4_V2_PCI_MIN_BANDWIDTH; + *reserved_down = USB4_V2_PCI_MIN_BANDWIDTH; + + tb_port_dbg(port, "reserving %u/%u Mb/s for PCIe\n", *reserved_up, + *reserved_down); + return true; +} + static bool tb_dp_is_usb4(const struct tb_switch *sw) { /* Titan Ridge DP adapters need the same treatment as USB4 */ @@ -614,8 +672,9 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) in_rate = tb_dp_cap_get_rate(in_dp_cap); in_lanes = tb_dp_cap_get_lanes(in_dp_cap); - tb_port_dbg(in, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - in_rate, in_lanes, tb_dp_bandwidth(in_rate, in_lanes)); + tb_tunnel_dbg(tunnel, + "DP IN maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + in_rate, in_lanes, tb_dp_bandwidth(in_rate, in_lanes)); /* * If the tunnel bandwidth is limited (max_bw is set) then see @@ -624,10 +683,11 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) out_rate = tb_dp_cap_get_rate(out_dp_cap); out_lanes = tb_dp_cap_get_lanes(out_dp_cap); bw = tb_dp_bandwidth(out_rate, out_lanes); - tb_port_dbg(out, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - out_rate, out_lanes, bw); + tb_tunnel_dbg(tunnel, + "DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + out_rate, out_lanes, bw); - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) max_bw = tunnel->max_down; else max_bw = tunnel->max_up; @@ -639,13 +699,14 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) out_rate, out_lanes, &new_rate, &new_lanes); if (ret) { - tb_port_info(out, "not enough bandwidth for DP tunnel\n"); + tb_tunnel_info(tunnel, "not enough bandwidth\n"); return ret; } new_bw = tb_dp_bandwidth(new_rate, new_lanes); - tb_port_dbg(out, "bandwidth reduced to %u Mb/s x%u = %u Mb/s\n", - new_rate, new_lanes, new_bw); + tb_tunnel_dbg(tunnel, + "bandwidth reduced to %u Mb/s x%u = %u Mb/s\n", + new_rate, new_lanes, new_bw); /* * Set new rate and number of lanes before writing it to @@ -662,7 +723,7 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) */ if (tb_route(out->sw) && tb_switch_is_titan_ridge(out->sw)) { out_dp_cap |= DP_COMMON_CAP_LTTPR_NS; - tb_port_dbg(out, "disabling LTTPR\n"); + tb_tunnel_dbg(tunnel, "disabling LTTPR\n"); } return tb_port_write(in, &out_dp_cap, TB_CFG_PORT, @@ -712,8 +773,8 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) lanes = min(in_lanes, out_lanes); tmp = tb_dp_bandwidth(rate, lanes); - tb_port_dbg(in, "non-reduced bandwidth %u Mb/s x%u = %u Mb/s\n", rate, - lanes, tmp); + tb_tunnel_dbg(tunnel, "non-reduced bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tmp); ret = usb4_dp_port_set_nrd(in, rate, lanes); if (ret) @@ -728,15 +789,15 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) rate = min(in_rate, out_rate); tmp = tb_dp_bandwidth(rate, lanes); - tb_port_dbg(in, - "maximum bandwidth through allocation mode %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tmp); + tb_tunnel_dbg(tunnel, + "maximum bandwidth through allocation mode %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tmp); for (granularity = 250; tmp / granularity > 255 && granularity <= 1000; granularity *= 2) ; - tb_port_dbg(in, "granularity %d Mb/s\n", granularity); + tb_tunnel_dbg(tunnel, "granularity %d Mb/s\n", granularity); /* * Returns -EINVAL if granularity above is outside of the @@ -751,12 +812,12 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) * max_up/down fields. For discovery we just read what the * estimation was set to. */ - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) estimated_bw = tunnel->max_down; else estimated_bw = tunnel->max_up; - tb_port_dbg(in, "estimated bandwidth %d Mb/s\n", estimated_bw); + tb_tunnel_dbg(tunnel, "estimated bandwidth %d Mb/s\n", estimated_bw); ret = usb4_dp_port_set_estimated_bandwidth(in, estimated_bw); if (ret) @@ -767,7 +828,7 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) if (ret) return ret; - tb_port_dbg(in, "bandwidth allocation mode enabled\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode enabled\n"); return 0; } @@ -788,7 +849,7 @@ static int tb_dp_init(struct tb_tunnel *tunnel) if (!usb4_dp_port_bandwidth_mode_supported(in)) return 0; - tb_port_dbg(in, "bandwidth allocation mode supported\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode supported\n"); ret = usb4_dp_port_set_cm_id(in, tb->index); if (ret) @@ -805,7 +866,7 @@ static void tb_dp_deinit(struct tb_tunnel *tunnel) return; if (usb4_dp_port_bandwidth_mode_enabled(in)) { usb4_dp_port_set_cm_bandwidth_mode_supported(in, false); - tb_port_dbg(in, "bandwidth allocation mode disabled\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode disabled\n"); } } @@ -921,10 +982,7 @@ static int tb_dp_bandwidth_mode_consumed_bandwidth(struct tb_tunnel *tunnel, if (allocated_bw == max_bw) allocated_bw = ret; - tb_port_dbg(in, "consumed bandwidth through allocation mode %d Mb/s\n", - allocated_bw); - - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { *consumed_up = 0; *consumed_down = allocated_bw; } else { @@ -959,7 +1017,7 @@ static int tb_dp_allocated_bandwidth(struct tb_tunnel *tunnel, int *allocated_up if (allocated_bw == max_bw) allocated_bw = ret; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { *allocated_up = 0; *allocated_down = allocated_bw; } else { @@ -987,7 +1045,7 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, if (ret < 0) return ret; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { tmp = min(*alloc_down, max_bw); ret = usb4_dp_port_allocate_bandwidth(in, tmp); if (ret) @@ -1006,9 +1064,6 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, /* Now we can use BW mode registers to figure out the bandwidth */ /* TODO: need to handle discovery too */ tunnel->bw_mode = true; - - tb_port_dbg(in, "allocated bandwidth through allocation mode %d Mb/s\n", - tmp); return 0; } @@ -1035,8 +1090,7 @@ static int tb_dp_read_dprx(struct tb_tunnel *tunnel, u32 *rate, u32 *lanes, *rate = tb_dp_cap_get_rate(val); *lanes = tb_dp_cap_get_lanes(val); - tb_port_dbg(in, "consumed bandwidth through DPRX %d Mb/s\n", - tb_dp_bandwidth(*rate, *lanes)); + tb_tunnel_dbg(tunnel, "DPRX read done\n"); return 0; } usleep_range(100, 150); @@ -1073,9 +1127,6 @@ static int tb_dp_read_cap(struct tb_tunnel *tunnel, unsigned int cap, u32 *rate, *rate = tb_dp_cap_get_rate(val); *lanes = tb_dp_cap_get_lanes(val); - - tb_port_dbg(in, "bandwidth from %#x capability %d Mb/s\n", cap, - tb_dp_bandwidth(*rate, *lanes)); return 0; } @@ -1092,7 +1143,7 @@ static int tb_dp_maximum_bandwidth(struct tb_tunnel *tunnel, int *max_up, if (ret < 0) return ret; - if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { + if (tb_port_path_direction_downstream(in, tunnel->dst_port)) { *max_up = 0; *max_down = ret; } else { @@ -1150,7 +1201,7 @@ static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, return 0; } - if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { + if (tb_port_path_direction_downstream(in, tunnel->dst_port)) { *consumed_up = 0; *consumed_down = tb_dp_bandwidth(rate, lanes); } else { @@ -1172,7 +1223,7 @@ static void tb_dp_init_aux_credits(struct tb_path_hop *hop) hop->initial_credits = 1; } -static void tb_dp_init_aux_path(struct tb_path *path) +static void tb_dp_init_aux_path(struct tb_path *path, bool pm_support) { struct tb_path_hop *hop; @@ -1180,11 +1231,14 @@ static void tb_dp_init_aux_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 2; - path->weight = 1; + path->priority = TB_DP_AUX_PRIORITY; + path->weight = TB_DP_AUX_WEIGHT; - tb_path_for_each_hop(path, hop) + tb_path_for_each_hop(path, hop) { tb_dp_init_aux_credits(hop); + if (pm_support) + tb_init_pm_support(hop); + } } static int tb_dp_init_video_credits(struct tb_path_hop *hop) @@ -1216,7 +1270,7 @@ static int tb_dp_init_video_credits(struct tb_path_hop *hop) return 0; } -static int tb_dp_init_video_path(struct tb_path *path) +static int tb_dp_init_video_path(struct tb_path *path, bool pm_support) { struct tb_path_hop *hop; @@ -1224,8 +1278,8 @@ static int tb_dp_init_video_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 1; - path->weight = 1; + path->priority = TB_DP_VIDEO_PRIORITY; + path->weight = TB_DP_VIDEO_WEIGHT; tb_path_for_each_hop(path, hop) { int ret; @@ -1233,6 +1287,8 @@ static int tb_dp_init_video_path(struct tb_path *path) ret = tb_dp_init_video_credits(hop); if (ret) return ret; + if (pm_support) + tb_init_pm_support(hop); } return 0; @@ -1253,8 +1309,9 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(in, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, + "DP IN maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); out = tunnel->dst_port; @@ -1265,8 +1322,9 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(out, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, + "DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); if (tb_port_read(in, &dp_cap, TB_CFG_PORT, in->cap_adap + DP_REMOTE_CAP, 1)) @@ -1275,8 +1333,8 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(in, "reduced bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, "reduced bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); } /** @@ -1322,7 +1380,7 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, goto err_free; } tunnel->paths[TB_DP_VIDEO_PATH_OUT] = path; - if (tb_dp_init_video_path(tunnel->paths[TB_DP_VIDEO_PATH_OUT])) + if (tb_dp_init_video_path(tunnel->paths[TB_DP_VIDEO_PATH_OUT], false)) goto err_free; path = tb_path_discover(in, TB_DP_AUX_TX_HOPID, NULL, -1, NULL, "AUX TX", @@ -1330,14 +1388,14 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, if (!path) goto err_deactivate; tunnel->paths[TB_DP_AUX_PATH_OUT] = path; - tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_OUT]); + tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_OUT], false); path = tb_path_discover(tunnel->dst_port, -1, in, TB_DP_AUX_RX_HOPID, &port, "AUX RX", alloc_hopid); if (!path) goto err_deactivate; tunnel->paths[TB_DP_AUX_PATH_IN] = path; - tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_IN]); + tb_dp_init_aux_path(tunnel->paths[TB_DP_AUX_PATH_IN], false); /* Validate that the tunnel is complete */ if (!tb_port_is_dpout(tunnel->dst_port)) { @@ -1392,6 +1450,7 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, struct tb_tunnel *tunnel; struct tb_path **paths; struct tb_path *path; + bool pm_support; if (WARN_ON(!in->cap_adap || !out->cap_adap)) return NULL; @@ -1413,26 +1472,27 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, tunnel->max_down = max_down; paths = tunnel->paths; + pm_support = usb4_switch_version(in->sw) >= 2; path = tb_path_alloc(tb, in, TB_DP_VIDEO_HOPID, out, TB_DP_VIDEO_HOPID, link_nr, "Video"); if (!path) goto err_free; - tb_dp_init_video_path(path); + tb_dp_init_video_path(path, pm_support); paths[TB_DP_VIDEO_PATH_OUT] = path; path = tb_path_alloc(tb, in, TB_DP_AUX_TX_HOPID, out, TB_DP_AUX_TX_HOPID, link_nr, "AUX TX"); if (!path) goto err_free; - tb_dp_init_aux_path(path); + tb_dp_init_aux_path(path, pm_support); paths[TB_DP_AUX_PATH_OUT] = path; path = tb_path_alloc(tb, out, TB_DP_AUX_RX_HOPID, in, TB_DP_AUX_RX_HOPID, link_nr, "AUX RX"); if (!path) goto err_free; - tb_dp_init_aux_path(path); + tb_dp_init_aux_path(path, pm_support); paths[TB_DP_AUX_PATH_IN] = path; return tunnel; @@ -1497,8 +1557,8 @@ static int tb_dma_init_rx_path(struct tb_path *path, unsigned int credits) path->ingress_fc_enable = TB_PATH_ALL; path->egress_shared_buffer = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 5; - path->weight = 1; + path->priority = TB_DMA_PRIORITY; + path->weight = TB_DMA_WEIGHT; path->clear_fc = true; /* @@ -1531,8 +1591,8 @@ static int tb_dma_init_tx_path(struct tb_path *path, unsigned int credits) path->ingress_fc_enable = TB_PATH_ALL; path->egress_shared_buffer = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 5; - path->weight = 1; + path->priority = TB_DMA_PRIORITY; + path->weight = TB_DMA_WEIGHT; path->clear_fc = true; tb_path_for_each_hop(path, hop) { @@ -1758,14 +1818,23 @@ static int tb_usb3_activate(struct tb_tunnel *tunnel, bool activate) static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, int *consumed_down) { - int pcie_enabled = tb_acpi_may_tunnel_pcie(); + struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw); + int pcie_weight = tb_acpi_may_tunnel_pcie() ? TB_PCI_WEIGHT : 0; /* * PCIe tunneling, if enabled, affects the USB3 bandwidth so * take that it into account here. */ - *consumed_up = tunnel->allocated_up * (3 + pcie_enabled) / 3; - *consumed_down = tunnel->allocated_down * (3 + pcie_enabled) / 3; + *consumed_up = tunnel->allocated_up * + (TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT; + *consumed_down = tunnel->allocated_down * + (TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT; + + if (tb_port_get_link_generation(port) >= 4) { + *consumed_up = max(*consumed_up, USB4_V2_USB3_MIN_BANDWIDTH); + *consumed_down = max(*consumed_down, USB4_V2_USB3_MIN_BANDWIDTH); + } + return 0; } @@ -1790,17 +1859,10 @@ static void tb_usb3_reclaim_available_bandwidth(struct tb_tunnel *tunnel, { int ret, max_rate, allocate_up, allocate_down; - ret = usb4_usb3_port_actual_link_rate(tunnel->src_port); + ret = tb_usb3_max_link_rate(tunnel->dst_port, tunnel->src_port); if (ret < 0) { - tb_tunnel_warn(tunnel, "failed to read actual link rate\n"); + tb_tunnel_warn(tunnel, "failed to read maximum link rate\n"); return; - } else if (!ret) { - /* Use maximum link rate if the link valid is not set */ - ret = tb_usb3_max_link_rate(tunnel->dst_port, tunnel->src_port); - if (ret < 0) { - tb_tunnel_warn(tunnel, "failed to read maximum link rate\n"); - return; - } } /* @@ -1871,8 +1933,8 @@ static void tb_usb3_init_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 3; - path->weight = 3; + path->priority = TB_USB3_PRIORITY; + path->weight = TB_USB3_WEIGHT; path->drop_packages = 0; tb_path_for_each_hop(path, hop) @@ -2387,3 +2449,8 @@ void tb_tunnel_reclaim_available_bandwidth(struct tb_tunnel *tunnel, tunnel->reclaim_available_bandwidth(tunnel, available_up, available_down); } + +const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel) +{ + return tb_tunnel_names[tunnel->type]; +} diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index bf690f7beeee..b4cff5482112 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -80,6 +80,8 @@ struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up, struct tb_port *down); +bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up, + int *reserved_down); struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, @@ -137,5 +139,27 @@ static inline bool tb_tunnel_is_usb3(const struct tb_tunnel *tunnel) return tunnel->type == TB_TUNNEL_USB3; } -#endif +const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel); +#define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \ + do { \ + struct tb_tunnel *__tunnel = (tunnel); \ + level(__tunnel->tb, "%llx:%u <-> %llx:%u (%s): " fmt, \ + tb_route(__tunnel->src_port->sw), \ + __tunnel->src_port->port, \ + tb_route(__tunnel->dst_port->sw), \ + __tunnel->dst_port->port, \ + tb_tunnel_type_name(__tunnel), \ + ## arg); \ + } while (0) + +#define tb_tunnel_WARN(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_WARN, tunnel, fmt, ##arg) +#define tb_tunnel_warn(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_warn, tunnel, fmt, ##arg) +#define tb_tunnel_info(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_info, tunnel, fmt, ##arg) +#define tb_tunnel_dbg(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_dbg, tunnel, fmt, ##arg) + +#endif diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 05ddb224c464..4277733d0021 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1454,6 +1454,112 @@ bool usb4_port_clx_supported(struct tb_port *port) return !!(val & PORT_CS_18_CPS); } +/** + * usb4_port_asym_supported() - If the port supports asymmetric link + * @port: USB4 port + * + * Checks if the port and the cable supports asymmetric link and returns + * %true in that case. + */ +bool usb4_port_asym_supported(struct tb_port *port) +{ + u32 val; + + if (!port->cap_usb4) + return false; + + if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1)) + return false; + + return !!(val & PORT_CS_18_CSA); +} + +/** + * usb4_port_asym_set_link_width() - Set link width to asymmetric or symmetric + * @port: USB4 port + * @width: Asymmetric width to configure + * + * Sets USB4 port link width to @width. Can be called for widths where + * usb4_port_asym_width_supported() returned @true. + */ +int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width) +{ + u32 val; + int ret; + + if (!port->cap_phy) + return -EINVAL; + + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_phy + LANE_ADP_CS_1, 1); + if (ret) + return ret; + + val &= ~LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK; + switch (width) { + case TB_LINK_WIDTH_DUAL: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_DUAL); + break; + case TB_LINK_WIDTH_ASYM_TX: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_TX); + break; + case TB_LINK_WIDTH_ASYM_RX: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_RX); + break; + default: + return -EINVAL; + } + + return tb_port_write(port, &val, TB_CFG_PORT, + port->cap_phy + LANE_ADP_CS_1, 1); +} + +/** + * usb4_port_asym_start() - Start symmetry change and wait for completion + * @port: USB4 port + * + * Start symmetry change of the link to asymmetric or symmetric + * (according to what was previously set in tb_port_set_link_width(). + * Wait for completion of the change. + * + * Returns %0 in case of success, %-ETIMEDOUT if case of timeout or + * a negative errno in case of a failure. + */ +int usb4_port_asym_start(struct tb_port *port) +{ + int ret; + u32 val; + + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); + if (ret) + return ret; + + val &= ~PORT_CS_19_START_ASYM; + val |= FIELD_PREP(PORT_CS_19_START_ASYM, 1); + + ret = tb_port_write(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); + if (ret) + return ret; + + /* + * Wait for PORT_CS_19_START_ASYM to be 0. This means the USB4 + * port started the symmetry transition. + */ + ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_19, + PORT_CS_19_START_ASYM, 0, 1000); + if (ret) + return ret; + + /* Then wait for the transtion to be completed */ + return usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_18, + PORT_CS_18_TIP, 0, 5000); +} + /** * usb4_port_margining_caps() - Read USB4 port marginig capabilities * @port: USB4 port @@ -1946,35 +2052,6 @@ int usb4_usb3_port_max_link_rate(struct tb_port *port) return usb4_usb3_port_max_bandwidth(port, ret); } -/** - * usb4_usb3_port_actual_link_rate() - Established USB3 link rate - * @port: USB3 adapter port - * - * Return actual established link rate of a USB3 adapter in Mb/s. If the - * link is not up returns %0 and negative errno in case of failure. - */ -int usb4_usb3_port_actual_link_rate(struct tb_port *port) -{ - int ret, lr; - u32 val; - - if (!tb_port_is_usb3_down(port) && !tb_port_is_usb3_up(port)) - return -EINVAL; - - ret = tb_port_read(port, &val, TB_CFG_PORT, - port->cap_adap + ADP_USB3_CS_4, 1); - if (ret) - return ret; - - if (!(val & ADP_USB3_CS_4_ULV)) - return 0; - - lr = val & ADP_USB3_CS_4_ALR_MASK; - ret = lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000; - - return usb4_usb3_port_max_bandwidth(port, ret); -} - static int usb4_usb3_port_cm_request(struct tb_port *port, bool request) { int ret; diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 98764e740c07..34c01874f45b 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -377,18 +377,21 @@ void xen_console_resume(void) #ifdef CONFIG_HVC_XEN_FRONTEND static void xencons_disconnect_backend(struct xencons_info *info) { - if (info->irq > 0) - unbind_from_irqhandler(info->irq, NULL); - info->irq = 0; + if (info->hvc != NULL) + hvc_remove(info->hvc); + info->hvc = NULL; + if (info->irq > 0) { + evtchn_put(info->evtchn); + info->irq = 0; + info->evtchn = 0; + } + /* evtchn_put() will also close it so this is only an error path */ if (info->evtchn > 0) xenbus_free_evtchn(info->xbdev, info->evtchn); info->evtchn = 0; if (info->gntref > 0) gnttab_free_grant_references(info->gntref); info->gntref = 0; - if (info->hvc != NULL) - hvc_remove(info->hvc); - info->hvc = NULL; } static void xencons_free(struct xencons_info *info) @@ -433,7 +436,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, if (ret) return ret; info->evtchn = evtchn; - irq = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn); + irq = bind_evtchn_to_irq_lateeoi(evtchn); if (irq < 0) return irq; info->irq = irq; @@ -553,10 +556,23 @@ static void xencons_backend_changed(struct xenbus_device *dev, if (dev->state == XenbusStateClosed) break; fallthrough; /* Missed the backend's CLOSING state */ - case XenbusStateClosing: + case XenbusStateClosing: { + struct xencons_info *info = dev_get_drvdata(&dev->dev);; + + /* + * Don't tear down the evtchn and grant ref before the other + * end has disconnected, but do stop userspace from trying + * to use the device before we allow the backend to close. + */ + if (info->hvc) { + hvc_remove(info->hvc); + info->hvc = NULL; + } + xenbus_frontend_closed(dev); break; } + } } static const struct xenbus_device_id xencons_ids[] = { @@ -588,7 +604,7 @@ static int __init xen_hvc_init(void) ops = &dom0_hvc_ops; r = xen_initial_domain_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); } else { ops = &domU_hvc_ops; @@ -597,7 +613,7 @@ static int __init xen_hvc_init(void) else r = xen_pv_console_init(); if (r < 0) - return r; + goto register_fe; info = vtermno_to_xencons(HVC_COOKIE); info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn); @@ -616,12 +632,13 @@ static int __init xen_hvc_init(void) list_del(&info->list); spin_unlock_irqrestore(&xencons_lock, flags); if (info->irq) - unbind_from_irqhandler(info->irq, NULL); + evtchn_put(info->evtchn); kfree(info); return r; } r = 0; + register_fe: #ifdef CONFIG_HVC_XEN_FRONTEND r = xenbus_register_frontend(&xencons_driver); #endif diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 98433a53bae1..f57fd9095f75 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -664,7 +664,6 @@ static void hvcs_return_index(int index) static void hvcs_destruct_port(struct tty_port *p) { struct hvcs_struct *hvcsd = container_of(p, struct hvcs_struct, port); - struct vio_dev *vdev; struct completion *comp; unsigned long flags; @@ -686,7 +685,6 @@ static void hvcs_destruct_port(struct tty_port *p) printk(KERN_INFO "HVCS: Destroyed hvcs_struct for vty-server@%X.\n", hvcsd->vdev->unit_address); - vdev = hvcsd->vdev; hvcsd->vdev = NULL; hvcsd->p_unit_address = 0; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 10aa4ed38793..6ce7f259968f 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -288,7 +288,7 @@ struct mxser_board { enum mxser_must_hwid must_hwid; speed_t max_baud; - struct mxser_port ports[]; + struct mxser_port ports[] __counted_by(nports); }; static DECLARE_BITMAP(mxser_boards, MXSER_BOARDS); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1f3aba607cd5..a3ab3946e4ad 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2,6 +2,7 @@ /* * n_gsm.c GSM 0710 tty multiplexor * Copyright (c) 2009/10 Intel Corporation + * Copyright (c) 2022/23 Siemens Mobility GmbH * * * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE * * @@ -4108,6 +4109,8 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk) static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk) { + if (dlci->gsm->dead) + return -EL2HLT; if (dlci->adaption == 2) { /* Send convergence layer type 2 empty data frame. */ gsm_modem_upd_via_data(dlci, brk); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 6c9a408d67cd..f252d0b5a434 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -249,15 +249,12 @@ static void n_tty_check_throttle(struct tty_struct *tty) if (ldata->icanon && ldata->canon_head == ldata->read_tail) return; - while (1) { - int throttled; + do { tty_set_flow_change(tty, TTY_THROTTLE_SAFE); if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE) break; - throttled = tty_throttle_safe(tty); - if (!throttled) - break; - } + } while (!tty_throttle_safe(tty)); + __tty_set_flow_change(tty, 0); } @@ -279,16 +276,14 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) * we won't get any more characters. */ - while (1) { - int unthrottled; + do { tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE) break; + n_tty_kick_worker(tty); - unthrottled = tty_unthrottle_safe(tty); - if (!unthrottled) - break; - } + } while (!tty_unthrottle_safe(tty)); + __tty_set_flow_change(tty, 0); } @@ -1965,26 +1960,27 @@ static bool copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, size_t head = smp_load_acquire(&ldata->commit_head); size_t tail = MASK(ldata->read_tail); - n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); - n = min(*nr, n); - if (n) { - u8 *from = read_buf_addr(ldata, tail); - memcpy(*kbp, from, n); - is_eof = n == 1 && *from == EOF_CHAR(tty); - tty_audit_add_data(tty, from, n); - zero_buffer(tty, from, n); - smp_store_release(&ldata->read_tail, ldata->read_tail + n); - /* Turn single EOF into zero-length read */ - if (L_EXTPROC(tty) && ldata->icanon && is_eof && - (head == ldata->read_tail)) - return false; - *kbp += n; - *nr -= n; + n = min3(head - ldata->read_tail, N_TTY_BUF_SIZE - tail, *nr); + if (!n) + return false; - /* If we have more to copy, let the caller know */ - return head != ldata->read_tail; - } - return false; + u8 *from = read_buf_addr(ldata, tail); + memcpy(*kbp, from, n); + is_eof = n == 1 && *from == EOF_CHAR(tty); + tty_audit_add_data(tty, from, n); + zero_buffer(tty, from, n); + smp_store_release(&ldata->read_tail, ldata->read_tail + n); + + /* Turn single EOF into zero-length read */ + if (L_EXTPROC(tty) && ldata->icanon && is_eof && + head == ldata->read_tail) + return false; + + *kbp += n; + *nr -= n; + + /* If we have more to copy, let the caller know */ + return head != ldata->read_tail; } /** @@ -2154,9 +2150,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, struct n_tty_data *ldata = tty->disc_data; u8 *kb = kbuf; DEFINE_WAIT_FUNC(wait, woken_wake_function); - int c; int minimum, time; - ssize_t retval = 0; + ssize_t retval; long timeout; bool packet; size_t old_tail; @@ -2192,9 +2187,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, return kb - kbuf; } - c = job_control(tty, file); - if (c < 0) - return c; + retval = job_control(tty, file); + if (retval < 0) + return retval; /* * Internal serialization of reads. @@ -2499,7 +2494,7 @@ static int n_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct n_tty_data *ldata = tty->disc_data; - int retval; + unsigned int num; switch (cmd) { case TIOCOUTQ: @@ -2507,11 +2502,11 @@ static int n_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case TIOCINQ: down_write(&tty->termios_rwsem); if (L_ICANON(tty) && !L_EXTPROC(tty)) - retval = inq_canon(ldata); + num = inq_canon(ldata); else - retval = read_cnt(ldata); + num = read_cnt(ldata); up_write(&tty->termios_rwsem); - return put_user(retval, (unsigned int __user *) arg); + return put_user(num, (unsigned int __user *) arg); default: return n_tty_ioctl_helper(tty, cmd, arg); } diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index e7d663901c07..a5fdaf5e148e 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -15,9 +15,11 @@ #include #include #include +#include #include #include #include + #include static bool is_registered; @@ -185,30 +187,20 @@ void serdev_device_close(struct serdev_device *serdev) } EXPORT_SYMBOL_GPL(serdev_device_close); -static void devm_serdev_device_release(struct device *dev, void *dr) +static void devm_serdev_device_close(void *serdev) { - serdev_device_close(*(struct serdev_device **)dr); + serdev_device_close(serdev); } int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev) { - struct serdev_device **dr; int ret; - dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - ret = serdev_device_open(serdev); - if (ret) { - devres_free(dr); + if (ret) return ret; - } - *dr = serdev; - devres_add(dev, dr); - - return 0; + return devm_add_action_or_reset(dev, devm_serdev_device_close, serdev); } EXPORT_SYMBOL_GPL(devm_serdev_device_open); @@ -510,7 +502,7 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent, ctrl->dev.type = &serdev_ctrl_type; ctrl->dev.bus = &serdev_bus_type; ctrl->dev.parent = parent; - ctrl->dev.of_node = parent->of_node; + device_set_node(&ctrl->dev, dev_fwnode(parent)); serdev_controller_set_drvdata(ctrl, &ctrl[1]); dev_set_name(&ctrl->dev, "serial%d", id); @@ -673,7 +665,7 @@ static int acpi_serdev_check_resources(struct serdev_controller *ctrl, acpi_get_parent(adev->handle, &lookup.controller_handle); /* Make sure controller and ResourceSource handle match */ - if (ACPI_HANDLE(ctrl->dev.parent) != lookup.controller_handle) + if (!device_match_acpi_handle(ctrl->dev.parent, lookup.controller_handle)) return -ENODEV; return 0; diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index d756fcc884cb..4de0c975ebdc 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -185,14 +185,14 @@ static void serial21285_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int h_lcr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); h_lcr = *CSR_H_UBRLCR; if (break_state) h_lcr |= H_UBRLCR_BREAK; else h_lcr &= ~H_UBRLCR_BREAK; *CSR_H_UBRLCR = h_lcr; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int serial21285_startup(struct uart_port *port) @@ -272,7 +272,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, if (port->fifosize) h_lcr |= H_UBRLCR_FIFO; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -309,7 +309,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, *CSR_H_UBRLCR = h_lcr; *CSR_UARTCON = 1; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *serial21285_type(struct uart_port *port) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 4a9e71b2dbbc..d7482ae33a1c 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -34,7 +34,6 @@ struct aspeed_vuart { struct device *dev; - struct clk *clk; int line; struct timer_list unthrottle_timer; struct uart_8250_port *port; @@ -288,9 +287,9 @@ static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle) struct uart_8250_port *up = up_to_u8250p(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __aspeed_vuart_set_throttle(up, throttle); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void aspeed_vuart_throttle(struct uart_port *port) @@ -340,7 +339,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) if (iir & UART_IIR_NO_INT) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lsr = serial_port_in(port, UART_LSR); @@ -415,12 +414,14 @@ static int aspeed_vuart_map_irq_polarity(u32 dt) static int aspeed_vuart_probe(struct platform_device *pdev) { struct of_phandle_args sirq_polarity_sense_args; + struct device *dev = &pdev->dev; struct uart_8250_port port; struct aspeed_vuart *vuart; struct device_node *np; struct resource *res; u32 clk, prop, sirq[2]; int rc, sirq_polarity; + struct clk *vclk; np = pdev->dev.of_node; @@ -453,19 +454,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev) return rc; if (of_property_read_u32(np, "clock-frequency", &clk)) { - vuart->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(vuart->clk)) { - dev_warn(&pdev->dev, - "clk or clock-frequency not defined\n"); - rc = PTR_ERR(vuart->clk); + vclk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(vclk)) { + rc = dev_err_probe(dev, PTR_ERR(vclk), "clk or clock-frequency not defined\n"); goto err_sysfs_remove; } - rc = clk_prepare_enable(vuart->clk); - if (rc < 0) - goto err_sysfs_remove; - - clk = clk_get_rate(vuart->clk); + clk = clk_get_rate(vclk); } /* If current-speed was set, then try not to change it. */ @@ -533,7 +528,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev) rc = aspeed_vuart_set_lpc_address(vuart, prop); if (rc < 0) { - dev_err(&pdev->dev, "invalid value in aspeed,lpc-io-reg property\n"); + dev_err_probe(dev, rc, "invalid value in aspeed,lpc-io-reg property\n"); goto err_clk_disable; } @@ -545,14 +540,14 @@ static int aspeed_vuart_probe(struct platform_device *pdev) rc = aspeed_vuart_set_sirq(vuart, sirq[0]); if (rc < 0) { - dev_err(&pdev->dev, "invalid sirq number in aspeed,lpc-interrupts property\n"); + dev_err_probe(dev, rc, "invalid sirq number in aspeed,lpc-interrupts property\n"); goto err_clk_disable; } sirq_polarity = aspeed_vuart_map_irq_polarity(sirq[1]); if (sirq_polarity < 0) { - dev_err(&pdev->dev, "invalid sirq polarity in aspeed,lpc-interrupts property\n"); - rc = sirq_polarity; + rc = dev_err_probe(dev, sirq_polarity, + "invalid sirq polarity in aspeed,lpc-interrupts property\n"); goto err_clk_disable; } @@ -565,7 +560,6 @@ static int aspeed_vuart_probe(struct platform_device *pdev) return 0; err_clk_disable: - clk_disable_unprepare(vuart->clk); irq_dispose_mapping(port.port.irq); err_sysfs_remove: sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); @@ -580,7 +574,6 @@ static int aspeed_vuart_remove(struct platform_device *pdev) aspeed_vuart_set_enabled(vuart, false); serial8250_unregister_port(vuart->line); sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); - clk_disable_unprepare(vuart->clk); return 0; } diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index aa5aff046756..55dea2539c47 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -567,7 +567,7 @@ static irqreturn_t brcmuart_isr(int irq, void *dev_id) if (interrupts == 0) return IRQ_NONE; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); /* Clear all interrupts */ udma_writel(priv, REGS_DMA_ISR, UDMA_INTR_CLEAR, interrupts); @@ -581,7 +581,7 @@ static irqreturn_t brcmuart_isr(int irq, void *dev_id) if ((rval | tval) == 0) dev_warn(dev, "Spurious interrupt: 0x%x\n", interrupts); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); return IRQ_HANDLED; } @@ -608,10 +608,10 @@ static int brcmuart_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier &= ~UART_IER_RDI; serial_port_out(port, UART_IER, up->ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); priv->tx_running = false; priv->dma.rx_dma = NULL; @@ -629,7 +629,7 @@ static void brcmuart_shutdown(struct uart_port *port) struct brcmuart_priv *priv = up->port.private_data; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->shutdown = true; if (priv->dma_enabled) { stop_rx_dma(up); @@ -645,7 +645,7 @@ static void brcmuart_shutdown(struct uart_port *port) */ up->dma = NULL; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_do_shutdown(port); } @@ -788,7 +788,7 @@ static int brcmuart_handle_irq(struct uart_port *p) * interrupt but there is no data ready. */ if (((iir & UART_IIR_ID) == UART_IIR_RX_TIMEOUT) && !(priv->shutdown)) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_port_in(p, UART_LSR); if ((status & UART_LSR_DR) == 0) { @@ -813,7 +813,7 @@ static int brcmuart_handle_irq(struct uart_port *p) handled = 1; } - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); if (handled) return 1; } @@ -831,7 +831,7 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) if (priv->shutdown) return HRTIMER_NORESTART; - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_port_in(p, UART_LSR); /* @@ -855,7 +855,7 @@ static enum hrtimer_restart brcmuart_hrtimer_func(struct hrtimer *t) status |= UART_MCR_RTS; serial_port_out(p, UART_MCR, status); } - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); return HRTIMER_NORESTART; } @@ -984,10 +984,9 @@ static int brcmuart_probe(struct platform_device *pdev) } /* We should have just the uart base registers or all the registers */ - if (x != 1 && x != REGS_MAX) { - dev_warn(dev, "%s registers not specified\n", reg_names[x]); - return -EINVAL; - } + if (x != 1 && x != REGS_MAX) + return dev_err_probe(dev, -EINVAL, "%s registers not specified\n", + reg_names[x]); /* if the DMA registers were specified, try to enable DMA */ if (x > REGS_DMA_RX) { @@ -1016,27 +1015,23 @@ static int brcmuart_probe(struct platform_device *pdev) of_property_read_u32(np, "clock-frequency", &clk_rate); /* See if a Baud clock has been specified */ - baud_mux_clk = devm_clk_get(dev, "sw_baud"); - if (IS_ERR(baud_mux_clk)) { - if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto release_dma; - } - dev_dbg(dev, "BAUD MUX clock not specified\n"); - } else { + baud_mux_clk = devm_clk_get_optional_enabled(dev, "sw_baud"); + ret = PTR_ERR_OR_ZERO(baud_mux_clk); + if (ret) + goto release_dma; + if (baud_mux_clk) { dev_dbg(dev, "BAUD MUX clock found\n"); - ret = clk_prepare_enable(baud_mux_clk); - if (ret) - goto release_dma; + priv->baud_mux_clk = baud_mux_clk; init_real_clk_rates(dev, priv); clk_rate = priv->default_mux_rate; + } else { + dev_dbg(dev, "BAUD MUX clock not specified\n"); } if (clk_rate == 0) { - dev_err(dev, "clock-frequency or clk not defined\n"); - ret = -EINVAL; - goto err_clk_disable; + ret = dev_err_probe(dev, -EINVAL, "clock-frequency or clk not defined\n"); + goto release_dma; } dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not "); @@ -1093,7 +1088,7 @@ static int brcmuart_probe(struct platform_device *pdev) ret = serial8250_register_8250_port(&up); if (ret < 0) { - dev_err(dev, "unable to register 8250 port\n"); + dev_err_probe(dev, ret, "unable to register 8250 port\n"); goto err; } priv->line = ret; @@ -1102,14 +1097,13 @@ static int brcmuart_probe(struct platform_device *pdev) if (priv->dma_enabled) { dma_irq = platform_get_irq_byname(pdev, "dma"); if (dma_irq < 0) { - ret = dma_irq; - dev_err(dev, "no IRQ resource info\n"); + ret = dev_err_probe(dev, dma_irq, "no IRQ resource info\n"); goto err1; } ret = devm_request_irq(dev, dma_irq, brcmuart_isr, IRQF_SHARED, "uart DMA irq", &new_port->port); if (ret) { - dev_err(dev, "unable to register IRQ handler\n"); + dev_err_probe(dev, ret, "unable to register IRQ handler\n"); goto err1; } } @@ -1121,8 +1115,6 @@ err1: serial8250_unregister_port(priv->line); err: brcmuart_free_bufs(dev, priv); -err_clk_disable: - clk_disable_unprepare(baud_mux_clk); release_dma: if (priv->dma_enabled) brcmuart_arbitration(priv, 0); @@ -1137,7 +1129,6 @@ static int brcmuart_remove(struct platform_device *pdev) hrtimer_cancel(&priv->hrt); serial8250_unregister_port(priv->line); brcmuart_free_bufs(&pdev->dev, priv); - clk_disable_unprepare(priv->baud_mux_clk); if (priv->dma_enabled) brcmuart_arbitration(priv, 0); return 0; @@ -1154,10 +1145,10 @@ static int __maybe_unused brcmuart_suspend(struct device *dev) * This will prevent resume from enabling RTS before the * baud rate has been restored. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->saved_mctrl = port->mctrl; port->mctrl &= ~TIOCM_RTS; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_suspend_port(priv->line); clk_disable_unprepare(priv->baud_mux_clk); @@ -1196,10 +1187,10 @@ static int __maybe_unused brcmuart_resume(struct device *dev) if (priv->saved_mctrl & TIOCM_RTS) { /* Restore RTS */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl |= TIOCM_RTS; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } return 0; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 3449f8790e46..912733151858 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -259,7 +259,7 @@ static void serial8250_backup_timeout(struct timer_list *t) unsigned int iir, ier = 0, lsr; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Must disable interrupts or else we risk racing with the interrupt @@ -292,7 +292,7 @@ static void serial8250_backup_timeout(struct timer_list *t) if (up->port.irq) serial_out(up, UART_IER, ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* Standard timer interval plus 0.2s to keep the port running */ mod_timer(&up->timer, @@ -611,7 +611,7 @@ static int univ8250_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index >= UART_NR) + if (co->index < 0 || co->index >= UART_NR) co->index = 0; /* @@ -992,11 +992,11 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work) struct uart_port *port = &up->port; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->ier |= UART_IER_RLSI | UART_IER_RDI; up->port.read_status_mask |= UART_LSR_DR; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -1194,9 +1194,9 @@ void serial8250_unregister_port(int line) if (uart->em485) { unsigned long flags; - spin_lock_irqsave(&uart->port.lock, flags); + uart_port_lock_irqsave(&uart->port, &flags); serial8250_em485_destroy(uart); - spin_unlock_irqrestore(&uart->port.lock, flags); + uart_port_unlock_irqrestore(&uart->port, flags); } uart_remove_one_port(&serial8250_reg, &uart->port); diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 7fa66501792d..8b30ca8fdd3f 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -22,7 +22,7 @@ static void __dma_tx_complete(void *param) dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); dma->tx_running = 0; @@ -35,7 +35,7 @@ static void __dma_tx_complete(void *param) if (ret || !dma->tx_running) serial8250_set_THRI(p); - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static void __dma_rx_complete(struct uart_8250_port *p) @@ -70,7 +70,7 @@ static void dma_rx_complete(void *param) struct uart_8250_dma *dma = p->dma; unsigned long flags; - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (dma->rx_running) __dma_rx_complete(p); @@ -80,7 +80,7 @@ static void dma_rx_complete(void *param) */ if (!dma->rx_running && (serial_lsr_in(p) & UART_LSR_DR)) p->dma->rx_dma(p); - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } int serial8250_tx_dma(struct uart_8250_port *p) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index f4cafca1a7da..b94f567647cb 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -263,20 +263,20 @@ static int dw8250_handle_irq(struct uart_port *p) * so we limit the workaround only to non-DMA mode. */ if (!up->dma && rx_timeout) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_lsr_in(up); if (!(status & (UART_LSR_DR | UART_LSR_BI))) (void) p->serial_in(p, UART_RX); - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); } /* Manually stop the Rx DMA transfer when acting as flow controller */ if (quirks & DW_UART_QUIRK_IS_DMA_FC && up->dma && up->dma->rx_running && rx_timeout) { - spin_lock_irqsave(&p->lock, flags); + uart_port_lock_irqsave(p, &flags); status = serial_lsr_in(up); - spin_unlock_irqrestore(&p->lock, flags); + uart_port_unlock_irqrestore(p, flags); if (status & (UART_LSR_DR | UART_LSR_BI)) { dw8250_writel_ext(p, RZN1_UART_RDMACR, 0); @@ -498,11 +498,6 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) } } -static void dw8250_clk_disable_unprepare(void *data) -{ - clk_disable_unprepare(data); -} - static void dw8250_reset_control_assert(void *data) { reset_control_assert(data); @@ -598,23 +593,15 @@ static int dw8250_probe(struct platform_device *pdev) device_property_read_u32(dev, "clock-frequency", &p->uartclk); /* If there is separate baudclk, get the rate from it. */ - data->clk = devm_clk_get_optional(dev, "baudclk"); + data->clk = devm_clk_get_optional_enabled(dev, "baudclk"); if (data->clk == NULL) - data->clk = devm_clk_get_optional(dev, NULL); + data->clk = devm_clk_get_optional_enabled(dev, NULL); if (IS_ERR(data->clk)) return PTR_ERR(data->clk); INIT_WORK(&data->clk_work, dw8250_clk_work_cb); data->clk_notifier.notifier_call = dw8250_clk_notifier_cb; - err = clk_prepare_enable(data->clk); - if (err) - return dev_err_probe(dev, err, "could not enable optional baudclk\n"); - - err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->clk); - if (err) - return err; - if (data->clk) p->uartclk = clk_get_rate(data->clk); @@ -622,18 +609,10 @@ static int dw8250_probe(struct platform_device *pdev) if (!p->uartclk) return dev_err_probe(dev, -EINVAL, "clock rate not defined\n"); - data->pclk = devm_clk_get_optional(dev, "apb_pclk"); + data->pclk = devm_clk_get_optional_enabled(dev, "apb_pclk"); if (IS_ERR(data->pclk)) return PTR_ERR(data->pclk); - err = clk_prepare_enable(data->pclk); - if (err) - return dev_err_probe(dev, err, "could not enable apb_pclk\n"); - - err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->pclk); - if (err) - return err; - data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(data->rst)) return PTR_ERR(data->rst); diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 077c3ba3539e..6085d356ad86 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -47,12 +46,6 @@ #define PCI_SUBDEVICE_ID_USR_2980 0x0128 #define PCI_SUBDEVICE_ID_USR_2981 0x0129 -#define PCI_DEVICE_ID_SEALEVEL_710xC 0x1001 -#define PCI_DEVICE_ID_SEALEVEL_720xC 0x1002 -#define PCI_DEVICE_ID_SEALEVEL_740xC 0x1004 -#define PCI_DEVICE_ID_SEALEVEL_780xC 0x1008 -#define PCI_DEVICE_ID_SEALEVEL_716xC 0x1010 - #define UART_EXAR_INT0 0x80 #define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ #define UART_EXAR_SLEEP 0x8b /* Sleep mode */ @@ -84,6 +77,9 @@ #define UART_EXAR_RS485_DLY(x) ((x) << 4) +#define UART_EXAR_DLD 0x02 /* Divisor Fractional */ +#define UART_EXAR_DLD_485_POLARITY 0x80 /* RS-485 Enable Signal Polarity */ + /* * IOT2040 MPIO wiring semantics: * @@ -201,9 +197,9 @@ static int xr17v35x_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_port_out(port, UART_IER, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); return serial8250_do_startup(port); } @@ -445,6 +441,44 @@ static int generic_rs485_config(struct uart_port *port, struct ktermios *termios return 0; } +static int sealevel_rs485_config(struct uart_port *port, struct ktermios *termios, + struct serial_rs485 *rs485) +{ + u8 __iomem *p = port->membase; + u8 old_lcr; + u8 efr; + u8 dld; + int ret; + + ret = generic_rs485_config(port, termios, rs485); + if (ret) + return ret; + + if (rs485->flags & SER_RS485_ENABLED) { + old_lcr = readb(p + UART_LCR); + + /* Set EFR[4]=1 to enable enhanced feature registers */ + efr = readb(p + UART_XR_EFR); + efr |= UART_EFR_ECB; + writeb(efr, p + UART_XR_EFR); + + /* Set MCR to use DTR as Auto-RS485 Enable signal */ + writeb(UART_MCR_OUT1, p + UART_MCR); + + /* Set LCR[7]=1 to enable access to DLD register */ + writeb(old_lcr | UART_LCR_DLAB, p + UART_LCR); + + /* Set DLD[7]=1 for inverted RS485 Enable logic */ + dld = readb(p + UART_EXAR_DLD); + dld |= UART_EXAR_DLD_485_POLARITY; + writeb(dld, p + UART_EXAR_DLD); + + writeb(old_lcr, p + UART_LCR); + } + + return 0; +} + static const struct serial_rs485 generic_rs485_supported = { .flags = SER_RS485_ENABLED, }; @@ -566,6 +600,9 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, port->port.rs485_config = platform->rs485_config; port->port.rs485_supported = *(platform->rs485_supported); + if (pcidev->subsystem_vendor == PCI_VENDOR_ID_SEALEVEL) + port->port.rs485_config = sealevel_rs485_config; + /* * Setup the UART clock for the devices on expansion slot to * half the clock speed of the main chip (which is 125MHz) @@ -652,8 +689,6 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1); else if (board->num_ports) nr_ports = board->num_ports; - else if (pcidev->vendor == PCI_VENDOR_ID_SEALEVEL) - nr_ports = pcidev->device & 0xff; else nr_ports = pcidev->device & 0x0f; @@ -893,12 +928,6 @@ static const struct pci_device_id exar_pci_tbl[] = { EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8), - - EXAR_DEVICE(SEALEVEL, 710xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 720xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 740xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 780xC, pbn_exar_XR17V35x), - EXAR_DEVICE(SEALEVEL, 716xC, pbn_exar_XR17V35x), { 0, } }; MODULE_DEVICE_TABLE(pci, exar_pci_tbl); diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 6af4e1c1210a..f522eb5026c9 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -30,11 +30,11 @@ int fsl8250_handle_irq(struct uart_port *port) unsigned int iir; struct uart_8250_port *up = up_to_u8250p(port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); iir = port->serial_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) { - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -54,7 +54,7 @@ int fsl8250_handle_irq(struct uart_port *port) if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) { up->lsr_saved_flags &= ~UART_LSR_BI; port->serial_in(port, UART_RX); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 1; } diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 2cc78a4bf7a1..8ec03863606e 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c @@ -12,7 +12,6 @@ #include #include -#include #include "8250.h" @@ -32,9 +31,9 @@ struct mid8250; struct mid8250_board { - unsigned int flags; unsigned long freq; unsigned int base_baud; + unsigned int bar; int (*setup)(struct mid8250 *, struct uart_port *p); void (*exit)(struct mid8250 *); }; @@ -169,7 +168,6 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) { struct hsu_dma_chip *chip = &mid->dma_chip; struct pci_dev *pdev = to_pci_dev(p->dev); - unsigned int bar = FL_GET_BASE(mid->board->flags); int ret; pci_set_master(pdev); @@ -183,7 +181,7 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p) chip->dev = &pdev->dev; chip->irq = pci_irq_vector(pdev, 0); chip->regs = p->membase; - chip->length = pci_resource_len(pdev, bar); + chip->length = pci_resource_len(pdev, mid->board->bar); chip->offset = DNV_DMA_CHAN_OFFSET; /* Falling back to PIO mode if DMA probing fails */ @@ -291,7 +289,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct uart_8250_port uart; struct mid8250 *mid; - unsigned int bar; int ret; ret = pcim_enable_device(pdev); @@ -303,7 +300,6 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; mid->board = (struct mid8250_board *)id->driver_data; - bar = FL_GET_BASE(mid->board->flags); memset(&uart, 0, sizeof(struct uart_8250_port)); @@ -316,8 +312,8 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id) uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; uart.port.set_termios = mid8250_set_termios; - uart.port.mapbase = pci_resource_start(pdev, bar); - uart.port.membase = pcim_iomap(pdev, bar, 0); + uart.port.mapbase = pci_resource_start(pdev, mid->board->bar); + uart.port.membase = pcim_iomap(pdev, mid->board->bar, 0); if (!uart.port.membase) return -ENOMEM; @@ -353,25 +349,25 @@ static void mid8250_remove(struct pci_dev *pdev) } static const struct mid8250_board pnw_board = { - .flags = FL_BASE0, .freq = 50000000, .base_baud = 115200, + .bar = 0, .setup = pnw_setup, .exit = pnw_exit, }; static const struct mid8250_board tng_board = { - .flags = FL_BASE0, .freq = 38400000, .base_baud = 1843200, + .bar = 0, .setup = tng_setup, .exit = tng_exit, }; static const struct mid8250_board dnv_board = { - .flags = FL_BASE1, .freq = 133333333, .base_baud = 115200, + .bar = 1, .setup = dnv_setup, .exit = dnv_exit, }; diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 74da5676ce67..23457daae8a1 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -102,7 +102,7 @@ static void mtk8250_dma_rx_complete(void *param) if (data->rx_status == DMA_RX_SHUTDOWN) return; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); total = dma->rx_size - state.residue; @@ -128,7 +128,7 @@ static void mtk8250_dma_rx_complete(void *param) mtk8250_rx_dma(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void mtk8250_rx_dma(struct uart_8250_port *up) @@ -368,7 +368,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -416,7 +416,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, if (uart_console(port)) up->port.cons->cflag = termios->c_cflag; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 51329625c48a..ef3e745bd09c 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -33,7 +33,8 @@ static int of_platform_serial_setup(struct platform_device *ofdev, struct of_serial_info *info) { struct resource resource; - struct device_node *np = ofdev->dev.of_node; + struct device *dev = &ofdev->dev; + struct device_node *np = dev->of_node; struct uart_port *port = &up->port; u32 clk, spd, prop; int ret, irq; @@ -46,19 +47,12 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_property_read_u32(np, "clock-frequency", &clk)) { /* Get clk rate through clk driver if present */ - info->clk = devm_clk_get(&ofdev->dev, NULL); + info->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(info->clk)) { - ret = PTR_ERR(info->clk); - if (ret != -EPROBE_DEFER) - dev_warn(&ofdev->dev, - "failed to get clock: %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(info->clk), "failed to get clock\n"); goto err_pmruntime; } - ret = clk_prepare_enable(info->clk); - if (ret < 0) - goto err_pmruntime; - clk = clk_get_rate(info->clk); } /* If current-speed was set, then try not to change it. */ @@ -67,8 +61,8 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { - dev_warn(&ofdev->dev, "invalid address\n"); - goto err_unprepare; + dev_err_probe(dev, ret, "invalid address\n"); + goto err_pmruntime; } port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | @@ -85,10 +79,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, /* Check for shifted address mapping */ if (of_property_read_u32(np, "reg-offset", &prop) == 0) { if (prop >= port->mapsize) { - dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n", - prop, &port->mapsize); - ret = -EINVAL; - goto err_unprepare; + ret = dev_err_probe(dev, -EINVAL, "reg-offset %u exceeds region size %pa\n", + prop, &port->mapsize); + goto err_pmruntime; } port->mapbase += prop; @@ -109,10 +102,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev, UPIO_MEM32BE : UPIO_MEM32; break; default: - dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", - prop); - ret = -EINVAL; - goto err_unprepare; + ret = dev_err_probe(dev, -EINVAL, "unsupported reg-io-width (%u)\n", + prop); + goto err_pmruntime; } } port->flags |= UPF_IOREMAP; @@ -139,7 +131,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (irq < 0) { if (irq == -EPROBE_DEFER) { ret = -EPROBE_DEFER; - goto err_unprepare; + goto err_pmruntime; } /* IRQ support not mandatory */ irq = 0; @@ -150,12 +142,12 @@ static int of_platform_serial_setup(struct platform_device *ofdev, info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); if (IS_ERR(info->rst)) { ret = PTR_ERR(info->rst); - goto err_unprepare; + goto err_pmruntime; } ret = reset_control_deassert(info->rst); if (ret) - goto err_unprepare; + goto err_pmruntime; port->type = type; port->uartclk = clk; @@ -173,7 +165,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, case PORT_RT2880: ret = rt288x_setup(port); if (ret) - goto err_unprepare; + goto err_pmruntime; break; } @@ -185,8 +177,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, } return 0; -err_unprepare: - clk_disable_unprepare(info->clk); err_pmruntime: pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); @@ -253,7 +243,6 @@ err_dispose: irq_dispose_mapping(port8250.port.irq); pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); - clk_disable_unprepare(info->clk); err_free: kfree(info); return ret; @@ -271,7 +260,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) reset_control_assert(info->rst); pm_runtime_put_sync(&ofdev->dev); pm_runtime_disable(&ofdev->dev); - clk_disable_unprepare(info->clk); kfree(info); return 0; } diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index ca972fd37725..2d42f485c987 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include "8250.h" @@ -114,6 +116,12 @@ /* RX FIFO occupancy indicator */ #define UART_OMAP_RX_LVL 0x19 +/* + * Copy of the genpd flags for the console. + * Only used if console suspend is disabled + */ +static unsigned int genpd_flags_console; + struct omap8250_priv { void __iomem *membase; int line; @@ -130,6 +138,7 @@ struct omap8250_priv { u8 tx_trigger; u8 rx_trigger; + atomic_t active; bool is_suspending; int wakeirq; int wakeups_enabled; @@ -401,7 +410,7 @@ static void omap_8250_set_termios(struct uart_port *port, * interrupts disabled. */ pm_runtime_get_sync(port->dev); - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); /* * Update the per-port timeout. @@ -504,7 +513,7 @@ static void omap_8250_set_termios(struct uart_port *port, } omap8250_restore_regs(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -529,7 +538,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, pm_runtime_get_sync(port->dev); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); efr = serial_in(up, UART_EFR); @@ -541,7 +550,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -632,14 +641,23 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) unsigned int iir, lsr; int ret; + pm_runtime_get_noresume(port->dev); + + /* Shallow idle state wake-up to an IO interrupt? */ + if (atomic_add_unless(&priv->active, 1, 1)) { + priv->latency = priv->calc_latency; + schedule_work(&priv->qos_work); + } + #ifdef CONFIG_SERIAL_8250_DMA if (up->dma) { ret = omap_8250_dma_handle_irq(port); + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put(port->dev); return IRQ_RETVAL(ret); } #endif - serial8250_rpm_get(up); lsr = serial_port_in(port, UART_LSR); iir = serial_port_in(port, UART_IIR); ret = serial8250_handle_irq(port, iir); @@ -660,7 +678,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) unsigned long delay; /* Synchronize UART_IER access against the console. */ - spin_lock(&port->lock); + uart_port_lock(port); up->ier = port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { port->ops->stop_rx(port); @@ -670,13 +688,14 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) */ cancel_delayed_work(&up->overrun_backoff); } - spin_unlock(&port->lock); + uart_port_unlock(port); delay = msecs_to_jiffies(up->overrun_backoff_time_ms); schedule_delayed_work(&up->overrun_backoff, delay); } - serial8250_rpm_put(up); + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put(port->dev); return IRQ_RETVAL(ret); } @@ -717,10 +736,10 @@ static int omap_8250_startup(struct uart_port *port) } /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); #ifdef CONFIG_PM up->capabilities |= UART_CAP_RPM; @@ -733,9 +752,9 @@ static int omap_8250_startup(struct uart_port *port) serial_out(up, UART_OMAP_WER, priv->wer); if (up->dma && !(priv->habit & UART_HAS_EFR2)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->dma->rx_dma(up); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } enable_irq(up->port.irq); @@ -761,10 +780,10 @@ static void omap_8250_shutdown(struct uart_port *port) serial_out(up, UART_OMAP_EFR2, 0x0); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); up->ier = 0; serial_out(up, UART_IER, 0); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); disable_irq_nosync(up->port.irq); dev_pm_clear_wake_irq(port->dev); @@ -789,10 +808,10 @@ static void omap_8250_throttle(struct uart_port *port) pm_runtime_get_sync(port->dev); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->ops->stop_rx(port); priv->throttled = true; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -807,14 +826,14 @@ static void omap_8250_unthrottle(struct uart_port *port) pm_runtime_get_sync(port->dev); /* Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); priv->throttled = false; if (up->dma) up->dma->rx_dma(up); up->ier |= UART_IER_RLSI | UART_IER_RDI; port->read_status_mask |= UART_LSR_DR; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); @@ -958,7 +977,7 @@ static void __dma_rx_complete(void *param) unsigned long flags; /* Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); /* * If the tx status is not DMA_COMPLETE, then this is a delayed @@ -967,7 +986,7 @@ static void __dma_rx_complete(void *param) */ if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != DMA_COMPLETE) { - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); return; } __dma_rx_do_complete(p); @@ -978,7 +997,7 @@ static void __dma_rx_complete(void *param) omap_8250_rx_dma(p); } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static void omap_8250_rx_dma_flush(struct uart_8250_port *p) @@ -1083,7 +1102,7 @@ static void omap_8250_dma_tx_complete(void *param) dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); dma->tx_running = 0; @@ -1112,7 +1131,7 @@ static void omap_8250_dma_tx_complete(void *param) serial8250_set_THRI(p); } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); } static int omap_8250_tx_dma(struct uart_8250_port *p) @@ -1270,15 +1289,12 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) u16 status; u8 iir; - serial8250_rpm_get(up); - iir = serial_port_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) { - serial8250_rpm_put(up); return IRQ_HANDLED; } - spin_lock(&port->lock); + uart_port_lock(port); status = serial_port_in(port, UART_LSR); @@ -1305,7 +1321,6 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) uart_unlock_and_check_sysrq(port); - serial8250_rpm_put(up); return 1; } @@ -1503,8 +1518,6 @@ static int omap8250_probe(struct platform_device *pdev) if (!of_get_available_child_count(pdev->dev.of_node)) pm_runtime_set_autosuspend_delay(&pdev->dev, -1); - pm_runtime_irq_safe(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(&up, priv); @@ -1617,6 +1630,7 @@ static int omap8250_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); int err = 0; serial8250_suspend_port(priv->line); @@ -1627,8 +1641,19 @@ static int omap8250_suspend(struct device *dev) if (!device_may_wakeup(dev)) priv->wer = 0; serial_out(up, UART_OMAP_WER, priv->wer); - if (uart_console(&up->port) && console_suspend_enabled) - err = pm_runtime_force_suspend(dev); + if (uart_console(&up->port)) { + if (console_suspend_enabled) + err = pm_runtime_force_suspend(dev); + else { + /* + * The pd shall not be powered-off (no console suspend). + * Make copy of genpd flags before to set it always on. + * The original value is restored during the resume. + */ + genpd_flags_console = genpd->flags; + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + } + } flush_work(&priv->qos_work); return err; @@ -1638,12 +1663,16 @@ static int omap8250_resume(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); int err; if (uart_console(&up->port) && console_suspend_enabled) { - err = pm_runtime_force_resume(dev); - if (err) - return err; + if (console_suspend_enabled) { + err = pm_runtime_force_resume(dev); + if (err) + return err; + } else + genpd->flags = genpd_flags_console; } serial8250_resume_port(priv->line); @@ -1743,6 +1772,7 @@ static int omap8250_runtime_suspend(struct device *dev) priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; schedule_work(&priv->qos_work); + atomic_set(&priv->active, 0); return 0; } @@ -1752,23 +1782,29 @@ static int omap8250_runtime_resume(struct device *dev) struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = NULL; + /* Did the hardware wake to a device IO interrupt before a wakeirq? */ + if (atomic_read(&priv->active)) + return 0; + if (priv->line >= 0) up = serial8250_get_port(priv->line); if (up && omap8250_lost_context(up)) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); omap8250_restore_regs(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); omap_8250_rx_dma(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } + atomic_set(&priv->active, 1); priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); + return 0; } diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 62a9bd30b4db..614be0f13a31 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -26,6 +26,84 @@ #include "8250.h" #include "8250_pcilib.h" +#define PCI_VENDOR_ID_SBSMODULARIO 0x124B +#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B +#define PCI_DEVICE_ID_OCTPRO 0x0001 +#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 +#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 +#define PCI_SUBDEVICE_ID_POCTAL232 0x0308 +#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 +#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 +#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 +#define PCI_VENDOR_ID_ADVANTECH 0x13fe +#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611 +#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 +#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 +#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 +#define PCI_DEVICE_ID_TITAN_200I 0x8028 +#define PCI_DEVICE_ID_TITAN_400I 0x8048 +#define PCI_DEVICE_ID_TITAN_800I 0x8088 +#define PCI_DEVICE_ID_TITAN_800EH 0xA007 +#define PCI_DEVICE_ID_TITAN_800EHB 0xA008 +#define PCI_DEVICE_ID_TITAN_400EH 0xA009 +#define PCI_DEVICE_ID_TITAN_100E 0xA010 +#define PCI_DEVICE_ID_TITAN_200E 0xA012 +#define PCI_DEVICE_ID_TITAN_400E 0xA013 +#define PCI_DEVICE_ID_TITAN_800E 0xA014 +#define PCI_DEVICE_ID_TITAN_200EI 0xA016 +#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 +#define PCI_DEVICE_ID_TITAN_200V3 0xA306 +#define PCI_DEVICE_ID_TITAN_400V3 0xA310 +#define PCI_DEVICE_ID_TITAN_410V3 0xA312 +#define PCI_DEVICE_ID_TITAN_800V3 0xA314 +#define PCI_DEVICE_ID_TITAN_800V3B 0xA315 +#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 +#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 +#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 +#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d +#define PCI_VENDOR_ID_WCH 0x4348 +#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 +#define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 +#define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 +#define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 +#define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 +#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 +#define PCI_VENDOR_ID_AGESTAR 0x5372 +#define PCI_DEVICE_ID_AGESTAR_9375 0x6872 +#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a +#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e + +#define PCIE_VENDOR_ID_WCH 0x1c00 +#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 +#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 +#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853 +#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253 + +#define PCI_DEVICE_ID_MOXA_CP102E 0x1024 +#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 +#define PCI_DEVICE_ID_MOXA_CP102N 0x1027 +#define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045 +#define PCI_DEVICE_ID_MOXA_CP104N 0x1046 +#define PCI_DEVICE_ID_MOXA_CP112N 0x1121 +#define PCI_DEVICE_ID_MOXA_CP114EL 0x1144 +#define PCI_DEVICE_ID_MOXA_CP114N 0x1145 +#define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160 +#define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161 +#define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182 +#define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183 +#define PCI_DEVICE_ID_MOXA_CP132EL 0x1322 +#define PCI_DEVICE_ID_MOXA_CP132N 0x1323 +#define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342 +#define PCI_DEVICE_ID_MOXA_CP134N 0x1343 +#define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 +#define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 + +/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 + /* * init function returns: * > 0 - number of ports @@ -1887,6 +1965,49 @@ pci_sunix_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, 0); } +#define MOXA_PUART_GPIO_EN 0x09 +#define MOXA_PUART_GPIO_OUT 0x0A + +#define MOXA_GPIO_PIN2 BIT(2) + +static bool pci_moxa_is_mini_pcie(unsigned short device) +{ + if (device == PCI_DEVICE_ID_MOXA_CP102N || + device == PCI_DEVICE_ID_MOXA_CP104N || + device == PCI_DEVICE_ID_MOXA_CP112N || + device == PCI_DEVICE_ID_MOXA_CP114N || + device == PCI_DEVICE_ID_MOXA_CP132N || + device == PCI_DEVICE_ID_MOXA_CP134N) + return true; + + return false; +} + +static int pci_moxa_init(struct pci_dev *dev) +{ + unsigned short device = dev->device; + resource_size_t iobar_addr = pci_resource_start(dev, 2); + unsigned int num_ports = (device & 0x00F0) >> 4; + u8 val; + + /* + * Enable hardware buffer to prevent break signal output when system boots up. + * This hardware buffer is only supported on Mini PCIe series. + */ + if (pci_moxa_is_mini_pcie(device)) { + /* Set GPIO direction */ + val = inb(iobar_addr + MOXA_PUART_GPIO_EN); + val |= MOXA_GPIO_PIN2; + outb(val, iobar_addr + MOXA_PUART_GPIO_EN); + /* Enable low GPIO */ + val = inb(iobar_addr + MOXA_PUART_GPIO_OUT); + val &= ~MOXA_GPIO_PIN2; + outb(val, iobar_addr + MOXA_PUART_GPIO_OUT); + } + + return num_ports; +} + static int pci_moxa_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -1903,78 +2024,6 @@ pci_moxa_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, 0); } -#define PCI_VENDOR_ID_SBSMODULARIO 0x124B -#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B -#define PCI_DEVICE_ID_OCTPRO 0x0001 -#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108 -#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 -#define PCI_SUBDEVICE_ID_POCTAL232 0x0308 -#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 -#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 -#define PCI_VENDOR_ID_ADVANTECH 0x13fe -#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 -#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 -#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611 -#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 -#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 -#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 -#define PCI_DEVICE_ID_TITAN_200I 0x8028 -#define PCI_DEVICE_ID_TITAN_400I 0x8048 -#define PCI_DEVICE_ID_TITAN_800I 0x8088 -#define PCI_DEVICE_ID_TITAN_800EH 0xA007 -#define PCI_DEVICE_ID_TITAN_800EHB 0xA008 -#define PCI_DEVICE_ID_TITAN_400EH 0xA009 -#define PCI_DEVICE_ID_TITAN_100E 0xA010 -#define PCI_DEVICE_ID_TITAN_200E 0xA012 -#define PCI_DEVICE_ID_TITAN_400E 0xA013 -#define PCI_DEVICE_ID_TITAN_800E 0xA014 -#define PCI_DEVICE_ID_TITAN_200EI 0xA016 -#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 -#define PCI_DEVICE_ID_TITAN_200V3 0xA306 -#define PCI_DEVICE_ID_TITAN_400V3 0xA310 -#define PCI_DEVICE_ID_TITAN_410V3 0xA312 -#define PCI_DEVICE_ID_TITAN_800V3 0xA314 -#define PCI_DEVICE_ID_TITAN_800V3B 0xA315 -#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 -#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 -#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 -#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d -#define PCI_VENDOR_ID_WCH 0x4348 -#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 -#define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 -#define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 -#define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 -#define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 -#define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 -#define PCI_VENDOR_ID_AGESTAR 0x5372 -#define PCI_DEVICE_ID_AGESTAR_9375 0x6872 -#define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a -#define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e - -#define PCIE_VENDOR_ID_WCH 0x1c00 -#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 -#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 -#define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853 -#define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253 - -#define PCI_DEVICE_ID_MOXA_CP102E 0x1024 -#define PCI_DEVICE_ID_MOXA_CP102EL 0x1025 -#define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045 -#define PCI_DEVICE_ID_MOXA_CP114EL 0x1144 -#define PCI_DEVICE_ID_MOXA_CP116E_A_A 0x1160 -#define PCI_DEVICE_ID_MOXA_CP116E_A_B 0x1161 -#define PCI_DEVICE_ID_MOXA_CP118EL_A 0x1182 -#define PCI_DEVICE_ID_MOXA_CP118E_A_I 0x1183 -#define PCI_DEVICE_ID_MOXA_CP132EL 0x1322 -#define PCI_DEVICE_ID_MOXA_CP134EL_A 0x1342 -#define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 -#define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 - -/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ -#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 -#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 - /* * Master list of serial port init/setup/exit quirks. * This does not describe the general nature of the port. @@ -2429,6 +2478,153 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .init = pci_oxsemi_tornado_init, .setup = pci_oxsemi_tornado_setup, }, + /* + * Brainboxes devices - all Oxsemi based + */ + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4027, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4028, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4029, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4019, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4016, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4015, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400A, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400E, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400C, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400B, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x400F, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4010, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4011, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x401D, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x401E, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4013, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4017, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTASHIELD, + .device = 0x4018, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_oxsemi_tornado_init, + .setup = pci_oxsemi_tornado_setup, + }, { .vendor = PCI_VENDOR_ID_INTEL, .device = 0x8811, @@ -2635,6 +2831,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .device = PCI_ANY_ID, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, + .init = pci_moxa_init, .setup = pci_moxa_setup, }, { @@ -2854,9 +3051,9 @@ enum pci_board_num_t { pbn_titan_2_4000000, pbn_titan_4_4000000, pbn_titan_8_4000000, - pbn_moxa8250_2p, - pbn_moxa8250_4p, - pbn_moxa8250_8p, + pbn_moxa_2, + pbn_moxa_4, + pbn_moxa_8, }; /* @@ -3628,19 +3825,19 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 0x200, .first_offset = 0x1000, }, - [pbn_moxa8250_2p] = { + [pbn_moxa_2] = { .flags = FL_BASE1, .num_ports = 2, .base_baud = 921600, .uart_offset = 0x200, }, - [pbn_moxa8250_4p] = { + [pbn_moxa_4] = { .flags = FL_BASE1, .num_ports = 4, .base_baud = 921600, .uart_offset = 0x200, }, - [pbn_moxa8250_8p] = { + [pbn_moxa_8] = { .flags = FL_BASE1, .num_ports = 8, .base_baud = 921600, @@ -4913,11 +5110,17 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b1_bt_1_115200 }, + /* + * IntaShield IS-100 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D60, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_1_115200 }, /* * IntaShield IS-200 */ { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0d80 */ pbn_b2_2_115200 }, /* * IntaShield IS-400 @@ -4925,6 +5128,27 @@ static const struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ pbn_b2_4_115200 }, + /* + * IntaShield IX-100 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4027, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * IntaShield IX-200 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4028, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * IntaShield IX-400 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4029, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, /* Brainboxes Devices */ /* * Brainboxes UC-101 @@ -4940,10 +5164,14 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AA2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_1_115200 }, /* - * Brainboxes UC-257 + * Brainboxes UC-253/UC-734 */ - { PCI_VENDOR_ID_INTASHIELD, 0x0861, + { PCI_VENDOR_ID_INTASHIELD, 0x0CA1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, @@ -4979,6 +5207,14 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08E3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes UC-310 */ @@ -4989,6 +5225,14 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-313 */ + { PCI_VENDOR_ID_INTASHIELD, 0x08A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x08A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x08A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5003,6 +5247,10 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * Brainboxes UC-346 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0B02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5014,6 +5262,10 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0A82, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, { PCI_VENDOR_ID_INTASHIELD, 0x0A83, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -5026,12 +5278,94 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_b2_4_115200 }, /* - * Brainboxes UC-420/431 + * Brainboxes UC-420 */ { PCI_VENDOR_ID_INTASHIELD, 0x0921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_4_115200 }, + /* + * Brainboxes UC-607 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x09A1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x09A3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UC-836 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0D41, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_4_115200 }, + /* + * Brainboxes UP-189 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0AC1, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC2, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0AC3, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-200 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0B21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0B23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-869 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C01, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C02, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C03, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + /* + * Brainboxes UP-880 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0C21, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C22, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0C23, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_2_115200 }, /* * Brainboxes PX-101 */ @@ -5064,7 +5398,7 @@ static const struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_INTASHIELD, 0x4015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_4_15625000 }, + pbn_oxsemi_2_15625000 }, /* * Brainboxes PX-260/PX-701 */ @@ -5072,6 +5406,13 @@ static const struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-275/279 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x0E41, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b2_8_115200 }, /* * Brainboxes PX-310 */ @@ -5119,18 +5460,40 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, 0, pbn_oxsemi_4_15625000 }, /* - * Brainboxes PX-803 + * Brainboxes PX-475 */ - { PCI_VENDOR_ID_INTASHIELD, 0x4009, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b0_1_115200 }, - { PCI_VENDOR_ID_INTASHIELD, 0x401E, + { PCI_VENDOR_ID_INTASHIELD, 0x401D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi_1_15625000 }, /* - * Brainboxes PX-846 + * Brainboxes PX-803/PX-857 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4009, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4018, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + { PCI_VENDOR_ID_INTASHIELD, 0x401E, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * Brainboxes PX-820 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4002, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_4_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4013, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-835/PX-846 */ { PCI_VENDOR_ID_INTASHIELD, 0x4008, PCI_ANY_ID, PCI_ANY_ID, @@ -5349,42 +5712,24 @@ static const struct pci_device_id serial_pci_tbl[] = { /* * MOXA */ - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118E_A_I, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132EL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_2p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_4p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP138E_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, - { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL_A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_moxa8250_8p }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102E), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102EL), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL_A), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP112N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114EL), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP116E_A_B), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118E_A_I), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132EL), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132N), pbn_moxa_2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134EL_A), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134N), pbn_moxa_4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP138E_A), pbn_moxa_8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL_A), pbn_moxa_8 }, /* * ADDI-DATA GmbH communication cards diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c index a3b25779d921..9f9e21981929 100644 --- a/drivers/tty/serial/8250/8250_pci1xxxx.c +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c @@ -107,7 +107,7 @@ static const int logical_to_physical_port_idx[][MAX_PORTS] = { struct pci1xxxx_8250 { unsigned int nr; void __iomem *membase; - int line[]; + int line[] __counted_by(nr); }; static int pci1xxxx_get_num_ports(struct pci_dev *dev) @@ -225,10 +225,10 @@ static bool pci1xxxx_port_suspend(int line) if (port->suspended == 0 && port->dev) { wakeup_mask = readb(up->port.membase + UART_WAKE_MASK_REG); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl &= ~TIOCM_OUT2; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = (wakeup_mask & UART_WAKE_SRCS) != UART_WAKE_SRCS; } @@ -251,10 +251,10 @@ static void pci1xxxx_port_resume(int line) writeb(UART_WAKE_SRCS, port->membase + UART_WAKE_REG); if (port->suspended == 0) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl |= TIOCM_OUT2; port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } mutex_unlock(&tport->mutex); } diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 141627370aab..925ee1d61afb 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -689,7 +689,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) if (p->capabilities & UART_CAP_SLEEP) { /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&p->port.lock); + uart_port_lock_irq(&p->port); if (p->capabilities & UART_CAP_EFR) { lcr = serial_in(p, UART_LCR); efr = serial_in(p, UART_EFR); @@ -703,7 +703,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) serial_out(p, UART_EFR, efr); serial_out(p, UART_LCR, lcr); } - spin_unlock_irq(&p->port.lock); + uart_port_unlock_irq(&p->port); } serial8250_rpm_put(p); @@ -746,9 +746,9 @@ static void enable_rsa(struct uart_8250_port *up) { if (up->port.type == PORT_RSA) { if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); __enable_rsa(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) serial_out(up, UART_RSA_FRR, 0); @@ -768,7 +768,7 @@ static void disable_rsa(struct uart_8250_port *up) if (up->port.type == PORT_RSA && up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); mode = serial_in(up, UART_RSA_MSR); result = !(mode & UART_RSA_MSR_FIFO); @@ -781,7 +781,7 @@ static void disable_rsa(struct uart_8250_port *up) if (result) up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } } #endif /* CONFIG_SERIAL_8250_RSA */ @@ -1008,12 +1008,11 @@ static void autoconfig_16550a(struct uart_8250_port *up) serial_out(up, UART_LCR, 0); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | - UART_IIR_FIFO_ENABLED); + status1 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, 0); serial_out(up, UART_LCR, 0); - if (status1 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED)) + if (status1 == UART_IIR_FIFO_ENABLED_16750) up->port.type = PORT_16550A_FSL64; else DEBUG_AUTOCONF("Motorola 8xxx DUART "); @@ -1081,12 +1080,12 @@ static void autoconfig_16550a(struct uart_8250_port *up) */ serial_out(up, UART_LCR, 0); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status1 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); + status1 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); - status2 = serial_in(up, UART_IIR) & (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED); + status2 = serial_in(up, UART_IIR) & UART_IIR_FIFO_ENABLED_16750; serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); serial_out(up, UART_LCR, 0); @@ -1094,7 +1093,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); if (status1 == UART_IIR_FIFO_ENABLED_16550A && - status2 == (UART_IIR_64BYTE_FIFO | UART_IIR_FIFO_ENABLED_16550A)) { + status2 == UART_IIR_FIFO_ENABLED_16750) { up->port.type = PORT_16750; up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; return; @@ -1172,7 +1171,7 @@ static void autoconfig(struct uart_8250_port *up) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->capabilities = 0; up->bugs = 0; @@ -1211,7 +1210,7 @@ static void autoconfig(struct uart_8250_port *up) /* * We failed; there's nothing here */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", scratch2, scratch3); goto out; @@ -1235,7 +1234,7 @@ static void autoconfig(struct uart_8250_port *up) status1 = serial_in(up, UART_MSR) & UART_MSR_STATUS_BITS; serial8250_out_MCR(up, save_mcr); if (status1 != (UART_MSR_DCD | UART_MSR_CTS)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); DEBUG_AUTOCONF("LOOP test failed (%02x) ", status1); goto out; @@ -1304,7 +1303,7 @@ static void autoconfig(struct uart_8250_port *up) serial8250_clear_IER(up); out_unlock: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Check if the device is a Fintek F81216A @@ -1344,9 +1343,9 @@ static void autoconfig_irq(struct uart_8250_port *up) probe_irq_off(probe_irq_on()); save_mcr = serial8250_in_MCR(up); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); save_ier = serial_in(up, UART_IER); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); irqs = probe_irq_on(); @@ -1359,9 +1358,9 @@ static void autoconfig_irq(struct uart_8250_port *up) UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); } /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_IER, UART_IER_ALL_INTR); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); serial_in(up, UART_LSR); serial_in(up, UART_RX); serial_in(up, UART_IIR); @@ -1372,9 +1371,9 @@ static void autoconfig_irq(struct uart_8250_port *up) serial8250_out_MCR(up, save_mcr); /* Synchronize UART_IER access against the console. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial_out(up, UART_IER, save_ier); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); @@ -1442,13 +1441,13 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) unsigned long flags; serial8250_rpm_get(p); - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (em485->active_timer == &em485->stop_tx_timer) { p->rs485_stop_tx(p); em485->active_timer = NULL; em485->tx_stopped = true; } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); serial8250_rpm_put(p); return HRTIMER_NORESTART; @@ -1630,12 +1629,12 @@ static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) struct uart_8250_port *p = em485->port; unsigned long flags; - spin_lock_irqsave(&p->port.lock, flags); + uart_port_lock_irqsave(&p->port, &flags); if (em485->active_timer == &em485->start_tx_timer) { __start_tx(&p->port); em485->active_timer = NULL; } - spin_unlock_irqrestore(&p->port.lock, flags); + uart_port_unlock_irqrestore(&p->port, flags); return HRTIMER_NORESTART; } @@ -1918,7 +1917,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) if (iir & UART_IIR_NO_INT) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = serial_lsr_in(up); @@ -1988,9 +1987,9 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) if ((iir & UART_IIR_ID) == UART_IIR_THRI) { struct uart_8250_port *up = up_to_u8250p(port); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); serial8250_tx_chars(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } iir = serial_port_in(port, UART_IIR); @@ -2005,10 +2004,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up))) result = TIOCSER_TEMT; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); @@ -2070,13 +2069,13 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) unsigned long flags; serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_port_out(port, UART_LCR, up->lcr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); } @@ -2211,7 +2210,7 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->acr = 0; serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); @@ -2221,7 +2220,7 @@ int serial8250_do_startup(struct uart_port *port) serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); serial_port_out(port, UART_LCR, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } if (port->type == PORT_DA830) { @@ -2230,10 +2229,10 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); serial_port_out(port, UART_IER, 0); serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); mdelay(10); /* Enable Tx, Rx and free run mode */ @@ -2347,7 +2346,7 @@ int serial8250_do_startup(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); wait_for_xmitr(up, UART_LSR_THRE); serial_port_out_sync(port, UART_IER, UART_IER_THRI); @@ -2359,7 +2358,7 @@ int serial8250_do_startup(struct uart_port *port) iir = serial_port_in(port, UART_IIR); serial_port_out(port, UART_IER, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irqflags & IRQF_SHARED) enable_irq(port->irq); @@ -2382,7 +2381,7 @@ int serial8250_do_startup(struct uart_port *port) */ serial_port_out(port, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (up->port.flags & UPF_FOURPORT) { if (!up->port.irq) up->port.mctrl |= TIOCM_OUT1; @@ -2428,7 +2427,7 @@ int serial8250_do_startup(struct uart_port *port) } dont_test_tx_en: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Clear the interrupt registers again for luck, and clear the @@ -2499,17 +2498,17 @@ void serial8250_do_shutdown(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->ier = 0; serial_port_out(port, UART_IER, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); synchronize_irq(port->irq); if (up->dma) serial8250_release_dma(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((port->iobase & 0xfe0) | 0x1f); @@ -2518,7 +2517,7 @@ void serial8250_do_shutdown(struct uart_port *port) port->mctrl &= ~TIOCM_OUT2; serial8250_set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * Disable break condition and FIFOs @@ -2754,14 +2753,14 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) quot = serial8250_get_divisor(port, baud, &frac); serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); serial8250_set_divisor(port, baud, quot, frac); serial_port_out(port, UART_LCR, up->lcr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); out_unlock: @@ -2798,7 +2797,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, * Synchronize UART_IER access against the console. */ serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); up->lcr = cval; /* Save computed LCR */ @@ -2901,7 +2900,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, serial_port_out(port, UART_FCR, up->fcr); /* set fcr */ } serial8250_set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); serial8250_rpm_put(up); /* Don't rewrite B0 */ @@ -2924,15 +2923,15 @@ void serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial8250_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); serial8250_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } @@ -3406,9 +3405,9 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, touch_nmi_watchdog(); if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * First save the IER then disable the interrupts @@ -3478,7 +3477,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, serial8250_modem_status(up); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int probe_baud(struct uart_port *port) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c12978311a09..8b9a2c4902e2 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -148,7 +148,7 @@ config SERIAL_8250_PCI config SERIAL_8250_EXAR tristate "8250/16550 Exar/Commtech PCI/PCIe device support" - depends on SERIAL_8250_PCI + depends on SERIAL_8250 && PCI default SERIAL_8250 help This builds support for XR17C1xx, XR17V3xx and some Commtech diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 628b75be312e..ea2e81f58eac 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -13,39 +13,41 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o 8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o 8250_base-$(CONFIG_SERIAL_8250_PCILIB) += 8250_pcilib.o -obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o -obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o -obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o -obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o -obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o + +obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o + +obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += 8250_aspeed_vuart.o obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o -obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o -obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o -obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o -obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o -obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o -obj-$(CONFIG_SERIAL_8250_PCI1XXXX) += 8250_pci1xxxx.o -obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o -obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_DFL) += 8250_dfl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o -obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o -obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o -obj-$(CONFIG_SERIAL_8250_RT288X) += 8250_rt288x.o -obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o -obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o -obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o +obj-$(CONFIG_SERIAL_8250_EXAR) += 8250_exar.o +obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o +obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o +obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o +obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o +obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o +obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o +obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o +obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o +obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_PCI1XXXX) += 8250_pci1xxxx.o obj-$(CONFIG_SERIAL_8250_PERICOM) += 8250_pericom.o obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o +obj-$(CONFIG_SERIAL_8250_RT288X) += 8250_rt288x.o +obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o +obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o obj-$(CONFIG_SERIAL_8250_TEGRA) += 8250_tegra.o -obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o -obj-$(CONFIG_SERIAL_OF_PLATFORM) += 8250_of.o CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 78b1f6a99c42..a6cc020f25e6 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1577,6 +1577,32 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE but you can alter that using a kernel command line option such as "console=ttyNVTx". +config SERIAL_ESP32 + tristate "Espressif ESP32 UART support" + depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Driver for the UART controllers of the Espressif ESP32xx SoCs. + When earlycon option is enabled the following kernel command line + snippets may be used: + earlycon=esp32s3uart,mmio32,0x60000000,115200n8,40000000 + earlycon=esp32uart,mmio32,0x3ff40000,115200n8 + +config SERIAL_ESP32_ACM + tristate "Espressif ESP32 USB ACM gadget support" + depends on XTENSA_PLATFORM_ESP32 || (COMPILE_TEST && OF) + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Driver for the CDC ACM gadget controller of the Espressif ESP32S3 + SoCs that share separate USB controller with the JTAG adapter. + When earlycon option is enabled the following kernel command line + snippet may be used: + earlycon=esp32s3acm,mmio32,0x60038000 + endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 138abbc89738..b25e9b54a660 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -24,70 +24,72 @@ obj-$(CONFIG_SERIAL_21285) += 21285.o # Now bring in any enabled 8250/16450/16550 type drivers. obj-y += 8250/ -obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o -obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o -obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o -obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o -obj-$(CONFIG_SERIAL_SA1100) += sa1100.o -obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o -obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o -obj-$(CONFIG_SERIAL_MAX3100) += max3100.o -obj-$(CONFIG_SERIAL_MAX310X) += max310x.o -obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o -obj-$(CONFIG_SERIAL_MUX) += mux.o -obj-$(CONFIG_SERIAL_MCF) += mcf.o -obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o -obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o -obj-$(CONFIG_SERIAL_DZ) += dz.o -obj-$(CONFIG_SERIAL_ZS) += zs.o -obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o -obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o -obj-$(CONFIG_SERIAL_IMX) += imx.o -obj-$(CONFIG_SERIAL_IMX_EARLYCON) += imx_earlycon.o -obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o -obj-$(CONFIG_SERIAL_ICOM) += icom.o -obj-$(CONFIG_SERIAL_MESON) += meson_uart.o -obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o -obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o -obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o -obj-$(CONFIG_SERIAL_JSM) += jsm/ -obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o -obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o -obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o -obj-$(CONFIG_SERIAL_MSM) += msm_serial.o -obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o -obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o -obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o -obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o -obj-$(CONFIG_SERIAL_QE) += ucc_uart.o -obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o +obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o +obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o +obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o +obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o -obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o -obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o -obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o -obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o -obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o -obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o -obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o -obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o -obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o -obj-$(CONFIG_SERIAL_ARC) += arc_uart.o -obj-$(CONFIG_SERIAL_RP2) += rp2.o -obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o -obj-$(CONFIG_SERIAL_FSL_LINFLEXUART) += fsl_linflexuart.o +obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o +obj-$(CONFIG_SERIAL_ARC) += arc_uart.o +obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o +obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o +obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o -obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o -obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o -obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o -obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o -obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o -obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o -obj-$(CONFIG_SERIAL_OWL) += owl-uart.o -obj-$(CONFIG_SERIAL_RDA) += rda-uart.o -obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o -obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o -obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o -obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o +obj-$(CONFIG_SERIAL_DZ) += dz.o +obj-$(CONFIG_SERIAL_ESP32) += esp32_uart.o +obj-$(CONFIG_SERIAL_ESP32_ACM) += esp32_acm.o +obj-$(CONFIG_SERIAL_FSL_LINFLEXUART) += fsl_linflexuart.o +obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o +obj-$(CONFIG_SERIAL_ICOM) += icom.o +obj-$(CONFIG_SERIAL_IMX) += imx.o +obj-$(CONFIG_SERIAL_IMX_EARLYCON) += imx_earlycon.o +obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o +obj-$(CONFIG_SERIAL_JSM) += jsm/ +obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o +obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o +obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o +obj-$(CONFIG_SERIAL_MAX3100) += max3100.o +obj-$(CONFIG_SERIAL_MAX310X) += max310x.o +obj-$(CONFIG_SERIAL_MCF) += mcf.o +obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o +obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o +obj-$(CONFIG_SERIAL_MESON) += meson_uart.o +obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o +obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o +obj-$(CONFIG_SERIAL_MSM) += msm_serial.o +obj-$(CONFIG_SERIAL_MUX) += mux.o +obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o +obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o +obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o +obj-$(CONFIG_SERIAL_OWL) += owl-uart.o +obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o +obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o +obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o +obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o +obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o +obj-$(CONFIG_SERIAL_QE) += ucc_uart.o +obj-$(CONFIG_SERIAL_RDA) += rda-uart.o +obj-$(CONFIG_SERIAL_RP2) += rp2.o +obj-$(CONFIG_SERIAL_SA1100) += sa1100.o +obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o +obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o +obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o +obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o +obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o +obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o +obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o +obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o +obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o +obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o +obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o +obj-$(CONFIG_SERIAL_TEGRA_TCU) += tegra-tcu.o +obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o +obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o +obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o +obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o +obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o +obj-$(CONFIG_SERIAL_ZS) += zs.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 5fab4c978891..7090b251dd4d 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -147,14 +147,14 @@ static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> ALTERA_JTAGUART_CONTROL_RI_OFF) & port->read_status_mask; - spin_lock(&port->lock); + uart_port_lock(port); if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) altera_jtaguart_rx_chars(port); if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) altera_jtaguart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_RETVAL(isr); } @@ -180,14 +180,14 @@ static int altera_jtaguart_startup(struct uart_port *port) return ret; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Enable RX interrupts now */ port->read_status_mask = ALTERA_JTAGUART_CONTROL_RE_MSK; writel(port->read_status_mask, port->membase + ALTERA_JTAGUART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -196,14 +196,14 @@ static void altera_jtaguart_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ port->read_status_mask = 0; writel(port->read_status_mask, port->membase + ALTERA_JTAGUART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -264,33 +264,33 @@ static void altera_jtaguart_console_putc(struct uart_port *port, unsigned char c unsigned long flags; u32 status; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (!altera_jtaguart_tx_space(port, &status)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) { return; /* no connection activity */ } cpu_relax(); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); } writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #else static void altera_jtaguart_console_putc(struct uart_port *port, unsigned char c) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (!altera_jtaguart_tx_space(port, NULL)) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); cpu_relax(); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); } writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index a9c41942190c..77835ac68df2 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -164,13 +164,13 @@ static void altera_uart_break_ctl(struct uart_port *port, int break_state) struct altera_uart *pp = container_of(port, struct altera_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; else pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void altera_uart_set_termios(struct uart_port *port, @@ -187,10 +187,10 @@ static void altera_uart_set_termios(struct uart_port *port, tty_termios_copy_hw(termios, old); tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* * FIXME: port->read_status_mask and port->ignore_status_mask @@ -264,12 +264,12 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (isr & ALTERA_UART_STATUS_RRDY_MSK) altera_uart_rx_chars(port); if (isr & ALTERA_UART_STATUS_TRDY_MSK) altera_uart_tx_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_RETVAL(isr); } @@ -313,13 +313,13 @@ static int altera_uart_startup(struct uart_port *port) } } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Enable RX interrupts now */ pp->imr = ALTERA_UART_CONTROL_RRDY_MSK; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -329,13 +329,13 @@ static void altera_uart_shutdown(struct uart_port *port) struct altera_uart *pp = container_of(port, struct altera_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ pp->imr = 0; altera_uart_update_ctrl_reg(pp); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irq) free_irq(port->irq, port); diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index b5a7404cbacb..eabbf8afc9b5 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -207,7 +207,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id) unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; int handled = 0; - spin_lock(&port->lock); + uart_port_lock(port); status = readb(port->membase + UART010_IIR); if (status) { @@ -228,7 +228,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id) handled = 1; } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_RETVAL(handled); } @@ -270,14 +270,14 @@ static void pl010_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int lcr_h; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lcr_h = readb(port->membase + UART010_LCRH); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; writel(lcr_h, port->membase + UART010_LCRH); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int pl010_startup(struct uart_port *port) @@ -385,7 +385,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, if (port->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -438,22 +438,22 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, writel(lcr_h, port->membase + UART010_LCRH); writel(old_cr, port->membase + UART010_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); pl010_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); pl010_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 3dc9b0fcab1c..61cc24cd90e4 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -345,9 +345,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) flag = TTY_FRAME; } - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); sysrq = uart_handle_sysrq_char(&uap->port, ch & 255); - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); if (!sysrq) uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); @@ -421,7 +421,7 @@ static void pl011_dma_probe(struct uart_amba_port *uap) /* We need platform data */ if (!plat || !plat->dma_filter) { - dev_info(uap->port.dev, "no DMA platform data\n"); + dev_dbg(uap->port.dev, "no DMA platform data\n"); return; } @@ -550,7 +550,7 @@ static void pl011_dma_tx_callback(void *data) unsigned long flags; u16 dmacr; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); if (uap->dmatx.queued) dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, DMA_TO_DEVICE); @@ -571,7 +571,7 @@ static void pl011_dma_tx_callback(void *data) if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) || uart_circ_empty(&uap->port.state->xmit)) { uap->dmatx.queued = false; - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return; } @@ -582,7 +582,7 @@ static void pl011_dma_tx_callback(void *data) */ pl011_start_tx_pio(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } /* @@ -1009,7 +1009,7 @@ static void pl011_dma_rx_callback(void *data) * routine to flush out the secondary DMA buffer while * we immediately trigger the next DMA job. */ - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); /* * Rx data can be taken by the UART interrupts during * the DMA irq handler. So we check the residue here. @@ -1025,7 +1025,7 @@ static void pl011_dma_rx_callback(void *data) ret = pl011_dma_rx_trigger_dma(uap); pl011_dma_rx_chars(uap, pending, lastbuf, false); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * Do this check after we picked the DMA chars so we don't * get some IRQ immediately from RX. @@ -1091,11 +1091,11 @@ static void pl011_dma_rx_poll(struct timer_list *t) if (jiffies_to_msecs(jiffies - dmarx->last_jiffies) > uap->dmarx.poll_timeout) { - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); pl011_dma_rx_stop(uap); uap->im |= UART011_RXIM; pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); uap->dmarx.running = false; dmaengine_terminate_all(rxchan); @@ -1191,10 +1191,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy) cpu_relax(); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); pl011_write(uap->dmacr, uap, REG_DMACR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); if (uap->using_tx_dma) { /* In theory, this should already be done by pl011_dma_flush_buffer */ @@ -1374,9 +1374,9 @@ static void pl011_throttle_rx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pl011_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void pl011_enable_ms(struct uart_port *port) @@ -1394,7 +1394,7 @@ __acquires(&uap->port.lock) { pl011_fifo_to_tty(uap); - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); tty_flip_buffer_push(&uap->port.state->port); /* * If we were temporarily out of DMA mode for a while, @@ -1419,7 +1419,7 @@ __acquires(&uap->port.lock) #endif } } - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); } static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, @@ -1555,7 +1555,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; int handled = 0; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); status = pl011_read(uap, REG_RIS) & uap->im; if (status) { do { @@ -1585,7 +1585,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) handled = 1; } - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return IRQ_RETVAL(handled); } @@ -1657,14 +1657,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int lcr_h; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); lcr_h = pl011_read(uap, REG_LCRH_TX); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; pl011_write(lcr_h, uap, REG_LCRH_TX); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } #ifdef CONFIG_CONSOLE_POLL @@ -1803,7 +1803,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) unsigned long flags; unsigned int i; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); /* Clear out any spuriously appearing RX interrupts */ pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); @@ -1825,7 +1825,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap) if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } static void pl011_unthrottle_rx(struct uart_port *port) @@ -1833,7 +1833,7 @@ static void pl011_unthrottle_rx(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) @@ -1841,7 +1841,7 @@ static void pl011_unthrottle_rx(struct uart_port *port) pl011_write(uap->im, uap, REG_IMSC); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } static int pl011_startup(struct uart_port *port) @@ -1861,7 +1861,7 @@ static int pl011_startup(struct uart_port *port) pl011_write(uap->vendor->ifls, uap, REG_IFLS); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); cr = pl011_read(uap, REG_CR); cr &= UART011_CR_RTS | UART011_CR_DTR; @@ -1872,7 +1872,7 @@ static int pl011_startup(struct uart_port *port) pl011_write(cr, uap, REG_CR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * initialise the old status of the modem signals @@ -1933,12 +1933,12 @@ static void pl011_disable_uart(struct uart_amba_port *uap) unsigned int cr; uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); cr = pl011_read(uap, REG_CR); cr &= UART011_CR_RTS | UART011_CR_DTR; cr |= UART01x_CR_UARTEN | UART011_CR_TXE; pl011_write(cr, uap, REG_CR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); /* * disable break condition and fifos @@ -1950,14 +1950,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap) static void pl011_disable_interrupts(struct uart_amba_port *uap) { - spin_lock_irq(&uap->port.lock); + uart_port_lock_irq(&uap->port); /* mask all interrupts and clear all pending ones */ uap->im = 0; pl011_write(uap->im, uap, REG_IMSC); pl011_write(0xffff, uap, REG_ICR); - spin_unlock_irq(&uap->port.lock); + uart_port_unlock_irq(&uap->port); } static void pl011_shutdown(struct uart_port *port) @@ -2102,7 +2102,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, bits = tty_get_frame_size(termios->c_cflag); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Update the per-port timeout. @@ -2176,7 +2176,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr |= UART011_CR_RXE; pl011_write(old_cr, uap, REG_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void @@ -2194,10 +2194,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios, termios->c_cflag &= ~(CMSPAR | CRTSCTS); termios->c_cflag |= CS8 | CLOCAL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, CS8, uap->fixed_baud); pl011_setup_status_masks(port, termios); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *pl011_type(struct uart_port *port) @@ -2336,9 +2336,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) if (uap->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&uap->port.lock); + locked = uart_port_trylock(&uap->port); else - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); /* * First save the CR then disable the interrupts @@ -2364,7 +2364,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) pl011_write(old_cr, uap, REG_CR); if (locked) - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); local_irq_restore(flags); clk_disable(uap->clk); diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index d7658f380838..716cb014c028 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -133,7 +133,7 @@ static irqreturn_t apbuart_int(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned int status; - spin_lock(&port->lock); + uart_port_lock(port); status = UART_GET_STATUS(port); if (status & UART_STATUS_DR) @@ -141,7 +141,7 @@ static irqreturn_t apbuart_int(int irq, void *dev_id) if (status & UART_STATUS_THE) apbuart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -228,7 +228,7 @@ static void apbuart_set_termios(struct uart_port *port, if (termios->c_cflag & CRTSCTS) cr |= UART_CTRL_FL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); @@ -251,7 +251,7 @@ static void apbuart_set_termios(struct uart_port *port, UART_PUT_SCAL(port, quot); UART_PUT_CTRL(port, cr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *apbuart_type(struct uart_port *port) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 924c1a89347c..ffd234673177 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -133,9 +133,9 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port) unsigned long flags; unsigned int rdata; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT; } @@ -220,14 +220,14 @@ static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) container_of(port, struct ar933x_uart_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, AR933X_UART_CS_TX_BREAK); else ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, AR933X_UART_CS_TX_BREAK); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* @@ -318,7 +318,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* disable the UART */ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, @@ -352,7 +352,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (tty_termios_baud_rate(new)) tty_termios_encode_baud_rate(new, baud, baud); @@ -450,7 +450,7 @@ static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) if ((status & AR933X_UART_CS_HOST_INT) == 0) return IRQ_NONE; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); status = ar933x_uart_read(up, AR933X_UART_INT_REG); status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG); @@ -468,7 +468,7 @@ static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) ar933x_uart_tx_chars(up); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); return IRQ_HANDLED; } @@ -485,7 +485,7 @@ static int ar933x_uart_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* Enable HOST interrupts */ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, @@ -498,7 +498,7 @@ static int ar933x_uart_startup(struct uart_port *port) /* Enable RX interrupts */ ar933x_uart_start_rx_interrupt(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -632,9 +632,9 @@ static void ar933x_uart_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -654,7 +654,7 @@ static void ar933x_uart_console_write(struct console *co, const char *s, ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index ad4ae19b6ce3..1aa5b2b49c26 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -279,9 +279,9 @@ static irqreturn_t arc_serial_isr(int irq, void *dev_id) if (status & RXIENB) { /* already in ISR, no need of xx_irqsave */ - spin_lock(&port->lock); + uart_port_lock(port); arc_serial_rx_chars(port, status); - spin_unlock(&port->lock); + uart_port_unlock(port); } if ((status & TXIENB) && (status & TXEMPTY)) { @@ -291,12 +291,12 @@ static irqreturn_t arc_serial_isr(int irq, void *dev_id) */ UART_TX_IRQ_DISABLE(port); - spin_lock(&port->lock); + uart_port_lock(port); if (!uart_tx_stopped(port)) arc_serial_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } return IRQ_HANDLED; @@ -366,7 +366,7 @@ arc_serial_set_termios(struct uart_port *port, struct ktermios *new, uartl = hw_val & 0xFF; uarth = (hw_val >> 8) & 0xFF; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); UART_ALL_IRQ_DISABLE(port); @@ -391,7 +391,7 @@ arc_serial_set_termios(struct uart_port *port, struct ktermios *new, uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *arc_serial_type(struct uart_port *port) @@ -521,9 +521,9 @@ static void arc_serial_console_write(struct console *co, const char *s, struct uart_port *port = &arc_uart_ports[co->index].port; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, arc_serial_console_putchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static struct console arc_console = { diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 88cdafa5ac54..1946fafc3f3e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -861,7 +861,7 @@ static void atmel_complete_tx_dma(void *arg) struct dma_chan *chan = atmel_port->chan_tx; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (chan) dmaengine_terminate_all(chan); @@ -893,7 +893,7 @@ static void atmel_complete_tx_dma(void *arg) atmel_port->tx_done_mask); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void atmel_release_tx_dma(struct uart_port *port) @@ -1711,9 +1711,9 @@ static void atmel_tasklet_rx_func(struct tasklet_struct *t) struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ - spin_lock(&port->lock); + uart_port_lock(port); atmel_port->schedule_rx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } static void atmel_tasklet_tx_func(struct tasklet_struct *t) @@ -1723,9 +1723,9 @@ static void atmel_tasklet_tx_func(struct tasklet_struct *t) struct uart_port *port = &atmel_port->uart; /* The interrupt handler does not take the lock */ - spin_lock(&port->lock); + uart_port_lock(port); atmel_port->schedule_tx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } static void atmel_init_property(struct atmel_uart_port *atmel_port, @@ -2175,7 +2175,7 @@ static void atmel_set_termios(struct uart_port *port, } else mode |= ATMEL_US_PAR_NONE; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = ATMEL_US_OVRE; if (termios->c_iflag & INPCK) @@ -2377,22 +2377,22 @@ gclk_fail: else atmel_disable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); atmel_enable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); atmel_disable_ms(port); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } } } diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 0dd8cceb837c..4a08fd5ee61b 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -201,7 +201,7 @@ static void bcm_uart_break_ctl(struct uart_port *port, int ctl) unsigned long flags; unsigned int val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = bcm_uart_readl(port, UART_CTL_REG); if (ctl) @@ -210,7 +210,7 @@ static void bcm_uart_break_ctl(struct uart_port *port, int ctl) val &= ~UART_CTL_XMITBRK_MASK; bcm_uart_writel(port, val, UART_CTL_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -332,7 +332,7 @@ static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) unsigned int irqstat; port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); irqstat = bcm_uart_readl(port, UART_IR_REG); if (irqstat & UART_RX_INT_STAT) @@ -353,7 +353,7 @@ static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) estat & UART_EXTINP_DCD_MASK); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -451,9 +451,9 @@ static void bcm_uart_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); bcm_uart_writel(port, 0, UART_IR_REG); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); bcm_uart_disable(port); bcm_uart_flush(port); @@ -470,7 +470,7 @@ static void bcm_uart_set_termios(struct uart_port *port, struct ktermios *new, unsigned long flags; int tries; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Drain the hot tub fully before we power it off for the winter. */ for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--) @@ -546,7 +546,7 @@ static void bcm_uart_set_termios(struct uart_port *port, struct ktermios *new, uart_update_timeout(port, new->c_cflag, baud); bcm_uart_enable(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -712,9 +712,9 @@ static void bcm_console_write(struct console *co, const char *s, /* bcm_uart_interrupt() already took the lock */ locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -725,7 +725,7 @@ static void bcm_console_write(struct console *co, const char *s, wait_for_xmitr(port); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/cpm_uart.c b/drivers/tty/serial/cpm_uart.c index 626423022d62..be4af6eda4c2 100644 --- a/drivers/tty/serial/cpm_uart.c +++ b/drivers/tty/serial/cpm_uart.c @@ -569,7 +569,7 @@ static void cpm_uart_set_termios(struct uart_port *port, if ((termios->c_cflag & CREAD) == 0) port->read_status_mask &= ~BD_SC_EMPTY; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (IS_SMC(pinfo)) { unsigned int bits = tty_get_frame_size(termios->c_cflag); @@ -609,7 +609,7 @@ static void cpm_uart_set_termios(struct uart_port *port, clk_set_rate(pinfo->clk, baud); else cpm_setbrg(pinfo->brg - 1, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *cpm_uart_type(struct uart_port *port) @@ -1386,9 +1386,9 @@ static void cpm_uart_console_write(struct console *co, const char *s, cpm_uart_early_write(pinfo, s, count, true); local_irq_restore(flags); } else { - spin_lock_irqsave(&pinfo->port.lock, flags); + uart_port_lock_irqsave(&pinfo->port, &flags); cpm_uart_early_write(pinfo, s, count, true); - spin_unlock_irqrestore(&pinfo->port.lock, flags); + uart_port_unlock_irqrestore(&pinfo->port, flags); } } diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index 128b5479e813..5004125f3045 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -133,7 +133,7 @@ static void digicolor_uart_rx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (1) { u8 status, ch, ch_flag; @@ -172,7 +172,7 @@ static void digicolor_uart_rx(struct uart_port *port) ch_flag); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); tty_flip_buffer_push(&port->state->port); } @@ -185,7 +185,7 @@ static void digicolor_uart_tx(struct uart_port *port) if (digicolor_uart_tx_full(port)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->x_char) { writeb_relaxed(port->x_char, port->membase + UA_EMI_REC); @@ -211,7 +211,7 @@ static void digicolor_uart_tx(struct uart_port *port) uart_write_wakeup(port); out: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static irqreturn_t digicolor_uart_int(int irq, void *dev_id) @@ -333,7 +333,7 @@ static void digicolor_uart_set_termios(struct uart_port *port, port->ignore_status_mask |= UA_STATUS_OVERRUN_ERR | UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); @@ -341,7 +341,7 @@ static void digicolor_uart_set_termios(struct uart_port *port, writeb_relaxed(divisor & 0xff, port->membase + UA_HBAUD_LO); writeb_relaxed(divisor >> 8, port->membase + UA_HBAUD_HI); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *digicolor_uart_type(struct uart_port *port) @@ -398,14 +398,14 @@ static void digicolor_uart_console_write(struct console *co, const char *c, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, c, n, digicolor_uart_console_putchar); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Wait for transmitter to become empty */ do { diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 667f52e83277..6df7af9edc1c 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -268,9 +268,9 @@ static inline void dz_transmit_chars(struct dz_mux *mux) } /* If nothing to do or stopped or hardware stopped. */ if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { - spin_lock(&dport->port.lock); + uart_port_lock(&dport->port); dz_stop_tx(&dport->port); - spin_unlock(&dport->port.lock); + uart_port_unlock(&dport->port); return; } @@ -287,9 +287,9 @@ static inline void dz_transmit_chars(struct dz_mux *mux) /* Are we are done. */ if (uart_circ_empty(xmit)) { - spin_lock(&dport->port.lock); + uart_port_lock(&dport->port); dz_stop_tx(&dport->port); - spin_unlock(&dport->port.lock); + uart_port_unlock(&dport->port); } } @@ -415,14 +415,14 @@ static int dz_startup(struct uart_port *uport) return ret; } - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); /* Enable interrupts. */ tmp = dz_in(dport, DZ_CSR); tmp |= DZ_RIE | DZ_TIE; dz_out(dport, DZ_CSR, tmp); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); return 0; } @@ -443,9 +443,9 @@ static void dz_shutdown(struct uart_port *uport) int irq_guard; u16 tmp; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); dz_stop_tx(&dport->port); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); irq_guard = atomic_add_return(-1, &mux->irq_guard); if (!irq_guard) { @@ -491,14 +491,14 @@ static void dz_break_ctl(struct uart_port *uport, int break_state) unsigned long flags; unsigned short tmp, mask = 1 << dport->port.line; - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); tmp = dz_in(dport, DZ_TCR); if (break_state) tmp |= mask; else tmp &= ~mask; dz_out(dport, DZ_TCR, tmp); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static int dz_encode_baud_rate(unsigned int baud) @@ -608,7 +608,7 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, if (termios->c_cflag & CREAD) cflag |= DZ_RXENAB; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); uart_update_timeout(uport, termios->c_cflag, baud); @@ -631,7 +631,7 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, if (termios->c_iflag & IGNBRK) dport->port.ignore_status_mask |= DZ_BREAK; - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); } /* @@ -645,12 +645,12 @@ static void dz_pm(struct uart_port *uport, unsigned int state, struct dz_port *dport = to_dport(uport); unsigned long flags; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); if (state < 3) dz_start_tx(&dport->port); else dz_stop_tx(&dport->port); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); } @@ -811,7 +811,7 @@ static void dz_console_putchar(struct uart_port *uport, unsigned char ch) unsigned short csr, tcr, trdy, mask; int loops = 10000; - spin_lock_irqsave(&dport->port.lock, flags); + uart_port_lock_irqsave(&dport->port, &flags); csr = dz_in(dport, DZ_CSR); dz_out(dport, DZ_CSR, csr & ~DZ_TIE); tcr = dz_in(dport, DZ_TCR); @@ -819,7 +819,7 @@ static void dz_console_putchar(struct uart_port *uport, unsigned char ch) mask = tcr; dz_out(dport, DZ_TCR, mask); iob(); - spin_unlock_irqrestore(&dport->port.lock, flags); + uart_port_unlock_irqrestore(&dport->port, flags); do { trdy = dz_in(dport, DZ_CSR); diff --git a/drivers/tty/serial/esp32_acm.c b/drivers/tty/serial/esp32_acm.c new file mode 100644 index 000000000000..cb28a87736aa --- /dev/null +++ b/drivers/tty/serial/esp32_acm.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "esp32s3-acm" +#define DEV_NAME "ttyGS" +#define UART_NR 4 + +#define ESP32S3_ACM_TX_FIFO_SIZE 64 + +#define USB_SERIAL_JTAG_EP1_REG 0x00 +#define USB_SERIAL_JTAG_EP1_CONF_REG 0x04 +#define USB_SERIAL_JTAG_WR_DONE BIT(0) +#define USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE BIT(1) +#define USB_SERIAL_JTAG_INT_ST_REG 0x0c +#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST BIT(2) +#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST BIT(3) +#define USB_SERIAL_JTAG_INT_ENA_REG 0x10 +#define USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA BIT(2) +#define USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA BIT(3) +#define USB_SERIAL_JTAG_INT_CLR_REG 0x14 +#define USB_SERIAL_JTAG_IN_EP1_ST_REG 0x2c +#define USB_SERIAL_JTAG_IN_EP1_WR_ADDR GENMASK(8, 2) +#define USB_SERIAL_JTAG_OUT_EP1_ST_REG 0x3c +#define USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT GENMASK(22, 16) + +static const struct of_device_id esp32s3_acm_dt_ids[] = { + { + .compatible = "esp,esp32s3-acm", + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, esp32s3_acm_dt_ids); + +static struct uart_port *esp32s3_acm_ports[UART_NR]; + +static void esp32s3_acm_write(struct uart_port *port, unsigned long reg, u32 v) +{ + writel(v, port->membase + reg); +} + +static u32 esp32s3_acm_read(struct uart_port *port, unsigned long reg) +{ + return readl(port->membase + reg); +} + +static u32 esp32s3_acm_tx_fifo_free(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_CONF_REG); + + return status & USB_SERIAL_JTAG_SERIAL_IN_EP_DATA_FREE; +} + +static u32 esp32s3_acm_tx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_IN_EP1_ST_REG); + + return FIELD_GET(USB_SERIAL_JTAG_IN_EP1_WR_ADDR, status); +} + +static u32 esp32s3_acm_rx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32s3_acm_read(port, USB_SERIAL_JTAG_OUT_EP1_ST_REG); + + return FIELD_GET(USB_SERIAL_JTAG_OUT_EP1_REC_DATA_CNT, status); +} + +/* return TIOCSER_TEMT when transmitter is not busy */ +static unsigned int esp32s3_acm_tx_empty(struct uart_port *port) +{ + return esp32s3_acm_tx_fifo_cnt(port) == 0 ? TIOCSER_TEMT : 0; +} + +static void esp32s3_acm_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} + +static unsigned int esp32s3_acm_get_mctrl(struct uart_port *port) +{ + return TIOCM_CAR; +} + +static void esp32s3_acm_stop_tx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena &= ~USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); +} + +static void esp32s3_acm_rxint(struct uart_port *port) +{ + struct tty_port *tty_port = &port->state->port; + u32 rx_fifo_cnt = esp32s3_acm_rx_fifo_cnt(port); + unsigned long flags; + u32 i; + + if (!rx_fifo_cnt) + return; + + spin_lock_irqsave(&port->lock, flags); + + for (i = 0; i < rx_fifo_cnt; ++i) { + u32 rx = esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); + + ++port->icount.rx; + tty_insert_flip_char(tty_port, rx, TTY_NORMAL); + } + spin_unlock_irqrestore(&port->lock, flags); + + tty_flip_buffer_push(tty_port); +} + +static void esp32s3_acm_push(struct uart_port *port) +{ + if (esp32s3_acm_tx_fifo_free(port)) + esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_CONF_REG, + USB_SERIAL_JTAG_WR_DONE); +} + +static void esp32s3_acm_put_char(struct uart_port *port, u8 c) +{ + esp32s3_acm_write(port, USB_SERIAL_JTAG_EP1_REG, c); +} + +static void esp32s3_acm_put_char_sync(struct uart_port *port, u8 c) +{ + unsigned long timeout = jiffies + HZ; + + while (!esp32s3_acm_tx_fifo_free(port)) { + if (time_after(jiffies, timeout)) { + dev_warn(port->dev, "timeout waiting for TX FIFO\n"); + return; + } + cpu_relax(); + } + esp32s3_acm_put_char(port, c); + esp32s3_acm_push(port); +} + +static void esp32s3_acm_transmit_buffer(struct uart_port *port) +{ + u32 tx_fifo_used; + unsigned int pending; + u8 ch; + + if (!esp32s3_acm_tx_fifo_free(port)) + return; + + tx_fifo_used = esp32s3_acm_tx_fifo_cnt(port); + pending = uart_port_tx_limited(port, ch, + ESP32S3_ACM_TX_FIFO_SIZE - tx_fifo_used, + true, esp32s3_acm_put_char(port, ch), + ({})); + if (pending) { + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena |= USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); + } + esp32s3_acm_push(port); +} + +static void esp32s3_acm_txint(struct uart_port *port) +{ + esp32s3_acm_transmit_buffer(port); +} + +static irqreturn_t esp32s3_acm_int(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + u32 status; + + status = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ST_REG); + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_CLR_REG, status); + + if (status & USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ST) + esp32s3_acm_rxint(port); + if (status & USB_SERIAL_JTAG_SERIAL_IN_EMPTY_INT_ST) + esp32s3_acm_txint(port); + + return IRQ_RETVAL(status); +} + +static void esp32s3_acm_start_tx(struct uart_port *port) +{ + esp32s3_acm_transmit_buffer(port); +} + +static void esp32s3_acm_stop_rx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32s3_acm_read(port, USB_SERIAL_JTAG_INT_ENA_REG); + int_ena &= ~USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, int_ena); +} + +static int esp32s3_acm_startup(struct uart_port *port) +{ + int ret; + + ret = request_irq(port->irq, esp32s3_acm_int, 0, DRIVER_NAME, port); + if (ret) + return ret; + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, + USB_SERIAL_JTAG_SERIAL_OUT_RECV_PKT_INT_ENA); + + return 0; +} + +static void esp32s3_acm_shutdown(struct uart_port *port) +{ + esp32s3_acm_write(port, USB_SERIAL_JTAG_INT_ENA_REG, 0); + free_irq(port->irq, port); +} + +static void esp32s3_acm_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ +} + +static const char *esp32s3_acm_type(struct uart_port *port) +{ + return "ESP32S3 ACM"; +} + +/* configure/auto-configure the port */ +static void esp32s3_acm_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + port->type = PORT_GENERIC; +} + +#ifdef CONFIG_CONSOLE_POLL +static void esp32s3_acm_poll_put_char(struct uart_port *port, unsigned char c) +{ + esp32s3_acm_put_char_sync(port, c); +} + +static int esp32s3_acm_poll_get_char(struct uart_port *port) +{ + if (esp32s3_acm_rx_fifo_cnt(port)) + return esp32s3_acm_read(port, USB_SERIAL_JTAG_EP1_REG); + else + return NO_POLL_CHAR; +} +#endif + +static const struct uart_ops esp32s3_acm_pops = { + .tx_empty = esp32s3_acm_tx_empty, + .set_mctrl = esp32s3_acm_set_mctrl, + .get_mctrl = esp32s3_acm_get_mctrl, + .stop_tx = esp32s3_acm_stop_tx, + .start_tx = esp32s3_acm_start_tx, + .stop_rx = esp32s3_acm_stop_rx, + .startup = esp32s3_acm_startup, + .shutdown = esp32s3_acm_shutdown, + .set_termios = esp32s3_acm_set_termios, + .type = esp32s3_acm_type, + .config_port = esp32s3_acm_config_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_put_char = esp32s3_acm_poll_put_char, + .poll_get_char = esp32s3_acm_poll_get_char, +#endif +}; + +static void esp32s3_acm_string_write(struct uart_port *port, const char *s, + unsigned int count) +{ + uart_console_write(port, s, count, esp32s3_acm_put_char_sync); +} + +static void +esp32s3_acm_console_write(struct console *co, const char *s, unsigned int count) +{ + struct uart_port *port = esp32s3_acm_ports[co->index]; + unsigned long flags; + bool locked = true; + + if (port->sysrq) + locked = false; + else if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); + + esp32s3_acm_string_write(port, s, count); + + if (locked) + spin_unlock_irqrestore(&port->lock, flags); +} + +static struct uart_driver esp32s3_acm_reg; +static struct console esp32s3_acm_console = { + .name = DEV_NAME, + .write = esp32s3_acm_console_write, + .device = uart_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &esp32s3_acm_reg, +}; + +static void esp32s3_acm_earlycon_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, esp32s3_acm_put_char_sync); +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32s3_acm_earlycon_read(struct console *con, char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + unsigned int num_read = 0; + + while (num_read < n) { + int c = esp32s3_acm_poll_get_char(&dev->port); + + if (c == NO_POLL_CHAR) + break; + s[num_read++] = c; + } + return num_read; +} +#endif + +static int __init esp32s3_acm_early_console_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = esp32s3_acm_earlycon_write; +#ifdef CONFIG_CONSOLE_POLL + device->con->read = esp32s3_acm_earlycon_read; +#endif + return 0; +} + +OF_EARLYCON_DECLARE(esp32s3acm, "esp,esp32s3-acm", + esp32s3_acm_early_console_setup); + +static struct uart_driver esp32s3_acm_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(esp32s3_acm_ports), + .cons = &esp32s3_acm_console, +}; + +static int esp32s3_acm_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct uart_port *port; + struct resource *res; + int ret; + + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return ret; + } + if (ret >= UART_NR) { + dev_err(&pdev->dev, "driver limited to %d serial ports\n", + UART_NR); + return -ENOMEM; + } + + port->line = ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + port->mapbase = res->start; + port->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + + port->dev = &pdev->dev; + port->type = PORT_GENERIC; + port->iotype = UPIO_MEM; + port->irq = platform_get_irq(pdev, 0); + port->ops = &esp32s3_acm_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->has_sysrq = 1; + port->fifosize = ESP32S3_ACM_TX_FIFO_SIZE; + + esp32s3_acm_ports[port->line] = port; + + platform_set_drvdata(pdev, port); + + return uart_add_one_port(&esp32s3_acm_reg, port); +} + +static int esp32s3_acm_remove(struct platform_device *pdev) +{ + struct uart_port *port = platform_get_drvdata(pdev); + + uart_remove_one_port(&esp32s3_acm_reg, port); + return 0; +} + + +static struct platform_driver esp32s3_acm_driver = { + .probe = esp32s3_acm_probe, + .remove = esp32s3_acm_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = esp32s3_acm_dt_ids, + }, +}; + +static int __init esp32s3_acm_init(void) +{ + int ret; + + ret = uart_register_driver(&esp32s3_acm_reg); + if (ret) + return ret; + + ret = platform_driver_register(&esp32s3_acm_driver); + if (ret) + uart_unregister_driver(&esp32s3_acm_reg); + + return ret; +} + +static void __exit esp32s3_acm_exit(void) +{ + platform_driver_unregister(&esp32s3_acm_driver); + uart_unregister_driver(&esp32s3_acm_reg); +} + +module_init(esp32s3_acm_init); +module_exit(esp32s3_acm_exit); + +MODULE_AUTHOR("Max Filippov "); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/esp32_uart.c b/drivers/tty/serial/esp32_uart.c new file mode 100644 index 000000000000..85c9c5ad7cc5 --- /dev/null +++ b/drivers/tty/serial/esp32_uart.c @@ -0,0 +1,784 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "esp32-uart" +#define DEV_NAME "ttyS" +#define UART_NR 3 + +#define ESP32_UART_TX_FIFO_SIZE 127 +#define ESP32_UART_RX_FIFO_SIZE 127 + +#define UART_FIFO_REG 0x00 +#define UART_INT_RAW_REG 0x04 +#define UART_INT_ST_REG 0x08 +#define UART_INT_ENA_REG 0x0c +#define UART_INT_CLR_REG 0x10 +#define UART_RXFIFO_FULL_INT BIT(0) +#define UART_TXFIFO_EMPTY_INT BIT(1) +#define UART_BRK_DET_INT BIT(7) +#define UART_CLKDIV_REG 0x14 +#define ESP32_UART_CLKDIV GENMASK(19, 0) +#define ESP32S3_UART_CLKDIV GENMASK(11, 0) +#define UART_CLKDIV_SHIFT 0 +#define UART_CLKDIV_FRAG GENMASK(23, 20) +#define UART_STATUS_REG 0x1c +#define ESP32_UART_RXFIFO_CNT GENMASK(7, 0) +#define ESP32S3_UART_RXFIFO_CNT GENMASK(9, 0) +#define UART_RXFIFO_CNT_SHIFT 0 +#define UART_DSRN BIT(13) +#define UART_CTSN BIT(14) +#define ESP32_UART_TXFIFO_CNT GENMASK(23, 16) +#define ESP32S3_UART_TXFIFO_CNT GENMASK(25, 16) +#define UART_TXFIFO_CNT_SHIFT 16 +#define UART_CONF0_REG 0x20 +#define UART_PARITY BIT(0) +#define UART_PARITY_EN BIT(1) +#define UART_BIT_NUM GENMASK(3, 2) +#define UART_BIT_NUM_5 0 +#define UART_BIT_NUM_6 1 +#define UART_BIT_NUM_7 2 +#define UART_BIT_NUM_8 3 +#define UART_STOP_BIT_NUM GENMASK(5, 4) +#define UART_STOP_BIT_NUM_1 1 +#define UART_STOP_BIT_NUM_2 3 +#define UART_SW_RTS BIT(6) +#define UART_SW_DTR BIT(7) +#define UART_LOOPBACK BIT(14) +#define UART_TX_FLOW_EN BIT(15) +#define UART_RTS_INV BIT(23) +#define UART_DTR_INV BIT(24) +#define UART_CONF1_REG 0x24 +#define UART_RXFIFO_FULL_THRHD_SHIFT 0 +#define ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT 8 +#define ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT 10 +#define ESP32_UART_RX_FLOW_EN BIT(23) +#define ESP32S3_UART_RX_FLOW_EN BIT(22) +#define ESP32S3_UART_CLK_CONF_REG 0x78 +#define ESP32S3_UART_SCLK_DIV_B GENMASK(5, 0) +#define ESP32S3_UART_SCLK_DIV_A GENMASK(11, 6) +#define ESP32S3_UART_SCLK_DIV_NUM GENMASK(19, 12) +#define ESP32S3_UART_SCLK_SEL GENMASK(21, 20) +#define APB_CLK 1 +#define RC_FAST_CLK 2 +#define XTAL_CLK 3 +#define ESP32S3_UART_SCLK_EN BIT(22) +#define ESP32S3_UART_RST_CORE BIT(23) +#define ESP32S3_UART_TX_SCLK_EN BIT(24) +#define ESP32S3_UART_RX_SCLK_EN BIT(25) +#define ESP32S3_UART_TX_RST_CORE BIT(26) +#define ESP32S3_UART_RX_RST_CORE BIT(27) + +#define ESP32S3_UART_CLK_CONF_DEFAULT \ + (ESP32S3_UART_RX_SCLK_EN | \ + ESP32S3_UART_TX_SCLK_EN | \ + ESP32S3_UART_SCLK_EN | \ + FIELD_PREP(ESP32S3_UART_SCLK_SEL, XTAL_CLK)) + +struct esp32_port { + struct uart_port port; + struct clk *clk; +}; + +struct esp32_uart_variant { + u32 clkdiv_mask; + u32 rxfifo_cnt_mask; + u32 txfifo_cnt_mask; + u32 txfifo_empty_thrhd_shift; + u32 rx_flow_en; + const char *type; + bool has_clkconf; +}; + +static const struct esp32_uart_variant esp32_variant = { + .clkdiv_mask = ESP32_UART_CLKDIV, + .rxfifo_cnt_mask = ESP32_UART_RXFIFO_CNT, + .txfifo_cnt_mask = ESP32_UART_TXFIFO_CNT, + .txfifo_empty_thrhd_shift = ESP32_UART_TXFIFO_EMPTY_THRHD_SHIFT, + .rx_flow_en = ESP32_UART_RX_FLOW_EN, + .type = "ESP32 UART", +}; + +static const struct esp32_uart_variant esp32s3_variant = { + .clkdiv_mask = ESP32S3_UART_CLKDIV, + .rxfifo_cnt_mask = ESP32S3_UART_RXFIFO_CNT, + .txfifo_cnt_mask = ESP32S3_UART_TXFIFO_CNT, + .txfifo_empty_thrhd_shift = ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT, + .rx_flow_en = ESP32S3_UART_RX_FLOW_EN, + .type = "ESP32S3 UART", + .has_clkconf = true, +}; + +static const struct of_device_id esp32_uart_dt_ids[] = { + { + .compatible = "esp,esp32-uart", + .data = &esp32_variant, + }, { + .compatible = "esp,esp32s3-uart", + .data = &esp32s3_variant, + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, esp32_uart_dt_ids); + +static struct esp32_port *esp32_uart_ports[UART_NR]; + +static const struct esp32_uart_variant *port_variant(struct uart_port *port) +{ + return port->private_data; +} + +static void esp32_uart_write(struct uart_port *port, unsigned long reg, u32 v) +{ + writel(v, port->membase + reg); +} + +static u32 esp32_uart_read(struct uart_port *port, unsigned long reg) +{ + return readl(port->membase + reg); +} + +static u32 esp32_uart_tx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + + return (status & port_variant(port)->txfifo_cnt_mask) >> UART_TXFIFO_CNT_SHIFT; +} + +static u32 esp32_uart_rx_fifo_cnt(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + + return (status & port_variant(port)->rxfifo_cnt_mask) >> UART_RXFIFO_CNT_SHIFT; +} + +/* return TIOCSER_TEMT when transmitter is not busy */ +static unsigned int esp32_uart_tx_empty(struct uart_port *port) +{ + return esp32_uart_tx_fifo_cnt(port) ? 0 : TIOCSER_TEMT; +} + +static void esp32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + u32 conf0 = esp32_uart_read(port, UART_CONF0_REG); + + conf0 &= ~(UART_LOOPBACK | + UART_SW_RTS | UART_RTS_INV | + UART_SW_DTR | UART_DTR_INV); + + if (mctrl & TIOCM_RTS) + conf0 |= UART_SW_RTS; + if (mctrl & TIOCM_DTR) + conf0 |= UART_SW_DTR; + if (mctrl & TIOCM_LOOP) + conf0 |= UART_LOOPBACK; + + esp32_uart_write(port, UART_CONF0_REG, conf0); +} + +static unsigned int esp32_uart_get_mctrl(struct uart_port *port) +{ + u32 status = esp32_uart_read(port, UART_STATUS_REG); + unsigned int ret = TIOCM_CAR; + + if (status & UART_DSRN) + ret |= TIOCM_DSR; + if (status & UART_CTSN) + ret |= TIOCM_CTS; + + return ret; +} + +static void esp32_uart_stop_tx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena &= ~UART_TXFIFO_EMPTY_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); +} + +static void esp32_uart_rxint(struct uart_port *port) +{ + struct tty_port *tty_port = &port->state->port; + u32 rx_fifo_cnt = esp32_uart_rx_fifo_cnt(port); + unsigned long flags; + u32 i; + + if (!rx_fifo_cnt) + return; + + spin_lock_irqsave(&port->lock, flags); + + for (i = 0; i < rx_fifo_cnt; ++i) { + u32 rx = esp32_uart_read(port, UART_FIFO_REG); + + if (!rx && + (esp32_uart_read(port, UART_INT_ST_REG) & UART_BRK_DET_INT)) { + esp32_uart_write(port, UART_INT_CLR_REG, UART_BRK_DET_INT); + ++port->icount.brk; + uart_handle_break(port); + } else { + if (uart_handle_sysrq_char(port, (unsigned char)rx)) + continue; + tty_insert_flip_char(tty_port, rx, TTY_NORMAL); + ++port->icount.rx; + } + } + spin_unlock_irqrestore(&port->lock, flags); + + tty_flip_buffer_push(tty_port); +} + +static void esp32_uart_put_char(struct uart_port *port, u8 c) +{ + esp32_uart_write(port, UART_FIFO_REG, c); +} + +static void esp32_uart_put_char_sync(struct uart_port *port, u8 c) +{ + unsigned long timeout = jiffies + HZ; + + while (esp32_uart_tx_fifo_cnt(port) >= ESP32_UART_TX_FIFO_SIZE) { + if (time_after(jiffies, timeout)) { + dev_warn(port->dev, "timeout waiting for TX FIFO\n"); + return; + } + cpu_relax(); + } + esp32_uart_put_char(port, c); +} + +static void esp32_uart_transmit_buffer(struct uart_port *port) +{ + u32 tx_fifo_used = esp32_uart_tx_fifo_cnt(port); + unsigned int pending; + u8 ch; + + if (tx_fifo_used >= ESP32_UART_TX_FIFO_SIZE) + return; + + pending = uart_port_tx_limited(port, ch, + ESP32_UART_TX_FIFO_SIZE - tx_fifo_used, + true, esp32_uart_put_char(port, ch), + ({})); + if (pending) { + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena |= UART_TXFIFO_EMPTY_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); + } +} + +static void esp32_uart_txint(struct uart_port *port) +{ + esp32_uart_transmit_buffer(port); +} + +static irqreturn_t esp32_uart_int(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + u32 status; + + status = esp32_uart_read(port, UART_INT_ST_REG); + + if (status & (UART_RXFIFO_FULL_INT | UART_BRK_DET_INT)) + esp32_uart_rxint(port); + if (status & UART_TXFIFO_EMPTY_INT) + esp32_uart_txint(port); + + esp32_uart_write(port, UART_INT_CLR_REG, status); + + return IRQ_RETVAL(status); +} + +static void esp32_uart_start_tx(struct uart_port *port) +{ + esp32_uart_transmit_buffer(port); +} + +static void esp32_uart_stop_rx(struct uart_port *port) +{ + u32 int_ena; + + int_ena = esp32_uart_read(port, UART_INT_ENA_REG); + int_ena &= ~UART_RXFIFO_FULL_INT; + esp32_uart_write(port, UART_INT_ENA_REG, int_ena); +} + +static int esp32_uart_startup(struct uart_port *port) +{ + int ret = 0; + unsigned long flags; + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + ret = clk_prepare_enable(sport->clk); + if (ret) + return ret; + + ret = request_irq(port->irq, esp32_uart_int, 0, DRIVER_NAME, port); + if (ret) { + clk_disable_unprepare(sport->clk); + return ret; + } + + spin_lock_irqsave(&port->lock, flags); + if (port_variant(port)->has_clkconf) + esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, + ESP32S3_UART_CLK_CONF_DEFAULT); + esp32_uart_write(port, UART_CONF1_REG, + (1 << UART_RXFIFO_FULL_THRHD_SHIFT) | + (1 << port_variant(port)->txfifo_empty_thrhd_shift)); + esp32_uart_write(port, UART_INT_CLR_REG, UART_RXFIFO_FULL_INT | UART_BRK_DET_INT); + esp32_uart_write(port, UART_INT_ENA_REG, UART_RXFIFO_FULL_INT | UART_BRK_DET_INT); + spin_unlock_irqrestore(&port->lock, flags); + + return ret; +} + +static void esp32_uart_shutdown(struct uart_port *port) +{ + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + esp32_uart_write(port, UART_INT_ENA_REG, 0); + free_irq(port->irq, port); + clk_disable_unprepare(sport->clk); +} + +static bool esp32_uart_set_baud(struct uart_port *port, u32 baud) +{ + u32 sclk = port->uartclk; + u32 div = sclk / baud; + + if (port_variant(port)->has_clkconf) { + u32 sclk_div = div / port_variant(port)->clkdiv_mask; + + if (div > port_variant(port)->clkdiv_mask) { + sclk /= (sclk_div + 1); + div = sclk / baud; + } + esp32_uart_write(port, ESP32S3_UART_CLK_CONF_REG, + FIELD_PREP(ESP32S3_UART_SCLK_DIV_NUM, sclk_div) | + ESP32S3_UART_CLK_CONF_DEFAULT); + } + + if (div <= port_variant(port)->clkdiv_mask) { + u32 frag = (sclk * 16) / baud - div * 16; + + esp32_uart_write(port, UART_CLKDIV_REG, + div | FIELD_PREP(UART_CLKDIV_FRAG, frag)); + return true; + } + + return false; +} + +static void esp32_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ + unsigned long flags; + u32 conf0, conf1; + u32 baud; + const u32 rx_flow_en = port_variant(port)->rx_flow_en; + u32 max_div = port_variant(port)->clkdiv_mask; + + termios->c_cflag &= ~CMSPAR; + + if (port_variant(port)->has_clkconf) + max_div *= FIELD_MAX(ESP32S3_UART_SCLK_DIV_NUM); + + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / max_div, + port->uartclk / 16); + + spin_lock_irqsave(&port->lock, flags); + + conf0 = esp32_uart_read(port, UART_CONF0_REG); + conf0 &= ~(UART_PARITY_EN | UART_PARITY | UART_BIT_NUM | UART_STOP_BIT_NUM); + + conf1 = esp32_uart_read(port, UART_CONF1_REG); + conf1 &= ~rx_flow_en; + + if (termios->c_cflag & PARENB) { + conf0 |= UART_PARITY_EN; + if (termios->c_cflag & PARODD) + conf0 |= UART_PARITY; + } + + switch (termios->c_cflag & CSIZE) { + case CS5: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_5); + break; + case CS6: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_6); + break; + case CS7: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_7); + break; + case CS8: + conf0 |= FIELD_PREP(UART_BIT_NUM, UART_BIT_NUM_8); + break; + } + + if (termios->c_cflag & CSTOPB) + conf0 |= FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_2); + else + conf0 |= FIELD_PREP(UART_STOP_BIT_NUM, UART_STOP_BIT_NUM_1); + + if (termios->c_cflag & CRTSCTS) + conf1 |= rx_flow_en; + + esp32_uart_write(port, UART_CONF0_REG, conf0); + esp32_uart_write(port, UART_CONF1_REG, conf1); + + if (baud) { + esp32_uart_set_baud(port, baud); + uart_update_timeout(port, termios->c_cflag, baud); + } else { + if (esp32_uart_set_baud(port, 115200)) { + baud = 115200; + tty_termios_encode_baud_rate(termios, baud, baud); + uart_update_timeout(port, termios->c_cflag, baud); + } else { + dev_warn(port->dev, + "unable to set speed to %d baud or the default 115200\n", + baud); + } + } + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *esp32_uart_type(struct uart_port *port) +{ + return port_variant(port)->type; +} + +/* configure/auto-configure the port */ +static void esp32_uart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + port->type = PORT_GENERIC; +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32_uart_poll_init(struct uart_port *port) +{ + struct esp32_port *sport = container_of(port, struct esp32_port, port); + + return clk_prepare_enable(sport->clk); +} + +static void esp32_uart_poll_put_char(struct uart_port *port, unsigned char c) +{ + esp32_uart_put_char_sync(port, c); +} + +static int esp32_uart_poll_get_char(struct uart_port *port) +{ + if (esp32_uart_rx_fifo_cnt(port)) + return esp32_uart_read(port, UART_FIFO_REG); + else + return NO_POLL_CHAR; + +} +#endif + +static const struct uart_ops esp32_uart_pops = { + .tx_empty = esp32_uart_tx_empty, + .set_mctrl = esp32_uart_set_mctrl, + .get_mctrl = esp32_uart_get_mctrl, + .stop_tx = esp32_uart_stop_tx, + .start_tx = esp32_uart_start_tx, + .stop_rx = esp32_uart_stop_rx, + .startup = esp32_uart_startup, + .shutdown = esp32_uart_shutdown, + .set_termios = esp32_uart_set_termios, + .type = esp32_uart_type, + .config_port = esp32_uart_config_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_init = esp32_uart_poll_init, + .poll_put_char = esp32_uart_poll_put_char, + .poll_get_char = esp32_uart_poll_get_char, +#endif +}; + +static void esp32_uart_console_putchar(struct uart_port *port, u8 c) +{ + esp32_uart_put_char_sync(port, c); +} + +static void esp32_uart_string_write(struct uart_port *port, const char *s, + unsigned int count) +{ + uart_console_write(port, s, count, esp32_uart_console_putchar); +} + +static void +esp32_uart_console_write(struct console *co, const char *s, unsigned int count) +{ + struct esp32_port *sport = esp32_uart_ports[co->index]; + struct uart_port *port = &sport->port; + unsigned long flags; + bool locked = true; + + if (port->sysrq) + locked = false; + else if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); + + esp32_uart_string_write(port, s, count); + + if (locked) + spin_unlock_irqrestore(&port->lock, flags); +} + +static int __init esp32_uart_console_setup(struct console *co, char *options) +{ + struct esp32_port *sport; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + + /* + * check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index == -1 || co->index >= ARRAY_SIZE(esp32_uart_ports)) + co->index = 0; + + sport = esp32_uart_ports[co->index]; + if (!sport) + return -ENODEV; + + ret = clk_prepare_enable(sport->clk); + if (ret) + return ret; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(&sport->port, co, baud, parity, bits, flow); +} + +static int esp32_uart_console_exit(struct console *co) +{ + struct esp32_port *sport = esp32_uart_ports[co->index]; + + clk_disable_unprepare(sport->clk); + return 0; +} + +static struct uart_driver esp32_uart_reg; +static struct console esp32_uart_console = { + .name = DEV_NAME, + .write = esp32_uart_console_write, + .device = uart_console_device, + .setup = esp32_uart_console_setup, + .exit = esp32_uart_console_exit, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &esp32_uart_reg, +}; + +static void esp32_uart_earlycon_putchar(struct uart_port *port, u8 c) +{ + esp32_uart_put_char_sync(port, c); +} + +static void esp32_uart_earlycon_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, esp32_uart_earlycon_putchar); +} + +#ifdef CONFIG_CONSOLE_POLL +static int esp32_uart_earlycon_read(struct console *con, char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + unsigned int num_read = 0; + + while (num_read < n) { + int c = esp32_uart_poll_get_char(&dev->port); + + if (c == NO_POLL_CHAR) + break; + s[num_read++] = c; + } + return num_read; +} +#endif + +static int __init esp32xx_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = esp32_uart_earlycon_write; +#ifdef CONFIG_CONSOLE_POLL + device->con->read = esp32_uart_earlycon_read; +#endif + if (device->port.uartclk != BASE_BAUD * 16) + esp32_uart_set_baud(&device->port, device->baud); + + return 0; +} + +static int __init esp32_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + device->port.private_data = (void *)&esp32_variant; + + return esp32xx_uart_early_console_setup(device, options); +} + +OF_EARLYCON_DECLARE(esp32uart, "esp,esp32-uart", + esp32_uart_early_console_setup); + +static int __init esp32s3_uart_early_console_setup(struct earlycon_device *device, + const char *options) +{ + device->port.private_data = (void *)&esp32s3_variant; + + return esp32xx_uart_early_console_setup(device, options); +} + +OF_EARLYCON_DECLARE(esp32s3uart, "esp,esp32s3-uart", + esp32s3_uart_early_console_setup); + +static struct uart_driver esp32_uart_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(esp32_uart_ports), + .cons = &esp32_uart_console, +}; + +static int esp32_uart_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + static const struct of_device_id *match; + struct uart_port *port; + struct esp32_port *sport; + struct resource *res; + int ret; + + match = of_match_device(esp32_uart_dt_ids, &pdev->dev); + if (!match) + return -ENODEV; + + sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); + if (!sport) + return -ENOMEM; + + port = &sport->port; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); + return ret; + } + if (ret >= UART_NR) { + dev_err(&pdev->dev, "driver limited to %d serial ports\n", UART_NR); + return -ENOMEM; + } + + port->line = ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + port->mapbase = res->start; + port->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + + sport->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(sport->clk)) + return PTR_ERR(sport->clk); + + port->uartclk = clk_get_rate(sport->clk); + port->dev = &pdev->dev; + port->type = PORT_GENERIC; + port->iotype = UPIO_MEM; + port->irq = platform_get_irq(pdev, 0); + port->ops = &esp32_uart_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->has_sysrq = 1; + port->fifosize = ESP32_UART_TX_FIFO_SIZE; + port->private_data = (void *)match->data; + + esp32_uart_ports[port->line] = sport; + + platform_set_drvdata(pdev, port); + + return uart_add_one_port(&esp32_uart_reg, port); +} + +static int esp32_uart_remove(struct platform_device *pdev) +{ + struct uart_port *port = platform_get_drvdata(pdev); + + uart_remove_one_port(&esp32_uart_reg, port); + + return 0; +} + + +static struct platform_driver esp32_uart_driver = { + .probe = esp32_uart_probe, + .remove = esp32_uart_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = esp32_uart_dt_ids, + }, +}; + +static int __init esp32_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&esp32_uart_reg); + if (ret) + return ret; + + ret = platform_driver_register(&esp32_uart_driver); + if (ret) + uart_unregister_driver(&esp32_uart_reg); + + return ret; +} + +static void __exit esp32_uart_exit(void) +{ + platform_driver_unregister(&esp32_uart_driver); + uart_unregister_driver(&esp32_uart_reg); +} + +module_init(esp32_uart_init); +module_exit(esp32_uart_exit); + +MODULE_AUTHOR("Max Filippov "); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index 249cb380c3c6..3bdaf1ddc309 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -203,7 +203,7 @@ static irqreturn_t linflex_txint(int irq, void *dev_id) struct circ_buf *xmit = &sport->state->xmit; unsigned long flags; - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); if (sport->x_char) { linflex_put_char(sport, sport->x_char); @@ -217,7 +217,7 @@ static irqreturn_t linflex_txint(int irq, void *dev_id) linflex_transmit_buffer(sport); out: - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); return IRQ_HANDLED; } @@ -230,7 +230,7 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) unsigned char rx; bool brk; - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); status = readl(sport->membase + UARTSR); while (status & LINFLEXD_UARTSR_RMB) { @@ -266,7 +266,7 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) } } - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); tty_flip_buffer_push(port); @@ -369,11 +369,11 @@ static int linflex_startup(struct uart_port *port) int ret = 0; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); linflex_setup_watermark(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = devm_request_irq(port->dev, port->irq, linflex_int, 0, DRIVER_NAME, port); @@ -386,14 +386,14 @@ static void linflex_shutdown(struct uart_port *port) unsigned long ier; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable interrupts */ ier = readl(port->membase + LINIER); ier &= ~(LINFLEXD_LINIER_DRIE | LINFLEXD_LINIER_DTIE); writel(ier, port->membase + LINIER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); devm_free_irq(port->dev, port->irq, port); } @@ -474,7 +474,7 @@ linflex_set_termios(struct uart_port *port, struct ktermios *termios, cr &= ~LINFLEXD_UARTCR_PCE; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = 0; @@ -507,7 +507,7 @@ linflex_set_termios(struct uart_port *port, struct ktermios *termios, writel(cr1, port->membase + LINCR1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *linflex_type(struct uart_port *port) @@ -646,14 +646,14 @@ linflex_console_write(struct console *co, const char *s, unsigned int count) if (sport->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->lock, flags); + locked = uart_port_trylock_irqsave(sport, &flags); else - spin_lock_irqsave(&sport->lock, flags); + uart_port_lock_irqsave(sport, &flags); linflex_string_write(sport, s, count); if (locked) - spin_unlock_irqrestore(&sport->lock, flags); + uart_port_unlock_irqrestore(sport, flags); } /* @@ -832,10 +832,14 @@ static int linflex_probe(struct platform_device *pdev) return PTR_ERR(sport->membase); sport->mapbase = res->start; + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + sport->dev = &pdev->dev; sport->type = PORT_LINFLEXUART; sport->iotype = UPIO_MEM; - sport->irq = platform_get_irq(pdev, 0); + sport->irq = ret; sport->ops = &linflex_pops; sport->flags = UPF_BOOT_AUTOCONF; sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE); diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index f72e1340b47d..6d0cfb2e86b4 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -532,9 +532,9 @@ static void lpuart_dma_tx_complete(void *arg) struct dma_chan *chan = sport->dma_tx_chan; unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!sport->dma_tx_in_progress) { - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -543,7 +543,7 @@ static void lpuart_dma_tx_complete(void *arg) uart_xmit_advance(&sport->port, sport->dma_tx_bytes); sport->dma_tx_in_progress = false; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); @@ -553,12 +553,12 @@ static void lpuart_dma_tx_complete(void *arg) return; } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!lpuart_stopped_or_empty(&sport->port)) lpuart_dma_tx(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport) @@ -651,7 +651,7 @@ static int lpuart_poll_init(struct uart_port *port) sport->port.fifosize = 0; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Disable Rx & Tx */ writeb(0, sport->port.membase + UARTCR2); @@ -675,7 +675,7 @@ static int lpuart_poll_init(struct uart_port *port) /* Enable Rx and Tx */ writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -703,7 +703,7 @@ static int lpuart32_poll_init(struct uart_port *port) sport->port.fifosize = 0; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Disable Rx & Tx */ lpuart32_write(&sport->port, 0, UARTCTRL); @@ -724,7 +724,7 @@ static int lpuart32_poll_init(struct uart_port *port) /* Enable Rx and Tx */ lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -879,9 +879,9 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static void lpuart_txint(struct lpuart_port *sport) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); lpuart_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); } static void lpuart_rxint(struct lpuart_port *sport) @@ -890,7 +890,7 @@ static void lpuart_rxint(struct lpuart_port *sport) struct tty_port *port = &sport->port.state->port; unsigned char rx, sr; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -956,9 +956,9 @@ out: static void lpuart32_txint(struct lpuart_port *sport) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); lpuart32_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); } static void lpuart32_rxint(struct lpuart_port *sport) @@ -968,7 +968,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) unsigned long rx, sr; bool is_break; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -1170,12 +1170,12 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) async_tx_ack(sport->dma_rx_desc); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); dmastat = dmaengine_tx_status(chan, sport->dma_rx_cookie, &state); if (dmastat == DMA_ERROR) { dev_err(sport->port.dev, "Rx DMA transfer failed!\n"); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -1244,7 +1244,7 @@ exit: dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); tty_flip_buffer_push(port); if (!sport->dma_idle_int) @@ -1335,9 +1335,9 @@ static void lpuart_timer_func(struct timer_list *t) mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout); - if (spin_trylock_irqsave(&sport->port.lock, flags)) { + if (uart_port_trylock_irqsave(&sport->port, &flags)) { sport->last_residue = state.residue; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } } @@ -1802,14 +1802,14 @@ static void lpuart_hw_setup(struct lpuart_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); lpuart_setup_watermark_enable(sport); lpuart_rx_dma_startup(sport); lpuart_tx_dma_startup(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int lpuart_startup(struct uart_port *port) @@ -1859,7 +1859,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); lpuart32_hw_disable(sport); @@ -1869,7 +1869,7 @@ static void lpuart32_hw_setup(struct lpuart_port *sport) lpuart32_setup_watermark_enable(sport); lpuart32_configure(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int lpuart32_startup(struct uart_port *port) @@ -1932,7 +1932,7 @@ static void lpuart_shutdown(struct uart_port *port) unsigned char temp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable Rx/Tx and interrupts */ temp = readb(port->membase + UARTCR2); @@ -1940,7 +1940,7 @@ static void lpuart_shutdown(struct uart_port *port) UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); writeb(temp, port->membase + UARTCR2); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); lpuart_dma_shutdown(sport); } @@ -1952,7 +1952,7 @@ static void lpuart32_shutdown(struct uart_port *port) unsigned long temp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* clear status */ temp = lpuart32_read(&sport->port, UARTSTAT); @@ -1969,7 +1969,7 @@ static void lpuart32_shutdown(struct uart_port *port) UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_SBK); lpuart32_write(port, temp, UARTCTRL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); lpuart_dma_shutdown(sport); } @@ -2069,7 +2069,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) @@ -2124,7 +2124,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void __lpuart32_serial_setbrg(struct uart_port *port, @@ -2304,7 +2304,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) @@ -2359,7 +2359,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *lpuart_type(struct uart_port *port) @@ -2477,9 +2477,9 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* first save CR2 and then disable interrupts */ cr2 = old_cr2 = readb(sport->port.membase + UARTCR2); @@ -2495,7 +2495,7 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) writeb(old_cr2, sport->port.membase + UARTCR2); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void @@ -2507,9 +2507,9 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count) int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* first save CR2 and then disable interrupts */ cr = old_cr = lpuart32_read(&sport->port, UARTCTRL); @@ -2525,7 +2525,7 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count) lpuart32_write(&sport->port, old_cr, UARTCTRL); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -3089,7 +3089,7 @@ static int lpuart_suspend(struct device *dev) uart_suspend_port(&lpuart_reg, &sport->port); if (lpuart_uport_is_active(sport)) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { /* disable Rx/Tx and interrupts */ temp = lpuart32_read(&sport->port, UARTCTRL); @@ -3101,7 +3101,7 @@ static int lpuart_suspend(struct device *dev) temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); writeb(temp, sport->port.membase + UARTCR2); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); if (sport->lpuart_dma_rx_use) { /* @@ -3114,7 +3114,7 @@ static int lpuart_suspend(struct device *dev) lpuart_dma_rx_free(&sport->port); /* Disable Rx DMA to use UART port as wakeup source */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { temp = lpuart32_read(&sport->port, UARTBAUD); lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, @@ -3123,11 +3123,11 @@ static int lpuart_suspend(struct device *dev) writeb(readb(sport->port.membase + UARTCR5) & ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } if (sport->lpuart_dma_tx_use) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (lpuart_is_32(sport)) { temp = lpuart32_read(&sport->port, UARTBAUD); temp &= ~UARTBAUD_TDMAE; @@ -3137,7 +3137,7 @@ static int lpuart_suspend(struct device *dev) temp &= ~UARTCR5_TDMAS; writeb(temp, sport->port.membase + UARTCR5); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); sport->dma_tx_in_progress = false; dmaengine_terminate_sync(sport->dma_tx_chan); } diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 819f957b6b84..a75eafbcbea3 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -929,7 +929,7 @@ static inline void check_modem_status(struct icom_port *icom_port) char delta_status; unsigned char status; - spin_lock(&icom_port->uart_port.lock); + uart_port_lock(&icom_port->uart_port); /*modem input register */ status = readb(&icom_port->dram->isr); @@ -951,7 +951,7 @@ static inline void check_modem_status(struct icom_port *icom_port) port.delta_msr_wait); old_status = status; } - spin_unlock(&icom_port->uart_port.lock); + uart_port_unlock(&icom_port->uart_port); } static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) @@ -1093,7 +1093,7 @@ static void process_interrupt(u16 port_int_reg, struct icom_port *icom_port) { - spin_lock(&icom_port->uart_port.lock); + uart_port_lock(&icom_port->uart_port); trace(icom_port, "INTERRUPT", port_int_reg); if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED)) @@ -1102,7 +1102,7 @@ static void process_interrupt(u16 port_int_reg, if (port_int_reg & INT_RCV_COMPLETED) recv_interrupt(port_int_reg, icom_port); - spin_unlock(&icom_port->uart_port.lock); + uart_port_unlock(&icom_port->uart_port); } static irqreturn_t icom_interrupt(int irq, void *dev_id) @@ -1186,14 +1186,14 @@ static unsigned int icom_tx_empty(struct uart_port *port) int ret; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (le16_to_cpu(icom_port->statStg->xmit[0].flags) & SA_FLAGS_READY_TO_XMIT) ret = TIOCSER_TEMT; else ret = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -1276,7 +1276,7 @@ static void icom_send_xchar(struct uart_port *port, char ch) /* wait .1 sec to send char */ for (index = 0; index < 10; index++) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); xdata = readb(&icom_port->dram->xchar); if (xdata == 0x00) { trace(icom_port, "QUICK_WRITE", 0); @@ -1284,10 +1284,10 @@ static void icom_send_xchar(struct uart_port *port, char ch) /* flush write operation */ xdata = readb(&icom_port->dram->xchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); break; } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); msleep(10); } } @@ -1307,7 +1307,7 @@ static void icom_break(struct uart_port *port, int break_state) unsigned char cmdReg; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); trace(icom_port, "BREAK", 0); cmdReg = readb(&icom_port->dram->CmdReg); if (break_state == -1) { @@ -1315,7 +1315,7 @@ static void icom_break(struct uart_port *port, int break_state) } else { writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int icom_open(struct uart_port *port) @@ -1365,7 +1365,7 @@ static void icom_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long offset; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); trace(icom_port, "CHANGE_SPEED", 0); cflag = termios->c_cflag; @@ -1516,7 +1516,7 @@ static void icom_set_termios(struct uart_port *port, struct ktermios *termios, trace(icom_port, "XR_ENAB", 0); writeb(CMD_XMIT_RCV_ENABLE, &icom_port->dram->CmdReg); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *icom_type(struct uart_port *port) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 13cb78340709..708b9852a575 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -177,8 +177,6 @@ enum imx_uart_type { IMX1_UART, IMX21_UART, - IMX53_UART, - IMX6Q_UART, }; /* device type dependent stuff */ @@ -240,30 +238,26 @@ struct imx_port_ucrs { unsigned int ucr3; }; -static struct imx_uart_data imx_uart_devdata[] = { - [IMX1_UART] = { - .uts_reg = IMX1_UTS, - .devtype = IMX1_UART, - }, - [IMX21_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX21_UART, - }, - [IMX53_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX53_UART, - }, - [IMX6Q_UART] = { - .uts_reg = IMX21_UTS, - .devtype = IMX6Q_UART, - }, +static const struct imx_uart_data imx_uart_imx1_devdata = { + .uts_reg = IMX1_UTS, + .devtype = IMX1_UART, +}; + +static const struct imx_uart_data imx_uart_imx21_devdata = { + .uts_reg = IMX21_UTS, + .devtype = IMX21_UART, }; static const struct of_device_id imx_uart_dt_ids[] = { - { .compatible = "fsl,imx6q-uart", .data = &imx_uart_devdata[IMX6Q_UART], }, - { .compatible = "fsl,imx53-uart", .data = &imx_uart_devdata[IMX53_UART], }, - { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], }, - { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], }, + /* + * For reasons unknown to me, some UART devices (e.g. imx6ul's) are + * compatible to fsl,imx6q-uart, but not fsl,imx21-uart, while the + * original imx6q's UART is compatible to fsl,imx21-uart. This driver + * doesn't make any distinction between these two variants. + */ + { .compatible = "fsl,imx6q-uart", .data = &imx_uart_imx21_devdata, }, + { .compatible = "fsl,imx1-uart", .data = &imx_uart_imx1_devdata, }, + { .compatible = "fsl,imx21-uart", .data = &imx_uart_imx21_devdata, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_uart_dt_ids); @@ -575,7 +569,7 @@ static void imx_uart_dma_tx_callback(void *data) unsigned long flags; u32 ucr1; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); @@ -600,7 +594,7 @@ static void imx_uart_dma_tx_callback(void *data) imx_uart_writel(sport, ucr4, UCR4); } - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* called with port.lock taken and irqs off */ @@ -766,11 +760,11 @@ static irqreturn_t imx_uart_rtsint(int irq, void *dev_id) struct imx_port *sport = dev_id; irqreturn_t ret; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); ret = __imx_uart_rtsint(irq, dev_id); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -779,9 +773,9 @@ static irqreturn_t imx_uart_txint(int irq, void *dev_id) { struct imx_port *sport = dev_id; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_transmit_buffer(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return IRQ_HANDLED; } @@ -895,11 +889,11 @@ static irqreturn_t imx_uart_rxint(int irq, void *dev_id) struct imx_port *sport = dev_id; irqreturn_t ret; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); ret = __imx_uart_rxint(irq, dev_id); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -962,7 +956,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; irqreturn_t ret = IRQ_NONE; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); usr1 = imx_uart_readl(sport, USR1); usr2 = imx_uart_readl(sport, USR2); @@ -1032,7 +1026,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) ret = IRQ_HANDLED; } - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return ret; } @@ -1115,7 +1109,7 @@ static void imx_uart_break_ctl(struct uart_port *port, int break_state) unsigned long flags; u32 ucr1; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr1 = imx_uart_readl(sport, UCR1) & ~UCR1_SNDBRK; @@ -1124,7 +1118,7 @@ static void imx_uart_break_ctl(struct uart_port *port, int break_state) imx_uart_writel(sport, ucr1, UCR1); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -1137,9 +1131,9 @@ static void imx_uart_timeout(struct timer_list *t) unsigned long flags; if (sport->port.state) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); imx_uart_mctrl_check(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); } @@ -1169,9 +1163,9 @@ static void imx_uart_dma_rx_callback(void *data) status = dmaengine_tx_status(chan, sport->rx_cookie, &state); if (status == DMA_ERROR) { - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_clear_rx_errors(sport); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return; } @@ -1200,9 +1194,9 @@ static void imx_uart_dma_rx_callback(void *data) r_bytes = rx_ring->head - rx_ring->tail; /* If we received something, check for 0xff flood */ - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); imx_uart_check_flood(sport, imx_uart_readl(sport, USR2)); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) { @@ -1457,10 +1451,12 @@ static int imx_uart_startup(struct uart_port *port) imx_uart_writel(sport, ucr4 & ~UCR4_DREN, UCR4); /* Can we enable the DMA support? */ - if (!uart_console(port) && imx_uart_dma_init(sport) == 0) + if (!uart_console(port) && imx_uart_dma_init(sport) == 0) { + lockdep_set_subclass(&port->lock, 1); dma_is_inited = 1; + } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* Reset fifo's and state machines */ imx_uart_soft_reset(sport); @@ -1533,7 +1529,7 @@ static int imx_uart_startup(struct uart_port *port) imx_uart_disable_loopback_rs485(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -1558,21 +1554,21 @@ static void imx_uart_shutdown(struct uart_port *port) sport->dma_is_rxing = 0; } - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); imx_uart_stop_tx(port); imx_uart_stop_rx(port); imx_uart_disable_dma(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); imx_uart_dma_exit(sport); } mctrl_gpio_disable_ms(sport->gpios); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr2 = imx_uart_readl(sport, UCR2); ucr2 &= ~(UCR2_TXEN | UCR2_ATEN); imx_uart_writel(sport, ucr2, UCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); /* * Stop our timer. @@ -1583,7 +1579,7 @@ static void imx_uart_shutdown(struct uart_port *port) * Disable all interrupts, port and break condition. */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); ucr1 = imx_uart_readl(sport, UCR1); ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_RXDMAEN | @@ -1605,7 +1601,7 @@ static void imx_uart_shutdown(struct uart_port *port) ucr4 &= ~UCR4_TCEN; imx_uart_writel(sport, ucr4, UCR4); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); clk_disable_unprepare(sport->clk_per); clk_disable_unprepare(sport->clk_ipg); @@ -1668,7 +1664,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); quot = uart_get_divisor(port, baud); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * Read current UCR2 and save it for future use, then clear all the bits @@ -1796,7 +1792,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_uart_enable_ms(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *imx_uart_type(struct uart_port *port) @@ -1858,7 +1854,7 @@ static int imx_uart_poll_init(struct uart_port *port) imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * Be careful about the order of enabling bits here. First enable the @@ -1886,7 +1882,7 @@ static int imx_uart_poll_init(struct uart_port *port) imx_uart_writel(sport, ucr1 | UCR1_RRDYEN, UCR1); imx_uart_writel(sport, ucr2 | UCR2_ATEN, UCR2); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return 0; } @@ -2005,9 +2001,9 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) if (sport->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&sport->port.lock, flags); + locked = uart_port_trylock_irqsave(&sport->port, &flags); else - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); /* * First, save UCR1/2/3 and then disable interrupts @@ -2035,7 +2031,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) imx_uart_ucrs_restore(sport, &old_ucr); if (locked) - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } /* @@ -2193,10 +2189,10 @@ static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t) struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx); unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (sport->tx_state == WAIT_AFTER_RTS) imx_uart_start_tx(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return HRTIMER_NORESTART; } @@ -2206,10 +2202,10 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx); unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (sport->tx_state == WAIT_AFTER_SEND) imx_uart_stop_tx(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return HRTIMER_NORESTART; } @@ -2482,9 +2478,9 @@ static void imx_uart_restore_context(struct imx_port *sport) { unsigned long flags; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); if (!sport->context_saved) { - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); return; } @@ -2499,7 +2495,7 @@ static void imx_uart_restore_context(struct imx_port *sport) imx_uart_writel(sport, sport->saved_reg[2], UCR3); imx_uart_writel(sport, sport->saved_reg[3], UCR4); sport->context_saved = false; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void imx_uart_save_context(struct imx_port *sport) @@ -2507,7 +2503,7 @@ static void imx_uart_save_context(struct imx_port *sport) unsigned long flags; /* Save necessary regs */ - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->saved_reg[0] = imx_uart_readl(sport, UCR1); sport->saved_reg[1] = imx_uart_readl(sport, UCR2); sport->saved_reg[2] = imx_uart_readl(sport, UCR3); @@ -2519,7 +2515,7 @@ static void imx_uart_save_context(struct imx_port *sport) sport->saved_reg[8] = imx_uart_readl(sport, UBMR); sport->saved_reg[9] = imx_uart_readl(sport, IMX21_UTS); sport->context_saved = true; - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 845ff706bc59..320b29cd4683 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -432,7 +432,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) unsigned char r3; bool push = false; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); r3 = read_zsreg(channel, R3); /* Channel A */ @@ -448,7 +448,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) if (r3 & CHATxIP) ip22zilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (push) tty_flip_buffer_push(&up->port.state->port); @@ -458,7 +458,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) channel = ZILOG_CHANNEL_FROM_PORT(&up->port); push = false; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { writeb(RES_H_IUS, &channel->control); ZSDELAY(); @@ -471,7 +471,7 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) if (r3 & CHBTxIP) ip22zilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (push) tty_flip_buffer_push(&up->port.state->port); @@ -504,11 +504,11 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) unsigned char status; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = ip22zilog_read_channel_status(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; @@ -664,7 +664,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != up->curregs[R5]) { @@ -674,7 +674,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) write_zsreg(channel, R5, up->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void __ip22zilog_reset(struct uart_ip22zilog_port *up) @@ -735,9 +735,9 @@ static int ip22zilog_startup(struct uart_port *port) if (ZS_IS_CONS(up)) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __ip22zilog_startup(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -775,7 +775,7 @@ static void ip22zilog_shutdown(struct uart_port *port) if (ZS_IS_CONS(up)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); channel = ZILOG_CHANNEL_FROM_PORT(port); @@ -788,7 +788,7 @@ static void ip22zilog_shutdown(struct uart_port *port) up->curregs[R5] &= ~SND_BRK; ip22zilog_maybe_update_regs(up, channel); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -880,7 +880,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 1200, 76800); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); @@ -894,7 +894,7 @@ ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port)); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *ip22zilog_type(struct uart_port *port) @@ -1016,10 +1016,10 @@ ip22zilog_console_write(struct console *con, const char *s, unsigned int count) struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, count, ip22zilog_put_char); udelay(2); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init ip22zilog_console_setup(struct console *con, char *options) @@ -1034,13 +1034,13 @@ static int __init ip22zilog_console_setup(struct console *con, char *options) printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->curregs[R15] |= BRKIE; __ip22zilog_startup(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 0c78f66276cd..2bd640428970 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -816,9 +816,9 @@ static void neo_parse_isr(struct jsm_board *brd, u32 port) /* Parse any modem signal changes */ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "MOD_STAT: sending to parse_modem_sigs\n"); - spin_lock_irqsave(&ch->uart_port.lock, lock_flags); + uart_port_lock_irqsave(&ch->uart_port, &lock_flags); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); - spin_unlock_irqrestore(&ch->uart_port.lock, lock_flags); + uart_port_unlock_irqrestore(&ch->uart_port, lock_flags); } } diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 222afc270c88..ce0fef7e2c66 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -152,14 +152,14 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) container_of(port, struct jsm_channel, uart_port); struct ktermios *termios; - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); termios = &port->state->port.tty->termios; if (ch == termios->c_cc[VSTART]) channel->ch_bd->bd_ops->send_start_character(channel); if (ch == termios->c_cc[VSTOP]) channel->ch_bd->bd_ops->send_stop_character(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static void jsm_tty_stop_rx(struct uart_port *port) @@ -176,13 +176,13 @@ static void jsm_tty_break(struct uart_port *port, int break_state) struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); if (break_state == -1) channel->ch_bd->bd_ops->send_break(channel); else channel->ch_bd->bd_ops->clear_break(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static int jsm_tty_open(struct uart_port *port) @@ -241,7 +241,7 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); termios = &port->state->port.tty->termios; channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; @@ -261,7 +261,7 @@ static int jsm_tty_open(struct uart_port *port) jsm_carrier(channel); channel->ch_open_count++; - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); return 0; @@ -307,7 +307,7 @@ static void jsm_tty_set_termios(struct uart_port *port, struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); - spin_lock_irqsave(&port->lock, lock_flags); + uart_port_lock_irqsave(port, &lock_flags); channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; channel->ch_c_oflag = termios->c_oflag; @@ -317,7 +317,7 @@ static void jsm_tty_set_termios(struct uart_port *port, channel->ch_bd->bd_ops->param(channel); jsm_carrier(channel); - spin_unlock_irqrestore(&port->lock, lock_flags); + uart_port_unlock_irqrestore(port, lock_flags); } static const char *jsm_tty_type(struct uart_port *port) diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index d881cdd2a58f..a25ab1efe38f 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -139,13 +139,13 @@ static irqreturn_t liteuart_interrupt(int irq, void *data) * if polling, the context would be "in_serving_softirq", so use * irq[save|restore] spin_lock variants to cover all possibilities */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); isr = litex_read8(port->membase + OFF_EV_PENDING) & uart->irq_reg; if (isr & EV_RX) liteuart_rx_chars(port); if (isr & EV_TX) liteuart_tx_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_RETVAL(isr); } @@ -195,10 +195,10 @@ static int liteuart_startup(struct uart_port *port) } } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* only enabling rx irqs during startup */ liteuart_update_irq_reg(port, true, EV_RX); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (!port->irq) { timer_setup(&uart->timer, liteuart_timer, 0); @@ -213,9 +213,9 @@ static void liteuart_shutdown(struct uart_port *port) struct liteuart_port *uart = to_liteuart_port(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); liteuart_update_irq_reg(port, false, EV_RX | EV_TX); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (port->irq) free_irq(port->irq, port); @@ -229,13 +229,13 @@ static void liteuart_set_termios(struct uart_port *port, struct ktermios *new, unsigned int baud; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* update baudrate */ baud = uart_get_baud_rate(port, new, old, 0, 460800); uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *liteuart_type(struct uart_port *port) @@ -382,9 +382,9 @@ static void liteuart_console_write(struct console *co, const char *s, uart = (struct liteuart_port *)xa_load(&liteuart_array, co->index); port = &uart->port; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, liteuart_putchar); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int liteuart_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index b38fe4728c26..5149a947b7fe 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -140,15 +140,15 @@ static void lpc32xx_hsuart_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar); wait_for_xmit_empty(&up->port); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } @@ -298,7 +298,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) struct tty_port *tport = &port->state->port; u32 status; - spin_lock(&port->lock); + uart_port_lock(port); /* Read UART status and clear latched interrupts */ status = readl(LPC32XX_HSUART_IIR(port->membase)); @@ -333,7 +333,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) __serial_lpc32xx_tx(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -404,14 +404,14 @@ static void serial_lpc32xx_break_ctl(struct uart_port *port, unsigned long flags; u32 tmp; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); if (break_state != 0) tmp |= LPC32XX_HSU_BREAK; else tmp &= ~LPC32XX_HSU_BREAK; writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* port->lock is not held. */ @@ -421,7 +421,7 @@ static int serial_lpc32xx_startup(struct uart_port *port) unsigned long flags; u32 tmp; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __serial_uart_flush(port); @@ -441,7 +441,7 @@ static int serial_lpc32xx_startup(struct uart_port *port) lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); retval = request_irq(port->irq, serial_lpc32xx_interrupt, 0, MODNAME, port); @@ -458,7 +458,7 @@ static void serial_lpc32xx_shutdown(struct uart_port *port) u32 tmp; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; @@ -466,7 +466,7 @@ static void serial_lpc32xx_shutdown(struct uart_port *port) lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -491,7 +491,7 @@ static void serial_lpc32xx_set_termios(struct uart_port *port, quot = __serial_get_clock_div(port->uartclk, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Ignore characters? */ tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); @@ -505,7 +505,7 @@ static void serial_lpc32xx_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c index 465b1def9e11..a6a7c405892e 100644 --- a/drivers/tty/serial/ma35d1_serial.c +++ b/drivers/tty/serial/ma35d1_serial.c @@ -269,16 +269,16 @@ static void receive_chars(struct uart_ma35d1_port *up) if (uart_handle_sysrq_char(&up->port, ch)) continue; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); uart_insert_char(&up->port, fsr, MA35_FSR_RX_OVER_IF, ch, flag); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); fsr = serial_in(up, MA35_FSR_REG); } while (!(fsr & MA35_FSR_RX_EMPTY) && (max_count-- > 0)); - spin_lock(&up->port.lock); + uart_port_lock(&up->port); tty_flip_buffer_push(&up->port.state->port); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); } static irqreturn_t ma35d1serial_interrupt(int irq, void *dev_id) @@ -364,14 +364,14 @@ static void ma35d1serial_break_ctl(struct uart_port *port, int break_state) unsigned long flags; u32 lcr; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); lcr = serial_in(up, MA35_LCR_REG); if (break_state != 0) lcr |= MA35_LCR_BREAK; else lcr &= ~MA35_LCR_BREAK; serial_out(up, MA35_LCR_REG, lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int ma35d1serial_startup(struct uart_port *port) @@ -441,7 +441,7 @@ static void ma35d1serial_set_termios(struct uart_port *port, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.read_status_mask = MA35_FSR_RX_OVER_IF; if (termios->c_iflag & INPCK) @@ -475,7 +475,7 @@ static void ma35d1serial_set_termios(struct uart_port *port, serial_out(up, MA35_LCR_REG, lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *ma35d1serial_type(struct uart_port *port) @@ -560,9 +560,9 @@ static void ma35d1serial_console_write(struct console *co, const char *s, u32 co if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * First save the IER then disable the interrupts @@ -576,7 +576,7 @@ static void ma35d1serial_console_write(struct console *co, const char *s, u32 co serial_out(up, MA35_IER_REG, ier); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init ma35d1serial_console_setup(struct console *co, char *options) @@ -695,6 +695,9 @@ static int ma35d1serial_probe(struct platform_device *pdev) up->port.iobase = res_mem->start; up->port.membase = ioremap(up->port.iobase, MA35_UART_REG_SIZE); + if (!up->port.membase) + return -ENOMEM; + up->port.ops = &ma35d1serial_ops; spin_lock_init(&up->port.lock); diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index db3204d2a305..97e4965b73d4 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -402,7 +402,7 @@ static int max14830_detect(struct device *dev) ret = s->if_cfg->extended_reg_enable(dev, true); if (ret) return ret; - + regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val); s->if_cfg->extended_reg_enable(dev, false); if (((val & MAX310x_REV_MASK) != MAX14830_REV_ID)) { diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 1666ce012e5e..91b15243f6c6 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -135,12 +135,12 @@ static void mcf_break_ctl(struct uart_port *port, int break_state) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (break_state == -1) writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR); else writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -150,7 +150,7 @@ static int mcf_startup(struct uart_port *port) struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Reset UART, get it into known state... */ writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); @@ -164,7 +164,7 @@ static int mcf_startup(struct uart_port *port) pp->imr = MCFUART_UIR_RXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -176,7 +176,7 @@ static void mcf_shutdown(struct uart_port *port) struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable all interrupts now */ pp->imr = 0; @@ -186,7 +186,7 @@ static void mcf_shutdown(struct uart_port *port) writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -252,7 +252,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, mr2 |= MCFUART_MR2_TXCTS; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); mr2 |= MCFUART_MR2_TXRTS; @@ -273,7 +273,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, port->membase + MCFUART_UCSR); writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /****************************************************************************/ @@ -350,7 +350,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) isr = readb(port->membase + MCFUART_UISR) & pp->imr; - spin_lock(&port->lock); + uart_port_lock(port); if (isr & MCFUART_UIR_RXREADY) { mcf_rx_chars(pp); ret = IRQ_HANDLED; @@ -359,7 +359,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) mcf_tx_chars(pp); ret = IRQ_HANDLED; } - spin_unlock(&port->lock); + uart_port_unlock(port); return ret; } diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index d2502aaa3e8c..8048fa542fc4 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -392,7 +392,7 @@ static irqreturn_t men_z135_intr(int irq, void *data) if (!irq_id) goto out; - spin_lock(&port->lock); + uart_port_lock(port); /* It's save to write to IIR[7:6] RXC[9:8] */ iowrite8(irq_id, port->membase + MEN_Z135_STAT_REG); @@ -418,7 +418,7 @@ static irqreturn_t men_z135_intr(int irq, void *data) handled = true; } - spin_unlock(&port->lock); + uart_port_unlock(port); out: return IRQ_RETVAL(handled); } @@ -708,7 +708,7 @@ static void men_z135_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, uart_freq / 16); - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); @@ -716,7 +716,7 @@ static void men_z135_set_termios(struct uart_port *port, iowrite32(bd_reg, port->membase + MEN_Z135_BAUD_REG); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); } static const char *men_z135_type(struct uart_port *port) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 790d910dafa5..8dd84617e715 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -129,14 +129,14 @@ static void meson_uart_shutdown(struct uart_port *port) free_irq(port->irq, port); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = readl(port->membase + AML_UART_CONTROL); val &= ~AML_UART_RX_EN; val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); writel(val, port->membase + AML_UART_CONTROL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void meson_uart_start_tx(struct uart_port *port) @@ -238,7 +238,7 @@ static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) { struct uart_port *port = (struct uart_port *)dev_id; - spin_lock(&port->lock); + uart_port_lock(port); if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) meson_receive_chars(port); @@ -248,7 +248,7 @@ static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) meson_uart_start_tx(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -284,7 +284,7 @@ static int meson_uart_startup(struct uart_port *port) u32 val; int ret = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = readl(port->membase + AML_UART_CONTROL); val |= AML_UART_CLEAR_ERR; @@ -301,7 +301,7 @@ static int meson_uart_startup(struct uart_port *port) val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2)); writel(val, port->membase + AML_UART_MISC); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, meson_uart_interrupt, 0, port->name, port); @@ -341,7 +341,7 @@ static void meson_uart_set_termios(struct uart_port *port, unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); cflags = termios->c_cflag; iflags = termios->c_iflag; @@ -380,10 +380,14 @@ static void meson_uart_set_termios(struct uart_port *port, else val |= AML_UART_STOP_BIT_1SB; - if (cflags & CRTSCTS) - val &= ~AML_UART_TWO_WIRE_EN; - else + if (cflags & CRTSCTS) { + if (port->flags & UPF_HARD_FLOW) + val &= ~AML_UART_TWO_WIRE_EN; + else + termios->c_cflag &= ~CRTSCTS; + } else { val |= AML_UART_TWO_WIRE_EN; + } writel(val, port->membase + AML_UART_CONTROL); @@ -401,7 +405,7 @@ static void meson_uart_set_termios(struct uart_port *port, AML_UART_FRAME_ERR; uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int meson_uart_verify_port(struct uart_port *port, @@ -460,14 +464,14 @@ static int meson_uart_poll_get_char(struct uart_port *port) u32 c; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY) c = NO_POLL_CHAR; else c = readl(port->membase + AML_UART_RFIFO); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return c; } @@ -478,7 +482,7 @@ static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c) u32 reg; int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Wait until FIFO is empty or timeout */ ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg, @@ -502,7 +506,7 @@ static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c) dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n"); out: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif /* CONFIG_CONSOLE_POLL */ @@ -559,9 +563,9 @@ static void meson_serial_port_write(struct uart_port *port, const char *s, if (port->sysrq) { locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -573,7 +577,7 @@ static void meson_serial_port_write(struct uart_port *port, const char *s, writel(val, port->membase + AML_UART_CONTROL); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } @@ -646,8 +650,8 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt return 0; } -OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", - meson_serial_early_console_setup); +OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); +OF_EARLYCON_DECLARE(meson, "amlogic,meson-s4-uart", meson_serial_early_console_setup); #define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname) #else @@ -705,6 +709,7 @@ static int meson_uart_probe(struct platform_device *pdev) u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ int ret = 0; int irq; + bool has_rtscts; if (pdev->dev.of_node) pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); @@ -732,6 +737,7 @@ static int meson_uart_probe(struct platform_device *pdev) return irq; of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); + has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts"); if (meson_ports[pdev->id]) { return dev_err_probe(&pdev->dev, -EBUSY, @@ -762,6 +768,8 @@ static int meson_uart_probe(struct platform_device *pdev) port->mapsize = resource_size(res_mem); port->irq = irq; port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY; + if (has_rtscts) + port->flags |= UPF_HARD_FLOW; port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE); port->dev = &pdev->dev; port->line = pdev->id; diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index 70a910085e93..db3b81f2aa57 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -207,9 +207,9 @@ static irqreturn_t mlb_usio_rx_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); mlb_usio_rx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -218,10 +218,10 @@ static irqreturn_t mlb_usio_tx_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; - spin_lock(&port->lock); + uart_port_lock(port); if (readb(port->membase + MLB_USIO_REG_SSR) & MLB_USIO_SSR_TBI) mlb_usio_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -267,7 +267,7 @@ static int mlb_usio_startup(struct uart_port *port) escr = readb(port->membase + MLB_USIO_REG_ESCR); if (of_property_read_bool(port->dev->of_node, "auto-flow-control")) escr |= MLB_USIO_ESCR_FLWEN; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); writeb(0, port->membase + MLB_USIO_REG_SCR); writeb(escr, port->membase + MLB_USIO_REG_ESCR); writeb(MLB_USIO_SCR_UPCL, port->membase + MLB_USIO_REG_SCR); @@ -282,7 +282,7 @@ static int mlb_usio_startup(struct uart_port *port) writeb(MLB_USIO_SCR_TXE | MLB_USIO_SCR_RIE | MLB_USIO_SCR_TBIE | MLB_USIO_SCR_RXE, port->membase + MLB_USIO_REG_SCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -337,7 +337,7 @@ static void mlb_usio_set_termios(struct uart_port *port, else quot = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = MLB_USIO_SSR_ORE | MLB_USIO_SSR_RDRF | MLB_USIO_SSR_TDRE; @@ -367,7 +367,7 @@ static void mlb_usio_set_termios(struct uart_port *port, writew(BIT(12), port->membase + MLB_USIO_REG_FBYTE); writeb(MLB_USIO_SCR_RIE | MLB_USIO_SCR_RXE | MLB_USIO_SCR_TBIE | MLB_USIO_SCR_TXE, port->membase + MLB_USIO_REG_SCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *mlb_usio_type(struct uart_port *port) diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 916507b8f31d..a252465e745f 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1096,14 +1096,14 @@ static void mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (ctl == -1) psc_ops->command(port, MPC52xx_PSC_START_BRK); else psc_ops->command(port, MPC52xx_PSC_STOP_BRK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int @@ -1214,7 +1214,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, } /* Get the lock */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Do our best to flush TX & RX, so we don't lose anything */ /* But we don't wait indefinitely ! */ @@ -1250,7 +1250,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, psc_ops->command(port, MPC52xx_PSC_RX_ENABLE); /* We're all set, release the lock */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char * @@ -1477,11 +1477,11 @@ mpc52xx_uart_int(int irq, void *dev_id) struct uart_port *port = dev_id; irqreturn_t ret; - spin_lock(&port->lock); + uart_port_lock(port); ret = psc_ops->handle_irq(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return ret; } diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index ea5a7911cb15..2a4c09f3a834 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -188,12 +188,12 @@ static irqreturn_t mps2_uart_rxirq(int irq, void *data) if (unlikely(!(irqflag & UARTn_INT_RX))) return IRQ_NONE; - spin_lock(&port->lock); + uart_port_lock(port); mps2_uart_write8(port, UARTn_INT_RX, UARTn_INT); mps2_uart_rx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -206,12 +206,12 @@ static irqreturn_t mps2_uart_txirq(int irq, void *data) if (unlikely(!(irqflag & UARTn_INT_TX))) return IRQ_NONE; - spin_lock(&port->lock); + uart_port_lock(port); mps2_uart_write8(port, UARTn_INT_TX, UARTn_INT); mps2_uart_tx_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -222,7 +222,7 @@ static irqreturn_t mps2_uart_oerrirq(int irq, void *data) struct uart_port *port = data; u8 irqflag = mps2_uart_read8(port, UARTn_INT); - spin_lock(&port->lock); + uart_port_lock(port); if (irqflag & UARTn_INT_RX_OVERRUN) { struct tty_port *tport = &port->state->port; @@ -244,7 +244,7 @@ static irqreturn_t mps2_uart_oerrirq(int irq, void *data) handled = IRQ_HANDLED; } - spin_unlock(&port->lock); + uart_port_unlock(port); return handled; } @@ -356,12 +356,12 @@ mps2_uart_set_termios(struct uart_port *port, struct ktermios *termios, bauddiv = DIV_ROUND_CLOSEST(port->uartclk, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); mps2_uart_write32(port, bauddiv, UARTn_BAUDDIV); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 90953e679e38..597264b546fd 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -444,7 +444,7 @@ static void msm_complete_tx_dma(void *args) unsigned int count; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Already stopped */ if (!dma->count) @@ -476,7 +476,7 @@ static void msm_complete_tx_dma(void *args) msm_handle_tx(port); done: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int msm_handle_tx_dma(struct msm_port *msm_port, unsigned int count) @@ -549,7 +549,7 @@ static void msm_complete_rx_dma(void *args) unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Already stopped */ if (!dma->count) @@ -587,16 +587,16 @@ static void msm_complete_rx_dma(void *args) if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) flag = TTY_NORMAL; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); sysrq = uart_handle_sysrq_char(port, dma->virt[i]); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (!sysrq) tty_insert_flip_char(tport, dma->virt[i], flag); } msm_start_rx_dma(msm_port); done: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (count) tty_flip_buffer_push(tport); @@ -762,9 +762,9 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK)) flag = TTY_NORMAL; - spin_unlock(&port->lock); + uart_port_unlock(port); sysrq = uart_handle_sysrq_char(port, buf[i]); - spin_lock(&port->lock); + uart_port_lock(port); if (!sysrq) tty_insert_flip_char(tport, buf[i], flag); } @@ -824,9 +824,9 @@ static void msm_handle_rx(struct uart_port *port) else if (sr & MSM_UART_SR_PAR_FRAME_ERR) flag = TTY_FRAME; - spin_unlock(&port->lock); + uart_port_unlock(port); sysrq = uart_handle_sysrq_char(port, c); - spin_lock(&port->lock); + uart_port_lock(port); if (!sysrq) tty_insert_flip_char(tport, c, flag); } @@ -951,7 +951,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) unsigned int misr; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); misr = msm_read(port, MSM_UART_MISR); msm_write(port, 0, MSM_UART_IMR); /* disable interrupt */ @@ -983,7 +983,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id) msm_handle_delta_cts(port); msm_write(port, msm_port->imr, MSM_UART_IMR); /* restore interrupt */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -1128,13 +1128,13 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud, unsigned long flags, rate; flags = *saved_flags; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); entry = msm_find_best_baud(port, baud, &rate); clk_set_rate(msm_port->clk, rate); baud = rate / 16 / entry->divisor; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); *saved_flags = flags; port->uartclk = rate; @@ -1266,7 +1266,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int baud, mr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (dma->chan) /* Terminate if any */ msm_stop_dma(port, dma); @@ -1338,7 +1338,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios, /* Try to use DMA */ msm_start_rx_dma(msm_port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *msm_type(struct uart_port *port) @@ -1620,9 +1620,9 @@ static void __msm_console_write(struct uart_port *port, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); else - spin_lock(&port->lock); + uart_port_lock(port); if (is_uartdm) msm_reset_dm_count(port, count); @@ -1661,7 +1661,7 @@ static void __msm_console_write(struct uart_port *port, const char *s, } if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index ea924e9b913b..0255646bc175 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -187,9 +187,9 @@ static unsigned int mvebu_uart_tx_empty(struct uart_port *port) unsigned long flags; unsigned int st; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); st = readl(port->membase + UART_STAT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return (st & STAT_TX_EMP) ? TIOCSER_TEMT : 0; } @@ -249,14 +249,14 @@ static void mvebu_uart_break_ctl(struct uart_port *port, int brk) unsigned int ctl; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = readl(port->membase + UART_CTRL(port)); if (brk == -1) ctl |= CTRL_SND_BRK_SEQ; else ctl &= ~CTRL_SND_BRK_SEQ; writel(ctl, port->membase + UART_CTRL(port)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) @@ -540,7 +540,7 @@ static void mvebu_uart_set_termios(struct uart_port *port, unsigned long flags; unsigned int baud, min_baud, max_baud; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = STAT_RX_RDY(port) | STAT_OVR_ERR | STAT_TX_RDY(port) | STAT_TX_FIFO_FUL; @@ -589,7 +589,7 @@ static void mvebu_uart_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *mvebu_uart_type(struct uart_port *port) @@ -735,9 +735,9 @@ static void mvebu_uart_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ier = readl(port->membase + UART_CTRL(port)) & CTRL_BRK_INT; intr = readl(port->membase + UART_INTR(port)) & @@ -758,7 +758,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s, } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int mvebu_uart_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 0ead88c5a19a..ad4c1c5d0a7f 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -390,10 +390,10 @@ static void serial_omap_throttle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void serial_omap_unthrottle(struct uart_port *port) @@ -401,10 +401,10 @@ static void serial_omap_unthrottle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static unsigned int check_modem_status(struct uart_omap_port *up) @@ -527,7 +527,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; int max_count = 256; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); do { iir = serial_in(up, UART_IIR); @@ -563,7 +563,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) } } while (max_count--); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); tty_flip_buffer_push(&up->port.state->port); @@ -579,9 +579,9 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port) unsigned int ret = 0; dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -647,13 +647,13 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) unsigned long flags; dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int serial_omap_startup(struct uart_port *port) @@ -701,13 +701,13 @@ static int serial_omap_startup(struct uart_port *port) * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Most PC uarts need OUT2 raised to enable interrupts. */ up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); up->msr_saved_flags = 0; /* @@ -742,10 +742,10 @@ static void serial_omap_shutdown(struct uart_port *port) up->ier = 0; serial_out(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -815,7 +815,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Update the per-port timeout. @@ -1013,7 +1013,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); } @@ -1216,9 +1216,9 @@ serial_omap_console_write(struct console *co, const char *s, if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -1245,7 +1245,7 @@ serial_omap_console_write(struct console *co, const char *s, check_modem_status(up); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index e99970a9437f..919f5e5aa0f1 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -125,12 +125,12 @@ static unsigned int owl_uart_tx_empty(struct uart_port *port) u32 val; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_STAT); ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -232,7 +232,7 @@ static irqreturn_t owl_uart_irq(int irq, void *dev_id) unsigned long flags; u32 stat; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stat = owl_uart_read(port, OWL_UART_STAT); @@ -246,7 +246,7 @@ static irqreturn_t owl_uart_irq(int irq, void *dev_id) stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP; owl_uart_write(port, stat, OWL_UART_STAT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -256,14 +256,14 @@ static void owl_uart_shutdown(struct uart_port *port) u32 val; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_CTL); val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE | OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN); owl_uart_write(port, val, OWL_UART_CTL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -279,7 +279,7 @@ static int owl_uart_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = owl_uart_read(port, OWL_UART_STAT); val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP @@ -291,7 +291,7 @@ static int owl_uart_startup(struct uart_port *port) val |= OWL_UART_CTL_EN; owl_uart_write(port, val, OWL_UART_CTL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -311,7 +311,7 @@ static void owl_uart_set_termios(struct uart_port *port, u32 ctl; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = owl_uart_read(port, OWL_UART_CTL); @@ -371,7 +371,7 @@ static void owl_uart_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void owl_uart_release_port(struct uart_port *port) @@ -515,9 +515,9 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -541,7 +541,7 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, owl_uart_write(port, old_ctl, OWL_UART_CTL); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index cc83b772b7ca..436cc6d52a11 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1347,7 +1347,7 @@ static void pch_uart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); spin_lock_irqsave(&priv->lock, flags); - spin_lock(&port->lock); + uart_port_lock(port); uart_update_timeout(port, termios->c_cflag, baud); rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); @@ -1360,7 +1360,7 @@ static void pch_uart_set_termios(struct uart_port *port, tty_termios_encode_baud_rate(termios, baud, baud); out: - spin_unlock(&port->lock); + uart_port_unlock(port); spin_unlock_irqrestore(&priv->lock, flags); } @@ -1581,10 +1581,10 @@ pch_console_write(struct console *co, const char *s, unsigned int count) port_locked = 0; } else if (oops_in_progress) { priv_locked = spin_trylock(&priv->lock); - port_locked = spin_trylock(&priv->port.lock); + port_locked = uart_port_trylock(&priv->port); } else { spin_lock(&priv->lock); - spin_lock(&priv->port.lock); + uart_port_lock(&priv->port); } /* @@ -1604,7 +1604,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count) iowrite8(ier, priv->membase + UART_IER); if (port_locked) - spin_unlock(&priv->port.lock); + uart_port_unlock(&priv->port); if (priv_locked) spin_unlock(&priv->lock); local_irq_restore(flags); diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index e308d5022b3f..3a95bf5d55d3 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -243,7 +243,7 @@ static void pic32_uart_break_ctl(struct uart_port *port, int ctl) struct pic32_sport *sport = to_pic32_sport(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (ctl) pic32_uart_writel(sport, PIC32_SET(PIC32_UART_STA), @@ -252,7 +252,7 @@ static void pic32_uart_break_ctl(struct uart_port *port, int ctl) pic32_uart_writel(sport, PIC32_CLR(PIC32_UART_STA), PIC32_UART_STA_UTXBRK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* get port type in string format */ @@ -274,7 +274,7 @@ static void pic32_uart_do_rx(struct uart_port *port) */ max_count = PIC32_UART_RX_FIFO_DEPTH; - spin_lock(&port->lock); + uart_port_lock(port); tty = &port->state->port; @@ -331,7 +331,7 @@ static void pic32_uart_do_rx(struct uart_port *port) } while (--max_count); - spin_unlock(&port->lock); + uart_port_unlock(port); tty_flip_buffer_push(tty); } @@ -410,9 +410,9 @@ static irqreturn_t pic32_uart_tx_interrupt(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pic32_uart_do_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -580,9 +580,9 @@ static void pic32_uart_shutdown(struct uart_port *port) unsigned long flags; /* disable uart */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pic32_uart_dsbl_and_mask(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); clk_disable_unprepare(sport->clk); /* free all 3 interrupts for this UART */ @@ -604,7 +604,7 @@ static void pic32_uart_set_termios(struct uart_port *port, unsigned int quot; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* disable uart and mask all interrupts while changing speed */ pic32_uart_dsbl_and_mask(port); @@ -672,7 +672,7 @@ static void pic32_uart_set_termios(struct uart_port *port, /* enable uart */ pic32_uart_en_and_unmask(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* serial core request to claim uart iomem */ diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 13668ffdb1e7..c8bf08c19c64 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -246,9 +246,9 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap) #endif /* USE_CTRL_O_SYSRQ */ if (uap->port.sysrq) { int swallow; - spin_unlock(&uap->port.lock); + uart_port_unlock(&uap->port); swallow = uart_handle_sysrq_char(&uap->port, ch); - spin_lock(&uap->port.lock); + uart_port_lock(&uap->port); if (swallow) goto next_char; } @@ -435,7 +435,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) uap_a = pmz_get_port_A(uap); uap_b = uap_a->mate; - spin_lock(&uap_a->port.lock); + uart_port_lock(&uap_a->port); r3 = read_zsreg(uap_a, R3); /* Channel A */ @@ -456,14 +456,14 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) rc = IRQ_HANDLED; } skip_a: - spin_unlock(&uap_a->port.lock); + uart_port_unlock(&uap_a->port); if (push) tty_flip_buffer_push(&uap->port.state->port); if (!uap_b) goto out; - spin_lock(&uap_b->port.lock); + uart_port_lock(&uap_b->port); push = false; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { if (!ZS_IS_OPEN(uap_b)) { @@ -481,7 +481,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) rc = IRQ_HANDLED; } skip_b: - spin_unlock(&uap_b->port.lock); + uart_port_unlock(&uap_b->port); if (push) tty_flip_buffer_push(&uap->port.state->port); @@ -497,9 +497,9 @@ static inline u8 pmz_peek_status(struct uart_pmac_port *uap) unsigned long flags; u8 status; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); status = read_zsreg(uap, R0); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); return status; } @@ -685,7 +685,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != uap->curregs[R5]) { @@ -693,7 +693,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) write_zsreg(uap, R5, uap->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #ifdef CONFIG_PPC_PMAC @@ -865,18 +865,18 @@ static void pmz_irda_reset(struct uart_pmac_port *uap) { unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->curregs[R5] |= DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); msleep(110); - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); uap->curregs[R5] &= ~DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); msleep(10); } @@ -896,9 +896,9 @@ static int pmz_startup(struct uart_port *port) * initialize the chip */ if (!ZS_IS_CONS(uap)) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pwr_delay = __pmz_startup(uap); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line); if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, @@ -921,9 +921,9 @@ static int pmz_startup(struct uart_port *port) pmz_irda_reset(uap); /* Enable interrupt requests for the channel */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); pmz_interrupt_control(uap, 1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -933,7 +933,7 @@ static void pmz_shutdown(struct uart_port *port) struct uart_pmac_port *uap = to_pmz(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable interrupt requests for the channel */ pmz_interrupt_control(uap, 0); @@ -948,19 +948,19 @@ static void pmz_shutdown(struct uart_port *port) pmz_maybe_update_regs(uap); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Release interrupt handler */ free_irq(uap->port.irq, uap); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uap->flags &= ~PMACZILOG_FLAG_IS_OPEN; if (!ZS_IS_CONS(uap)) pmz_set_scc_power(uap, 0); /* Shut the chip down */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -1247,7 +1247,7 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, struct uart_pmac_port *uap = to_pmz(port); unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable IRQs on the port */ pmz_interrupt_control(uap, 0); @@ -1259,7 +1259,7 @@ static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, if (ZS_IS_OPEN(uap)) pmz_interrupt_control(uap, 1); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *pmz_type(struct uart_port *port) @@ -1896,7 +1896,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c struct uart_pmac_port *uap = &pmz_ports[con->index]; unsigned long flags; - spin_lock_irqsave(&uap->port.lock, flags); + uart_port_lock_irqsave(&uap->port, &flags); /* Turn of interrupts and enable the transmitter. */ write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); @@ -1908,7 +1908,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c write_zsreg(uap, R1, uap->curregs[1]); /* Don't disable the transmitter. */ - spin_unlock_irqrestore(&uap->port.lock, flags); + uart_port_unlock_irqrestore(&uap->port, flags); } /* diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 73c60f5ea027..46e70e155aab 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -225,14 +225,14 @@ static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) iir = serial_in(up, UART_IIR); if (iir & UART_IIR_NO_INT) return IRQ_NONE; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); lsr = serial_in(up, UART_LSR); if (lsr & UART_LSR_DR) receive_chars(up, &lsr); check_modem_status(up); if (lsr & UART_LSR_THRE) transmit_chars(up); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); return IRQ_HANDLED; } @@ -242,9 +242,9 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -295,13 +295,13 @@ static void serial_pxa_break_ctl(struct uart_port *port, int break_state) struct uart_pxa_port *up = (struct uart_pxa_port *)port; unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int serial_pxa_startup(struct uart_port *port) @@ -346,10 +346,10 @@ static int serial_pxa_startup(struct uart_port *port) */ serial_out(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl |= TIOCM_OUT2; serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Finally, enable interrupts. Note: Modem status interrupts @@ -383,10 +383,10 @@ static void serial_pxa_shutdown(struct uart_port *port) up->ier = 0; serial_out(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl &= ~TIOCM_OUT2; serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -434,7 +434,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Ensure the port will be enabled. @@ -504,7 +504,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, up->lcr = cval; /* Save LCR */ serial_pxa_set_mctrl(&up->port, up->port.mctrl); serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -608,9 +608,9 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) if (up->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); + locked = uart_port_trylock(&up->port); else - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * First save the IER then disable the interrupts @@ -628,7 +628,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) serial_out(up, UART_IER, ier); if (locked) - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); local_irq_restore(flags); clk_disable(up->clk); diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index b8aa4c1293ba..7e78f97e8f43 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -482,9 +482,9 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s, uport = &port->uport; if (oops_in_progress) - locked = spin_trylock_irqsave(&uport->lock, flags); + locked = uart_port_trylock_irqsave(uport, &flags); else - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); geni_status = readl(uport->membase + SE_GENI_STATUS); @@ -520,7 +520,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s, qcom_geni_serial_setup_tx(uport, port->tx_remaining); if (locked) - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) @@ -970,7 +970,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev) if (uport->suspended) return IRQ_NONE; - spin_lock(&uport->lock); + uart_port_lock(uport); m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c index be5c842b5ba9..d824c8318f33 100644 --- a/drivers/tty/serial/rda-uart.c +++ b/drivers/tty/serial/rda-uart.c @@ -139,12 +139,12 @@ static unsigned int rda_uart_tx_empty(struct uart_port *port) unsigned int ret; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = rda_uart_read(port, RDA_UART_STATUS); ret = (val & RDA_UART_TX_FIFO_MASK) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret; } @@ -246,7 +246,7 @@ static void rda_uart_set_termios(struct uart_port *port, unsigned int baud; u32 irq_mask; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); baud = uart_get_baud_rate(port, termios, old, 9600, port->uartclk / 4); rda_uart_change_baudrate(rda_port, baud); @@ -325,7 +325,7 @@ static void rda_uart_set_termios(struct uart_port *port, /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rda_uart_send_chars(struct uart_port *port) @@ -408,7 +408,7 @@ static irqreturn_t rda_interrupt(int irq, void *dev_id) unsigned long flags; u32 val, irq_mask; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Clear IRQ cause */ val = rda_uart_read(port, RDA_UART_IRQ_CAUSE); @@ -425,7 +425,7 @@ static irqreturn_t rda_interrupt(int irq, void *dev_id) rda_uart_send_chars(port); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -436,16 +436,16 @@ static int rda_uart_startup(struct uart_port *port) int ret; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rda_uart_write(port, 0, RDA_UART_IRQ_MASK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, rda_interrupt, IRQF_NO_SUSPEND, "rda-uart", port); if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); val = rda_uart_read(port, RDA_UART_CTRL); val |= RDA_UART_ENABLE; @@ -456,7 +456,7 @@ static int rda_uart_startup(struct uart_port *port) val |= (RDA_UART_RX_DATA_AVAILABLE | RDA_UART_RX_TIMEOUT); rda_uart_write(port, val, RDA_UART_IRQ_MASK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -466,7 +466,7 @@ static void rda_uart_shutdown(struct uart_port *port) unsigned long flags; u32 val; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rda_uart_stop_tx(port); rda_uart_stop_rx(port); @@ -475,7 +475,7 @@ static void rda_uart_shutdown(struct uart_port *port) val &= ~RDA_UART_ENABLE; rda_uart_write(port, val, RDA_UART_CTRL); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *rda_uart_type(struct uart_port *port) @@ -515,7 +515,7 @@ static void rda_uart_config_port(struct uart_port *port, int flags) rda_uart_request_port(port); } - spin_lock_irqsave(&port->lock, irq_flags); + uart_port_lock_irqsave(port, &irq_flags); /* Clear mask, so no surprise interrupts. */ rda_uart_write(port, 0, RDA_UART_IRQ_MASK); @@ -523,7 +523,7 @@ static void rda_uart_config_port(struct uart_port *port, int flags) /* Clear status register */ rda_uart_write(port, 0, RDA_UART_STATUS); - spin_unlock_irqrestore(&port->lock, irq_flags); + uart_port_unlock_irqrestore(port, irq_flags); } static void rda_uart_release_port(struct uart_port *port) @@ -597,9 +597,9 @@ static void rda_uart_port_write(struct uart_port *port, const char *s, if (port->sysrq) { locked = 0; } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); + locked = uart_port_trylock(port); } else { - spin_lock(&port->lock); + uart_port_lock(port); locked = 1; } @@ -615,7 +615,7 @@ static void rda_uart_port_write(struct uart_port *port, const char *s, rda_uart_write(port, old_irq_mask, RDA_UART_IRQ_MASK); if (locked) - spin_unlock(&port->lock); + uart_port_unlock(port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index de220ac8ca54..d46a81cddfcd 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -276,9 +276,9 @@ static unsigned int rp2_uart_tx_empty(struct uart_port *port) * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is * enabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return tx_fifo_bytes ? 0 : TIOCSER_TEMT; } @@ -323,10 +323,10 @@ static void rp2_uart_break_ctl(struct uart_port *port, int break_state) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, break_state ? RP2_TXRX_CTL_BREAK_m : 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rp2_uart_enable_ms(struct uart_port *port) @@ -383,7 +383,7 @@ static void rp2_uart_set_termios(struct uart_port *port, struct ktermios *new, if (tty_termios_baud_rate(new)) tty_termios_encode_baud_rate(new, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* ignore all characters if CREAD is not set */ port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; @@ -391,7 +391,7 @@ static void rp2_uart_set_termios(struct uart_port *port, struct ktermios *new, __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); uart_update_timeout(port, new->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void rp2_rx_chars(struct rp2_uart_port *up) @@ -440,7 +440,7 @@ static void rp2_ch_interrupt(struct rp2_uart_port *up) { u32 status; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); /* * The IRQ status bits are clear-on-write. Other status bits in @@ -456,7 +456,7 @@ static void rp2_ch_interrupt(struct rp2_uart_port *up) if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) wake_up_interruptible(&up->port.state->port.delta_msr_wait); - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); } static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) @@ -516,10 +516,10 @@ static void rp2_uart_shutdown(struct uart_port *port) rp2_uart_break_ctl(port, 0); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); rp2_mask_ch_irq(up, up->idx, 0); rp2_rmw(up, RP2_CHAN_STAT, 0, 0); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *rp2_uart_type(struct uart_port *port) diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index ad011f1e2f4d..be7bcd75d9f4 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -115,9 +115,9 @@ static void sa1100_timeout(struct timer_list *t) unsigned long flags; if (sport->port.state) { - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sa1100_mctrl_check(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); } @@ -247,7 +247,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) struct sa1100_port *sport = dev_id; unsigned int status, pass_counter = 0; - spin_lock(&sport->port.lock); + uart_port_lock(&sport->port); status = UART_GET_UTSR0(sport); status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS; do { @@ -276,7 +276,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS; } while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID)); - spin_unlock(&sport->port.lock); + uart_port_unlock(&sport->port); return IRQ_HANDLED; } @@ -321,14 +321,14 @@ static void sa1100_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int utcr3; - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); utcr3 = UART_GET_UTCR3(sport); if (break_state == -1) utcr3 |= UTCR3_BRK; else utcr3 &= ~UTCR3_BRK; UART_PUT_UTCR3(sport, utcr3); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static int sa1100_startup(struct uart_port *port) @@ -354,9 +354,9 @@ static int sa1100_startup(struct uart_port *port) /* * Enable modem status interrupts */ - spin_lock_irq(&sport->port.lock); + uart_port_lock_irq(&sport->port); sa1100_enable_ms(&sport->port); - spin_unlock_irq(&sport->port.lock); + uart_port_unlock_irq(&sport->port); return 0; } @@ -423,7 +423,7 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, del_timer_sync(&sport->timer); - spin_lock_irqsave(&sport->port.lock, flags); + uart_port_lock_irqsave(&sport->port, &flags); sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); @@ -485,7 +485,7 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) sa1100_enable_ms(&sport->port); - spin_unlock_irqrestore(&sport->port.lock, flags); + uart_port_unlock_irqrestore(&sport->port, flags); } static const char *sa1100_type(struct uart_port *port) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 07fb8a9dac63..3bd552841cd2 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -64,7 +64,6 @@ #define RXSTAT_DUMMY_READ (0x10000000) enum s3c24xx_port_type { - TYPE_S3C24XX, TYPE_S3C6400, TYPE_APPLE_S5L, }; @@ -128,8 +127,6 @@ struct s3c24xx_uart_dma { }; struct s3c24xx_uart_port { - unsigned char rx_claimed; - unsigned char tx_claimed; unsigned char rx_enabled; unsigned char tx_enabled; unsigned int pm_level; @@ -248,7 +245,7 @@ static void s3c24xx_serial_rx_enable(struct uart_port *port) unsigned int ucon, ufcon; int count = 10000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (--count && !s3c24xx_serial_txempty_nofifo(port)) udelay(100); @@ -262,7 +259,7 @@ static void s3c24xx_serial_rx_enable(struct uart_port *port) wr_regl(port, S3C2410_UCON, ucon); ourport->rx_enabled = 1; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c24xx_serial_rx_disable(struct uart_port *port) @@ -271,14 +268,14 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port) unsigned long flags; unsigned int ucon; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ucon = rd_regl(port, S3C2410_UCON); ucon &= ~S3C2410_UCON_RXIRQMODE; wr_regl(port, S3C2410_UCON, ucon); ourport->rx_enabled = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c24xx_serial_stop_tx(struct uart_port *port) @@ -344,7 +341,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args) dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_xmit_advance(port, count); ourport->tx_in_progress = 0; @@ -353,7 +350,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args) uart_write_wakeup(port); s3c24xx_serial_start_next_tx(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void enable_tx_dma(struct s3c24xx_uart_port *ourport) @@ -619,7 +616,7 @@ static void s3c24xx_serial_rx_dma_complete(void *args) received = dma->rx_bytes_requested - state.residue; async_tx_ack(dma->rx_desc); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (received) s3c24xx_uart_copy_rx_to_tty(ourport, t, received); @@ -631,7 +628,7 @@ static void s3c24xx_serial_rx_dma_complete(void *args) s3c64xx_start_rx_dma(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport) @@ -722,7 +719,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id) utrstat = rd_regl(port, S3C2410_UTRSTAT); rd_regl(port, S3C2410_UFSTAT); - spin_lock(&port->lock); + uart_port_lock(port); if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) { s3c64xx_start_rx_dma(ourport); @@ -751,7 +748,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id) wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT); finish: - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -849,9 +846,9 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) struct s3c24xx_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; - spin_lock(&port->lock); + uart_port_lock(port); s3c24xx_serial_rx_drain_fifo(ourport); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -932,11 +929,11 @@ static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id) struct s3c24xx_uart_port *ourport = id; struct uart_port *port = &ourport->port; - spin_lock(&port->lock); + uart_port_lock(port); s3c24xx_serial_tx_chars(ourport); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -1033,7 +1030,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned int ucon; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ucon = rd_regl(port, S3C2410_UCON); @@ -1044,7 +1041,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) wr_regl(port, S3C2410_UCON, ucon); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) @@ -1166,29 +1163,6 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) } } -static void s3c24xx_serial_shutdown(struct uart_port *port) -{ - struct s3c24xx_uart_port *ourport = to_ourport(port); - - if (ourport->tx_claimed) { - free_irq(ourport->tx_irq, ourport); - ourport->tx_enabled = 0; - ourport->tx_claimed = 0; - ourport->tx_mode = 0; - } - - if (ourport->rx_claimed) { - free_irq(ourport->rx_irq, ourport); - ourport->rx_claimed = 0; - ourport->rx_enabled = 0; - } - - if (ourport->dma) - s3c24xx_serial_release_dma(ourport); - - ourport->tx_in_progress = 0; -} - static void s3c64xx_serial_shutdown(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); @@ -1234,48 +1208,6 @@ static void apple_s5l_serial_shutdown(struct uart_port *port) ourport->tx_in_progress = 0; } -static int s3c24xx_serial_startup(struct uart_port *port) -{ - struct s3c24xx_uart_port *ourport = to_ourport(port); - int ret; - - ourport->rx_enabled = 1; - - ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0, - s3c24xx_serial_portname(port), ourport); - - if (ret != 0) { - dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); - return ret; - } - - ourport->rx_claimed = 1; - - dev_dbg(port->dev, "requesting tx irq...\n"); - - ourport->tx_enabled = 1; - - ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0, - s3c24xx_serial_portname(port), ourport); - - if (ret) { - dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); - goto err; - } - - ourport->tx_claimed = 1; - - /* the port reset code should have done the correct - * register setup for the port controls - */ - - return ret; - -err: - s3c24xx_serial_shutdown(port); - return ret; -} - static int s3c64xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); @@ -1303,7 +1235,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) ourport->rx_enabled = 1; ourport->tx_enabled = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; @@ -1313,7 +1245,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) enable_rx_pio(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Enable Rx Interrupt */ s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM); @@ -1341,7 +1273,7 @@ static int apple_s5l_serial_startup(struct uart_port *port) ourport->rx_enabled = 1; ourport->tx_enabled = 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8; @@ -1351,7 +1283,7 @@ static int apple_s5l_serial_startup(struct uart_port *port) enable_rx_pio(ourport); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Enable Rx Interrupt */ s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON); @@ -1626,7 +1558,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, ulcon |= S3C2410_LCON_PNONE; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dev_dbg(port->dev, "setting ulcon to %08x, brddiv to %d, udivslot %08x\n", @@ -1684,7 +1616,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= RXSTAT_DUMMY_READ; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *s3c24xx_serial_type(struct uart_port *port) @@ -1692,8 +1624,6 @@ static const char *s3c24xx_serial_type(struct uart_port *port) const struct s3c24xx_uart_port *ourport = to_ourport(port); switch (ourport->info->type) { - case TYPE_S3C24XX: - return "S3C24XX"; case TYPE_S3C6400: return "S3C6400/10"; case TYPE_APPLE_S5L: @@ -1753,27 +1683,6 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, unsigned char c); #endif -static const struct uart_ops s3c24xx_serial_ops = { - .pm = s3c24xx_serial_pm, - .tx_empty = s3c24xx_serial_tx_empty, - .get_mctrl = s3c24xx_serial_get_mctrl, - .set_mctrl = s3c24xx_serial_set_mctrl, - .stop_tx = s3c24xx_serial_stop_tx, - .start_tx = s3c24xx_serial_start_tx, - .stop_rx = s3c24xx_serial_stop_rx, - .break_ctl = s3c24xx_serial_break_ctl, - .startup = s3c24xx_serial_startup, - .shutdown = s3c24xx_serial_shutdown, - .set_termios = s3c24xx_serial_set_termios, - .type = s3c24xx_serial_type, - .config_port = s3c24xx_serial_config_port, - .verify_port = s3c24xx_serial_verify_port, -#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL) - .poll_get_char = s3c24xx_serial_get_poll_char, - .poll_put_char = s3c24xx_serial_put_poll_char, -#endif -}; - static const struct uart_ops s3c64xx_serial_ops = { .pm = s3c24xx_serial_pm, .tx_empty = s3c24xx_serial_tx_empty, @@ -1836,7 +1745,6 @@ static void s3c24xx_serial_init_port_default(int index) { port->iotype = UPIO_MEM; port->uartclk = 0; port->fifosize = 16; - port->ops = &s3c24xx_serial_ops; port->flags = UPF_BOOT_AUTOCONF; port->line = index; } @@ -1954,16 +1862,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ourport->tx_irq = ret + 1; } - switch (ourport->info->type) { - case TYPE_S3C24XX: - ret = platform_get_irq(platdev, 1); - if (ret > 0) - ourport->tx_irq = ret; - break; - default: - break; - } - /* * DMA is currently supported only on DT platforms, if DMA properties * are specified. @@ -2083,9 +1981,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) &ourport->drv_data->def_cfg; switch (ourport->info->type) { - case TYPE_S3C24XX: - ourport->port.ops = &s3c24xx_serial_ops; - break; case TYPE_S3C6400: ourport->port.ops = &s3c64xx_serial_ops; break; @@ -2376,14 +2271,14 @@ s3c24xx_serial_console_write(struct console *co, const char *s, if (cons_uart->sysrq) locked = false; else if (oops_in_progress) - locked = spin_trylock_irqsave(&cons_uart->lock, flags); + locked = uart_port_trylock_irqsave(cons_uart, &flags); else - spin_lock_irqsave(&cons_uart->lock, flags); + uart_port_lock_irqsave(cons_uart, &flags); uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); if (locked) - spin_unlock_irqrestore(&cons_uart->lock, flags); + uart_port_unlock_irqrestore(cons_uart, flags); } /* Shouldn't be __init, as it can be instantiated from other module */ @@ -2840,17 +2735,7 @@ static struct samsung_early_console_data s3c2410_early_console_data = { .rxfifo_mask = S3C2410_UFSTAT_RXFULL | S3C2410_UFSTAT_RXMASK, }; -static int __init s3c2410_early_console_setup(struct earlycon_device *device, - const char *opt) -{ - device->port.private_data = &s3c2410_early_console_data; - return samsung_early_console_setup(device, opt); -} - -OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", - s3c2410_early_console_setup); - -/* S3C2412, S3C2440, S3C64xx */ +/* S3C64xx */ static struct samsung_early_console_data s3c2440_early_console_data = { .txfull_mask = S3C2440_UFSTAT_TXFULL, .rxfifo_mask = S3C2440_UFSTAT_RXFULL | S3C2440_UFSTAT_RXMASK, @@ -2863,10 +2748,6 @@ static int __init s3c2440_early_console_setup(struct earlycon_device *device, return samsung_early_console_setup(device, opt); } -OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", - s3c2440_early_console_setup); -OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", - s3c2440_early_console_setup); OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", s3c2440_early_console_setup); diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index f3cd69346482..dbec29d9a6c3 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -610,7 +610,7 @@ static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios, else aux &= ~M_DUART_CTS_CHNG_ENA; - spin_lock(&uport->lock); + uart_port_lock(uport); if (sport->tx_stopped) command |= M_DUART_TX_DIS; @@ -632,7 +632,7 @@ static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios, write_sbdchn(sport, R_DUART_CMD, command); - spin_unlock(&uport->lock); + uart_port_unlock(uport); } @@ -839,22 +839,22 @@ static void sbd_console_write(struct console *co, const char *s, unsigned int mask; /* Disable transmit interrupts and enable the transmitter. */ - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2)); write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask & ~M_DUART_IMR_TX); write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); uart_console_write(&sport->port, s, count, sbd_console_putchar); /* Restore transmit interrupts and the transmitter enable. */ - spin_lock_irqsave(&uport->lock, flags); + uart_port_lock_irqsave(uport, &flags); sbd_line_drain(sport); if (sport->tx_stopped) write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS); write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask); - spin_unlock_irqrestore(&uport->lock, flags); + uart_port_unlock_irqrestore(uport, flags); } static int __init sbd_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index f61d98e09dc3..db2bb1c0d36c 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -223,7 +223,7 @@ * trigger levels. Trigger levels from 4 characters to 60 characters are * available with a granularity of four. * - * When the trigger level setting in TLR is zero, the SC16IS740/750/760 uses the + * When the trigger level setting in TLR is zero, the SC16IS74x/75x/76x uses the * trigger level setting defined in FCR. If TLR has non-zero trigger level value * the trigger level defined in FCR is discarded. This applies to both transmit * FIFO and receive FIFO trigger level setting. @@ -234,7 +234,7 @@ #define SC16IS7XX_TLR_TX_TRIGGER(words) ((((words) / 4) & 0x0f) << 0) #define SC16IS7XX_TLR_RX_TRIGGER(words) ((((words) / 4) & 0x0f) << 4) -/* IOControl register bits (Only 750/760) */ +/* IOControl register bits (Only 75x/76x) */ #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ #define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */ #define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */ @@ -249,9 +249,9 @@ #define SC16IS7XX_EFCR_RTS_INVERT_BIT (1 << 5) /* RTS output inversion */ #define SC16IS7XX_EFCR_IRDA_MODE_BIT (1 << 7) /* IrDA mode * 0 = rate upto 115.2 kbit/s - * - Only 750/760 + * - Only 75x/76x * 1 = rate upto 1.152 Mbit/s - * - Only 760 + * - Only 76x */ /* EFR register bits */ @@ -358,7 +358,6 @@ static struct uart_driver sc16is7xx_uart = { static void sc16is7xx_ier_set(struct uart_port *port, u8 bit); static void sc16is7xx_stop_tx(struct uart_port *port); -#define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e))) #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e))) static int sc16is7xx_line(struct uart_port *port) @@ -667,9 +666,9 @@ static void sc16is7xx_handle_tx(struct uart_port *port) } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -695,13 +694,13 @@ static void sc16is7xx_handle_tx(struct uart_port *port) sc16is7xx_fifo_write(port, to_send); } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_get_hwmctrl(struct uart_port *port) @@ -733,7 +732,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) one->old_mctrl = status; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if ((changed & TIOCM_RNG) && (status & TIOCM_RNG)) port->icount.rng++; if (changed & TIOCM_DSR) @@ -744,7 +743,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) uart_handle_cts_change(port, status & TIOCM_CTS); wake_up_interruptible(&port->state->port.delta_msr_wait); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) @@ -823,9 +822,9 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws) sc16is7xx_handle_tx(port); mutex_unlock(&s->efr_lock); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sc16is7xx_reconf_rs485(struct uart_port *port) @@ -836,14 +835,14 @@ static void sc16is7xx_reconf_rs485(struct uart_port *port) struct serial_rs485 *rs485 = &port->rs485; unsigned long irqflags; - spin_lock_irqsave(&port->lock, irqflags); + uart_port_lock_irqsave(port, &irqflags); if (rs485->flags & SER_RS485_ENABLED) { efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT; if (rs485->flags & SER_RS485_RTS_AFTER_SEND) efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT; } - spin_unlock_irqrestore(&port->lock, irqflags); + uart_port_unlock_irqrestore(port, irqflags); sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr); } @@ -854,10 +853,10 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws) struct sc16is7xx_one_config config; unsigned long irqflags; - spin_lock_irqsave(&one->port.lock, irqflags); + uart_port_lock_irqsave(&one->port, &irqflags); config = one->config; memset(&one->config, 0, sizeof(one->config)); - spin_unlock_irqrestore(&one->port.lock, irqflags); + uart_port_unlock_irqrestore(&one->port, irqflags); if (config.flags & SC16IS7XX_RECONF_MD) { u8 mcr = 0; @@ -963,18 +962,18 @@ static void sc16is7xx_throttle(struct uart_port *port) * value set in MCR register. Stop reading data from RX FIFO so the * AutoRTS feature will de-activate RTS output. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sc16is7xx_unthrottle(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_set(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_tx_empty(struct uart_port *port) @@ -1113,7 +1112,7 @@ static void sc16is7xx_set_termios(struct uart_port *port, /* Setup baudrate generator */ baud = sc16is7xx_set_baud(port, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); @@ -1121,7 +1120,7 @@ static void sc16is7xx_set_termios(struct uart_port *port, if (UART_ENABLE_MS(port, termios->c_cflag)) sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sc16is7xx_config_rs485(struct uart_port *port, struct ktermios *termios, @@ -1208,9 +1207,9 @@ static int sc16is7xx_startup(struct uart_port *port) sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); /* Enable modem status polling */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -1409,6 +1408,29 @@ static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) } #endif +static void sc16is7xx_setup_irda_ports(struct sc16is7xx_port *s) +{ + int i; + int ret; + int count; + u32 irda_port[2]; + struct device *dev = s->p[0].port.dev; + + count = device_property_count_u32(dev, "irda-mode-ports"); + if (count < 0 || count > ARRAY_SIZE(irda_port)) + return; + + ret = device_property_read_u32_array(dev, "irda-mode-ports", + irda_port, count); + if (ret) + return; + + for (i = 0; i < count; i++) { + if (irda_port[i] < s->devtype->nr_uart) + s->p[irda_port[i]].irda_mode = true; + } +} + /* * Configure ports designated to operate as modem control lines. */ @@ -1591,16 +1613,7 @@ static int sc16is7xx_probe(struct device *dev, sc16is7xx_power(&s->p[i].port, 0); } - if (dev->of_node) { - struct property *prop; - const __be32 *p; - u32 u; - - of_property_for_each_u32(dev->of_node, "irda-mode-ports", - prop, p, u) - if (u < devtype->nr_uart) - s->p[u].irda_mode = true; - } + sc16is7xx_setup_irda_ports(s); ret = sc16is7xx_setup_mctrl_ports(s); if (ret) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index d4ec943cb8e9..6d4006b41975 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -411,7 +411,7 @@ static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) divisor = DIV_ROUND_CLOSEST(rate, baud * 16); } - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); lcr = tup->lcr_shadow; lcr |= UART_LCR_DLAB; tegra_uart_write(tup, lcr, UART_LCR); @@ -424,7 +424,7 @@ static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) /* Dummy read to ensure the write is posted */ tegra_uart_read(tup, UART_SCR); - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); tup->current_baud = baud; @@ -522,13 +522,13 @@ static void tegra_uart_tx_dma_complete(void *args) dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); count = tup->tx_bytes_requested - state.residue; async_tx_ack(tup->tx_dma_desc); - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); uart_xmit_advance(&tup->uport, count); tup->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&tup->uport); tegra_uart_start_next_tx(tup); - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); } static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup, @@ -598,13 +598,13 @@ static unsigned int tegra_uart_tx_empty(struct uart_port *u) unsigned int ret = 0; unsigned long flags; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); if (!tup->tx_in_progress) { unsigned long lsr = tegra_uart_read(tup, UART_LSR); if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) ret = TIOCSER_TEMT; } - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); return ret; } @@ -727,7 +727,7 @@ static void tegra_uart_rx_dma_complete(void *args) struct dma_tx_state state; enum dma_status status; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); @@ -749,7 +749,7 @@ static void tegra_uart_rx_dma_complete(void *args) set_rts(tup, true); done: - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); } static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup) @@ -836,7 +836,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) bool is_rx_int = false; unsigned long flags; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); while (1) { iir = tegra_uart_read(tup, UART_IIR); if (iir & UART_IIR_NO_INT) { @@ -852,7 +852,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) } else if (is_rx_start) { tegra_uart_start_rx_dma(tup); } - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); return IRQ_HANDLED; } @@ -969,11 +969,11 @@ static void tegra_uart_hw_deinit(struct tegra_uart_port *tup) } } - spin_lock_irqsave(&tup->uport.lock, flags); + uart_port_lock_irqsave(&tup->uport, &flags); /* Reset the Rx and Tx FIFOs */ tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); tup->current_baud = 0; - spin_unlock_irqrestore(&tup->uport.lock, flags); + uart_port_unlock_irqrestore(&tup->uport, flags); tup->rx_in_progress = 0; tup->tx_in_progress = 0; @@ -1292,7 +1292,7 @@ static void tegra_uart_set_termios(struct uart_port *u, int ret; max_divider *= 16; - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); /* Changing configuration, it is safe to stop any rx now */ if (tup->rts_active) @@ -1341,7 +1341,7 @@ static void tegra_uart_set_termios(struct uart_port *u, baud = uart_get_baud_rate(u, termios, oldtermios, parent_clk_rate/max_divider, parent_clk_rate/16); - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); ret = tegra_set_baudrate(tup, baud); if (ret < 0) { dev_err(tup->uport.dev, "Failed to set baud rate\n"); @@ -1349,7 +1349,7 @@ static void tegra_uart_set_termios(struct uart_port *u, } if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&u->lock, flags); + uart_port_lock_irqsave(u, &flags); /* Flow control */ if (termios->c_cflag & CRTSCTS) { @@ -1382,7 +1382,7 @@ static void tegra_uart_set_termios(struct uart_port *u, if (termios->c_iflag & IGNBRK) tup->uport.ignore_status_mask |= UART_LSR_BI; - spin_unlock_irqrestore(&u->lock, flags); + uart_port_unlock_irqrestore(u, flags); } static const char *tegra_uart_type(struct uart_port *u) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d5ba6e90bd95..f1348a509552 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -79,7 +79,7 @@ static inline void uart_port_deref(struct uart_port *uport) ({ \ struct uart_port *__uport = uart_port_ref(state); \ if (__uport) \ - spin_lock_irqsave(&__uport->lock, flags); \ + uart_port_lock_irqsave(__uport, &flags); \ __uport; \ }) @@ -87,7 +87,7 @@ static inline void uart_port_deref(struct uart_port *uport) ({ \ struct uart_port *__uport = uport; \ if (__uport) { \ - spin_unlock_irqrestore(&__uport->lock, flags); \ + uart_port_unlock_irqrestore(__uport, flags); \ uart_port_deref(__uport); \ } \ }) @@ -146,7 +146,7 @@ static void __uart_start(struct uart_state *state) /* Increment the runtime PM usage count for the active check below */ err = pm_runtime_get(&port_dev->dev); - if (err < 0) { + if (err < 0 && err != -EINPROGRESS) { pm_runtime_put_noidle(&port_dev->dev); return; } @@ -179,12 +179,12 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) unsigned long flags; unsigned int old; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); old = port->mctrl; port->mctrl = (old & ~clear) | set; if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) @@ -219,7 +219,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state /* * Set modem status enables based on termios cflag */ - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (termios->c_cflag & CRTSCTS) uport->status |= UPSTAT_CTS_ENABLE; else @@ -240,7 +240,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state else __uart_start(state); } - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } /* @@ -431,7 +431,7 @@ EXPORT_SYMBOL(uart_update_timeout); * baud. * * If the new baud rate is invalid, try the @old termios setting. If it's still - * invalid, we try 9600 baud. + * invalid, we try 9600 baud. If that is also invalid 0 is returned. * * The @termios structure is updated to reflect the baud rate we're actually * going to be using. Don't do this for the case where B0 is requested ("hang @@ -515,8 +515,6 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, max - 1, max - 1); } } - /* Should never happen */ - WARN_ON(1); return 0; } EXPORT_SYMBOL(uart_get_baud_rate); @@ -702,11 +700,11 @@ static void uart_send_xchar(struct tty_struct *tty, char ch) if (port->ops->send_xchar) port->ops->send_xchar(port, ch); else { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->x_char = ch; if (ch) port->ops->start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } uart_port_deref(port); } @@ -775,6 +773,9 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) struct uart_port *uport; int ret = -ENODEV; + /* Initialize structure in case we error out later to prevent any stack info leakage. */ + *retinfo = (struct serial_struct){}; + /* * Ensure the state we copy is consistent and no hardware changes * occur as we go @@ -1085,9 +1086,9 @@ static int uart_tiocmget(struct tty_struct *tty) if (!tty_io_error(tty)) { result = uport->mctrl; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); result |= uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } out: mutex_unlock(&port->mutex); @@ -1223,16 +1224,16 @@ static int uart_wait_modem_status(struct uart_state *state, unsigned long arg) uport = uart_port_ref(state); if (!uport) return -EIO; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); uart_enable_ms(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); add_wait_queue(&port->delta_msr_wait, &wait); for (;;) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); set_current_state(TASK_INTERRUPTIBLE); @@ -1277,9 +1278,9 @@ static int uart_get_icount(struct tty_struct *tty, uport = uart_port_ref(state); if (!uport) return -EIO; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_deref(uport); icount->cts = cnow.cts; @@ -1413,9 +1414,9 @@ static int uart_rs485_config(struct uart_port *port) uart_sanitize_serial_rs485(port, rs485); uart_set_rs485_termination(port, rs485); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->rs485_config(port, NULL, rs485); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) memset(rs485, 0, sizeof(*rs485)); @@ -1428,9 +1429,9 @@ static int uart_get_rs485_config(struct uart_port *port, unsigned long flags; struct serial_rs485 aux; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); aux = port->rs485; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (copy_to_user(rs485, &aux, sizeof(aux))) return -EFAULT; @@ -1457,7 +1458,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, uart_sanitize_serial_rs485(port, &rs485); uart_set_rs485_termination(port, &rs485); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->rs485_config(port, &tty->termios, &rs485); if (!ret) { port->rs485 = rs485; @@ -1466,7 +1467,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, if (!(rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) return ret; @@ -1485,9 +1486,9 @@ static int uart_get_iso7816_config(struct uart_port *port, if (!port->iso7816_config) return -ENOTTY; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); aux = port->iso7816; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (copy_to_user(iso7816, &aux, sizeof(aux))) return -EFAULT; @@ -1516,9 +1517,9 @@ static int uart_set_iso7816_config(struct uart_port *port, if (iso7816.reserved[i]) return -EINVAL; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = port->iso7816_config(port, &iso7816); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (ret) return ret; @@ -1735,9 +1736,9 @@ static void uart_tty_port_shutdown(struct tty_port *port) if (WARN(!uport, "detached port still initialized!\n")) return; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_shutdown(port); @@ -1751,10 +1752,10 @@ static void uart_tty_port_shutdown(struct tty_port *port) /* * Free the transmit buffer. */ - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); buf = state->xmit.buf; state->xmit.buf = NULL; - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); free_page((unsigned long)buf); @@ -1897,10 +1898,10 @@ static bool uart_carrier_raised(struct tty_port *port) */ if (WARN_ON(!uport)) return true; - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uart_enable_ms(uport); mctrl = uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); uart_port_deref(uport); return mctrl & TIOCM_CAR; @@ -2017,9 +2018,9 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) pm_state = state->pm_state; if (pm_state != UART_PM_STATE_ON) uart_change_pm(state, UART_PM_STATE_ON); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); status = uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); if (pm_state != UART_PM_STATE_ON) uart_change_pm(state, pm_state); @@ -2358,9 +2359,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) */ if (!console_suspend_enabled && uart_console(uport)) { if (uport->ops->start_rx) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } goto unlock; } @@ -2375,7 +2376,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) tty_port_set_suspended(port, true); tty_port_set_initialized(port, false); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); ops->stop_tx(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, 0); @@ -2383,7 +2384,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) mctrl = uport->mctrl; uport->mctrl = 0; ops->stop_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); /* * Wait for the transmitter to empty. @@ -2455,9 +2456,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) uart_change_pm(state, UART_PM_STATE_ON); uport->ops->set_termios(uport, &termios, NULL); if (!console_suspend_enabled && uport->ops->start_rx) { - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); uport->ops->start_rx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); } if (console_suspend_enabled) console_start(uport->cons); @@ -2468,10 +2469,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) int ret; uart_change_pm(state, UART_PM_STATE_ON); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, 0); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); if (console_suspend_enabled || !uart_console(uport)) { /* Protected by port mutex for now */ struct tty_struct *tty = port->tty; @@ -2481,11 +2482,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (tty) uart_change_line_settings(tty, state, NULL); uart_rs485_config(uport); - spin_lock_irq(&uport->lock); + uart_port_lock_irq(uport); if (!(uport->rs485.flags & SER_RS485_ENABLED)) ops->set_mctrl(uport, uport->mctrl); ops->start_tx(uport); - spin_unlock_irq(&uport->lock); + uart_port_unlock_irq(uport); tty_port_set_initialized(port, true); } else { /* @@ -2588,11 +2589,11 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, * keep the DTR setting that is set in uart_set_options() * We probably don't need a spinlock around this, but */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->mctrl &= TIOCM_DTR; if (!(port->rs485.flags & SER_RS485_ENABLED)) port->ops->set_mctrl(port, port->mctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); uart_rs485_config(port); @@ -3564,9 +3565,10 @@ int uart_get_rs485_mode(struct uart_port *port) { struct serial_rs485 *rs485conf = &port->rs485; struct device *dev = port->dev; + enum gpiod_flags dflags; + struct gpio_desc *desc; u32 rs485_delay[2]; int ret; - int rx_during_tx_gpio_flag; ret = device_property_read_u32_array(dev, "rs485-rts-delay", rs485_delay, 2); @@ -3605,26 +3607,19 @@ int uart_get_rs485_mode(struct uart_port *port) * bus participants enable it, no communication is possible at all. * Works fine for short cables and users may enable for longer cables. */ - port->rs485_term_gpio = devm_gpiod_get_optional(dev, "rs485-term", - GPIOD_OUT_LOW); - if (IS_ERR(port->rs485_term_gpio)) { - ret = PTR_ERR(port->rs485_term_gpio); - port->rs485_term_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n"); - } + desc = devm_gpiod_get_optional(dev, "rs485-term", GPIOD_OUT_LOW); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-term-gpios\n"); + port->rs485_term_gpio = desc; if (port->rs485_term_gpio) port->rs485_supported.flags |= SER_RS485_TERMINATE_BUS; - rx_during_tx_gpio_flag = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? - GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - port->rs485_rx_during_tx_gpio = devm_gpiod_get_optional(dev, - "rs485-rx-during-tx", - rx_during_tx_gpio_flag); - if (IS_ERR(port->rs485_rx_during_tx_gpio)) { - ret = PTR_ERR(port->rs485_rx_during_tx_gpio); - port->rs485_rx_during_tx_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-rx-during-tx-gpios\n"); - } + dflags = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? + GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + desc = devm_gpiod_get_optional(dev, "rs485-rx-during-tx", dflags); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-rx-during-tx-gpios\n"); + port->rs485_rx_during_tx_gpio = desc; return 0; } diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 7d5aaa8d422b..e51ca593ab86 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -184,7 +184,7 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) mctrl_gpio_get(gpios, &mctrl); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); mctrl_diff = mctrl ^ gpios->mctrl_prev; gpios->mctrl_prev = mctrl; @@ -205,7 +205,7 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) wake_up_interruptible(&port->state->port.delta_msr_wait); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c index 862423237007..88975a4df306 100644 --- a/drivers/tty/serial/serial_port.c +++ b/drivers/tty/serial/serial_port.c @@ -35,10 +35,10 @@ static int serial_port_runtime_resume(struct device *dev) goto out; /* Flush any pending TX for the port */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (__serial_port_busy(port)) port->ops->start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); out: pm_runtime_mark_last_busy(dev); diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index be08fb6f749c..eaa980722455 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -335,13 +335,13 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) unsigned int status; while (1) { - spin_lock(&up->lock); + uart_port_lock(up); status = sio_in(up, TXX9_SIDISR); if (!(sio_in(up, TXX9_SIDICR) & TXX9_SIDICR_TIE)) status &= ~TXX9_SIDISR_TDIS; if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | TXX9_SIDISR_TOUT))) { - spin_unlock(&up->lock); + uart_port_unlock(up); break; } @@ -353,7 +353,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | TXX9_SIDISR_TOUT); - spin_unlock(&up->lock); + uart_port_unlock(up); if (pass_counter++ > PASS_LIMIT) break; @@ -367,9 +367,9 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *up) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); ret = (sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS) ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); return ret; } @@ -399,12 +399,12 @@ static void serial_txx9_break_ctl(struct uart_port *up, int break_state) { unsigned long flags; - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); if (break_state == -1) sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); else sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); } #if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) @@ -517,9 +517,9 @@ static int serial_txx9_startup(struct uart_port *up) /* * Now, initialize the UART */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); /* Enable RX/TX */ sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); @@ -541,9 +541,9 @@ static void serial_txx9_shutdown(struct uart_port *up) */ sio_out(up, TXX9_SIDICR, 0); /* disable all intrs */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); /* * Disable break condition @@ -625,7 +625,7 @@ serial_txx9_set_termios(struct uart_port *up, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->lock, flags); + uart_port_lock_irqsave(up, &flags); /* * Update the per-port timeout. @@ -676,7 +676,7 @@ serial_txx9_set_termios(struct uart_port *up, struct ktermios *termios, sio_out(up, TXX9_SIFCR, fcr); serial_txx9_set_mctrl(up, up->mctrl); - spin_unlock_irqrestore(&up->lock, flags); + uart_port_unlock_irqrestore(up, flags); } static void diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a560b729fa3b..84ab434c94ba 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1205,7 +1205,7 @@ static void sci_dma_tx_complete(void *arg) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_xmit_advance(port, s->tx_dma_len); @@ -1229,7 +1229,7 @@ static void sci_dma_tx_complete(void *arg) } } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Locking: called with port lock held */ @@ -1320,7 +1320,7 @@ static void sci_dma_rx_complete(void *arg) dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line, s->active_rx); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); active = sci_dma_rx_find_active(s); if (active >= 0) @@ -1347,20 +1347,20 @@ static void sci_dma_rx_complete(void *arg) dma_async_issue_pending(chan); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n", __func__, s->cookie_rx[active], active, s->active_rx); return; fail: - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); /* Switch to PIO */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dmaengine_terminate_async(chan); sci_dma_rx_chan_invalidate(s); sci_dma_rx_reenable_irq(s); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sci_dma_tx_release(struct sci_port *s) @@ -1409,13 +1409,13 @@ static int sci_dma_rx_submit(struct sci_port *s, bool port_lock_held) fail: /* Switch to PIO */ if (!port_lock_held) - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (i) dmaengine_terminate_async(chan); sci_dma_rx_chan_invalidate(s); sci_start_rx(port); if (!port_lock_held) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return -EAGAIN; } @@ -1437,14 +1437,14 @@ static void sci_dma_tx_work_fn(struct work_struct *work) * transmit till the end, and then the rest. Take the port lock to get a * consistent xmit buffer state. */ - spin_lock_irq(&port->lock); + uart_port_lock_irq(port); head = xmit->head; tail = xmit->tail; buf = s->tx_dma_addr + tail; s->tx_dma_len = CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE); if (!s->tx_dma_len) { /* Transmit buffer has been flushed */ - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); return; } @@ -1452,7 +1452,7 @@ static void sci_dma_tx_work_fn(struct work_struct *work) DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n"); goto switch_to_pio; } @@ -1464,12 +1464,12 @@ static void sci_dma_tx_work_fn(struct work_struct *work) desc->callback_param = s; s->cookie_tx = dmaengine_submit(desc); if (dma_submit_error(s->cookie_tx)) { - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); goto switch_to_pio; } - spin_unlock_irq(&port->lock); + uart_port_unlock_irq(port); dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, xmit->buf, tail, head, s->cookie_tx); @@ -1477,10 +1477,10 @@ static void sci_dma_tx_work_fn(struct work_struct *work) return; switch_to_pio: - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); s->chan_tx = NULL; sci_start_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -1497,17 +1497,17 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) dev_dbg(port->dev, "DMA Rx timed out\n"); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); active = sci_dma_rx_find_active(s); if (active < 0) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return HRTIMER_NORESTART; } status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); if (status == DMA_COMPLETE) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "Cookie %d #%d has already completed\n", s->active_rx, active); @@ -1525,7 +1525,7 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) */ status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); if (status == DMA_COMPLETE) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); dev_dbg(port->dev, "Transaction complete after DMA engine was stopped"); return HRTIMER_NORESTART; } @@ -1546,7 +1546,7 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t) sci_dma_rx_reenable_irq(s); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return HRTIMER_NORESTART; } @@ -1770,9 +1770,9 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr) struct uart_port *port = ptr; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -1786,11 +1786,11 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) if (port->type != PORT_SCI) return sci_tx_interrupt(irq, ptr); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctrl = serial_port_in(port, SCSCR); ctrl &= ~(SCSCR_TE | SCSCR_TEIE); serial_port_out(port, SCSCR, ctrl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return IRQ_HANDLED; } @@ -2187,7 +2187,7 @@ static void sci_break_ctl(struct uart_port *port, int break_state) return; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); scsptr = serial_port_in(port, SCSPTR); scscr = serial_port_in(port, SCSCR); @@ -2201,7 +2201,7 @@ static void sci_break_ctl(struct uart_port *port, int break_state) serial_port_out(port, SCSPTR, scsptr); serial_port_out(port, SCSCR, scscr); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sci_startup(struct uart_port *port) @@ -2233,7 +2233,7 @@ static void sci_shutdown(struct uart_port *port) s->autorts = false; mctrl_gpio_disable_ms(to_sci_port(port)->gpios); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_stop_rx(port); sci_stop_tx(port); /* @@ -2243,7 +2243,7 @@ static void sci_shutdown(struct uart_port *port) scr = serial_port_in(port, SCSCR); serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0 | s->hscif_tot)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); #ifdef CONFIG_SERIAL_SH_SCI_DMA if (s->chan_rx_saved) { @@ -2545,7 +2545,7 @@ done: serial_port_out(port, SCCKS, sccks); } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sci_reset(port); @@ -2667,7 +2667,7 @@ done: if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); sci_port_disable(s); @@ -3052,9 +3052,9 @@ static void serial_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* first save SCSCR then disable interrupts, keep clock source */ ctrl = serial_port_in(port, SCSCR); @@ -3074,7 +3074,7 @@ static void serial_console_write(struct console *co, const char *s, serial_port_out(port, SCSCR, ctrl); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int serial_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index d195c5de52e7..b296e57a9dee 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -521,11 +521,11 @@ static irqreturn_t sifive_serial_irq(int irq, void *dev_id) struct sifive_serial_port *ssp = dev_id; u32 ip; - spin_lock(&ssp->port.lock); + uart_port_lock(&ssp->port); ip = __ssp_readl(ssp, SIFIVE_SERIAL_IP_OFFS); if (!ip) { - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); return IRQ_NONE; } @@ -534,7 +534,7 @@ static irqreturn_t sifive_serial_irq(int irq, void *dev_id) if (ip & SIFIVE_SERIAL_IP_TXWM_MASK) __ssp_transmit_chars(ssp); - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); return IRQ_HANDLED; } @@ -653,7 +653,7 @@ static void sifive_serial_set_termios(struct uart_port *port, ssp->port.uartclk / 16); __ssp_update_baud_rate(ssp, rate); - spin_lock_irqsave(&ssp->port.lock, flags); + uart_port_lock_irqsave(&ssp->port, &flags); /* Update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, rate); @@ -670,7 +670,7 @@ static void sifive_serial_set_termios(struct uart_port *port, if (v != old_v) __ssp_writel(v, SIFIVE_SERIAL_RXCTRL_OFFS, ssp); - spin_unlock_irqrestore(&ssp->port.lock, flags); + uart_port_unlock_irqrestore(&ssp->port, flags); } static void sifive_serial_release_port(struct uart_port *port) @@ -795,9 +795,9 @@ static void sifive_serial_console_write(struct console *co, const char *s, if (ssp->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&ssp->port.lock); + locked = uart_port_trylock(&ssp->port); else - spin_lock(&ssp->port.lock); + uart_port_lock(&ssp->port); ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS); __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp); @@ -807,7 +807,7 @@ static void sifive_serial_console_write(struct console *co, const char *s, __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp); if (locked) - spin_unlock(&ssp->port.lock); + uart_port_unlock(&ssp->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index f328fa57231f..f257525f9299 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -247,7 +247,7 @@ static void sprd_complete_tx_dma(void *data) struct circ_buf *xmit = &port->state->xmit; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); dma_unmap_single(port->dev, sp->tx_dma.phys_addr, sp->tx_dma.trans_len, DMA_TO_DEVICE); @@ -260,7 +260,7 @@ static void sprd_complete_tx_dma(void *data) sprd_tx_dma_config(port)) sp->tx_dma.trans_len = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_uart_dma_submit(struct uart_port *port, @@ -429,13 +429,13 @@ static void sprd_complete_rx_dma(void *data) enum dma_status status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = dmaengine_tx_status(sp->rx_dma.chn, sp->rx_dma.cookie, &state); if (status != DMA_COMPLETE) { sprd_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -449,7 +449,7 @@ static void sprd_complete_rx_dma(void *data) if (sprd_start_dma_rx(port)) sprd_stop_rx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_start_dma_rx(struct uart_port *port) @@ -638,12 +638,12 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned int ims; - spin_lock(&port->lock); + uart_port_lock(port); ims = serial_in(port, SPRD_IMSR); if (!ims) { - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_NONE; } @@ -660,7 +660,7 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) if (ims & SPRD_IMSR_TX_FIFO_EMPTY) sprd_tx(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -727,13 +727,13 @@ static int sprd_startup(struct uart_port *port) serial_out(port, SPRD_CTL1, fc); /* enable interrupt */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ien = serial_in(port, SPRD_IEN); ien |= SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; if (!sp->rx_dma.enable) ien |= SPRD_IEN_RX_FULL; serial_out(port, SPRD_IEN, ien); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -793,7 +793,7 @@ static void sprd_set_termios(struct uart_port *port, struct ktermios *termios, lcr |= SPRD_LCR_EVEN_PAR; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); @@ -837,7 +837,7 @@ static void sprd_set_termios(struct uart_port *port, struct ktermios *termios, fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; serial_out(port, SPRD_CTL1, fc); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) @@ -974,9 +974,9 @@ static void sprd_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_console_write(port, s, count, sprd_console_putchar); @@ -984,7 +984,7 @@ static void sprd_console_write(struct console *co, const char *s, wait_for_xmitr(port); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sprd_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 92b9f6894006..a821f5d76a26 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -319,7 +319,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr) struct uart_port *port = ptr; u32 status; - spin_lock(&port->lock); + uart_port_lock(port); status = asc_in(port, ASC_STA); @@ -334,7 +334,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr) asc_transmit_chars(port); } - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -452,10 +452,10 @@ static void asc_pm(struct uart_port *port, unsigned int state, * we can come to turning it off. Note this is not called with * the port spinlock held. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN; asc_out(port, ASC_CTL, ctl); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); clk_disable_unprepare(ascport->clk); break; } @@ -480,7 +480,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); cflag = termios->c_cflag; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* read control register */ ctrl_val = asc_in(port, ASC_CTL); @@ -594,7 +594,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios, /* write final value and enable port */ asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *asc_type(struct uart_port *port) @@ -849,9 +849,9 @@ static void asc_console_write(struct console *co, const char *s, unsigned count) if (port->sysrq) locked = 0; /* asc_interrupt has already claimed the lock */ else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Disable interrupts so we don't get the IRQ line bouncing @@ -869,7 +869,7 @@ static void asc_console_write(struct console *co, const char *s, unsigned count) asc_out(port, ASC_INTEN, intenable); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int asc_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 5e9cf0c48813..3048620315d6 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -537,7 +537,7 @@ static void stm32_usart_rx_dma_complete(void *arg) unsigned int size; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -643,9 +643,9 @@ static void stm32_usart_tx_dma_complete(void *arg) stm32_usart_tx_dma_terminate(stm32port); /* Let's see if we have pending data to send */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void stm32_usart_tx_interrupt_enable(struct uart_port *port) @@ -889,7 +889,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) if (!stm32_port->throttled) { if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_started(stm32_port)) || ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_started(stm32_port))) { - spin_lock(&port->lock); + uart_port_lock(port); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); if (size) @@ -898,14 +898,14 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) } if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { - spin_lock(&port->lock); + uart_port_lock(port); stm32_usart_transmit_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); } /* Receiver timeout irq for DMA RX */ if (stm32_usart_rx_dma_started(stm32_port) && !stm32_port->throttled) { - spin_lock(&port->lock); + uart_port_lock(port); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); if (size) @@ -993,7 +993,7 @@ static void stm32_usart_throttle(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* * Pause DMA transfer, so the RX data gets queued into the FIFO. @@ -1006,7 +1006,7 @@ static void stm32_usart_throttle(struct uart_port *port) stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); stm32_port->throttled = true; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Unthrottle the remote, the input buffer can now accept data. */ @@ -1016,7 +1016,7 @@ static void stm32_usart_unthrottle(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_set_bits(port, ofs->cr1, stm32_port->cr1_irq); if (stm32_port->cr3_irq) stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq); @@ -1030,7 +1030,7 @@ static void stm32_usart_unthrottle(struct uart_port *port) if (stm32_port->rx_ch) stm32_usart_rx_dma_start_or_resume(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Receive stop */ @@ -1047,9 +1047,20 @@ static void stm32_usart_stop_rx(struct uart_port *port) stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); } -/* Handle breaks - ignored by us */ static void stm32_usart_break_ctl(struct uart_port *port, int break_state) { + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + if (break_state) + stm32_usart_set_bits(port, ofs->rqr, USART_RQR_SBKRQ); + else + stm32_usart_clr_bits(port, ofs->rqr, USART_RQR_SBKRQ); + + spin_unlock_irqrestore(&port->lock, flags); } static int stm32_usart_startup(struct uart_port *port) @@ -1158,7 +1169,7 @@ static void stm32_usart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, @@ -1349,7 +1360,7 @@ static void stm32_usart_set_termios(struct uart_port *port, writel_relaxed(cr1, port->membase + ofs->cr1); stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); /* Handle modem control interrupts */ if (UART_ENABLE_MS(port, termios->c_cflag)) @@ -1399,9 +1410,9 @@ static void stm32_usart_pm(struct uart_port *port, unsigned int state, pm_runtime_get_sync(port->dev); break; case UART_PM_STATE_OFF: - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); pm_runtime_put_sync(port->dev); break; } @@ -1884,9 +1895,9 @@ static void stm32_usart_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Save and disable interrupts, enable the transmitter */ old_cr1 = readl_relaxed(port->membase + ofs->cr1); @@ -1900,7 +1911,7 @@ static void stm32_usart_console_write(struct console *co, const char *s, writel_relaxed(old_cr1, port->membase + ofs->cr1); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int stm32_usart_console_setup(struct console *co, char *options) @@ -2035,7 +2046,7 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, * low-power mode. */ if (stm32_port->rx_ch) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Poll data from DMA RX buffer if any */ if (!stm32_usart_rx_dma_pause(stm32_port)) size += stm32_usart_receive_chars(port, true); diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c671d674bce4..5bfc0040f17b 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -217,10 +217,10 @@ static irqreturn_t sunhv_interrupt(int irq, void *dev_id) struct tty_port *tport; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tport = receive_chars(port); transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (tport) tty_flip_buffer_push(tport); @@ -271,7 +271,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) if (ch == __DISABLED_CHAR) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(ch); @@ -280,7 +280,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* port->lock held by caller. */ @@ -295,7 +295,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) unsigned long flags; int limit = 10000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(CON_BREAK); @@ -304,7 +304,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } } @@ -328,7 +328,7 @@ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int iflag, cflag; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); iflag = termios->c_iflag; cflag = termios->c_cflag; @@ -343,7 +343,7 @@ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, cflag, (port->uartclk / (16 * quot))); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *sunhv_type(struct uart_port *port) @@ -437,9 +437,9 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign int locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (n > 0) { unsigned long ra = __pa(con_write_page); @@ -470,7 +470,7 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static inline void sunhv_console_putchar(struct uart_port *port, char c) @@ -492,9 +492,9 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig int i, locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); for (i = 0; i < n; i++) { if (*s == '\n') @@ -503,7 +503,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static struct console sunhv_console = { diff --git a/drivers/tty/serial/sunplus-uart.c b/drivers/tty/serial/sunplus-uart.c index 3aacd5eb414c..4251f4e1ba99 100644 --- a/drivers/tty/serial/sunplus-uart.c +++ b/drivers/tty/serial/sunplus-uart.c @@ -184,7 +184,7 @@ static void sunplus_break_ctl(struct uart_port *port, int ctl) unsigned long flags; unsigned int lcr; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); lcr = readl(port->membase + SUP_UART_LCR); @@ -195,7 +195,7 @@ static void sunplus_break_ctl(struct uart_port *port, int ctl) writel(lcr, port->membase + SUP_UART_LCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void transmit_chars(struct uart_port *port) @@ -277,7 +277,7 @@ static irqreturn_t sunplus_uart_irq(int irq, void *args) struct uart_port *port = args; unsigned int isc; - spin_lock(&port->lock); + uart_port_lock(port); isc = readl(port->membase + SUP_UART_ISC); @@ -287,7 +287,7 @@ static irqreturn_t sunplus_uart_irq(int irq, void *args) if (isc & SUP_UART_ISC_TX) transmit_chars(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -302,14 +302,14 @@ static int sunplus_startup(struct uart_port *port) if (ret) return ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* isc define Bit[7:4] int setting, Bit[3:0] int status * isc register will clean Bit[3:0] int status after read * only do a write to Bit[7:4] int setting */ isc |= SUP_UART_ISC_RXM; writel(isc, port->membase + SUP_UART_ISC); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -318,13 +318,13 @@ static void sunplus_shutdown(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* isc define Bit[7:4] int setting, Bit[3:0] int status * isc register will clean Bit[3:0] int status after read * only do a write to Bit[7:4] int setting */ writel(0, port->membase + SUP_UART_ISC); /* disable all interrupt */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -372,7 +372,7 @@ static void sunplus_set_termios(struct uart_port *port, lcr |= UART_LCR_EPAR; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); uart_update_timeout(port, termios->c_cflag, baud); @@ -407,7 +407,7 @@ static void sunplus_set_termios(struct uart_port *port, writel(div_l, port->membase + SUP_UART_DIV_L); writel(lcr, port->membase + SUP_UART_LCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sunplus_set_ldisc(struct uart_port *port, struct ktermios *termios) @@ -517,15 +517,15 @@ static void sunplus_console_write(struct console *co, if (sunplus_console_ports[co->index]->port.sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock(&sunplus_console_ports[co->index]->port.lock); + locked = uart_port_trylock(&sunplus_console_ports[co->index]->port); else - spin_lock(&sunplus_console_ports[co->index]->port.lock); + uart_port_lock(&sunplus_console_ports[co->index]->port); uart_console_write(&sunplus_console_ports[co->index]->port, s, count, sunplus_uart_console_putchar); if (locked) - spin_unlock(&sunplus_console_ports[co->index]->port.lock); + uart_port_unlock(&sunplus_console_ports[co->index]->port); local_irq_restore(flags); } diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 40eeaf835bba..6aa51a6f8063 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -310,7 +310,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) unsigned long flags; unsigned char gis; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); status.stat = 0; gis = readb(&up->regs->r.gis) >> up->gis_shift; @@ -331,7 +331,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) transmit_chars(up, &status); } - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); if (port) tty_flip_buffer_push(port); @@ -473,12 +473,12 @@ static void sunsab_send_xchar(struct uart_port *port, char ch) if (ch == __DISABLED_CHAR) return; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); sunsab_tec_wait(up); writeb(ch, &up->regs->w.tic); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* port->lock held by caller. */ @@ -499,7 +499,7 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) unsigned long flags; unsigned char val; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); val = up->cached_dafo; if (break_state) @@ -512,7 +512,7 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) if (test_bit(SAB82532_XPR, &up->irqflags)) sunsab_tx_idle(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* port->lock is not held. */ @@ -527,7 +527,7 @@ static int sunsab_startup(struct uart_port *port) if (err) return err; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Wait for any commands or immediate characters @@ -582,7 +582,7 @@ static int sunsab_startup(struct uart_port *port) set_bit(SAB82532_ALLS, &up->irqflags); set_bit(SAB82532_XPR, &up->irqflags); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -594,7 +594,7 @@ static void sunsab_shutdown(struct uart_port *port) container_of(port, struct uart_sunsab_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* Disable Interrupts */ up->interrupt_mask0 = 0xff; @@ -628,7 +628,7 @@ static void sunsab_shutdown(struct uart_port *port) writeb(tmp, &up->regs->rw.ccr0); #endif - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); free_irq(up->port.irq, up); } @@ -779,9 +779,9 @@ static void sunsab_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); unsigned int quot = uart_get_divisor(port, baud); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud, quot); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *sunsab_type(struct uart_port *port) @@ -857,15 +857,15 @@ static void sunsab_console_write(struct console *con, const char *s, unsigned n) int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, n, sunsab_console_putchar); sunsab_tec_wait(up); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int sunsab_console_setup(struct console *con, char *options) @@ -914,7 +914,7 @@ static int sunsab_console_setup(struct console *con, char *options) */ sunsab_startup(&up->port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Finally, enable interrupts @@ -932,7 +932,7 @@ static int sunsab_console_setup(struct console *con, char *options) sunsab_convert_to_sab(up, con->cflag, 0, baud, quot); sunsab_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 58a4342ad0f9..1e051cc2591c 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -212,9 +212,9 @@ static void enable_rsa(struct uart_sunsu_port *up) { if (up->port.type == PORT_RSA) { if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); __enable_rsa(up); - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) serial_outp(up, UART_RSA_FRR, 0); @@ -234,7 +234,7 @@ static void disable_rsa(struct uart_sunsu_port *up) if (up->port.type == PORT_RSA && up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { - spin_lock_irq(&up->port.lock); + uart_port_lock_irq(&up->port); mode = serial_inp(up, UART_RSA_MSR); result = !(mode & UART_RSA_MSR_FIFO); @@ -247,7 +247,7 @@ static void disable_rsa(struct uart_sunsu_port *up) if (result) up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; - spin_unlock_irq(&up->port.lock); + uart_port_unlock_irq(&up->port); } } #endif /* CONFIG_SERIAL_8250_RSA */ @@ -311,10 +311,10 @@ static void sunsu_enable_ms(struct uart_port *port) container_of(port, struct uart_sunsu_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -456,7 +456,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) unsigned long flags; unsigned char status; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); do { status = serial_inp(up, UART_LSR); @@ -470,7 +470,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) } while (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return IRQ_HANDLED; } @@ -545,9 +545,9 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return ret; } @@ -599,13 +599,13 @@ static void sunsu_break_ctl(struct uart_port *port, int break_state) container_of(port, struct uart_sunsu_port, port); unsigned long flags; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int sunsu_startup(struct uart_port *port) @@ -683,12 +683,12 @@ static int sunsu_startup(struct uart_port *port) */ serial_outp(up, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->port.mctrl |= TIOCM_OUT2; sunsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Finally, enable interrupts. Note: Modem status interrupts @@ -731,7 +731,7 @@ static void sunsu_shutdown(struct uart_port *port) up->ier = 0; serial_outp(up, UART_IER, 0); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (up->port.flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((up->port.iobase & 0xfe0) | 0x1f); @@ -740,7 +740,7 @@ static void sunsu_shutdown(struct uart_port *port) up->port.mctrl &= ~TIOCM_OUT2; sunsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); /* * Disable break condition and FIFOs @@ -826,7 +826,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * Update the per-port timeout. @@ -891,7 +891,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag, up->cflag = cflag; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static void @@ -1038,7 +1038,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) up->type_probed = PORT_UNKNOWN; up->port.iotype = UPIO_MEM; - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (!(up->port.flags & UPF_BUGGY_UART)) { /* @@ -1173,7 +1173,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) serial_outp(up, UART_IER, 0); out: - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static struct uart_driver sunsu_reg = { @@ -1298,9 +1298,9 @@ static void sunsu_console_write(struct console *co, const char *s, int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); /* * First save the UER then disable the interrupts @@ -1318,7 +1318,7 @@ static void sunsu_console_write(struct console *co, const char *s, serial_out(up, UART_IER, ier); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } /* diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index c8c71c56264c..d3b5e864b727 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -531,7 +531,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) struct tty_port *port; unsigned char r3; - spin_lock(&up->port.lock); + uart_port_lock(&up->port); r3 = read_zsreg(channel, R3); /* Channel A */ @@ -548,7 +548,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) if (r3 & CHATxIP) sunzilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (port) tty_flip_buffer_push(port); @@ -557,7 +557,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) up = up->next; channel = ZILOG_CHANNEL_FROM_PORT(&up->port); - spin_lock(&up->port.lock); + uart_port_lock(&up->port); port = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { writeb(RES_H_IUS, &channel->control); @@ -571,7 +571,7 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) if (r3 & CHBTxIP) sunzilog_transmit_chars(up, channel); } - spin_unlock(&up->port.lock); + uart_port_unlock(&up->port); if (port) tty_flip_buffer_push(port); @@ -604,11 +604,11 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) unsigned char status; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = sunzilog_read_channel_status(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; @@ -764,7 +764,7 @@ static void sunzilog_break_ctl(struct uart_port *port, int break_state) else clear_bits |= SND_BRK; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; if (new_reg != up->curregs[R5]) { @@ -774,7 +774,7 @@ static void sunzilog_break_ctl(struct uart_port *port, int break_state) write_zsreg(channel, R5, up->curregs[R5]); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void __sunzilog_startup(struct uart_sunzilog_port *up) @@ -800,9 +800,9 @@ static int sunzilog_startup(struct uart_port *port) if (ZS_IS_CONS(up)) return 0; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); __sunzilog_startup(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -840,7 +840,7 @@ static void sunzilog_shutdown(struct uart_port *port) if (ZS_IS_CONS(up)) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); channel = ZILOG_CHANNEL_FROM_PORT(port); @@ -853,7 +853,7 @@ static void sunzilog_shutdown(struct uart_port *port) up->curregs[R5] &= ~SND_BRK; sunzilog_maybe_update_regs(up, channel); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* Shared by TTY driver and serial console setup. The port lock is held @@ -945,7 +945,7 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 1200, 76800); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); @@ -962,7 +962,7 @@ sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static const char *sunzilog_type(struct uart_port *port) @@ -1201,15 +1201,15 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count) int locked = 1; if (up->port.sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&up->port.lock, flags); + locked = uart_port_trylock_irqsave(&up->port, &flags); else - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); uart_console_write(&up->port, s, count, sunzilog_putchar); udelay(2); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); } static int __init sunzilog_console_setup(struct console *con, char *options) @@ -1244,7 +1244,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); up->curregs[R15] |= BRKIE; sunzilog_convert_to_zs(up, con->cflag, 0, brg); @@ -1252,7 +1252,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); __sunzilog_startup(up); - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); return 0; } @@ -1333,7 +1333,7 @@ static void sunzilog_init_hw(struct uart_sunzilog_port *up) channel = ZILOG_CHANNEL_FROM_PORT(&up->port); - spin_lock_irqsave(&up->port.lock, flags); + uart_port_lock_irqsave(&up->port, &flags); if (ZS_IS_CHANNEL_A(up)) { write_zsreg(channel, R9, FHWRES); ZSDELAY_LONG(); @@ -1383,7 +1383,7 @@ static void sunzilog_init_hw(struct uart_sunzilog_port *up) write_zsreg(channel, R9, up->curregs[R9]); } - spin_unlock_irqrestore(&up->port.lock, flags); + uart_port_unlock_irqrestore(&up->port, flags); #ifdef CONFIG_SERIO if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 0859394a78cd..0cc6524f5e8b 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -174,7 +174,7 @@ static void timbuart_tasklet(struct tasklet_struct *t) struct timbuart_port *uart = from_tasklet(uart, t, tasklet); u32 isr, ier = 0; - spin_lock(&uart->port.lock); + uart_port_lock(&uart->port); isr = ioread32(uart->port.membase + TIMBUART_ISR); dev_dbg(uart->port.dev, "%s ISR: %x\n", __func__, isr); @@ -189,7 +189,7 @@ static void timbuart_tasklet(struct tasklet_struct *t) iowrite32(ier, uart->port.membase + TIMBUART_IER); - spin_unlock(&uart->port.lock); + uart_port_unlock(&uart->port); dev_dbg(uart->port.dev, "%s leaving\n", __func__); } @@ -295,10 +295,10 @@ static void timbuart_set_termios(struct uart_port *port, tty_termios_copy_hw(termios, old); tty_termios_encode_baud_rate(termios, baud, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); iowrite8((u8)bindex, port->membase + TIMBUART_BAUDRATE); uart_update_timeout(port, termios->c_cflag, baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *timbuart_type(struct uart_port *port) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index b225a78f6175..404c14acafa5 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -216,11 +216,11 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) unsigned long flags; do { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); stat = uart_in32(ULITE_STATUS, port); busy = ulite_receive(port, stat); busy |= ulite_transmit(port, stat); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); n++; } while (busy); @@ -238,9 +238,9 @@ static unsigned int ulite_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); ret = uart_in32(ULITE_STATUS, port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; } @@ -323,7 +323,7 @@ static void ulite_set_termios(struct uart_port *port, termios->c_cflag |= pdata->cflags & (PARENB | PARODD | CSIZE); tty_termios_encode_baud_rate(termios, pdata->baud, pdata->baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); port->read_status_mask = ULITE_STATUS_RXVALID | ULITE_STATUS_OVERRUN | ULITE_STATUS_TXFULL; @@ -346,7 +346,7 @@ static void ulite_set_termios(struct uart_port *port, /* update timeout */ uart_update_timeout(port, termios->c_cflag, pdata->baud); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *ulite_type(struct uart_port *port) @@ -495,9 +495,9 @@ static void ulite_console_write(struct console *co, const char *s, int locked = 1; if (oops_in_progress) { - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); } else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* save and disable interrupt */ ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE; @@ -512,7 +512,7 @@ static void ulite_console_write(struct console *co, const char *s, uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int ulite_console_setup(struct console *co, char *options) diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index b06661b80f41..ed7a6bb5596a 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -931,7 +931,7 @@ static void qe_uart_set_termios(struct uart_port *port, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); /* Do we really need a spinlock here? */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); @@ -949,7 +949,7 @@ static void qe_uart_set_termios(struct uart_port *port, qe_setbrg(qe_port->us_info.tx_clock, baud, 16); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index c5d5c2765119..78a1c1eea11b 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -227,7 +227,7 @@ static irqreturn_t vt8500_irq(int irq, void *dev_id) struct uart_port *port = dev_id; unsigned long isr; - spin_lock(&port->lock); + uart_port_lock(port); isr = vt8500_read(port, VT8500_URISR); /* Acknowledge active status bits */ @@ -240,7 +240,7 @@ static irqreturn_t vt8500_irq(int irq, void *dev_id) if (isr & TCTS) handle_delta_cts(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -342,7 +342,7 @@ static void vt8500_set_termios(struct uart_port *port, unsigned int baud, lcr; unsigned int loops = 1000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* calculate and set baud rate */ baud = uart_get_baud_rate(port, termios, old, 900, 921600); @@ -410,7 +410,7 @@ static void vt8500_set_termios(struct uart_port *port, vt8500_write(&vt8500_port->uart, 0x881, VT8500_URFCR); vt8500_write(&vt8500_port->uart, vt8500_port->ier, VT8500_URIER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *vt8500_type(struct uart_port *port) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 2e5e86a00a77..66a45a634158 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -346,7 +346,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) struct uart_port *port = (struct uart_port *)dev_id; unsigned int isrstatus; - spin_lock(&port->lock); + uart_port_lock(port); /* Read the interrupt status register to determine which * interrupt(s) is/are active and clear them. @@ -369,7 +369,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS)) cdns_uart_handle_rx(dev_id, isrstatus); - spin_unlock(&port->lock); + uart_port_unlock(port); return IRQ_HANDLED; } @@ -506,14 +506,14 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, return NOTIFY_BAD; } - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); /* Disable the TX and RX to set baud rate */ ctrl_reg = readl(port->membase + CDNS_UART_CR); ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS; writel(ctrl_reg, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&cdns_uart->port->lock, flags); + uart_port_unlock_irqrestore(cdns_uart->port, flags); return NOTIFY_OK; } @@ -523,7 +523,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, * frequency. */ - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); locked = 1; port->uartclk = ndata->new_rate; @@ -533,7 +533,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, fallthrough; case ABORT_RATE_CHANGE: if (!locked) - spin_lock_irqsave(&cdns_uart->port->lock, flags); + uart_port_lock_irqsave(cdns_uart->port, &flags); /* Set TX/RX Reset */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -555,7 +555,7 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN; writel(ctrl_reg, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&cdns_uart->port->lock, flags); + uart_port_unlock_irqrestore(cdns_uart->port, flags); return NOTIFY_OK; default: @@ -652,19 +652,19 @@ static void cdns_uart_break_ctl(struct uart_port *port, int ctl) unsigned int status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); status = readl(port->membase + CDNS_UART_CR); if (ctl == -1) - writel(CDNS_UART_CR_STARTBRK | status, + writel(CDNS_UART_CR_STARTBRK | (~CDNS_UART_CR_STOPBRK & status), port->membase + CDNS_UART_CR); else { if ((status & CDNS_UART_CR_STOPBRK) == 0) writel(CDNS_UART_CR_STOPBRK | status, port->membase + CDNS_UART_CR); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -683,7 +683,7 @@ static void cdns_uart_set_termios(struct uart_port *port, unsigned long flags; unsigned int ctrl_reg, mode_reg; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable the TX and RX to set baud rate */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -794,7 +794,7 @@ static void cdns_uart_set_termios(struct uart_port *port, cval &= ~CDNS_UART_MODEMCR_FCM; writel(cval, port->membase + CDNS_UART_MODEMCR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -813,7 +813,7 @@ static int cdns_uart_startup(struct uart_port *port) is_brk_support = cdns_uart->quirks & CDNS_UART_RXBS_SUPPORT; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable the TX and RX */ writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, @@ -861,7 +861,7 @@ static int cdns_uart_startup(struct uart_port *port) writel(readl(port->membase + CDNS_UART_ISR), port->membase + CDNS_UART_ISR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); ret = request_irq(port->irq, cdns_uart_isr, 0, CDNS_UART_NAME, port); if (ret) { @@ -889,7 +889,7 @@ static void cdns_uart_shutdown(struct uart_port *port) int status; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Disable interrupts */ status = readl(port->membase + CDNS_UART_IMR); @@ -900,7 +900,7 @@ static void cdns_uart_shutdown(struct uart_port *port) writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS, port->membase + CDNS_UART_CR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); free_irq(port->irq, port); } @@ -1050,7 +1050,7 @@ static int cdns_uart_poll_get_char(struct uart_port *port) int c; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Check if FIFO is empty */ if (readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY) @@ -1058,7 +1058,7 @@ static int cdns_uart_poll_get_char(struct uart_port *port) else /* Read a character */ c = (unsigned char) readl(port->membase + CDNS_UART_FIFO); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return c; } @@ -1067,7 +1067,7 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Wait until FIFO is empty */ while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) @@ -1080,7 +1080,7 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY)) cpu_relax(); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif @@ -1232,9 +1232,9 @@ static void cdns_uart_console_write(struct console *co, const char *s, if (port->sysrq) locked = 0; else if (oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* save and disable interrupt */ imr = readl(port->membase + CDNS_UART_IMR); @@ -1257,7 +1257,7 @@ static void cdns_uart_console_write(struct console *co, const char *s, writel(imr, port->membase + CDNS_UART_IER); if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /** @@ -1325,7 +1325,7 @@ static int cdns_uart_suspend(struct device *device) if (console_suspend_enabled && uart_console(port) && may_wake) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Empty the receive FIFO 1st before making changes */ while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY)) @@ -1334,7 +1334,7 @@ static int cdns_uart_suspend(struct device *device) writel(1, port->membase + CDNS_UART_RXWM); /* disable RX timeout interrups */ writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IDR); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* @@ -1372,7 +1372,7 @@ static int cdns_uart_resume(struct device *device) return ret; } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Set TX/RX Reset */ ctrl_reg = readl(port->membase + CDNS_UART_CR); @@ -1392,14 +1392,14 @@ static int cdns_uart_resume(struct device *device) clk_disable(cdns_uart->uartclk); clk_disable(cdns_uart->pclk); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } else { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* restore original rx trigger level */ writel(rx_trigger_level, port->membase + CDNS_UART_RXWM); /* enable RX timeout interrupt */ writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IER); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } return uart_resume_port(cdns_uart->cdns_uart_driver, port); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 5353531c2cab..dcf2e1ebf9c5 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -266,13 +266,14 @@ static void sysrq_handle_showallcpus(u8 key) if (in_hardirq()) regs = get_irq_regs(); - pr_info("CPU%d:\n", smp_processor_id()); + pr_info("CPU%d:\n", get_cpu()); if (regs) show_regs(regs); else show_stack(NULL, NULL, KERN_INFO); schedule_work(&sysrq_showallcpus); + put_cpu(); } } diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 50862f98273e..93cf5ef1e857 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -41,15 +41,20 @@ enum { }; /* Values for tty->flow_change */ -#define TTY_THROTTLE_SAFE 1 -#define TTY_UNTHROTTLE_SAFE 2 +enum tty_flow_change { + TTY_FLOW_NO_CHANGE, + TTY_THROTTLE_SAFE, + TTY_UNTHROTTLE_SAFE, +}; -static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +static inline void __tty_set_flow_change(struct tty_struct *tty, + enum tty_flow_change val) { tty->flow_change = val; } -static inline void tty_set_flow_change(struct tty_struct *tty, int val) +static inline void tty_set_flow_change(struct tty_struct *tty, + enum tty_flow_change val) { tty->flow_change = val; smp_mb(); diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 5f6d0cf67571..f8883afbeeba 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -69,12 +69,11 @@ EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive); void tty_buffer_unlock_exclusive(struct tty_port *port) { struct tty_bufhead *buf = &port->buf; - int restart; - - restart = buf->head->commit != buf->head->read; + bool restart = buf->head->commit != buf->head->read; atomic_dec(&buf->priority); mutex_unlock(&buf->lock); + if (restart) queue_work(system_unbound_wq, &buf->work); } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0216a468b438..06414e43e0b5 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -159,7 +159,7 @@ static int tty_fasync(int fd, struct file *filp, int on); static void release_tty(struct tty_struct *tty, int idx); /** - * free_tty_struct - free a disused tty + * free_tty_struct - free a disused tty * @tty: tty struct to free * * Free the write buffers, tty queue and tty memory itself. @@ -233,7 +233,7 @@ static void tty_del_file(struct file *file) } /** - * tty_name - return tty naming + * tty_name - return tty naming * @tty: tty structure * * Convert a tty structure into a name. The name reflects the kernel naming @@ -295,7 +295,7 @@ static void check_tty_count(struct tty_struct *tty, const char *routine) } /** - * get_tty_driver - find device of a tty + * get_tty_driver - find device of a tty * @device: device identifier * @index: returns the index of the tty * @@ -320,7 +320,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) } /** - * tty_dev_name_to_number - return dev_t for device name + * tty_dev_name_to_number - return dev_t for device name * @name: user space name of device under /dev * @number: pointer to dev_t that this function will populate * @@ -372,7 +372,7 @@ EXPORT_SYMBOL_GPL(tty_dev_name_to_number); #ifdef CONFIG_CONSOLE_POLL /** - * tty_find_polling_driver - find device of a polled tty + * tty_find_polling_driver - find device of a polled tty * @name: name string to match * @line: pointer to resulting tty line nr * @@ -505,7 +505,7 @@ static DEFINE_SPINLOCK(redirect_lock); static struct file *redirect; /** - * tty_wakeup - request more data + * tty_wakeup - request more data * @tty: terminal * * Internal and external helper for wakeups of tty. This function informs the @@ -529,7 +529,7 @@ void tty_wakeup(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_wakeup); /** - * tty_release_redirect - Release a redirect on a pty if present + * tty_release_redirect - Release a redirect on a pty if present * @tty: tty device * * This is available to the pty code so if the master closes, if the slave is a @@ -550,7 +550,7 @@ static struct file *tty_release_redirect(struct tty_struct *tty) } /** - * __tty_hangup - actual handler for hangup events + * __tty_hangup - actual handler for hangup events * @tty: tty device * @exit_session: if non-zero, signal all foreground group processes * @@ -673,7 +673,7 @@ static void do_tty_hangup(struct work_struct *work) } /** - * tty_hangup - trigger a hangup event + * tty_hangup - trigger a hangup event * @tty: tty to hangup * * A carrier loss (virtual or otherwise) has occurred on @tty. Schedule a @@ -687,7 +687,7 @@ void tty_hangup(struct tty_struct *tty) EXPORT_SYMBOL(tty_hangup); /** - * tty_vhangup - process vhangup + * tty_vhangup - process vhangup * @tty: tty to hangup * * The user has asked via system call for the terminal to be hung up. We do @@ -703,7 +703,7 @@ EXPORT_SYMBOL(tty_vhangup); /** - * tty_vhangup_self - process vhangup for own ctty + * tty_vhangup_self - process vhangup for own ctty * * Perform a vhangup on the current controlling tty */ @@ -719,7 +719,7 @@ void tty_vhangup_self(void) } /** - * tty_vhangup_session - hangup session leader exit + * tty_vhangup_session - hangup session leader exit * @tty: tty to hangup * * The session leader is exiting and hanging up its controlling terminal. @@ -735,7 +735,7 @@ void tty_vhangup_session(struct tty_struct *tty) } /** - * tty_hung_up_p - was tty hung up + * tty_hung_up_p - was tty hung up * @filp: file pointer of tty * * Return: true if the tty has been subject to a vhangup or a carrier loss @@ -756,7 +756,7 @@ void __stop_tty(struct tty_struct *tty) } /** - * stop_tty - propagate flow control + * stop_tty - propagate flow control * @tty: tty to stop * * Perform flow control to the driver. May be called on an already stopped @@ -790,7 +790,7 @@ void __start_tty(struct tty_struct *tty) } /** - * start_tty - propagate flow control + * start_tty - propagate flow control * @tty: tty to start * * Start a tty that has been stopped if at all possible. If @tty was previously @@ -902,7 +902,7 @@ static ssize_t iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, /** - * tty_read - read method for tty device files + * tty_read - read method for tty device files * @iocb: kernel I/O control block * @to: destination for the data read * @@ -1095,7 +1095,7 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ } /** - * tty_write - write method for tty device file + * tty_write - write method for tty device file * @iocb: kernel I/O control block * @from: iov_iter with data to write * @@ -1137,7 +1137,7 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) } /** - * tty_send_xchar - send priority character + * tty_send_xchar - send priority character * @tty: the tty to send to * @ch: xchar to send * @@ -1171,7 +1171,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch) } /** - * pty_line_name - generate name for a pty + * pty_line_name - generate name for a pty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 6 bytes @@ -1192,7 +1192,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) } /** - * tty_line_name - generate name for a tty + * tty_line_name - generate name for a tty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 7 bytes @@ -1243,7 +1243,7 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, } /** - * tty_init_termios - helper for termios setup + * tty_init_termios - helper for termios setup * @tty: the tty to set up * * Initialise the termios structure for this tty. This runs under the @@ -1326,7 +1326,7 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct * } /** - * tty_reopen() - fast re-open of an open tty + * tty_reopen() - fast re-open of an open tty * @tty: the tty to open * * Re-opens on master ptys are not allowed and return -%EIO. @@ -1370,7 +1370,7 @@ static int tty_reopen(struct tty_struct *tty) } /** - * tty_init_dev - initialise a tty device + * tty_init_dev - initialise a tty device * @driver: tty driver we are opening a device on * @idx: device index * @@ -1492,7 +1492,7 @@ void tty_save_termios(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_save_termios); /** - * tty_flush_works - flush all works of a tty/pty pair + * tty_flush_works - flush all works of a tty/pty pair * @tty: tty device to flush works for (or either end of a pty pair) * * Sync flush all works belonging to @tty (and the 'other' tty). @@ -1508,7 +1508,7 @@ static void tty_flush_works(struct tty_struct *tty) } /** - * release_one_tty - release tty structure memory + * release_one_tty - release tty structure memory * @work: work of tty we are obliterating * * Releases memory associated with a tty structure, and clears out the @@ -1556,7 +1556,7 @@ static void queue_release_one_tty(struct kref *kref) } /** - * tty_kref_put - release a tty kref + * tty_kref_put - release a tty kref * @tty: tty device * * Release a reference to the @tty device and if need be let the kref layer @@ -1570,7 +1570,7 @@ void tty_kref_put(struct tty_struct *tty) EXPORT_SYMBOL(tty_kref_put); /** - * release_tty - release tty structure memory + * release_tty - release tty structure memory * @tty: tty device release * @idx: index of the tty device release * @@ -1647,7 +1647,7 @@ static int tty_release_checks(struct tty_struct *tty, int idx) } /** - * tty_kclose - closes tty opened by tty_kopen + * tty_kclose - closes tty opened by tty_kopen * @tty: tty device * * Performs the final steps to release and free a tty device. It is the same as @@ -1677,7 +1677,7 @@ void tty_kclose(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_kclose); /** - * tty_release_struct - release a tty struct + * tty_release_struct - release a tty struct * @tty: tty device * @idx: index of the tty * @@ -1706,7 +1706,7 @@ void tty_release_struct(struct tty_struct *tty, int idx) EXPORT_SYMBOL_GPL(tty_release_struct); /** - * tty_release - vfs callback for close + * tty_release - vfs callback for close * @inode: inode of tty * @filp: file pointer for handle to tty * @@ -1987,7 +1987,7 @@ out: } /** - * tty_kopen_exclusive - open a tty device for kernel + * tty_kopen_exclusive - open a tty device for kernel * @device: dev_t of device to open * * Opens tty exclusively for kernel. Performs the driver lookup, makes sure @@ -2007,7 +2007,7 @@ struct tty_struct *tty_kopen_exclusive(dev_t device) EXPORT_SYMBOL_GPL(tty_kopen_exclusive); /** - * tty_kopen_shared - open a tty device for shared in-kernel use + * tty_kopen_shared - open a tty device for shared in-kernel use * @device: dev_t of device to open * * Opens an already existing tty for in-kernel use. Compared to @@ -2022,7 +2022,7 @@ struct tty_struct *tty_kopen_shared(dev_t device) EXPORT_SYMBOL_GPL(tty_kopen_shared); /** - * tty_open_by_driver - open a tty device + * tty_open_by_driver - open a tty device * @device: dev_t of device to open * @filp: file pointer to tty * @@ -2090,7 +2090,7 @@ out: } /** - * tty_open - open a tty device + * tty_open - open a tty device * @inode: inode of device file * @filp: file pointer to tty * @@ -2184,7 +2184,7 @@ retry_open: /** - * tty_poll - check tty status + * tty_poll - check tty status * @filp: file being polled * @wait: poll wait structures to update * @@ -2262,7 +2262,7 @@ static int tty_fasync(int fd, struct file *filp, int on) static bool tty_legacy_tiocsti __read_mostly = IS_ENABLED(CONFIG_LEGACY_TIOCSTI); /** - * tiocsti - fake input character + * tiocsti - fake input character * @tty: tty to fake input into * @p: pointer to character * @@ -2299,7 +2299,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) } /** - * tiocgwinsz - implement window query ioctl + * tiocgwinsz - implement window query ioctl * @tty: tty * @arg: user buffer for result * @@ -2320,7 +2320,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) } /** - * tty_do_resize - resize event + * tty_do_resize - resize event * @tty: tty being resized * @ws: new dimensions * @@ -2350,7 +2350,7 @@ done: EXPORT_SYMBOL(tty_do_resize); /** - * tiocswinsz - implement window size set ioctl + * tiocswinsz - implement window size set ioctl * @tty: tty side of tty * @arg: user buffer for result * @@ -2377,7 +2377,7 @@ static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) } /** - * tioccons - allow admin to move logical console + * tioccons - allow admin to move logical console * @file: the file to become console * * Allow the administrator to move the redirected console device. @@ -2416,7 +2416,7 @@ static int tioccons(struct file *file) } /** - * tiocsetd - set line discipline + * tiocsetd - set line discipline * @tty: tty device * @p: pointer to user data * @@ -2438,7 +2438,7 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) } /** - * tiocgetd - get line discipline + * tiocgetd - get line discipline * @tty: tty device * @p: pointer to user data * @@ -2461,7 +2461,7 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) } /** - * send_break - performed time break + * send_break - performed time break * @tty: device to break on * @duration: timeout in mS * @@ -2479,27 +2479,27 @@ static int send_break(struct tty_struct *tty, unsigned int duration) return 0; if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) - retval = tty->ops->break_ctl(tty, duration); - else { - /* Do the work ourselves */ - if (tty_write_lock(tty, false) < 0) - return -EINTR; - retval = tty->ops->break_ctl(tty, -1); - if (retval) - goto out; - if (!signal_pending(current)) - msleep_interruptible(duration); + return tty->ops->break_ctl(tty, duration); + + /* Do the work ourselves */ + if (tty_write_lock(tty, false) < 0) + return -EINTR; + + retval = tty->ops->break_ctl(tty, -1); + if (!retval) { + msleep_interruptible(duration); retval = tty->ops->break_ctl(tty, 0); -out: - tty_write_unlock(tty); - if (signal_pending(current)) - retval = -EINTR; } + tty_write_unlock(tty); + + if (signal_pending(current)) + retval = -EINTR; + return retval; } /** - * tty_tiocmget - get modem status + * tty_tiocmget - get modem status * @tty: tty device * @p: pointer to result * @@ -2522,7 +2522,7 @@ static int tty_tiocmget(struct tty_struct *tty, int __user *p) } /** - * tty_tiocmset - set modem status + * tty_tiocmset - set modem status * @tty: tty device * @cmd: command - clear bits, set bits or set all * @p: pointer to desired bits @@ -2563,7 +2563,7 @@ static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, } /** - * tty_get_icount - get tty statistics + * tty_get_icount - get tty statistics * @tty: tty device * @icount: output parameter * @@ -3126,7 +3126,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) } /** - * tty_put_char - write one character to a tty + * tty_put_char - write one character to a tty * @tty: tty * @ch: character to write * @@ -3304,7 +3304,7 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) EXPORT_SYMBOL(tty_unregister_device); /** - * __tty_alloc_driver -- allocate tty driver + * __tty_alloc_driver - allocate tty driver * @lines: count of lines this driver can handle at most * @owner: module which is responsible for this driver * @flags: some of %TTY_DRIVER_ flags, will be set in driver->flags @@ -3397,7 +3397,7 @@ static void destruct_tty_driver(struct kref *kref) } /** - * tty_driver_kref_put -- drop a reference to a tty driver + * tty_driver_kref_put - drop a reference to a tty driver * @driver: driver of which to drop the reference * * The final put will destroy and free up the driver. @@ -3409,7 +3409,7 @@ void tty_driver_kref_put(struct tty_driver *driver) EXPORT_SYMBOL(tty_driver_kref_put); /** - * tty_register_driver -- register a tty driver + * tty_register_driver - register a tty driver * @driver: driver to register * * Called by a tty driver to register itself. @@ -3474,7 +3474,7 @@ err: EXPORT_SYMBOL(tty_register_driver); /** - * tty_unregister_driver -- unregister a tty driver + * tty_unregister_driver - unregister a tty driver * @driver: driver to unregister * * Called by a tty driver to unregister itself. diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 7958bf6d27c4..4b499301a3db 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -38,16 +38,13 @@ #define TERMIOS_TERMIO BIT(2) #define TERMIOS_OLD BIT(3) - /** - * tty_chars_in_buffer - characters pending - * @tty: terminal + * tty_chars_in_buffer - characters pending + * @tty: terminal * - * Return the number of bytes of data in the device private - * output queue. If no private method is supplied there is assumed - * to be no queue on the device. + * Returns: the number of bytes of data in the device private output queue. If + * no private method is supplied there is assumed to be no queue on the device. */ - unsigned int tty_chars_in_buffer(struct tty_struct *tty) { if (tty->ops->chars_in_buffer) @@ -57,16 +54,15 @@ unsigned int tty_chars_in_buffer(struct tty_struct *tty) EXPORT_SYMBOL(tty_chars_in_buffer); /** - * tty_write_room - write queue space - * @tty: terminal + * tty_write_room - write queue space + * @tty: terminal * - * Return the number of bytes that can be queued to this device - * at the present time. The result should be treated as a guarantee - * and the driver cannot offer a value it later shrinks by more than - * the number of bytes written. If no method is provided 2K is always - * returned and data may be lost as there will be no flow control. + * Returns: the number of bytes that can be queued to this device at the present + * time. The result should be treated as a guarantee and the driver cannot + * offer a value it later shrinks by more than the number of bytes written. If + * no method is provided, 2K is always returned and data may be lost as there + * will be no flow control. */ - unsigned int tty_write_room(struct tty_struct *tty) { if (tty->ops->write_room) @@ -76,12 +72,12 @@ unsigned int tty_write_room(struct tty_struct *tty) EXPORT_SYMBOL(tty_write_room); /** - * tty_driver_flush_buffer - discard internal buffer - * @tty: terminal + * tty_driver_flush_buffer - discard internal buffer + * @tty: terminal * - * Discard the internal output buffer for this device. If no method - * is provided then either the buffer cannot be hardware flushed or - * there is no buffer driver side. + * Discard the internal output buffer for this device. If no method is provided, + * then either the buffer cannot be hardware flushed or there is no buffer + * driver side. */ void tty_driver_flush_buffer(struct tty_struct *tty) { @@ -91,50 +87,47 @@ void tty_driver_flush_buffer(struct tty_struct *tty) EXPORT_SYMBOL(tty_driver_flush_buffer); /** - * tty_unthrottle - flow control - * @tty: terminal + * tty_unthrottle - flow control + * @tty: terminal * - * Indicate that a tty may continue transmitting data down the stack. - * Takes the termios rwsem to protect against parallel throttle/unthrottle - * and also to ensure the driver can consistently reference its own - * termios data at this point when implementing software flow control. + * Indicate that a @tty may continue transmitting data down the stack. Takes + * the &tty_struct->termios_rwsem to protect against parallel + * throttle/unthrottle and also to ensure the driver can consistently reference + * its own termios data at this point when implementing software flow control. * - * Drivers should however remember that the stack can issue a throttle, - * then change flow control method, then unthrottle. + * Drivers should however remember that the stack can issue a throttle, then + * change flow control method, then unthrottle. */ - void tty_unthrottle(struct tty_struct *tty) { down_write(&tty->termios_rwsem); if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && tty->ops->unthrottle) tty->ops->unthrottle(tty); - tty->flow_change = 0; + tty->flow_change = TTY_FLOW_NO_CHANGE; up_write(&tty->termios_rwsem); } EXPORT_SYMBOL(tty_unthrottle); /** - * tty_throttle_safe - flow control - * @tty: terminal + * tty_throttle_safe - flow control + * @tty: terminal * - * Indicate that a tty should stop transmitting data down the stack. - * tty_throttle_safe will only attempt throttle if tty->flow_change is - * TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race - * conditions when throttling is conditional on factors evaluated prior to - * throttling. + * Indicate that a @tty should stop transmitting data down the stack. + * tty_throttle_safe() will only attempt throttle if @tty->flow_change is + * %TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race conditions + * when throttling is conditional on factors evaluated prior to throttling. * - * Returns 0 if tty is throttled (or was already throttled) + * Returns: %true if @tty is throttled (or was already throttled) */ - -int tty_throttle_safe(struct tty_struct *tty) +bool tty_throttle_safe(struct tty_struct *tty) { - int ret = 0; + bool ret = true; mutex_lock(&tty->throttle_mutex); if (!tty_throttled(tty)) { if (tty->flow_change != TTY_THROTTLE_SAFE) - ret = 1; + ret = false; else { set_bit(TTY_THROTTLED, &tty->flags); if (tty->ops->throttle) @@ -147,25 +140,24 @@ int tty_throttle_safe(struct tty_struct *tty) } /** - * tty_unthrottle_safe - flow control - * @tty: terminal + * tty_unthrottle_safe - flow control + * @tty: terminal * - * Similar to tty_unthrottle() but will only attempt unthrottle - * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental - * unthrottle due to race conditions when unthrottling is conditional - * on factors evaluated prior to unthrottling. + * Similar to tty_unthrottle() but will only attempt unthrottle if + * @tty->flow_change is %TTY_UNTHROTTLE_SAFE. Prevents an accidental unthrottle + * due to race conditions when unthrottling is conditional on factors evaluated + * prior to unthrottling. * - * Returns 0 if tty is unthrottled (or was already unthrottled) + * Returns: %true if @tty is unthrottled (or was already unthrottled) */ - -int tty_unthrottle_safe(struct tty_struct *tty) +bool tty_unthrottle_safe(struct tty_struct *tty) { - int ret = 0; + bool ret = true; mutex_lock(&tty->throttle_mutex); if (tty_throttled(tty)) { if (tty->flow_change != TTY_UNTHROTTLE_SAFE) - ret = 1; + ret = false; else { clear_bit(TTY_THROTTLED, &tty->flags); if (tty->ops->unthrottle) @@ -178,14 +170,14 @@ int tty_unthrottle_safe(struct tty_struct *tty) } /** - * tty_wait_until_sent - wait for I/O to finish - * @tty: tty we are waiting for - * @timeout: how long we will wait + * tty_wait_until_sent - wait for I/O to finish + * @tty: tty we are waiting for + * @timeout: how long we will wait * - * Wait for characters pending in a tty driver to hit the wire, or - * for a timeout to occur (eg due to flow control) + * Wait for characters pending in a tty driver to hit the wire, or for a + * timeout to occur (eg due to flow control). * - * Locking: none + * Locking: none */ void tty_wait_until_sent(struct tty_struct *tty, long timeout) @@ -231,16 +223,15 @@ static void unset_locked_termios(struct tty_struct *tty, const struct ktermios * } /** - * tty_termios_copy_hw - copy hardware settings - * @new: New termios - * @old: Old termios + * tty_termios_copy_hw - copy hardware settings + * @new: new termios + * @old: old termios * - * Propagate the hardware specific terminal setting bits from - * the old termios structure to the new one. This is used in cases - * where the hardware does not support reconfiguration or as a helper - * in some cases where only minimal reconfiguration is supported + * Propagate the hardware specific terminal setting bits from the @old termios + * structure to the @new one. This is used in cases where the hardware does not + * support reconfiguration or as a helper in some cases where only minimal + * reconfiguration is supported. */ - void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old) { /* The bits a dumb device handles in software. Smart devices need @@ -253,14 +244,15 @@ void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old) EXPORT_SYMBOL(tty_termios_copy_hw); /** - * tty_termios_hw_change - check for setting change - * @a: termios - * @b: termios to compare + * tty_termios_hw_change - check for setting change + * @a: termios + * @b: termios to compare * - * Check if any of the bits that affect a dumb device have changed - * between the two termios structures, or a speed change is needed. + * Check if any of the bits that affect a dumb device have changed between the + * two termios structures, or a speed change is needed. + * + * Returns: %true if change is needed */ - bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) { if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) @@ -272,11 +264,10 @@ bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) EXPORT_SYMBOL(tty_termios_hw_change); /** - * tty_get_char_size - get size of a character - * @cflag: termios cflag value + * tty_get_char_size - get size of a character + * @cflag: termios cflag value * - * Get the size (in bits) of a character depending on @cflag's %CSIZE - * setting. + * Returns: size (in bits) of a character depending on @cflag's %CSIZE setting */ unsigned char tty_get_char_size(unsigned int cflag) { @@ -295,13 +286,14 @@ unsigned char tty_get_char_size(unsigned int cflag) EXPORT_SYMBOL_GPL(tty_get_char_size); /** - * tty_get_frame_size - get size of a frame - * @cflag: termios cflag value + * tty_get_frame_size - get size of a frame + * @cflag: termios cflag value * - * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, - * and %PARENB setting. The result is a sum of character size, start and - * stop bits -- one bit each -- second stop bit (if set), and parity bit - * (if set). + * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, and + * %PARENB setting. The result is a sum of character size, start and stop bits + * -- one bit each -- second stop bit (if set), and parity bit (if set). + * + * Returns: size (in bits) of a frame depending on @cflag's setting. */ unsigned char tty_get_frame_size(unsigned int cflag) { @@ -319,16 +311,15 @@ unsigned char tty_get_frame_size(unsigned int cflag) EXPORT_SYMBOL_GPL(tty_get_frame_size); /** - * tty_set_termios - update termios values - * @tty: tty to update - * @new_termios: desired new value + * tty_set_termios - update termios values + * @tty: tty to update + * @new_termios: desired new value * - * Perform updates to the termios values set on this terminal. - * A master pty's termios should never be set. + * Perform updates to the termios values set on this @tty. A master pty's + * termios should never be set. * - * Locking: termios_rwsem + * Locking: &tty_struct->termios_rwsem */ - int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) { struct ktermios old_termios; @@ -441,18 +432,19 @@ __weak int kernel_termios_to_user_termios(struct termios __user *u, #endif /* TCGETS2 */ /** - * set_termios - set termios values for a tty - * @tty: terminal device - * @arg: user data - * @opt: option information + * set_termios - set termios values for a tty + * @tty: terminal device + * @arg: user data + * @opt: option information * - * Helper function to prepare termios data and run necessary other - * functions before using tty_set_termios to do the actual changes. + * Helper function to prepare termios data and run necessary other functions + * before using tty_set_termios() to do the actual changes. * - * Locking: - * Called functions take ldisc and termios_rwsem locks + * Locking: called functions take &tty_struct->ldisc_sem and + * &tty_struct->termios_rwsem locks + * + * Returns: 0 on success, an error otherwise */ - static int set_termios(struct tty_struct *tty, void __user *arg, int opt) { struct ktermios tmp_termios; @@ -624,16 +616,16 @@ static void set_sgflags(struct ktermios *termios, int flags) } /** - * set_sgttyb - set legacy terminal values - * @tty: tty structure - * @sgttyb: pointer to old style terminal structure + * set_sgttyb - set legacy terminal values + * @tty: tty structure + * @sgttyb: pointer to old style terminal structure * - * Updates a terminal from the legacy BSD style terminal information - * structure. + * Updates a terminal from the legacy BSD style terminal information structure. * - * Locking: termios_rwsem + * Locking: &tty_struct->termios_rwsem + * + * Returns: 0 on success, an error otherwise */ - static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) { int retval; @@ -735,14 +727,17 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) #endif /** - * tty_change_softcar - carrier change ioctl helper - * @tty: tty to update - * @enable: enable/disable CLOCAL + * tty_change_softcar - carrier change ioctl helper + * @tty: tty to update + * @enable: enable/disable %CLOCAL * - * Perform a change to the CLOCAL state and call into the driver - * layer to make it visible. All done with the termios rwsem + * Perform a change to the %CLOCAL state and call into the driver layer to make + * it visible. + * + * Locking: &tty_struct->termios_rwsem. + * + * Returns: 0 on success, an error otherwise */ - static int tty_change_softcar(struct tty_struct *tty, bool enable) { int ret = 0; @@ -762,16 +757,15 @@ static int tty_change_softcar(struct tty_struct *tty, bool enable) } /** - * tty_mode_ioctl - mode related ioctls - * @tty: tty for the ioctl - * @cmd: command - * @arg: ioctl argument + * tty_mode_ioctl - mode related ioctls + * @tty: tty for the ioctl + * @cmd: command + * @arg: ioctl argument * - * Perform non line discipline specific mode control ioctls. This - * is designed to be called by line disciplines to ensure they provide - * consistent mode setting. + * Perform non-line discipline specific mode control ioctls. This is designed + * to be called by line disciplines to ensure they provide consistent mode + * setting. */ - int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct tty_struct *real_tty; diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index 0d04287da098..ef8741c3e662 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -300,12 +300,7 @@ void disassociate_ctty(int on_exit) return; } - spin_lock_irq(¤t->sighand->siglock); - put_pid(current->signal->tty_old_pgrp); - current->signal->tty_old_pgrp = NULL; - tty = tty_kref_get(current->signal->tty); - spin_unlock_irq(¤t->sighand->siglock); - + tty = get_current_tty(); if (tty) { unsigned long flags; @@ -320,6 +315,16 @@ void disassociate_ctty(int on_exit) tty_kref_put(tty); } + /* If tty->ctrl.pgrp is not NULL, it may be assigned to + * current->signal->tty_old_pgrp in a race condition, and + * cause pid memleak. Release current->signal->tty_old_pgrp + * after tty->ctrl.pgrp set to NULL. + */ + spin_lock_irq(¤t->sighand->siglock); + put_pid(current->signal->tty_old_pgrp); + current->signal->tty_old_pgrp = NULL; + spin_unlock_irq(¤t->sighand->siglock); + /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); session_clear_tty(task_session(current)); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 624d104bd145..63c125250961 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -79,7 +79,7 @@ const struct tty_port_client_operations tty_port_default_client_ops = { EXPORT_SYMBOL_GPL(tty_port_default_client_ops); /** - * tty_port_init -- initialize tty_port + * tty_port_init - initialize tty_port * @port: tty_port to initialize * * Initializes the state of struct tty_port. When a port was initialized using @@ -267,7 +267,7 @@ void tty_port_free_xmit_buf(struct tty_port *port) EXPORT_SYMBOL(tty_port_free_xmit_buf); /** - * tty_port_destroy -- destroy inited port + * tty_port_destroy - destroy inited port * @port: tty port to be destroyed * * When a port was initialized using tty_port_init(), one has to destroy the @@ -297,7 +297,7 @@ static void tty_port_destructor(struct kref *kref) } /** - * tty_port_put -- drop a reference to tty_port + * tty_port_put - drop a reference to tty_port * @port: port to drop a reference of (can be NULL) * * The final put will destroy and free up the @port using diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index a39ed981bfd3..5b625f20233b 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -579,18 +579,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) return -ENOMEM; name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); + if (!name) { + rv = -ENOMEM; + goto free_port; + } rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, ARRAY_SIZE(vcc_versions), NULL, name); if (rv) - goto free_port; + goto free_name; port->vio.debug = vcc_dbg_vio; vcc_ldc_cfg.debug = vcc_dbg_ldc; rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); if (rv) - goto free_port; + goto free_name; spin_lock_init(&port->lock); @@ -624,6 +628,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto unreg_tty; } port->domain = kstrdup(domain, GFP_KERNEL); + if (!port->domain) { + rv = -ENOMEM; + goto unreg_tty; + } + mdesc_release(hp); @@ -653,8 +662,9 @@ free_table: vcc_table_remove(port->index); free_ldc: vio_ldc_free(&port->vio); -free_port: +free_name: kfree(name); +free_port: kfree(port); return rv; diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index f02d21e2a96e..5e39a4f430ee 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -205,7 +205,7 @@ static enum translation_map inv_translate[MAX_NR_CONSOLES]; FIELD_PREP(UNI_GLYPH_BITS, (glyph))) /** - * struct uni_pagedict -- unicode directory + * struct uni_pagedict - unicode directory * * @uni_pgdir: 32*32*64 table with glyphs * @refcount: reference count of this structure diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 1fe6107b539b..12a192e1196b 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -2079,12 +2079,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) return -ENOMEM; spin_lock_irqsave(&func_buf_lock, flags); - len = strlcpy(kbs, func_table[kb_func] ? : "", len); + len = strscpy(kbs, func_table[kb_func] ? : "", len); spin_unlock_irqrestore(&func_buf_lock, flags); + if (len < 0) { + ret = -ENOSPC; + break; + } ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ? -EFAULT : 0; - break; } case KDSKBSENT: diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 829c4be66f3b..67e2cb7c96ee 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -174,7 +174,7 @@ vcs_poll_data_get(struct file *file) } /** - * vcs_vc -- return VC for @inode + * vcs_vc - return VC for @inode * @inode: inode for which to return a VC * @viewed: returns whether this console is currently foreground (viewed) * @@ -199,7 +199,7 @@ static struct vc_data *vcs_vc(struct inode *inode, bool *viewed) } /** - * vcs_size -- return size for a VC in @vc + * vcs_size - return size for a VC in @vc * @vc: which VC * @attr: does it use attributes? * @unicode: is it unicode? @@ -786,23 +786,22 @@ static const struct file_operations vcs_fops = { .release = vcs_release, }; -static struct class *vc_class; +static const struct class vc_class = { + .name = "vc", +}; void vcs_make_sysfs(int index) { - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, - "vcs%u", index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 65), NULL, - "vcsu%u", index + 1); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, - "vcsa%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, "vcs%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 65), NULL, "vcsu%u", index + 1); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, "vcsa%u", index + 1); } void vcs_remove_sysfs(int index) { - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1)); - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 65)); - device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 1)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 65)); + device_destroy(&vc_class, MKDEV(VCS_MAJOR, index + 129)); } int __init vcs_init(void) @@ -811,11 +810,12 @@ int __init vcs_init(void) if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); - vc_class = class_create("vc"); + if (class_register(&vc_class)) + panic("unable to create vc_class"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu"); - device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 64), NULL, "vcsu"); + device_create(&vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); for (i = 0; i < MIN_NR_CONSOLES; i++) vcs_make_sysfs(i); return 0; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 5c47f77804f0..156efda7c80d 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2588,7 +2588,7 @@ static inline int vc_translate_ascii(const struct vc_data *vc, int c) /** - * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD + * vc_sanitize_unicode - Replace invalid Unicode code points with U+FFFD * @c: the received character, or U+FFFD for invalid sequences. */ static inline int vc_sanitize_unicode(const int c) @@ -2600,7 +2600,7 @@ static inline int vc_sanitize_unicode(const int c) } /** - * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char + * vc_translate_unicode - Combine UTF-8 into Unicode in @vc_utf_char * @vc: virtual console * @c: character to translate * @rescan: we return true if we need more (continuation) data @@ -3155,9 +3155,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) switch (type) { case TIOCL_SETSEL: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return set_selection_user((struct tiocl_selection __user *)(p+1), tty); case TIOCL_PASTESEL: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return paste_selection(tty); case TIOCL_UNBLANKSCREEN: console_lock(); @@ -3165,6 +3169,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) console_unlock(); break; case TIOCL_SELLOADLUT: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; console_lock(); ret = sel_loadlut(p); console_unlock(); @@ -3565,7 +3571,9 @@ int __init vty_init(const struct file_operations *console_fops) return 0; } -static struct class *vtconsole_class; +static const struct class vtconsole_class = { + .name = "vtconsole", +}; static int do_bind_con_driver(const struct consw *csw, int first, int last, int deflt) @@ -4092,7 +4100,7 @@ static int do_register_con_driver(const struct consw *csw, int first, int last) goto err; con_driver->dev = - device_create_with_groups(vtconsole_class, NULL, + device_create_with_groups(&vtconsole_class, NULL, MKDEV(0, con_driver->node), con_driver, con_dev_groups, "vtcon%i", con_driver->node); @@ -4173,7 +4181,7 @@ static void con_driver_unregister_callback(struct work_struct *ignored) console_unlock(); vtconsole_deinit_device(con_driver); - device_destroy(vtconsole_class, MKDEV(0, con_driver->node)); + device_destroy(&vtconsole_class, MKDEV(0, con_driver->node)); console_lock(); @@ -4234,12 +4242,9 @@ static int __init vtconsole_class_init(void) { int i; - vtconsole_class = class_create("vtconsole"); - if (IS_ERR(vtconsole_class)) { - pr_warn("Unable to create vt console class; errno = %ld\n", - PTR_ERR(vtconsole_class)); - vtconsole_class = NULL; - } + i = class_register(&vtconsole_class); + if (i) + pr_warn("Unable to create vt console class; errno = %d\n", i); /* Add system drivers to sysfs */ for (i = 0; i < MAX_NR_CON_DRIVER; i++) { @@ -4247,7 +4252,7 @@ static int __init vtconsole_class_init(void) if (con->con && !con->dev) { con->dev = - device_create_with_groups(vtconsole_class, NULL, + device_create_with_groups(&vtconsole_class, NULL, MKDEV(0, con->node), con, con_dev_groups, "vtcon%i", con->node); diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7f33bcc315f2..abf8c6cdea9e 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -91,6 +91,16 @@ config USB_PCI If you have such a device you may say N here and PCI related code will not be built in the USB driver. +config USB_PCI_AMD + bool "AMD PCI USB host support" + depends on USB_PCI && HAS_IOPORT + default X86 || MACH_LOONGSON64 || PPC_PASEMI + help + Enable workarounds for USB implementation quirks in SB600/SB700/SB800 + and later south bridge implementations. These are common on x86 PCs + with AMD CPUs but rarely used elsewhere, with the exception of a few + powerpc and mips desktop machines. + if USB source "drivers/usb/core/Kconfig" diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h index 6332a6b5dce6..6ba5adced61c 100644 --- a/drivers/usb/c67x00/c67x00-hcd.h +++ b/drivers/usb/c67x00/c67x00-hcd.h @@ -109,7 +109,6 @@ int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep); -void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg); void c67x00_sched_kick(struct c67x00_hcd *c67x00); int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00); void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00); diff --git a/drivers/usb/cdns3/cdnsp-debug.h b/drivers/usb/cdns3/cdnsp-debug.h index f0ca865cce2a..ad617b7455b9 100644 --- a/drivers/usb/cdns3/cdnsp-debug.h +++ b/drivers/usb/cdns3/cdnsp-debug.h @@ -131,8 +131,6 @@ static inline const char *cdnsp_trb_type_string(u8 type) return "Endpoint Not ready"; case TRB_HALT_ENDPOINT: return "Halt Endpoint"; - case TRB_FLUSH_ENDPOINT: - return "FLush Endpoint"; default: return "UNKNOWN"; } @@ -328,7 +326,6 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0, break; case TRB_RESET_EP: case TRB_HALT_ENDPOINT: - case TRB_FLUSH_ENDPOINT: ret = snprintf(str, size, "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", cdnsp_trb_type_string(type), diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c index 4b67749edb99..4a3f0f958256 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.c +++ b/drivers/usb/cdns3/cdnsp-gadget.c @@ -1024,10 +1024,8 @@ static int cdnsp_gadget_ep_disable(struct usb_ep *ep) pep->ep_state |= EP_DIS_IN_RROGRESS; /* Endpoint was unconfigured by Reset Device command. */ - if (!(pep->ep_state & EP_UNCONFIGURED)) { + if (!(pep->ep_state & EP_UNCONFIGURED)) cdnsp_cmd_stop_ep(pdev, pep); - cdnsp_cmd_flush_ep(pdev, pep); - } /* Remove all queued USB requests. */ while (!list_empty(&pep->pending_list)) { @@ -1424,8 +1422,6 @@ static void cdnsp_stop(struct cdnsp_device *pdev) { u32 temp; - cdnsp_cmd_flush_ep(pdev, &pdev->eps[0]); - /* Remove internally queued request for ep0. */ if (!list_empty(&pdev->eps[0].pending_list)) { struct cdnsp_request *req; diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h index e1b5801fdddf..dbee6f085277 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.h +++ b/drivers/usb/cdns3/cdnsp-gadget.h @@ -1128,8 +1128,6 @@ union cdnsp_trb { #define TRB_HALT_ENDPOINT 54 /* Doorbell Overflow Event. */ #define TRB_DRB_OVERFLOW 57 -/* Flush Endpoint Command. */ -#define TRB_FLUSH_ENDPOINT 58 #define TRB_TYPE_LINK(x) (((x) & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK)) #define TRB_TYPE_LINK_LE32(x) (((x) & cpu_to_le32(TRB_TYPE_BITMASK)) == \ @@ -1539,8 +1537,6 @@ void cdnsp_queue_configure_endpoint(struct cdnsp_device *pdev, void cdnsp_queue_reset_ep(struct cdnsp_device *pdev, unsigned int ep_index); void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index); -void cdnsp_queue_flush_endpoint(struct cdnsp_device *pdev, - unsigned int ep_index); void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num); void cdnsp_queue_reset_device(struct cdnsp_device *pdev); void cdnsp_queue_new_dequeue_state(struct cdnsp_device *pdev, @@ -1574,7 +1570,6 @@ void cdnsp_irq_reset(struct cdnsp_device *pdev); int cdnsp_halt_endpoint(struct cdnsp_device *pdev, struct cdnsp_ep *pep, int value); int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep); -int cdnsp_cmd_flush_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep); void cdnsp_setup_analyze(struct cdnsp_device *pdev); int cdnsp_status_stage(struct cdnsp_device *pdev); int cdnsp_reset_device(struct cdnsp_device *pdev); diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c index 07f6068342d4..af981778382d 100644 --- a/drivers/usb/cdns3/cdnsp-ring.c +++ b/drivers/usb/cdns3/cdnsp-ring.c @@ -2123,19 +2123,6 @@ ep_stopped: return ret; } -int cdnsp_cmd_flush_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep) -{ - int ret; - - cdnsp_queue_flush_endpoint(pdev, pep->idx); - cdnsp_ring_cmd_db(pdev); - ret = cdnsp_wait_for_cmd_compl(pdev); - - trace_cdnsp_handle_cmd_flush_ep(pep->out_ctx); - - return ret; -} - /* * The transfer burst count field of the isochronous TRB defines the number of * bursts that are required to move all packets in this TD. Only SuperSpeed @@ -2465,17 +2452,6 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index) EP_ID_FOR_TRB(ep_index)); } -/* - * Queue a flush endpoint request on the command ring. - */ -void cdnsp_queue_flush_endpoint(struct cdnsp_device *pdev, - unsigned int ep_index) -{ - cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_FLUSH_ENDPOINT) | - SLOT_ID_FOR_TRB(pdev->slot_id) | - EP_ID_FOR_TRB(ep_index)); -} - void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num) { u32 lo, mid; diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index c815824a0b2d..bab45bc62361 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -43,6 +43,10 @@ config USB_CHIPIDEA_MSM tristate "Enable MSM hsusb glue driver" if EXPERT default USB_CHIPIDEA +config USB_CHIPIDEA_NPCM + tristate "Enable NPCM hsusb glue driver" if EXPERT + default USB_CHIPIDEA + config USB_CHIPIDEA_IMX tristate "Enable i.MX USB glue driver" if EXPERT depends on OF diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 71afeab97e83..718cb24603dd 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -13,6 +13,7 @@ ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o obj-$(CONFIG_USB_CHIPIDEA_GENERIC) += ci_hdrc_usb2.o obj-$(CONFIG_USB_CHIPIDEA_MSM) += ci_hdrc_msm.o +obj-$(CONFIG_USB_CHIPIDEA_NPCM) += ci_hdrc_npcm.o obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o obj-$(CONFIG_USB_CHIPIDEA_IMX) += usbmisc_imx.o ci_hdrc_imx.o obj-$(CONFIG_USB_CHIPIDEA_TEGRA) += ci_hdrc_tegra.o diff --git a/drivers/usb/chipidea/ci_hdrc_npcm.c b/drivers/usb/chipidea/ci_hdrc_npcm.c new file mode 100644 index 000000000000..e4a191e02ceb --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_npcm.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2023 Nuvoton Technology corporation. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ci.h" + +struct npcm_udc_data { + struct platform_device *ci; + struct clk *core_clk; + struct ci_hdrc_platform_data pdata; +}; + +static int npcm_udc_notify_event(struct ci_hdrc *ci, unsigned event) +{ + struct device *dev = ci->dev->parent; + + switch (event) { + case CI_HDRC_CONTROLLER_RESET_EVENT: + /* clear all mode bits */ + hw_write(ci, OP_USBMODE, 0xffffffff, 0x0); + break; + default: + dev_dbg(dev, "unknown ci_hdrc event (%d)\n",event); + break; + } + + return 0; +} + +static int npcm_udc_probe(struct platform_device *pdev) +{ + int ret; + struct npcm_udc_data *ci; + struct platform_device *plat_ci; + struct device *dev = &pdev->dev; + + ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL); + if (!ci) + return -ENOMEM; + platform_set_drvdata(pdev, ci); + + ci->core_clk = devm_clk_get_optional(dev, NULL); + if (IS_ERR(ci->core_clk)) + return PTR_ERR(ci->core_clk); + + ret = clk_prepare_enable(ci->core_clk); + if (ret) + return dev_err_probe(dev, ret, "failed to enable the clock: %d\n", ret); + + ci->pdata.name = dev_name(dev); + ci->pdata.capoffset = DEF_CAPOFFSET; + ci->pdata.flags = CI_HDRC_REQUIRES_ALIGNED_DMA | + CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS; + ci->pdata.phy_mode = USBPHY_INTERFACE_MODE_UTMI; + ci->pdata.notify_event = npcm_udc_notify_event; + + plat_ci = ci_hdrc_add_device(dev, pdev->resource, pdev->num_resources, + &ci->pdata); + if (IS_ERR(plat_ci)) { + ret = PTR_ERR(plat_ci); + dev_err(dev, "failed to register HDRC NPCM device: %d\n", ret); + goto clk_err; + } + + pm_runtime_no_callbacks(dev); + pm_runtime_enable(dev); + + return 0; + +clk_err: + clk_disable_unprepare(ci->core_clk); + return ret; +} + +static int npcm_udc_remove(struct platform_device *pdev) +{ + struct npcm_udc_data *ci = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + ci_hdrc_remove_device(ci->ci); + clk_disable_unprepare(ci->core_clk); + + return 0; +} + +static const struct of_device_id npcm_udc_dt_match[] = { + { .compatible = "nuvoton,npcm750-udc", }, + { .compatible = "nuvoton,npcm845-udc", }, + { } +}; +MODULE_DEVICE_TABLE(of, npcm_udc_dt_match); + +static struct platform_driver npcm_udc_driver = { + .probe = npcm_udc_probe, + .remove = npcm_udc_remove, + .driver = { + .name = "npcm_udc", + .of_match_table = npcm_udc_dt_match, + }, +}; + +module_platform_driver(npcm_udc_driver); + +MODULE_DESCRIPTION("NPCM USB device controller driver"); +MODULE_AUTHOR("Tomer Maimon "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c index 8e78bf643e25..2cc305803217 100644 --- a/drivers/usb/chipidea/ci_hdrc_tegra.c +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -293,14 +293,12 @@ static int tegra_usb_probe(struct platform_device *pdev) usb->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); if (IS_ERR(usb->phy)) return dev_err_probe(&pdev->dev, PTR_ERR(usb->phy), - "failed to get PHY\n"); + "failed to get PHY"); usb->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(usb->clk)) { - err = PTR_ERR(usb->clk); - dev_err(&pdev->dev, "failed to get clock: %d\n", err); - return err; - } + if (IS_ERR(usb->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(usb->clk), + "failed to get clock"); err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); if (err) @@ -316,7 +314,7 @@ static int tegra_usb_probe(struct platform_device *pdev) err = tegra_usb_reset_controller(&pdev->dev); if (err) { - dev_err(&pdev->dev, "failed to reset controller: %d\n", err); + dev_err_probe(&pdev->dev, err, "failed to reset controller"); goto fail_power_off; } @@ -347,8 +345,8 @@ static int tegra_usb_probe(struct platform_device *pdev) usb->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource, pdev->num_resources, &usb->data); if (IS_ERR(usb->dev)) { - err = PTR_ERR(usb->dev); - dev_err(&pdev->dev, "failed to add HDRC device: %d\n", err); + err = dev_err_probe(&pdev->dev, PTR_ERR(usb->dev), + "failed to add HDRC device"); goto phy_shutdown; } diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index 1321ee67f3b8..97379f653b06 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -9,9 +9,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -51,8 +51,8 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ci_hdrc_usb2_priv *priv; struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); + const struct ci_hdrc_platform_data *data; int ret; - const struct of_device_id *match; if (!ci_pdata) { ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL); @@ -61,11 +61,10 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev) *ci_pdata = ci_default_pdata; /* struct copy */ } - match = of_match_device(ci_hdrc_usb2_of_match, &pdev->dev); - if (match && match->data) { + data = device_get_match_data(&pdev->dev); + if (data) /* struct copy */ - *ci_pdata = *(struct ci_hdrc_platform_data *)match->data; - } + *ci_pdata = *data; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -120,7 +119,7 @@ static struct platform_driver ci_hdrc_usb2_driver = { .remove_new = ci_hdrc_usb2_remove, .driver = { .name = "chipidea-usb2", - .of_match_table = of_match_ptr(ci_hdrc_usb2_of_match), + .of_match_table = ci_hdrc_usb2_of_match, }, }; module_platform_driver(ci_hdrc_usb2_driver); diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 08af26b762a2..0cce19208370 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -30,8 +30,7 @@ struct ehci_ci_priv { }; struct ci_hdrc_dma_aligned_buffer { - void *kmalloc_ptr; - void *old_xfer_buffer; + void *original_buffer; u8 data[]; }; @@ -380,59 +379,52 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd) return 0; } -static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb) +static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back) { struct ci_hdrc_dma_aligned_buffer *temp; - size_t length; if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) return; + urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; temp = container_of(urb->transfer_buffer, struct ci_hdrc_dma_aligned_buffer, data); + urb->transfer_buffer = temp->original_buffer; + + if (copy_back && usb_urb_dir_in(urb)) { + size_t length; - if (usb_urb_dir_in(urb)) { if (usb_pipeisoc(urb->pipe)) length = urb->transfer_buffer_length; else length = urb->actual_length; - memcpy(temp->old_xfer_buffer, temp->data, length); + memcpy(temp->original_buffer, temp->data, length); } - urb->transfer_buffer = temp->old_xfer_buffer; - kfree(temp->kmalloc_ptr); - urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; + kfree(temp); } static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) { - struct ci_hdrc_dma_aligned_buffer *temp, *kmalloc_ptr; - const unsigned int ci_hdrc_usb_dma_align = 32; - size_t kmalloc_size; + struct ci_hdrc_dma_aligned_buffer *temp; - if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0 || - !((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1))) + if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0) + return 0; + if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4) + && IS_ALIGNED(urb->transfer_buffer_length, 4)) return 0; - /* Allocate a buffer with enough padding for alignment */ - kmalloc_size = urb->transfer_buffer_length + - sizeof(struct ci_hdrc_dma_aligned_buffer) + - ci_hdrc_usb_dma_align - 1; - - kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); - if (!kmalloc_ptr) + temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags); + if (!temp) return -ENOMEM; - /* Position our struct dma_aligned_buffer such that data is aligned */ - temp = PTR_ALIGN(kmalloc_ptr + 1, ci_hdrc_usb_dma_align) - 1; - temp->kmalloc_ptr = kmalloc_ptr; - temp->old_xfer_buffer = urb->transfer_buffer; if (usb_urb_dir_out(urb)) memcpy(temp->data, urb->transfer_buffer, urb->transfer_buffer_length); - urb->transfer_buffer = temp->data; + temp->original_buffer = urb->transfer_buffer; + urb->transfer_buffer = temp->data; urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; return 0; @@ -449,7 +441,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); if (ret) - ci_hdrc_free_dma_aligned_buffer(urb); + ci_hdrc_free_dma_aligned_buffer(urb, false); return ret; } @@ -457,7 +449,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { usb_hcd_unmap_urb_for_dma(hcd, urb); - ci_hdrc_free_dma_aligned_buffer(urb); + ci_hdrc_free_dma_aligned_buffer(urb, true); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index f5490f2a5b6b..647e98f4e351 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -130,8 +130,11 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci) void ci_handle_vbus_change(struct ci_hdrc *ci) { - if (!ci->is_otg) + if (!ci->is_otg) { + if (ci->platdata->flags & CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS) + usb_gadget_vbus_connect(&ci->gadget); return; + } if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active) usb_gadget_vbus_connect(&ci->gadget); diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 990280688b25..ee3156f49533 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -206,8 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct hc_driver *driver) goto free_irq_vectors; } - hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) && - driver->flags & (HCD_USB11 | HCD_USB3)) ? 1 : 0; + hcd->amd_resume_bug = usb_hcd_amd_resume_bug(dev, driver); if (driver->flags & HCD_MEMORY) { /* EHCI, OHCI */ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0ff47eeffb49..b4584a0cd484 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2274,6 +2274,8 @@ void usb_disconnect(struct usb_device **pdev) */ if (!test_and_set_bit(port1, hub->child_usage_bits)) pm_runtime_get_sync(&port_dev->dev); + + typec_deattach(port_dev->connector, &udev->dev); } usb_remove_ep_devs(&udev->ep0); @@ -2620,6 +2622,8 @@ int usb_new_device(struct usb_device *udev) if (!test_and_set_bit(port1, hub->child_usage_bits)) pm_runtime_get_sync(&port_dev->dev); + + typec_attach(port_dev->connector, &udev->dev); } (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index d44dd7f6623e..43ce21c96a51 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "usb.h" struct usb_hub { @@ -82,6 +83,7 @@ struct usb_hub { * @dev: generic device interface * @port_owner: port's owner * @peer: related usb2 and usb3 ports (share the same connector) + * @connector: USB Type-C connector * @req: default pm qos request for hubs without port power control * @connect_type: port's connect type * @state: device state of the usb device attached to the port @@ -100,6 +102,7 @@ struct usb_port { struct device dev; struct usb_dev_state *port_owner; struct usb_port *peer; + struct typec_connector *connector; struct dev_pm_qos_request *req; enum usb_port_connect_type connect_type; enum usb_device_state state; diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 77be0dc28da9..c628c1abc907 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -653,6 +653,7 @@ static void find_and_link_peer(struct usb_hub *hub, int port1) static int connector_bind(struct device *dev, struct device *connector, void *data) { + struct usb_port *port_dev = to_usb_port(dev); int ret; ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector"); @@ -660,16 +661,30 @@ static int connector_bind(struct device *dev, struct device *connector, void *da return ret; ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev)); - if (ret) + if (ret) { sysfs_remove_link(&dev->kobj, "connector"); + return ret; + } - return ret; + port_dev->connector = data; + + /* + * If there is already USB device connected to the port, letting the + * Type-C connector know about it immediately. + */ + if (port_dev->child) + typec_attach(port_dev->connector, &port_dev->child->dev); + + return 0; } static void connector_unbind(struct device *dev, struct device *connector, void *data) { + struct usb_port *port_dev = to_usb_port(dev); + sysfs_remove_link(&connector->kobj, dev_name(dev)); sysfs_remove_link(&dev->kobj, "connector"); + port_dev->connector = NULL; } static const struct component_ops connector_ops = { @@ -698,6 +713,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) set_bit(port1, hub->power_bits); port_dev->dev.parent = hub->intfdev; if (hub_is_superspeed(hdev)) { + port_dev->is_superspeed = 1; port_dev->usb3_lpm_u1_permit = 1; port_dev->usb3_lpm_u2_permit = 1; port_dev->dev.groups = port_dev_usb3_group; @@ -705,8 +721,6 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) port_dev->dev.groups = port_dev_group; port_dev->dev.type = &usb_port_device_type; port_dev->dev.driver = &usb_port_driver; - if (hub_is_superspeed(hub->hdev)) - port_dev->is_superspeed = 1; dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev), port1); mutex_init(&port_dev->status_lock); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 657f1f659ffa..35c7a4df8e71 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4769,8 +4769,8 @@ fail3: if (qh_allocated && qh->channel && qh->channel->qh == qh) qh->channel->qh = NULL; fail2: - spin_unlock_irqrestore(&hsotg->lock, flags); urb->hcpriv = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); kfree(qtd); fail1: if (qh_allocated) { diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index 93f52e371cdd..fb03162ae9b7 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -968,26 +968,17 @@ typedef void (*set_params_cb)(struct dwc2_hsotg *data); int dwc2_init_params(struct dwc2_hsotg *hsotg) { - const struct of_device_id *match; set_params_cb set_params; dwc2_set_default_params(hsotg); dwc2_get_device_properties(hsotg); - match = of_match_device(dwc2_of_match_table, hsotg->dev); - if (match && match->data) { - set_params = match->data; + set_params = device_get_match_data(hsotg->dev); + if (set_params) { set_params(hsotg); - } else if (!match) { - const struct acpi_device_id *amatch; - const struct pci_device_id *pmatch = NULL; - - amatch = acpi_match_device(dwc2_acpi_match, hsotg->dev); - if (amatch && amatch->driver_data) { - set_params = (set_params_cb)amatch->driver_data; - set_params(hsotg); - } else if (!amatch) - pmatch = pci_match_id(dwc2_pci_ids, to_pci_dev(hsotg->dev->parent)); + } else { + const struct pci_device_id *pmatch = + pci_match_id(dwc2_pci_ids, to_pci_dev(hsotg->dev->parent)); if (pmatch && pmatch->driver_data) { set_params = (set_params_cb)pmatch->driver_data; diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 98efcbb76c88..5fc27b20df63 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -178,4 +178,15 @@ config USB_DWC3_OCTEON Only the host mode is currently supported. Say 'Y' or 'M' here if you have one such device. +config USB_DWC3_RTK + tristate "Realtek DWC3 Platform Driver" + depends on OF && ARCH_REALTEK + default USB_DWC3 + select USB_ROLE_SWITCH + help + RTK DHC RTD SoCs with DesignWare Core USB3 IP inside, + and IP Core configured for USB 2.0 and USB 3.0 in host + or dual-role mode. + Say 'Y' or 'M' if you have such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index fe1493d4bbe5..124eda2522d9 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -55,3 +55,4 @@ obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o +obj-$(CONFIG_USB_DWC3_RTK) += dwc3-rtk.o diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 343d2570189f..0328c86ef806 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -854,8 +854,20 @@ static int dwc3_clk_enable(struct dwc3 *dwc) if (ret) goto disable_ref_clk; + ret = clk_prepare_enable(dwc->utmi_clk); + if (ret) + goto disable_susp_clk; + + ret = clk_prepare_enable(dwc->pipe_clk); + if (ret) + goto disable_utmi_clk; + return 0; +disable_utmi_clk: + clk_disable_unprepare(dwc->utmi_clk); +disable_susp_clk: + clk_disable_unprepare(dwc->susp_clk); disable_ref_clk: clk_disable_unprepare(dwc->ref_clk); disable_bus_clk: @@ -865,6 +877,8 @@ disable_bus_clk: static void dwc3_clk_disable(struct dwc3 *dwc) { + clk_disable_unprepare(dwc->pipe_clk); + clk_disable_unprepare(dwc->utmi_clk); clk_disable_unprepare(dwc->susp_clk); clk_disable_unprepare(dwc->ref_clk); clk_disable_unprepare(dwc->bus_clk); @@ -1094,6 +1108,111 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) } } +static void dwc3_config_threshold(struct dwc3 *dwc) +{ + u32 reg; + u8 rx_thr_num; + u8 rx_maxburst; + u8 tx_thr_num; + u8 tx_maxburst; + + /* + * Must config both number of packets and max burst settings to enable + * RX and/or TX threshold. + */ + if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { + rx_thr_num = dwc->rx_thr_num_pkt_prd; + rx_maxburst = dwc->rx_max_burst_prd; + tx_thr_num = dwc->tx_thr_num_pkt_prd; + tx_maxburst = dwc->tx_max_burst_prd; + + if (rx_thr_num && rx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg |= DWC31_RXTHRNUMPKTSEL_PRD; + + reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); + reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); + + reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); + reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + } + + if (tx_thr_num && tx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg |= DWC31_TXTHRNUMPKTSEL_PRD; + + reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); + reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); + + reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); + reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + } + } + + rx_thr_num = dwc->rx_thr_num_pkt; + rx_maxburst = dwc->rx_max_burst; + tx_thr_num = dwc->tx_thr_num_pkt; + tx_maxburst = dwc->tx_max_burst; + + if (DWC3_IP_IS(DWC3)) { + if (rx_thr_num && rx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg |= DWC3_GRXTHRCFG_PKTCNTSEL; + + reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0); + reg |= DWC3_GRXTHRCFG_RXPKTCNT(rx_thr_num); + + reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0); + reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + } + + if (tx_thr_num && tx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg |= DWC3_GTXTHRCFG_PKTCNTSEL; + + reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0); + reg |= DWC3_GTXTHRCFG_TXPKTCNT(tx_thr_num); + + reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0); + reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + } + } else { + if (rx_thr_num && rx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg |= DWC31_GRXTHRCFG_PKTCNTSEL; + + reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0); + reg |= DWC31_GRXTHRCFG_RXPKTCNT(rx_thr_num); + + reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0); + reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + } + + if (tx_thr_num && tx_maxburst) { + reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg |= DWC31_GTXTHRCFG_PKTCNTSEL; + + reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0); + reg |= DWC31_GTXTHRCFG_TXPKTCNT(tx_thr_num); + + reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0); + reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); + + dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + } + } +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -1246,42 +1365,7 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); } - /* - * Must config both number of packets and max burst settings to enable - * RX and/or TX threshold. - */ - if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { - u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; - u8 rx_maxburst = dwc->rx_max_burst_prd; - u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; - u8 tx_maxburst = dwc->tx_max_burst_prd; - - if (rx_thr_num && rx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); - reg |= DWC31_RXTHRNUMPKTSEL_PRD; - - reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); - reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); - - reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); - reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); - - dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); - } - - if (tx_thr_num && tx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); - reg |= DWC31_TXTHRNUMPKTSEL_PRD; - - reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); - reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); - - reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); - reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); - - dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); - } - } + dwc3_config_threshold(dwc); return 0; @@ -1417,6 +1501,10 @@ static void dwc3_get_properties(struct dwc3 *dwc) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u8 rx_thr_num_pkt = 0; + u8 rx_max_burst = 0; + u8 tx_thr_num_pkt = 0; + u8 tx_max_burst = 0; u8 rx_thr_num_pkt_prd = 0; u8 rx_max_burst_prd = 0; u8 tx_thr_num_pkt_prd = 0; @@ -1479,6 +1567,14 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,usb2-lpm-disable"); dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, "snps,usb2-gadget-lpm-disable"); + device_property_read_u8(dev, "snps,rx-thr-num-pkt", + &rx_thr_num_pkt); + device_property_read_u8(dev, "snps,rx-max-burst", + &rx_max_burst); + device_property_read_u8(dev, "snps,tx-thr-num-pkt", + &tx_thr_num_pkt); + device_property_read_u8(dev, "snps,tx-max-burst", + &tx_max_burst); device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", &rx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,rx-max-burst-prd", @@ -1560,6 +1656,12 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->hird_threshold = hird_threshold; + dwc->rx_thr_num_pkt = rx_thr_num_pkt; + dwc->rx_max_burst = rx_max_burst; + + dwc->tx_thr_num_pkt = tx_thr_num_pkt; + dwc->tx_max_burst = tx_max_burst; + dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; dwc->rx_max_burst_prd = rx_max_burst_prd; @@ -1785,6 +1887,20 @@ static int dwc3_get_clocks(struct dwc3 *dwc) } } + /* specific to Rockchip RK3588 */ + dwc->utmi_clk = devm_clk_get_optional(dev, "utmi"); + if (IS_ERR(dwc->utmi_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->utmi_clk), + "could not get utmi clock\n"); + } + + /* specific to Rockchip RK3588 */ + dwc->pipe_clk = devm_clk_get_optional(dev, "pipe"); + if (IS_ERR(dwc->pipe_clk)) { + return dev_err_probe(dev, PTR_ERR(dwc->pipe_clk), + "could not get pipe clock\n"); + } + return 0; } diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index a69ac67d89fe..efe6caf4d0e8 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -211,6 +211,11 @@ #define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24) #define DWC3_GRXTHRCFG_PKTCNTSEL BIT(29) +/* Global TX Threshold Configuration Register */ +#define DWC3_GTXTHRCFG_MAXTXBURSTSIZE(n) (((n) & 0xff) << 16) +#define DWC3_GTXTHRCFG_TXPKTCNT(n) (((n) & 0xf) << 24) +#define DWC3_GTXTHRCFG_PKTCNTSEL BIT(29) + /* Global RX Threshold Configuration Register for DWC_usb31 only */ #define DWC31_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 16) #define DWC31_GRXTHRCFG_RXPKTCNT(n) (((n) & 0x1f) << 21) @@ -991,6 +996,8 @@ struct dwc3_scratchpad_array { * @bus_clk: clock for accessing the registers * @ref_clk: reference clock * @susp_clk: clock used when the SS phy is in low power (S3) state + * @utmi_clk: clock used for USB2 PHY communication + * @pipe_clk: clock used for USB3 PHY communication * @reset: reset control * @regs: base address for our registers * @regs_size: address space size @@ -1045,6 +1052,10 @@ struct dwc3_scratchpad_array { * @test_mode_nr: test feature selector * @lpm_nyet_threshold: LPM NYET response threshold * @hird_threshold: HIRD threshold + * @rx_thr_num_pkt: USB receive packet count + * @rx_max_burst: max USB receive burst size + * @tx_thr_num_pkt: USB transmit packet count + * @tx_max_burst: max USB transmit burst size * @rx_thr_num_pkt_prd: periodic ESS receive packet count * @rx_max_burst_prd: max periodic ESS receive burst size * @tx_thr_num_pkt_prd: periodic ESS transmit packet count @@ -1106,6 +1117,8 @@ struct dwc3_scratchpad_array { * instances in park mode. * @parkmode_disable_hs_quirk: set if we need to disable all HishSpeed * instances in park mode. + * @gfladj_refclk_lpm_sel: set if we need to enable SOF/ITP counter + * running based on ref_clk * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -1156,6 +1169,8 @@ struct dwc3 { struct clk *bus_clk; struct clk *ref_clk; struct clk *susp_clk; + struct clk *utmi_clk; + struct clk *pipe_clk; struct reset_control *reset; @@ -1273,6 +1288,10 @@ struct dwc3 { u8 test_mode_nr; u8 lpm_nyet_threshold; u8 hird_threshold; + u8 rx_thr_num_pkt; + u8 rx_max_burst; + u8 tx_thr_num_pkt; + u8 tx_max_burst; u8 rx_thr_num_pkt_prd; u8 rx_max_burst_prd; u8 tx_thr_num_pkt_prd; diff --git a/drivers/usb/dwc3/dwc3-rtk.c b/drivers/usb/dwc3/dwc3-rtk.c new file mode 100644 index 000000000000..590028e8fdcb --- /dev/null +++ b/drivers/usb/dwc3/dwc3-rtk.c @@ -0,0 +1,475 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dwc3-rtk.c - Realtek DWC3 Specific Glue layer + * + * Copyright (C) 2023 Realtek Semiconductor Corporation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" + +#define WRAP_CTR_REG 0x0 +#define DISABLE_MULTI_REQ BIT(1) +#define DESC_R2W_MULTI_DISABLE BIT(9) +#define FORCE_PIPE3_PHY_STATUS_TO_0 BIT(13) + +#define WRAP_USB2_PHY_UTMI_REG 0x8 +#define TXHSVM_EN BIT(3) + +#define WRAP_PHY_PIPE_REG 0xC +#define RESET_DISABLE_PIPE3_P0 BIT(0) +#define CLOCK_ENABLE_FOR_PIPE3_PCLK BIT(1) + +#define WRAP_USB_HMAC_CTR0_REG 0x60 +#define U3PORT_DIS BIT(8) + +#define WRAP_USB2_PHY_REG 0x70 +#define USB2_PHY_EN_PHY_PLL_PORT0 BIT(12) +#define USB2_PHY_EN_PHY_PLL_PORT1 BIT(13) +#define USB2_PHY_SWITCH_MASK 0x707 +#define USB2_PHY_SWITCH_DEVICE 0x0 +#define USB2_PHY_SWITCH_HOST 0x606 + +#define WRAP_APHY_REG 0x128 +#define USB3_MBIAS_ENABLE BIT(1) + +/* pm control */ +#define WRAP_USB_DBUS_PWR_CTRL_REG 0x160 +#define USB_DBUS_PWR_CTRL_REG 0x0 +#define DBUS_PWR_CTRL_EN BIT(0) + +struct dwc3_rtk { + struct device *dev; + void __iomem *regs; + size_t regs_size; + void __iomem *pm_base; + + struct dwc3 *dwc; + + enum usb_role cur_role; + struct usb_role_switch *role_switch; +}; + +static void switch_usb2_role(struct dwc3_rtk *rtk, enum usb_role role) +{ + void __iomem *reg; + int val; + + reg = rtk->regs + WRAP_USB2_PHY_REG; + val = ~USB2_PHY_SWITCH_MASK & readl(reg); + + switch (role) { + case USB_ROLE_DEVICE: + writel(USB2_PHY_SWITCH_DEVICE | val, reg); + break; + case USB_ROLE_HOST: + writel(USB2_PHY_SWITCH_HOST | val, reg); + break; + default: + dev_dbg(rtk->dev, "%s: role=%d\n", __func__, role); + break; + } +} + +static void switch_dwc3_role(struct dwc3_rtk *rtk, enum usb_role role) +{ + if (!rtk->dwc->role_sw) + return; + + usb_role_switch_set_role(rtk->dwc->role_sw, role); +} + +static enum usb_role dwc3_rtk_get_role(struct dwc3_rtk *rtk) +{ + enum usb_role role; + + role = rtk->cur_role; + + if (rtk->dwc && rtk->dwc->role_sw) + role = usb_role_switch_get_role(rtk->dwc->role_sw); + else + dev_dbg(rtk->dev, "%s not usb_role_switch role=%d\n", __func__, role); + + return role; +} + +static void dwc3_rtk_set_role(struct dwc3_rtk *rtk, enum usb_role role) +{ + rtk->cur_role = role; + + switch_dwc3_role(rtk, role); + mdelay(10); + switch_usb2_role(rtk, role); +} + +#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH) +static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, enum usb_role role) +{ + struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw); + + dwc3_rtk_set_role(rtk, role); + + return 0; +} + +static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) +{ + struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw); + + return dwc3_rtk_get_role(rtk); +} + +static int dwc3_rtk_setup_role_switch(struct dwc3_rtk *rtk) +{ + struct usb_role_switch_desc dwc3_role_switch = {NULL}; + + dwc3_role_switch.name = dev_name(rtk->dev); + dwc3_role_switch.driver_data = rtk; + dwc3_role_switch.allow_userspace_control = true; + dwc3_role_switch.fwnode = dev_fwnode(rtk->dev); + dwc3_role_switch.set = dwc3_usb_role_switch_set; + dwc3_role_switch.get = dwc3_usb_role_switch_get; + rtk->role_switch = usb_role_switch_register(rtk->dev, &dwc3_role_switch); + if (IS_ERR(rtk->role_switch)) + return PTR_ERR(rtk->role_switch); + + return 0; +} + +static int dwc3_rtk_remove_role_switch(struct dwc3_rtk *rtk) +{ + if (rtk->role_switch) + usb_role_switch_unregister(rtk->role_switch); + + rtk->role_switch = NULL; + + return 0; +} +#else +#define dwc3_rtk_setup_role_switch(x) 0 +#define dwc3_rtk_remove_role_switch(x) 0 +#endif + +static const char *const speed_names[] = { + [USB_SPEED_UNKNOWN] = "UNKNOWN", + [USB_SPEED_LOW] = "low-speed", + [USB_SPEED_FULL] = "full-speed", + [USB_SPEED_HIGH] = "high-speed", + [USB_SPEED_WIRELESS] = "wireless", + [USB_SPEED_SUPER] = "super-speed", + [USB_SPEED_SUPER_PLUS] = "super-speed-plus", +}; + +static enum usb_device_speed __get_dwc3_maximum_speed(struct device_node *np) +{ + struct device_node *dwc3_np; + const char *maximum_speed; + int ret; + + dwc3_np = of_get_compatible_child(np, "snps,dwc3"); + if (!dwc3_np) + return USB_SPEED_UNKNOWN; + + ret = of_property_read_string(dwc3_np, "maximum-speed", &maximum_speed); + if (ret < 0) + return USB_SPEED_UNKNOWN; + + ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed); + + return (ret < 0) ? USB_SPEED_UNKNOWN : ret; +} + +static int dwc3_rtk_init(struct dwc3_rtk *rtk) +{ + struct device *dev = rtk->dev; + void __iomem *reg; + int val; + enum usb_device_speed maximum_speed; + const struct soc_device_attribute rtk_soc_kylin_a00[] = { + { .family = "Realtek Kylin", .revision = "A00", }, + { /* empty */ } }; + const struct soc_device_attribute rtk_soc_hercules[] = { + { .family = "Realtek Hercules", }, { /* empty */ } }; + const struct soc_device_attribute rtk_soc_thor[] = { + { .family = "Realtek Thor", }, { /* empty */ } }; + + if (soc_device_match(rtk_soc_kylin_a00)) { + reg = rtk->regs + WRAP_CTR_REG; + val = readl(reg); + writel(DISABLE_MULTI_REQ | val, reg); + dev_info(dev, "[bug fixed] 1295/1296 A00: add workaround to disable multiple request for D-Bus"); + } + + if (soc_device_match(rtk_soc_hercules)) { + reg = rtk->regs + WRAP_USB2_PHY_REG; + val = readl(reg); + writel(USB2_PHY_EN_PHY_PLL_PORT1 | val, reg); + dev_info(dev, "[bug fixed] 1395 add workaround to disable usb2 port 2 suspend!"); + } + + reg = rtk->regs + WRAP_USB2_PHY_UTMI_REG; + val = readl(reg); + writel(TXHSVM_EN | val, reg); + + maximum_speed = __get_dwc3_maximum_speed(dev->of_node); + if (maximum_speed != USB_SPEED_UNKNOWN && maximum_speed <= USB_SPEED_HIGH) { + if (soc_device_match(rtk_soc_thor)) { + reg = rtk->regs + WRAP_USB_HMAC_CTR0_REG; + val = readl(reg); + writel(U3PORT_DIS | val, reg); + } else { + reg = rtk->regs + WRAP_CTR_REG; + val = readl(reg); + writel(FORCE_PIPE3_PHY_STATUS_TO_0 | val, reg); + + reg = rtk->regs + WRAP_PHY_PIPE_REG; + val = ~CLOCK_ENABLE_FOR_PIPE3_PCLK & readl(reg); + writel(RESET_DISABLE_PIPE3_P0 | val, reg); + + reg = rtk->regs + WRAP_USB_HMAC_CTR0_REG; + val = readl(reg); + writel(U3PORT_DIS | val, reg); + + reg = rtk->regs + WRAP_APHY_REG; + val = readl(reg); + writel(~USB3_MBIAS_ENABLE & val, reg); + + dev_dbg(rtk->dev, "%s: disable usb 3.0 phy\n", __func__); + } + } + + reg = rtk->regs + WRAP_CTR_REG; + val = readl(reg); + writel(DESC_R2W_MULTI_DISABLE | val, reg); + + /* Set phy Dp/Dm initial state to host mode to avoid the Dp glitch */ + reg = rtk->regs + WRAP_USB2_PHY_REG; + val = ~USB2_PHY_SWITCH_MASK & readl(reg); + writel(USB2_PHY_SWITCH_HOST | val, reg); + + if (rtk->pm_base) { + reg = rtk->pm_base + USB_DBUS_PWR_CTRL_REG; + val = DBUS_PWR_CTRL_EN | readl(reg); + writel(val, reg); + } + + return 0; +} + +static int dwc3_rtk_probe_dwc3_core(struct dwc3_rtk *rtk) +{ + struct device *dev = rtk->dev; + struct device_node *node = dev->of_node; + struct platform_device *dwc3_pdev; + struct device *dwc3_dev; + struct device_node *dwc3_node; + enum usb_dr_mode dr_mode; + int ret = 0; + + ret = dwc3_rtk_init(rtk); + if (ret) + return -EINVAL; + + ret = of_platform_populate(node, NULL, NULL, dev); + if (ret) { + dev_err(dev, "failed to add dwc3 core\n"); + return ret; + } + + dwc3_node = of_get_compatible_child(node, "snps,dwc3"); + if (!dwc3_node) { + dev_err(dev, "failed to find dwc3 core node\n"); + ret = -ENODEV; + goto depopulate; + } + + dwc3_pdev = of_find_device_by_node(dwc3_node); + if (!dwc3_pdev) { + dev_err(dev, "failed to find dwc3 core platform_device\n"); + ret = -ENODEV; + goto err_node_put; + } + + dwc3_dev = &dwc3_pdev->dev; + rtk->dwc = platform_get_drvdata(dwc3_pdev); + if (!rtk->dwc) { + dev_err(dev, "failed to find dwc3 core\n"); + ret = -ENODEV; + goto err_pdev_put; + } + + dr_mode = usb_get_dr_mode(dwc3_dev); + if (dr_mode != rtk->dwc->dr_mode) { + dev_info(dev, "dts set dr_mode=%d, but dwc3 set dr_mode=%d\n", + dr_mode, rtk->dwc->dr_mode); + dr_mode = rtk->dwc->dr_mode; + } + + switch (dr_mode) { + case USB_DR_MODE_PERIPHERAL: + rtk->cur_role = USB_ROLE_DEVICE; + break; + case USB_DR_MODE_HOST: + rtk->cur_role = USB_ROLE_HOST; + break; + default: + dev_dbg(rtk->dev, "%s: dr_mode=%d\n", __func__, dr_mode); + break; + } + + if (device_property_read_bool(dwc3_dev, "usb-role-switch")) { + ret = dwc3_rtk_setup_role_switch(rtk); + if (ret) { + dev_err(dev, "dwc3_rtk_setup_role_switch fail=%d\n", ret); + goto err_pdev_put; + } + rtk->cur_role = dwc3_rtk_get_role(rtk); + } + + switch_usb2_role(rtk, rtk->cur_role); + + return 0; + +err_pdev_put: + platform_device_put(dwc3_pdev); +err_node_put: + of_node_put(dwc3_node); +depopulate: + of_platform_depopulate(dev); + + return ret; +} + +static int dwc3_rtk_probe(struct platform_device *pdev) +{ + struct dwc3_rtk *rtk; + struct device *dev = &pdev->dev; + struct resource *res; + void __iomem *regs; + int ret = 0; + + rtk = devm_kzalloc(dev, sizeof(*rtk), GFP_KERNEL); + if (!rtk) { + ret = -ENOMEM; + goto out; + } + + platform_set_drvdata(pdev, rtk); + + rtk->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing memory resource\n"); + ret = -ENODEV; + goto out; + } + + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) { + ret = PTR_ERR(regs); + goto out; + } + + rtk->regs = regs; + rtk->regs_size = resource_size(res); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) { + rtk->pm_base = devm_ioremap_resource(dev, res); + if (IS_ERR(rtk->pm_base)) { + ret = PTR_ERR(rtk->pm_base); + goto out; + } + } + + ret = dwc3_rtk_probe_dwc3_core(rtk); + +out: + return ret; +} + +static void dwc3_rtk_remove(struct platform_device *pdev) +{ + struct dwc3_rtk *rtk = platform_get_drvdata(pdev); + + rtk->dwc = NULL; + + dwc3_rtk_remove_role_switch(rtk); + + of_platform_depopulate(rtk->dev); +} + +static void dwc3_rtk_shutdown(struct platform_device *pdev) +{ + struct dwc3_rtk *rtk = platform_get_drvdata(pdev); + + of_platform_depopulate(rtk->dev); +} + +static const struct of_device_id rtk_dwc3_match[] = { + { .compatible = "realtek,rtd-dwc3" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rtk_dwc3_match); + +#ifdef CONFIG_PM_SLEEP +static int dwc3_rtk_suspend(struct device *dev) +{ + return 0; +} + +static int dwc3_rtk_resume(struct device *dev) +{ + struct dwc3_rtk *rtk = dev_get_drvdata(dev); + + dwc3_rtk_init(rtk); + + switch_usb2_role(rtk, rtk->cur_role); + + /* runtime set active to reflect active state. */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} + +static const struct dev_pm_ops dwc3_rtk_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_rtk_suspend, dwc3_rtk_resume) +}; + +#define DEV_PM_OPS (&dwc3_rtk_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct platform_driver dwc3_rtk_driver = { + .probe = dwc3_rtk_probe, + .remove_new = dwc3_rtk_remove, + .driver = { + .name = "rtk-dwc3", + .of_match_table = rtk_dwc3_match, + .pm = DEV_PM_OPS, + }, + .shutdown = dwc3_rtk_shutdown, +}; + +module_platform_driver(dwc3_rtk_driver); + +MODULE_AUTHOR("Stanley Chang "); +MODULE_DESCRIPTION("DesignWare USB3 Realtek Glue Layer"); +MODULE_ALIAS("platform:rtk-dwc3"); +MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: phy_rtk_usb2 phy_rtk_usb3"); diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index 19307d24f3a0..5b7e92f476de 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -32,9 +32,6 @@ #define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C #define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 -/* Versal USB Reset ID */ -#define VERSAL_USB_RESET_ID 0xC104036 - #define XLNX_USB_FPD_PIPE_CLK 0x7c #define PIPE_CLK_DESELECT 1 #define PIPE_CLK_SELECT 0 @@ -72,20 +69,23 @@ static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) { struct device *dev = priv_data->dev; + struct reset_control *crst; int ret; + crst = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(crst)) + return dev_err_probe(dev, PTR_ERR(crst), "failed to get reset signal\n"); + dwc3_xlnx_mask_phy_rst(priv_data, false); /* Assert and De-assert reset */ - ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, - PM_RESET_ACTION_ASSERT); + ret = reset_control_assert(crst); if (ret < 0) { dev_err_probe(dev, ret, "failed to assert Reset\n"); return ret; } - ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, - PM_RESET_ACTION_RELEASE); + ret = reset_control_deassert(crst); if (ret < 0) { dev_err_probe(dev, ret, "failed to De-assert Reset\n"); return ret; diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index e6ab8cc225ff..cc0ed29a4adc 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1410,7 +1410,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_ncm *ncm = func_to_ncm(f); struct usb_string *us; - int status; + int status = 0; struct usb_ep *ep; struct f_ncm_opts *ncm_opts; @@ -1428,22 +1428,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; } - /* - * in drivers/usb/gadget/configfs.c:configfs_composite_bind() - * configurations are bound in sequence with list_for_each_entry, - * in each configuration its functions are bound in sequence - * with list_for_each_entry, so we assume no race condition - * with regard to ncm_opts->bound access - */ - if (!ncm_opts->bound) { - mutex_lock(&ncm_opts->lock); - gether_set_gadget(ncm_opts->net, cdev->gadget); + mutex_lock(&ncm_opts->lock); + gether_set_gadget(ncm_opts->net, cdev->gadget); + if (!ncm_opts->bound) status = gether_register_netdev(ncm_opts->net); - mutex_unlock(&ncm_opts->lock); - if (status) - goto fail; - ncm_opts->bound = true; - } + mutex_unlock(&ncm_opts->lock); + + if (status) + goto fail; + + ncm_opts->bound = true; + us = usb_gstrings_attach(cdev, ncm_strings, ARRAY_SIZE(ncm_string_defs)); if (IS_ERR(us)) { diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 0219cd79493a..f9a0f07a7476 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -212,7 +212,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = { .bDescriptorSubtype = UAC_INPUT_TERMINAL, /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), + /* .wTerminalType = DYNAMIC */ .bAssocTerminal = 0, /* .bCSourceID = DYNAMIC */ .iChannelNames = 0, @@ -240,7 +240,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = { .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), + /* .wTerminalType = DYNAMIC */ .bAssocTerminal = 0, /* .bSourceID = DYNAMIC */ /* .bCSourceID = DYNAMIC */ @@ -977,6 +977,9 @@ static void setup_descriptor(struct f_uac2_opts *opts) iad_desc.bInterfaceCount++; } + io_in_it_desc.wTerminalType = cpu_to_le16(opts->c_terminal_type); + io_out_ot_desc.wTerminalType = cpu_to_le16(opts->p_terminal_type); + setup_headers(opts, fs_audio_desc, USB_SPEED_FULL); setup_headers(opts, hs_audio_desc, USB_SPEED_HIGH); setup_headers(opts, ss_audio_desc, USB_SPEED_SUPER); @@ -2095,6 +2098,9 @@ UAC2_ATTRIBUTE(s16, c_volume_res); UAC2_ATTRIBUTE(u32, fb_max); UAC2_ATTRIBUTE_STRING(function_name); +UAC2_ATTRIBUTE(s16, p_terminal_type); +UAC2_ATTRIBUTE(s16, c_terminal_type); + static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_p_chmask, &f_uac2_opts_attr_p_srate, @@ -2122,6 +2128,9 @@ static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_function_name, + &f_uac2_opts_attr_p_terminal_type, + &f_uac2_opts_attr_c_terminal_type, + NULL, }; @@ -2180,6 +2189,9 @@ static struct usb_function_instance *afunc_alloc_inst(void) snprintf(opts->function_name, sizeof(opts->function_name), "Source/Sink"); + opts->p_terminal_type = UAC2_DEF_P_TERM_TYPE; + opts->c_terminal_type = UAC2_DEF_C_TERM_TYPE; + return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index faa398109431..786379f1b7b7 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -516,6 +516,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) void *mem; switch (speed) { + case USB_SPEED_SUPER_PLUS: case USB_SPEED_SUPER: uvc_control_desc = uvc->desc.ss_control; uvc_streaming_cls = uvc->desc.ss_streaming; @@ -564,7 +565,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) bytes += uvc_interrupt_ep.bLength + uvc_interrupt_cs_ep.bLength; n_desc += 2; - if (speed == USB_SPEED_SUPER) { + if (speed == USB_SPEED_SUPER || + speed == USB_SPEED_SUPER_PLUS) { bytes += uvc_ss_interrupt_comp.bLength; n_desc += 1; } @@ -619,7 +621,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) if (uvc->enable_interrupt_ep) { UVC_COPY_DESCRIPTOR(mem, dst, &uvc_interrupt_ep); - if (speed == USB_SPEED_SUPER) + if (speed == USB_SPEED_SUPER || + speed == USB_SPEED_SUPER_PLUS) UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_interrupt_comp); UVC_COPY_DESCRIPTOR(mem, dst, &uvc_interrupt_cs_ep); @@ -795,6 +798,13 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } + f->ssp_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER_PLUS); + if (IS_ERR(f->ssp_descriptors)) { + ret = PTR_ERR(f->ssp_descriptors); + f->ssp_descriptors = NULL; + goto error; + } + /* Preallocate control endpoint request. */ uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); uvc->control_buf = kmalloc(UVC_MAX_REQUEST_SIZE, GFP_KERNEL); diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 4bb0553da658..9d1c40c152d8 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1200,7 +1200,7 @@ void gether_disconnect(struct gether *link) DBG(dev, "%s\n", __func__); - netif_stop_queue(dev->net); + netif_device_detach(dev->net); netif_carrier_off(dev->net); /* disable endpoints, forcing (synchronous) completion diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index 0510c9bad58d..5e81bdd6c5fb 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -35,6 +35,11 @@ #define UAC2_DEF_REQ_NUM 2 #define UAC2_DEF_INT_REQ_NUM 10 +#define UAC2_DEF_P_TERM_TYPE 0x301 + /* UAC_OUTPUT_TERMINAL_SPEAKER */ +#define UAC2_DEF_C_TERM_TYPE 0x201 + /* UAC_INPUT_TERMINAL_MICROPHONE*/ + struct f_uac2_opts { struct usb_function_instance func_inst; int p_chmask; @@ -65,6 +70,9 @@ struct f_uac2_opts { char function_name[32]; + s16 p_terminal_type; + s16 c_terminal_type; + struct mutex lock; int refcnt; }; diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index cdc0926100fd..03179b1880fd 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -31,6 +31,12 @@ #include #include +#include /* for USB_GADGET_DELAYED_STATUS */ + +/* Undef helpers from linux/usb/composite.h as gadgetfs redefines them */ +#undef DBG +#undef ERROR +#undef INFO /* @@ -1511,7 +1517,16 @@ delegate: event->u.setup = *ctrl; ep0_readable (dev); spin_unlock (&dev->lock); - return 0; + /* + * Return USB_GADGET_DELAYED_STATUS as a workaround to + * stop some UDC drivers (e.g. dwc3) from automatically + * proceeding with the status stage for 0-length + * transfers. + * Should be removed once all UDC drivers are fixed to + * always delay the status stage until a response is + * queued to EP0. + */ + return w_length == 0 ? USB_GADGET_DELAYED_STATUS : 0; } } diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index e549022642e5..399fca32a8ac 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -64,7 +65,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue, struct usb_raw_event *event; spin_lock_irqsave(&queue->lock, flags); - if (WARN_ON(queue->size >= RAW_EVENT_QUEUE_SIZE)) { + if (queue->size >= RAW_EVENT_QUEUE_SIZE) { spin_unlock_irqrestore(&queue->lock, flags); return -ENOMEM; } @@ -310,9 +311,10 @@ static int gadget_bind(struct usb_gadget *gadget, dev->eps_num = i; spin_unlock_irqrestore(&dev->lock, flags); + dev_dbg(&gadget->dev, "gadget connected\n"); ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL); if (ret < 0) { - dev_err(&gadget->dev, "failed to queue event\n"); + dev_err(&gadget->dev, "failed to queue connect event\n"); set_gadget_data(gadget, NULL); return ret; } @@ -357,20 +359,65 @@ static int gadget_setup(struct usb_gadget *gadget, ret = raw_queue_event(dev, USB_RAW_EVENT_CONTROL, sizeof(*ctrl), ctrl); if (ret < 0) - dev_err(&gadget->dev, "failed to queue event\n"); + dev_err(&gadget->dev, "failed to queue control event\n"); goto out; out_unlock: spin_unlock_irqrestore(&dev->lock, flags); out: + if (ret == 0 && ctrl->wLength == 0) { + /* + * Return USB_GADGET_DELAYED_STATUS as a workaround to stop + * some UDC drivers (e.g. dwc3) from automatically proceeding + * with the status stage for 0-length transfers. + * Should be removed once all UDC drivers are fixed to always + * delay the status stage until a response is queued to EP0. + */ + return USB_GADGET_DELAYED_STATUS; + } return ret; } -/* These are currently unused but present in case UDC driver requires them. */ -static void gadget_disconnect(struct usb_gadget *gadget) { } -static void gadget_suspend(struct usb_gadget *gadget) { } -static void gadget_resume(struct usb_gadget *gadget) { } -static void gadget_reset(struct usb_gadget *gadget) { } +static void gadget_disconnect(struct usb_gadget *gadget) +{ + struct raw_dev *dev = get_gadget_data(gadget); + int ret; + + dev_dbg(&gadget->dev, "gadget disconnected\n"); + ret = raw_queue_event(dev, USB_RAW_EVENT_DISCONNECT, 0, NULL); + if (ret < 0) + dev_err(&gadget->dev, "failed to queue disconnect event\n"); +} +static void gadget_suspend(struct usb_gadget *gadget) +{ + struct raw_dev *dev = get_gadget_data(gadget); + int ret; + + dev_dbg(&gadget->dev, "gadget suspended\n"); + ret = raw_queue_event(dev, USB_RAW_EVENT_SUSPEND, 0, NULL); + if (ret < 0) + dev_err(&gadget->dev, "failed to queue suspend event\n"); +} +static void gadget_resume(struct usb_gadget *gadget) +{ + struct raw_dev *dev = get_gadget_data(gadget); + int ret; + + dev_dbg(&gadget->dev, "gadget resumed\n"); + ret = raw_queue_event(dev, USB_RAW_EVENT_RESUME, 0, NULL); + if (ret < 0) + dev_err(&gadget->dev, "failed to queue resume event\n"); +} +static void gadget_reset(struct usb_gadget *gadget) +{ + struct raw_dev *dev = get_gadget_data(gadget); + int ret; + + dev_dbg(&gadget->dev, "gadget reset\n"); + ret = raw_queue_event(dev, USB_RAW_EVENT_RESET, 0, NULL); + if (ret < 0) + dev_err(&gadget->dev, "failed to queue reset event\n"); +} /*----------------------------------------------------------------------*/ @@ -663,12 +710,12 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, if (WARN_ON(in && dev->ep0_out_pending)) { ret = -ENODEV; dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_unlock; } if (WARN_ON(!in && dev->ep0_in_pending)) { ret = -ENODEV; dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_unlock; } dev->req->buf = data; @@ -682,8 +729,7 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, dev_err(&dev->gadget->dev, "fail, usb_ep_queue returned %d\n", ret); spin_lock_irqsave(&dev->lock, flags); - dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_queue_failed; } ret = wait_for_completion_interruptible(&dev->ep0_done); @@ -692,13 +738,16 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, usb_ep_dequeue(dev->gadget->ep0, dev->req); wait_for_completion(&dev->ep0_done); spin_lock_irqsave(&dev->lock, flags); - goto out_done; + if (dev->ep0_status == -ECONNRESET) + dev->ep0_status = -EINTR; + goto out_interrupted; } spin_lock_irqsave(&dev->lock, flags); - ret = dev->ep0_status; -out_done: +out_interrupted: + ret = dev->ep0_status; +out_queue_failed: dev->ep0_urb_queued = false; out_unlock: spin_unlock_irqrestore(&dev->lock, flags); @@ -1066,8 +1115,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, dev_err(&dev->gadget->dev, "fail, usb_ep_queue returned %d\n", ret); spin_lock_irqsave(&dev->lock, flags); - dev->state = STATE_DEV_FAILED; - goto out_done; + goto out_queue_failed; } ret = wait_for_completion_interruptible(&done); @@ -1076,13 +1124,16 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, usb_ep_dequeue(ep->ep, ep->req); wait_for_completion(&done); spin_lock_irqsave(&dev->lock, flags); - goto out_done; + if (ep->status == -ECONNRESET) + ep->status = -EINTR; + goto out_interrupted; } spin_lock_irqsave(&dev->lock, flags); - ret = ep->status; -out_done: +out_interrupted: + ret = ep->status; +out_queue_failed: ep->urb_queued = false; out_unlock: spin_unlock_irqrestore(&dev->lock, flags); diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c index 2ef89a442f50..3916c8e2ba01 100644 --- a/drivers/usb/gadget/udc/aspeed_udc.c +++ b/drivers/usb/gadget/udc/aspeed_udc.c @@ -1432,15 +1432,24 @@ static void ast_udc_init_hw(struct ast_udc_dev *udc) ast_udc_write(udc, 0, AST_UDC_EP0_CTRL); } -static int ast_udc_remove(struct platform_device *pdev) +static void ast_udc_remove(struct platform_device *pdev) { struct ast_udc_dev *udc = platform_get_drvdata(pdev); unsigned long flags; u32 ctrl; usb_del_gadget_udc(&udc->gadget); - if (udc->driver) - return -EBUSY; + if (udc->driver) { + /* + * This is broken as only some cleanup is skipped, *udev is + * freed and the register mapping goes away. Any further usage + * probably crashes. Also the device is unbound, so the skipped + * cleanup is never catched up later. + */ + dev_alert(&pdev->dev, + "Driver is busy and still going away. Fasten your seat belts!\n"); + return; + } spin_lock_irqsave(&udc->lock, flags); @@ -1459,8 +1468,6 @@ static int ast_udc_remove(struct platform_device *pdev) udc->ep0_buf_dma); udc->ep0_buf = NULL; - - return 0; } static int ast_udc_probe(struct platform_device *pdev) @@ -1581,7 +1588,7 @@ MODULE_DEVICE_TABLE(of, ast_udc_of_dt_ids); static struct platform_driver ast_udc_driver = { .probe = ast_udc_probe, - .remove = ast_udc_remove, + .remove_new = ast_udc_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = ast_udc_of_dt_ids, diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 922b4187004b..30ea4a9d5301 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -2000,6 +2000,7 @@ static int at91udc_resume(struct platform_device *pdev) #endif static struct platform_driver at91_udc_driver = { + .probe = at91udc_probe, .remove = at91udc_remove, .shutdown = at91udc_shutdown, .suspend = at91udc_suspend, @@ -2010,7 +2011,7 @@ static struct platform_driver at91_udc_driver = { }, }; -module_platform_driver_probe(at91_udc_driver, at91udc_probe); +module_platform_driver(at91_udc_driver); MODULE_DESCRIPTION("AT91 udc driver"); MODULE_AUTHOR("Thomas Rathbone, David Brownell"); diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 7166d1117742..ded9531f141b 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1126,12 +1126,12 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state); /* ------------------------------------------------------------------------- */ /* Acquire connect_lock before calling this function. */ -static void usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) +static int usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) { if (udc->vbus) - usb_gadget_connect_locked(udc->gadget); + return usb_gadget_connect_locked(udc->gadget); else - usb_gadget_disconnect_locked(udc->gadget); + return usb_gadget_disconnect_locked(udc->gadget); } static void vbus_event_work(struct work_struct *work) @@ -1605,12 +1605,23 @@ static int gadget_bind_driver(struct device *dev) } usb_gadget_enable_async_callbacks(udc); udc->allow_connect = true; - usb_udc_connect_control_locked(udc); + ret = usb_udc_connect_control_locked(udc); + if (ret) + goto err_connect_control; + mutex_unlock(&udc->connect_lock); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; + err_connect_control: + udc->allow_connect = false; + usb_gadget_disable_async_callbacks(udc); + if (gadget->irq) + synchronize_irq(gadget->irq); + usb_gadget_udc_stop_locked(udc); + mutex_unlock(&udc->connect_lock); + err_start: driver->unbind(udc->gadget); diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 4aae86b47edf..4e88681a79b6 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -27,9 +27,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include @@ -2471,17 +2472,12 @@ static const struct of_device_id qe_udc_match[]; static int qe_udc_probe(struct platform_device *ofdev) { struct qe_udc *udc; - const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; unsigned int ret = 0; unsigned int i; const void *prop; - match = of_match_device(qe_udc_match, &ofdev->dev); - if (!match) - return -EINVAL; - prop = of_get_property(np, "mode", NULL); if (!prop || strcmp(prop, "peripheral")) return -ENODEV; @@ -2493,7 +2489,7 @@ static int qe_udc_probe(struct platform_device *ofdev) return -ENOMEM; } - udc->soc_type = (unsigned long)match->data; + udc->soc_type = (unsigned long)device_get_match_data(&ofdev->dev); udc->usb_regs = of_iomap(np, 0); if (!udc->usb_regs) { ret = -ENOMEM; diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index ee5705d336e3..2693a10eb0c7 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2666,6 +2666,7 @@ static const struct platform_device_id fsl_udc_devtype[] = { }; MODULE_DEVICE_TABLE(platform, fsl_udc_devtype); static struct platform_driver udc_driver = { + .probe = fsl_udc_probe, .remove = fsl_udc_remove, .id_table = fsl_udc_devtype, /* these suspend and resume are not usb suspend and resume */ @@ -2679,7 +2680,7 @@ static struct platform_driver udc_driver = { }, }; -module_platform_driver_probe(udc_driver, fsl_udc_probe); +module_platform_driver(udc_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index bd03d475f927..873265634ccc 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1506,10 +1506,11 @@ clean_up: } static struct platform_driver fusb300_driver = { - .remove_new = fusb300_remove, - .driver = { + .probe = fusb300_probe, + .remove_new = fusb300_remove, + .driver = { .name = udc_name, }, }; -module_platform_driver_probe(fusb300_driver, fusb300_probe); +module_platform_driver(fusb300_driver); diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index fe62db32dd0e..a917cc9a32ab 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3254,6 +3254,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_udc_of_match); #endif static struct platform_driver lpc32xx_udc_driver = { + .probe = lpc32xx_udc_probe, .remove = lpc32xx_udc_remove, .shutdown = lpc32xx_udc_shutdown, .suspend = lpc32xx_udc_suspend, @@ -3264,7 +3265,7 @@ static struct platform_driver lpc32xx_udc_driver = { }, }; -module_platform_driver_probe(lpc32xx_udc_driver, lpc32xx_udc_probe); +module_platform_driver(lpc32xx_udc_driver); MODULE_DESCRIPTION("LPC32XX udc driver"); MODULE_AUTHOR("Kevin Wells "); diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index e05f45a4b56b..bfaa5291e6c8 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1687,10 +1687,11 @@ clean_up: /*-------------------------------------------------------------------------*/ static struct platform_driver m66592_driver = { + .probe = m66592_probe, .remove_new = m66592_remove, .driver = { .name = udc_name, }, }; -module_platform_driver_probe(m66592_driver, m66592_probe); +module_platform_driver(m66592_driver); diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 51b665f15c8e..db4a10a979f9 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1964,13 +1964,14 @@ clean_up2: /*-------------------------------------------------------------------------*/ static struct platform_driver r8a66597_driver = { + .probe = r8a66597_probe, .remove_new = r8a66597_remove, .driver = { .name = udc_name, }, }; -module_platform_driver_probe(r8a66597_driver, r8a66597_probe); +module_platform_driver(r8a66597_driver); MODULE_DESCRIPTION("R8A66597 USB gadget driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2665832f9add..1f9c1b1435d8 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -60,6 +60,23 @@ #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ +/* ASMEDIA quirk use */ +#define ASMT_DATA_WRITE0_REG 0xF8 +#define ASMT_DATA_WRITE1_REG 0xFC +#define ASMT_CONTROL_REG 0xE0 +#define ASMT_CONTROL_WRITE_BIT 0x02 +#define ASMT_WRITEREG_CMD 0x10423 +#define ASMT_FLOWCTL_ADDR 0xFA30 +#define ASMT_FLOWCTL_DATA 0xBA +#define ASMT_PSEUDO_DATA 0 + +/* Intel quirk use */ +#define USB_INTEL_XUSB2PR 0xD0 +#define USB_INTEL_USB2PRM 0xD4 +#define USB_INTEL_USB3_PSSEN 0xD8 +#define USB_INTEL_USB3PRM 0xDC + +#ifdef CONFIG_USB_PCI_AMD /* AMD quirk use */ #define AB_REG_BAR_LOW 0xe0 #define AB_REG_BAR_HIGH 0xe1 @@ -93,21 +110,6 @@ #define NB_PIF0_PWRDOWN_0 0x01100012 #define NB_PIF0_PWRDOWN_1 0x01100013 -#define USB_INTEL_XUSB2PR 0xD0 -#define USB_INTEL_USB2PRM 0xD4 -#define USB_INTEL_USB3_PSSEN 0xD8 -#define USB_INTEL_USB3PRM 0xDC - -/* ASMEDIA quirk use */ -#define ASMT_DATA_WRITE0_REG 0xF8 -#define ASMT_DATA_WRITE1_REG 0xFC -#define ASMT_CONTROL_REG 0xE0 -#define ASMT_CONTROL_WRITE_BIT 0x02 -#define ASMT_WRITEREG_CMD 0x10423 -#define ASMT_FLOWCTL_ADDR 0xFA30 -#define ASMT_FLOWCTL_DATA 0xBA -#define ASMT_PSEUDO_DATA 0 - /* * amd_chipset_gen values represent AMD different chipset generations */ @@ -458,50 +460,6 @@ void usb_amd_quirk_pll_disable(void) } EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); -static int usb_asmedia_wait_write(struct pci_dev *pdev) -{ - unsigned long retry_count; - unsigned char value; - - for (retry_count = 1000; retry_count > 0; --retry_count) { - - pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value); - - if (value == 0xff) { - dev_err(&pdev->dev, "%s: check_ready ERROR", __func__); - return -EIO; - } - - if ((value & ASMT_CONTROL_WRITE_BIT) == 0) - return 0; - - udelay(50); - } - - dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); - return -ETIMEDOUT; -} - -void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) -{ - if (usb_asmedia_wait_write(pdev) != 0) - return; - - /* send command and address to device */ - pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD); - pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR); - pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); - - if (usb_asmedia_wait_write(pdev) != 0) - return; - - /* send data to device */ - pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA); - pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA); - pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); -} -EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol); - void usb_amd_quirk_pll_enable(void) { usb_amd_quirk_pll(0); @@ -630,7 +588,62 @@ bool usb_amd_pt_check_port(struct device *device, int port) return !(value & BIT(port_shift)); } EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); +#endif /* CONFIG_USB_PCI_AMD */ +static int usb_asmedia_wait_write(struct pci_dev *pdev) +{ + unsigned long retry_count; + unsigned char value; + + for (retry_count = 1000; retry_count > 0; --retry_count) { + + pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value); + + if (value == 0xff) { + dev_err(&pdev->dev, "%s: check_ready ERROR", __func__); + return -EIO; + } + + if ((value & ASMT_CONTROL_WRITE_BIT) == 0) + return 0; + + udelay(50); + } + + dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); + return -ETIMEDOUT; +} + +void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) +{ + if (usb_asmedia_wait_write(pdev) != 0) + return; + + /* send command and address to device */ + pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD); + pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR); + pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); + + if (usb_asmedia_wait_write(pdev) != 0) + return; + + /* send data to device */ + pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA); + pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA); + pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); +} +EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol); + +static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) +{ + u16 cmd; + + return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask); +} + +#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) + +#if defined(CONFIG_HAS_IOPORT) && IS_ENABLED(CONFIG_USB_UHCI_HCD) /* * Make sure the controller is completely inactive, unable to * generate interrupts or do DMA. @@ -712,14 +725,7 @@ reset_needed: } EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); -static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) -{ - u16 cmd; - return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask); -} - #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO) -#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) static void quirk_usb_handoff_uhci(struct pci_dev *pdev) { @@ -739,6 +745,12 @@ static void quirk_usb_handoff_uhci(struct pci_dev *pdev) uhci_check_and_reset_hc(pdev, base); } +#else /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */ + +static void quirk_usb_handoff_uhci(struct pci_dev *pdev) {} + +#endif /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */ + static int mmio_resource_enabled(struct pci_dev *pdev, int idx) { return pci_resource_start(pdev, idx) && mmio_enabled(pdev); diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index e729de21fad7..a5230b0b9e91 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -2,9 +2,7 @@ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H -#ifdef CONFIG_USB_PCI -void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); -int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +#ifdef CONFIG_USB_PCI_AMD int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); bool usb_amd_hang_symptom_quirk(void); bool usb_amd_prefetch_quirk(void); @@ -12,23 +10,41 @@ void usb_amd_dev_put(void); bool usb_amd_quirk_pll_check(void); void usb_amd_quirk_pll_disable(void); void usb_amd_quirk_pll_enable(void); -void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev); -void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); -void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); void sb800_prefetch(struct device *dev, int on); bool usb_amd_pt_check_port(struct device *device, int port); #else -struct pci_dev; +static inline bool usb_amd_hang_symptom_quirk(void) +{ + return false; +}; +static inline bool usb_amd_prefetch_quirk(void) +{ + return false; +} static inline void usb_amd_quirk_pll_disable(void) {} static inline void usb_amd_quirk_pll_enable(void) {} -static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} static inline void usb_amd_dev_put(void) {} -static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} +static inline bool usb_amd_quirk_pll_check(void) +{ + return false; +} static inline void sb800_prefetch(struct device *dev, int on) {} static inline bool usb_amd_pt_check_port(struct device *device, int port) { return false; } +#endif /* CONFIG_USB_PCI_AMD */ + +#ifdef CONFIG_USB_PCI +void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); +int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev); +void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); +void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); +#else +struct pci_dev; +static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} +static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} #endif /* CONFIG_USB_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index 99baa60ef50f..6d142cd61bd6 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -204,7 +204,7 @@ static void xhci_ring_dump_segment(struct seq_file *s, for (i = 0; i < TRBS_PER_SEGMENT; i++) { trb = &seg->trbs[i]; dma = seg->dma + i * sizeof(*trb); - seq_printf(s, "%pad: %s\n", &dma, + seq_printf(s, "%2u %pad: %s\n", seg->num, &dma, xhci_decode_trb(str, XHCI_MSG_MAX, le32_to_cpu(trb->generic.field[0]), le32_to_cpu(trb->generic.field[1]), le32_to_cpu(trb->generic.field[2]), diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index e8af0a125f84..96eb36a58738 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -79,6 +79,33 @@ /* true: Controller Not Ready to accept doorbell or op reg writes after reset */ #define XHCI_STS_CNR (1 << 11) +/** + * struct xhci_protocol_caps + * @revision: major revision, minor revision, capability ID, + * and next capability pointer. + * @name_string: Four ASCII characters to say which spec this xHC + * follows, typically "USB ". + * @port_info: Port offset, count, and protocol-defined information. + */ +struct xhci_protocol_caps { + u32 revision; + u32 name_string; + u32 port_info; +}; + +#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff) +#define XHCI_EXT_PORT_MINOR(x) (((x) >> 16) & 0xff) +#define XHCI_EXT_PORT_PSIC(x) (((x) >> 28) & 0x0f) +#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff) +#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff) + +#define XHCI_EXT_PORT_PSIV(x) (((x) >> 0) & 0x0f) +#define XHCI_EXT_PORT_PSIE(x) (((x) >> 4) & 0x03) +#define XHCI_EXT_PORT_PLT(x) (((x) >> 6) & 0x03) +#define XHCI_EXT_PORT_PFD(x) (((x) >> 8) & 0x01) +#define XHCI_EXT_PORT_LP(x) (((x) >> 14) & 0x03) +#define XHCI_EXT_PORT_PSIM(x) (((x) >> 16) & 0xffff) + #include /** diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 0df5d807a77e..0980ade2a234 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1262,7 +1262,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, retval = -ENODEV; break; } - trace_xhci_get_port_status(wIndex, temp); + trace_xhci_get_port_status(port, temp); status = xhci_get_port_status(hcd, bus_state, wIndex, temp, &flags); if (status == 0xffffffff) @@ -1687,7 +1687,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) retval = -ENODEV; break; } - trace_xhci_hub_status_data(i, temp); + trace_xhci_hub_status_data(ports[i], temp); if ((temp & mask) != 0 || (bus_state->port_c_suspend & 1 << i) || diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 0a37f0d511cf..62116586848b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -29,6 +29,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, unsigned int cycle_state, unsigned int max_packet, + unsigned int num, gfp_t flags) { struct xhci_segment *seg; @@ -60,6 +61,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, for (i = 0; i < TRBS_PER_SEGMENT; i++) seg->trbs[i].link.control = cpu_to_le32(TRB_CYCLE); } + seg->num = num; seg->dma = dma; seg->next = NULL; @@ -128,7 +130,7 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *first, struct xhci_segment *last, unsigned int num_segs) { - struct xhci_segment *next; + struct xhci_segment *next, *seg; bool chain_links; if (!ring || !first || !last) @@ -144,13 +146,18 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, xhci_link_segments(last, next, ring->type, chain_links); ring->num_segs += num_segs; - if (ring->type != TYPE_EVENT && ring->enq_seg == ring->last_seg) { - ring->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control - &= ~cpu_to_le32(LINK_TOGGLE); - last->trbs[TRBS_PER_SEGMENT-1].link.control - |= cpu_to_le32(LINK_TOGGLE); + if (ring->enq_seg == ring->last_seg) { + if (ring->type != TYPE_EVENT) { + ring->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control + &= ~cpu_to_le32(LINK_TOGGLE); + last->trbs[TRBS_PER_SEGMENT-1].link.control + |= cpu_to_le32(LINK_TOGGLE); + } ring->last_seg = last; } + + for (seg = last; seg != ring->last_seg; seg = seg->next) + seg->next->num = seg->num + 1; } /* @@ -320,8 +327,9 @@ void xhci_initialize_ring_info(struct xhci_ring *ring, /* Allocate segments and link them for a ring */ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, struct xhci_segment **first, struct xhci_segment **last, - unsigned int num_segs, unsigned int cycle_state, - enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) + unsigned int num_segs, unsigned int num, + unsigned int cycle_state, enum xhci_ring_type type, + unsigned int max_packet, gfp_t flags) { struct xhci_segment *prev; bool chain_links; @@ -331,16 +339,17 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST))); - prev = xhci_segment_alloc(xhci, cycle_state, max_packet, flags); + prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags); if (!prev) return -ENOMEM; - num_segs--; + num++; *first = prev; - while (num_segs > 0) { + while (num < num_segs) { struct xhci_segment *next; - next = xhci_segment_alloc(xhci, cycle_state, max_packet, flags); + next = xhci_segment_alloc(xhci, cycle_state, max_packet, num, + flags); if (!next) { prev = *first; while (prev) { @@ -353,7 +362,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, xhci_link_segments(prev, next, type, chain_links); prev = next; - num_segs--; + num++; } xhci_link_segments(prev, *first, type, chain_links); *last = prev; @@ -388,7 +397,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, return ring; ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg, - &ring->last_seg, num_segs, cycle_state, type, + &ring->last_seg, num_segs, 0, cycle_state, type, max_packet, flags); if (ret) goto fail; @@ -428,7 +437,8 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, int ret; ret = xhci_alloc_segments_for_ring(xhci, &first, &last, - num_new_segs, ring->cycle_state, ring->type, + num_new_segs, ring->enq_seg->num + 1, + ring->cycle_state, ring->type, ring->bounce_buf_len, flags); if (ret) return -ENOMEM; @@ -1766,7 +1776,7 @@ void xhci_free_command(struct xhci_hcd *xhci, kfree(command); } -int xhci_alloc_erst(struct xhci_hcd *xhci, +static int xhci_alloc_erst(struct xhci_hcd *xhci, struct xhci_ring *evt_ring, struct xhci_erst *erst, gfp_t flags) @@ -1797,23 +1807,13 @@ int xhci_alloc_erst(struct xhci_hcd *xhci, } static void -xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir) +xhci_remove_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir) { - struct device *dev = xhci_to_hcd(xhci)->self.sysdev; - size_t erst_size; - u64 tmp64; u32 tmp; if (!ir) return; - erst_size = sizeof(struct xhci_erst_entry) * ir->erst.num_entries; - if (ir->erst.entries) - dma_free_coherent(dev, erst_size, - ir->erst.entries, - ir->erst.erst_dma_addr); - ir->erst.entries = NULL; - /* * Clean out interrupter registers except ERSTBA. Clearing either the * low or high 32 bits of ERSTBA immediately causes the controller to @@ -1824,14 +1824,30 @@ xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir) tmp &= ERST_SIZE_MASK; writel(tmp, &ir->ir_set->erst_size); - tmp64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue); - tmp64 &= (u64) ERST_PTR_MASK; - xhci_write_64(xhci, tmp64, &ir->ir_set->erst_dequeue); + xhci_write_64(xhci, ERST_EHB, &ir->ir_set->erst_dequeue); } +} - /* free interrrupter event ring */ +static void +xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir) +{ + struct device *dev = xhci_to_hcd(xhci)->self.sysdev; + size_t erst_size; + + if (!ir) + return; + + erst_size = sizeof(struct xhci_erst_entry) * ir->erst.num_entries; + if (ir->erst.entries) + dma_free_coherent(dev, erst_size, + ir->erst.entries, + ir->erst.erst_dma_addr); + ir->erst.entries = NULL; + + /* free interrupter event ring */ if (ir->event_ring) xhci_ring_free(xhci, ir->event_ring); + ir->event_ring = NULL; kfree(ir); @@ -1844,6 +1860,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) cancel_delayed_work_sync(&xhci->cmd_timer); + xhci_remove_interrupter(xhci, xhci->interrupter); xhci_free_interrupter(xhci, xhci->interrupter); xhci->interrupter = NULL; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed primary event ring"); @@ -1933,7 +1950,6 @@ no_bw: static void xhci_set_hc_event_deq(struct xhci_hcd *xhci, struct xhci_interrupter *ir) { - u64 temp; dma_addr_t deq; deq = xhci_trb_virt_to_dma(ir->event_ring->deq_seg, @@ -1941,16 +1957,12 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci, struct xhci_interrupter if (!deq) xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr.\n"); /* Update HC event ring dequeue pointer */ - temp = xhci_read_64(xhci, &ir->ir_set->erst_dequeue); - temp &= ERST_PTR_MASK; /* Don't clear the EHB bit (which is RW1C) because * there might be more events to service. */ - temp &= ~ERST_EHB; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Write event ring dequeue pointer, preserving EHB bit"); - xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, - &ir->ir_set->erst_dequeue); + xhci_write_64(xhci, deq & ERST_PTR_MASK, &ir->ir_set->erst_dequeue); } static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, @@ -2238,14 +2250,18 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, gfp_t flags) { struct device *dev = xhci_to_hcd(xhci)->self.sysdev; struct xhci_interrupter *ir; + unsigned int num_segs; int ret; ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev)); if (!ir) return NULL; - ir->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, 1, TYPE_EVENT, - 0, flags); + num_segs = min_t(unsigned int, 1 << HCS_ERST_MAX(xhci->hcs_params2), + ERST_MAX_SEGS); + + ir->event_ring = xhci_ring_alloc(xhci, num_segs, 1, TYPE_EVENT, 0, + flags); if (!ir->event_ring) { xhci_warn(xhci, "Failed to allocate interrupter event ring\n"); kfree(ir); @@ -2281,7 +2297,7 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir, /* set ERST count with the number of entries in the segment table */ erst_size = readl(&ir->ir_set->erst_size); erst_size &= ERST_SIZE_MASK; - erst_size |= ERST_NUM_SEGS; + erst_size |= ir->event_ring->num_segs; writel(erst_size, &ir->ir_set->erst_size); erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base); diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 579899eb24c1..5b3cd455adec 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -19,6 +19,18 @@ #define HS_BW_BOUNDARY 6144 /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ #define FS_PAYLOAD_MAX 188 +#define LS_PAYLOAD_MAX 18 +/* section 11.18.1, per fs frame */ +#define FS_BW_BOUNDARY 1157 +#define LS_BW_BOUNDARY 144 + +/* + * max number of microframes for split transfer, assume extra-cs budget is 0 + * for fs isoc in : 1 ss + 1 idle + 6 cs (roundup(1023/188)) + */ +#define TT_MICROFRAMES_MAX 8 +/* offset from SS for fs/ls isoc/intr ep (ss + idle) */ +#define CS_OFFSET 2 #define DBG_BUF_EN 64 @@ -237,17 +249,26 @@ static void drop_tt(struct usb_device *udev) static struct mu3h_sch_ep_info * create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) { struct mu3h_sch_ep_info *sch_ep; struct mu3h_sch_bw_info *bw_info; struct mu3h_sch_tt *tt = NULL; + u32 len; bw_info = get_bw_info(mtk, udev, ep); if (!bw_info) return ERR_PTR(-ENODEV); - sch_ep = kzalloc(sizeof(*sch_ep), GFP_KERNEL); + if (is_fs_or_ls(udev->speed)) + len = TT_MICROFRAMES_MAX; + else if ((udev->speed >= USB_SPEED_SUPER) && + usb_endpoint_xfer_isoc(&ep->desc)) + len = get_esit(ep_ctx); + else + len = 1; + + sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table, len), GFP_KERNEL); if (!sch_ep) return ERR_PTR(-ENOMEM); @@ -279,7 +300,11 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, u32 mult; u32 esit_pkts; u32 max_esit_payload; + u32 bw_per_microframe; + u32 *bwb_table; + int i; + bwb_table = sch_ep->bw_budget_table; ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); @@ -313,7 +338,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, * opportunities per microframe */ sch_ep->pkts = max_burst + 1; - sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; + bwb_table[0] = maxpkt * sch_ep->pkts; } else if (sch_ep->speed >= USB_SPEED_SUPER) { /* usb3_r1 spec section4.4.7 & 4.4.8 */ sch_ep->cs_count = 0; @@ -330,6 +355,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { sch_ep->pkts = esit_pkts; sch_ep->num_budget_microframes = 1; + bwb_table[0] = maxpkt * sch_ep->pkts; } if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { @@ -346,18 +372,52 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, DIV_ROUND_UP(esit_pkts, sch_ep->pkts); sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); + bw_per_microframe = maxpkt * sch_ep->pkts; + + for (i = 0; i < sch_ep->num_budget_microframes - 1; i++) + bwb_table[i] = bw_per_microframe; + + /* last one <= bw_per_microframe */ + bwb_table[i] = maxpkt * esit_pkts - i * bw_per_microframe; } - sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; } else if (is_fs_or_ls(sch_ep->speed)) { sch_ep->pkts = 1; /* at most one packet for each microframe */ /* - * num_budget_microframes and cs_count will be updated when + * @cs_count will be updated to add extra-cs when * check TT for INT_OUT_EP, ISOC/INT_IN_EP type + * @maxpkt <= 1023; */ sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); sch_ep->num_budget_microframes = sch_ep->cs_count; - sch_ep->bw_cost_per_microframe = min_t(u32, maxpkt, FS_PAYLOAD_MAX); + + /* init budget table */ + if (ep_type == ISOC_OUT_EP) { + for (i = 0; i < sch_ep->cs_count - 1; i++) + bwb_table[i] = FS_PAYLOAD_MAX; + + bwb_table[i] = maxpkt - i * FS_PAYLOAD_MAX; + } else if (ep_type == INT_OUT_EP) { + /* only first one used (maxpkt <= 64), others zero */ + bwb_table[0] = maxpkt; + } else { /* INT_IN_EP or ISOC_IN_EP */ + bwb_table[0] = 0; /* start split */ + bwb_table[1] = 0; /* idle */ + /* + * @cs_count will be updated according to cs position + * (add 1 or 2 extra-cs), but assume only first + * @num_budget_microframes elements will be used later, + * although in fact it does not (extra-cs budget many receive + * some data for IN ep); + * @cs_count is 1 for INT_IN_EP (maxpkt <= 64); + */ + for (i = 0; i < sch_ep->cs_count - 1; i++) + bwb_table[i + CS_OFFSET] = FS_PAYLOAD_MAX; + + bwb_table[i + CS_OFFSET] = maxpkt - i * FS_PAYLOAD_MAX; + /* ss + idle */ + sch_ep->num_budget_microframes += CS_OFFSET; + } } } @@ -374,7 +434,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, for (j = 0; j < sch_ep->num_budget_microframes; j++) { k = XHCI_MTK_BW_INDEX(base + j); - bw = sch_bw->bus_bw[k] + sch_ep->bw_cost_per_microframe; + bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j]; if (bw > max_bw) max_bw = bw; } @@ -382,56 +442,152 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, return max_bw; } +/* + * for OUT: get first SS consumed bw; + * for IN: get first CS consumed bw; + */ +static u16 get_fs_bw(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u16 fs_bw; + + if (sch_ep->ep_type == ISOC_OUT_EP || sch_ep->ep_type == INT_OUT_EP) + fs_bw = tt->fs_bus_bw_out[XHCI_MTK_BW_INDEX(offset)]; + else /* skip ss + idle */ + fs_bw = tt->fs_bus_bw_in[XHCI_MTK_BW_INDEX(offset + CS_OFFSET)]; + + return fs_bw; +} + static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep, bool used) { - int bw_updated; u32 base; - int i, j; - - bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1); - - for (i = 0; i < sch_ep->num_esit; i++) { - base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->num_budget_microframes; j++) - sch_bw->bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated; - } -} - -static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) -{ - struct mu3h_sch_tt *tt = sch_ep->sch_tt; - u32 tmp; - int base; int i, j, k; for (i = 0; i < sch_ep->num_esit; i++) { - base = offset + i * sch_ep->esit; - - /* - * Compared with hs bus, no matter what ep type, - * the hub will always delay one uframe to send data - */ + base = sch_ep->offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { k = XHCI_MTK_BW_INDEX(base + j); - tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe; - if (tmp > FS_PAYLOAD_MAX) - return -ESCH_BW_OVERFLOW; + if (used) + sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j]; + else + sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j]; } } +} + +static int check_ls_budget_microframes(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + int i; + + if (sch_ep->speed != USB_SPEED_LOW) + return 0; + + if (sch_ep->ep_type == INT_OUT_EP) + i = XHCI_MTK_BW_INDEX(offset); + else if (sch_ep->ep_type == INT_IN_EP) + i = XHCI_MTK_BW_INDEX(offset + CS_OFFSET); /* skip ss + idle */ + else + return -EINVAL; + + if (tt->ls_bus_bw[i] + sch_ep->maxpkt > LS_PAYLOAD_MAX) + return -ESCH_BW_OVERFLOW; + + return 0; +} + +static int check_fs_budget_microframes(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u32 tmp; + int i, k; + + /* + * for OUT eps, will transfer exactly assigned length of data, + * so can't allocate more than 188 bytes; + * but it's not for IN eps, usually it can't receive full + * 188 bytes in a uframe, if it not assign full 188 bytes, + * can add another one; + */ + for (i = 0; i < sch_ep->num_budget_microframes; i++) { + k = XHCI_MTK_BW_INDEX(offset + i); + if (sch_ep->ep_type == ISOC_OUT_EP || sch_ep->ep_type == INT_OUT_EP) + tmp = tt->fs_bus_bw_out[k] + sch_ep->bw_budget_table[i]; + else /* ep_type : ISOC IN / INTR IN */ + tmp = tt->fs_bus_bw_in[k]; + + if (tmp > FS_PAYLOAD_MAX) + return -ESCH_BW_OVERFLOW; + } return 0; } -static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) +static int check_fs_budget_frames(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u32 head, tail; + int i, j, k; + + /* bugdet scheduled may cross at most two fs frames */ + j = XHCI_MTK_BW_INDEX(offset) / UFRAMES_PER_FRAME; + k = XHCI_MTK_BW_INDEX(offset + sch_ep->num_budget_microframes - 1) / UFRAMES_PER_FRAME; + + if (j != k) { + head = tt->fs_frame_bw[j]; + tail = tt->fs_frame_bw[k]; + } else { + head = tt->fs_frame_bw[j]; + tail = 0; + } + + j = roundup(offset, UFRAMES_PER_FRAME); + for (i = 0; i < sch_ep->num_budget_microframes; i++) { + if ((offset + i) < j) + head += sch_ep->bw_budget_table[i]; + else + tail += sch_ep->bw_budget_table[i]; + } + + if (head > FS_BW_BOUNDARY || tail > FS_BW_BOUNDARY) + return -ESCH_BW_OVERFLOW; + + return 0; +} + +static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + int i, base; + int ret = 0; + + for (i = 0; i < sch_ep->num_esit; i++) { + base = offset + i * sch_ep->esit; + + ret = check_ls_budget_microframes(sch_ep, base); + if (ret) + goto err; + + ret = check_fs_budget_microframes(sch_ep, base); + if (ret) + goto err; + + ret = check_fs_budget_frames(sch_ep, base); + if (ret) + goto err; + } + +err: + return ret; +} + +static int check_ss_and_cs(struct mu3h_sch_ep_info *sch_ep, u32 offset) { u32 start_ss, last_ss; u32 start_cs, last_cs; - if (!sch_ep->sch_tt) - return 0; - - start_ss = offset % 8; + start_ss = offset % UFRAMES_PER_FRAME; if (sch_ep->ep_type == ISOC_OUT_EP) { last_ss = start_ss + sch_ep->cs_count - 1; @@ -444,6 +600,7 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) return -ESCH_SS_Y6; } else { + /* maxpkt <= 1023, cs <= 6 */ u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); /* @@ -454,44 +611,164 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) return -ESCH_SS_Y6; /* one uframe for ss + one uframe for idle */ - start_cs = (start_ss + 2) % 8; + start_cs = (start_ss + CS_OFFSET) % UFRAMES_PER_FRAME; last_cs = start_cs + cs_count - 1; - if (last_cs > 7) return -ESCH_CS_OVERFLOW; + /* add extra-cs */ + cs_count += (last_cs == 7) ? 1 : 2; if (cs_count > 7) cs_count = 7; /* HW limit */ sch_ep->cs_count = cs_count; - /* ss, idle are ignored */ - sch_ep->num_budget_microframes = cs_count; - /* - * if interval=1, maxp >752, num_budge_micoframe is larger - * than sch_ep->esit, will overstep boundary - */ - if (sch_ep->num_budget_microframes > sch_ep->esit) - sch_ep->num_budget_microframes = sch_ep->esit; } + return 0; +} + +/* + * when isoc-out transfers 188 bytes in a uframe, and send isoc/intr's + * ss token in the uframe, may cause 'bit stuff error' in downstream + * port; + * when isoc-out transfer less than 188 bytes in a uframe, shall send + * isoc-in's ss after isoc-out's ss (but hw can't ensure the sequence, + * so just avoid overlap). + */ +static int check_isoc_ss_overlap(struct mu3h_sch_ep_info *sch_ep, u32 offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + int base; + int i, j, k; + + if (!tt) + return 0; + + for (i = 0; i < sch_ep->num_esit; i++) { + base = offset + i * sch_ep->esit; + + if (sch_ep->ep_type == ISOC_OUT_EP) { + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + k = XHCI_MTK_BW_INDEX(base + j + CS_OFFSET); + /* use cs to indicate existence of in-ss @(base+j) */ + if (tt->fs_bus_bw_in[k]) + return -ESCH_SS_OVERLAP; + } + } else if (sch_ep->ep_type == ISOC_IN_EP || sch_ep->ep_type == INT_IN_EP) { + k = XHCI_MTK_BW_INDEX(base); + /* only check IN's ss */ + if (tt->fs_bus_bw_out[k]) + return -ESCH_SS_OVERLAP; + } + } + + return 0; +} + +static int check_sch_tt_budget(struct mu3h_sch_ep_info *sch_ep, u32 offset) +{ + int ret; + + ret = check_ss_and_cs(sch_ep, offset); + if (ret) + return ret; + + ret = check_isoc_ss_overlap(sch_ep, offset); + if (ret) + return ret; + return check_fs_bus_bw(sch_ep, offset); } +/* allocate microframes in the ls/fs frame */ +static int alloc_sch_portion_of_frame(struct mu3h_sch_ep_info *sch_ep) +{ + struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info; + const u32 bw_boundary = get_bw_boundary(sch_ep->speed); + u32 bw_max, fs_bw_min; + u32 offset, offset_min; + u16 fs_bw; + int frames; + int i, j; + int ret; + + frames = sch_ep->esit / UFRAMES_PER_FRAME; + + for (i = 0; i < UFRAMES_PER_FRAME; i++) { + fs_bw_min = FS_PAYLOAD_MAX; + offset_min = XHCI_MTK_MAX_ESIT; + + for (j = 0; j < frames; j++) { + offset = (i + j * UFRAMES_PER_FRAME) % sch_ep->esit; + + ret = check_sch_tt_budget(sch_ep, offset); + if (ret) + continue; + + /* check hs bw domain */ + bw_max = get_max_bw(sch_bw, sch_ep, offset); + if (bw_max > bw_boundary) { + ret = -ESCH_BW_OVERFLOW; + continue; + } + + /* use best-fit between frames */ + fs_bw = get_fs_bw(sch_ep, offset); + if (fs_bw < fs_bw_min) { + fs_bw_min = fs_bw; + offset_min = offset; + } + + if (!fs_bw_min) + break; + } + + /* use first-fit between microframes in a frame */ + if (offset_min < XHCI_MTK_MAX_ESIT) + break; + } + + if (offset_min == XHCI_MTK_MAX_ESIT) + return -ESCH_BW_OVERFLOW; + + sch_ep->offset = offset_min; + + return 0; +} + static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; - int bw_updated; + u16 *fs_bus_bw; u32 base; - int i, j; + int i, j, k, f; - bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1); + if (sch_ep->ep_type == ISOC_OUT_EP || sch_ep->ep_type == INT_OUT_EP) + fs_bus_bw = tt->fs_bus_bw_out; + else + fs_bus_bw = tt->fs_bus_bw_in; for (i = 0; i < sch_ep->num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->num_budget_microframes; j++) - tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated; + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + k = XHCI_MTK_BW_INDEX(base + j); + f = k / UFRAMES_PER_FRAME; + if (used) { + if (sch_ep->speed == USB_SPEED_LOW) + tt->ls_bus_bw[k] += (u8)sch_ep->bw_budget_table[j]; + + fs_bus_bw[k] += (u16)sch_ep->bw_budget_table[j]; + tt->fs_frame_bw[f] += (u16)sch_ep->bw_budget_table[j]; + } else { + if (sch_ep->speed == USB_SPEED_LOW) + tt->ls_bus_bw[k] -= (u8)sch_ep->bw_budget_table[j]; + + fs_bus_bw[k] -= (u16)sch_ep->bw_budget_table[j]; + tt->fs_frame_bw[f] -= (u16)sch_ep->bw_budget_table[j]; + } + } } if (used) @@ -513,7 +790,8 @@ static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw, return 0; } -static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) +/* allocate microframes for hs/ss/ssp */ +static int alloc_sch_microframes(struct mu3h_sch_ep_info *sch_ep) { struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info; const u32 bw_boundary = get_bw_boundary(sch_ep->speed); @@ -521,16 +799,12 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) u32 worst_bw; u32 min_bw = ~0; int min_index = -1; - int ret = 0; /* * Search through all possible schedule microframes. * and find a microframe where its worst bandwidth is minimum. */ for (offset = 0; offset < sch_ep->esit; offset++) { - ret = check_sch_tt(sch_ep, offset); - if (ret) - continue; worst_bw = get_max_bw(sch_bw, sch_ep, offset); if (worst_bw > bw_boundary) @@ -540,21 +814,29 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) min_bw = worst_bw; min_index = offset; } - - /* use first-fit for LS/FS */ - if (sch_ep->sch_tt && min_index >= 0) - break; - - if (min_bw == 0) - break; } if (min_index < 0) - return ret ? ret : -ESCH_BW_OVERFLOW; + return -ESCH_BW_OVERFLOW; sch_ep->offset = min_index; - return load_ep_bw(sch_bw, sch_ep, true); + return 0; +} + +static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) +{ + int ret; + + if (sch_ep->sch_tt) + ret = alloc_sch_portion_of_frame(sch_ep); + else + ret = alloc_sch_microframes(sch_ep); + + if (ret) + return ret; + + return load_ep_bw(sch_ep->bw_info, sch_ep, true); } static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, @@ -651,7 +933,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); - sch_ep = create_sch_ep(mtk, udev, ep); + sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx); if (IS_ERR_OR_NULL(sch_ep)) return -ENOMEM; diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index faaaf05e36ce..865b55e23b15 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -30,12 +30,21 @@ #define XHCI_MTK_MAX_ESIT (1 << 6) #define XHCI_MTK_BW_INDEX(x) ((x) & (XHCI_MTK_MAX_ESIT - 1)) +#define UFRAMES_PER_FRAME 8 +#define XHCI_MTK_FRAMES_CNT (XHCI_MTK_MAX_ESIT / UFRAMES_PER_FRAME) + /** - * @fs_bus_bw: array to keep track of bandwidth already used for FS + * @fs_bus_bw_out: save bandwidth used by FS/LS OUT eps in each uframes + * @fs_bus_bw_in: save bandwidth used by FS/LS IN eps in each uframes + * @ls_bus_bw: save bandwidth used by LS eps in each uframes + * @fs_frame_bw: save bandwidth used by FS/LS eps in each FS frames * @ep_list: Endpoints using this TT */ struct mu3h_sch_tt { - u32 fs_bus_bw[XHCI_MTK_MAX_ESIT]; + u16 fs_bus_bw_out[XHCI_MTK_MAX_ESIT]; + u16 fs_bus_bw_in[XHCI_MTK_MAX_ESIT]; + u8 ls_bus_bw[XHCI_MTK_MAX_ESIT]; + u16 fs_frame_bw[XHCI_MTK_FRAMES_CNT]; struct list_head ep_list; }; @@ -58,7 +67,6 @@ struct mu3h_sch_bw_info { * @num_esit: number of @esit in a period * @num_budget_microframes: number of continuous uframes * (@repeat==1) scheduled within the interval - * @bw_cost_per_microframe: bandwidth cost per microframe * @hentry: hash table entry * @endpoint: linked into bandwidth domain which it belongs to * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to @@ -83,12 +91,12 @@ struct mu3h_sch_bw_info { * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets * according to @pkts and @repeat. normal mode is used by * default + * @bw_budget_table: table to record bandwidth budget per microframe */ struct mu3h_sch_ep_info { u32 esit; u32 num_esit; u32 num_budget_microframes; - u32 bw_cost_per_microframe; struct list_head endpoint; struct hlist_node hentry; struct list_head tt_endpoint; @@ -108,6 +116,7 @@ struct mu3h_sch_ep_info { u32 pkts; u32 cs_count; u32 burst_mode; + u32 bw_budget_table[]; }; #define MU3C_U3_PORT_MAX 4 diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b9ae5c2a2527..95ed9404f6f8 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -535,6 +535,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) /* xHC spec requires PCI devices to support D3hot and D3cold */ if (xhci->hci_version >= 0x120) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + else if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version >= 0x110) + xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, @@ -693,7 +695,9 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ pm_runtime_put_noidle(&dev->dev); - if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) + if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) + pm_runtime_forbid(&dev->dev); + else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) pm_runtime_allow(&dev->dev); dma_set_max_seg_size(&dev->dev, UINT_MAX); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 28218c8f1837..b93161374293 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -458,23 +458,38 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) int ret; if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { - clk_prepare_enable(xhci->clk); - clk_prepare_enable(xhci->reg_clk); + ret = clk_prepare_enable(xhci->clk); + if (ret) + return ret; + + ret = clk_prepare_enable(xhci->reg_clk); + if (ret) { + clk_disable_unprepare(xhci->clk); + return ret; + } } ret = xhci_priv_resume_quirk(hcd); if (ret) - return ret; + goto disable_clks; ret = xhci_resume(xhci, PMSG_RESUME); if (ret) - return ret; + goto disable_clks; pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; + +disable_clks: + if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { + clk_disable_unprepare(xhci->clk); + clk_disable_unprepare(xhci->reg_clk); + } + + return ret; } static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3e5dc0723a8f..f3b5e6345858 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -144,7 +144,7 @@ static void next_trb(struct xhci_hcd *xhci, struct xhci_segment **seg, union xhci_trb **trb) { - if (trb_is_link(*trb)) { + if (trb_is_link(*trb) || last_trb_on_seg(*seg, *trb)) { *seg = (*seg)->next; *trb = ((*seg)->trbs); } else { @@ -450,8 +450,9 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) * In the future we should distinguish between -ENODEV and -ETIMEDOUT * and try to recover a -ETIMEDOUT with a host controller reset. */ - ret = xhci_handshake(&xhci->op_regs->cmd_ring, - CMD_RING_RUNNING, 0, 5 * 1000 * 1000); + ret = xhci_handshake_check_state(xhci, &xhci->op_regs->cmd_ring, + CMD_RING_RUNNING, 0, 5 * 1000 * 1000, + XHCI_STATE_REMOVING); if (ret < 0) { xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret); xhci_halt(xhci); @@ -1879,7 +1880,6 @@ static void handle_port_status(struct xhci_hcd *xhci, if ((port_id <= 0) || (port_id > max_ports)) { xhci_warn(xhci, "Port change event with invalid port ID %d\n", port_id); - inc_deq(xhci, ir->event_ring); return; } @@ -1906,7 +1906,7 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_dbg(xhci, "Port change event, %d-%d, id %d, portsc: 0x%x\n", hcd->self.busnum, hcd_portnum + 1, port_id, portsc); - trace_xhci_handle_port_status(hcd_portnum, portsc); + trace_xhci_handle_port_status(port, portsc); if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); @@ -2007,8 +2007,6 @@ static void handle_port_status(struct xhci_hcd *xhci, } cleanup: - /* Update event ring dequeue pointer before dropping the lock */ - inc_deq(xhci, ir->event_ring); /* Don't make the USB core poll the roothub if we got a bad port status * change event. Besides, at that point we can't tell which roothub @@ -2884,13 +2882,6 @@ cleanup: trb_comp_code != COMP_MISSED_SERVICE_ERROR && trb_comp_code != COMP_NO_PING_RESPONSE_ERROR; - /* - * Do not update event ring dequeue pointer if we're in a loop - * processing missed tds. - */ - if (!handling_skipped_tds) - inc_deq(xhci, ir->event_ring); - /* * If ep->skip is set, it means there are missed tds on the * endpoint ring need to take care of. @@ -2922,9 +2913,7 @@ err_out: static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir) { union xhci_trb *event; - int update_ptrs = 1; u32 trb_type; - int ret; /* Event ring hasn't been allocated yet. */ if (!ir || !ir->event_ring || !ir->event_ring->dequeue) { @@ -2954,12 +2943,9 @@ static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir) break; case TRB_PORT_STATUS: handle_port_status(xhci, ir, event); - update_ptrs = 0; break; case TRB_TRANSFER: - ret = handle_tx_event(xhci, ir, &event->trans_event); - if (ret >= 0) - update_ptrs = 0; + handle_tx_event(xhci, ir, &event->trans_event); break; case TRB_DEV_NOTE: handle_device_notification(xhci, event); @@ -2979,9 +2965,8 @@ static int xhci_handle_event(struct xhci_hcd *xhci, struct xhci_interrupter *ir) return 0; } - if (update_ptrs) - /* Update SW event ring dequeue pointer */ - inc_deq(xhci, ir->event_ring); + /* Update SW event ring dequeue pointer */ + inc_deq(xhci, ir->event_ring); /* Are there more items on the event ring? Caller will call us again to * check. @@ -3013,13 +2998,12 @@ static void xhci_update_erst_dequeue(struct xhci_hcd *xhci, * Per 4.9.4, Software writes to the ERDP register shall * always advance the Event Ring Dequeue Pointer value. */ - if ((temp_64 & (u64) ~ERST_PTR_MASK) == - ((u64) deq & (u64) ~ERST_PTR_MASK)) + if ((temp_64 & ERST_PTR_MASK) == (deq & ERST_PTR_MASK)) return; /* Update HC event ring dequeue pointer */ - temp_64 &= ERST_DESI_MASK; - temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK); + temp_64 = ir->event_ring->deq_seg->num & ERST_DESI_MASK; + temp_64 |= deq & ERST_PTR_MASK; } /* Clear the event handler busy flag (RW1C) */ diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index d6b32f2ad90e..ac47b1c0544a 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -509,35 +509,38 @@ DEFINE_EVENT(xhci_log_ring, xhci_inc_deq, ); DECLARE_EVENT_CLASS(xhci_log_portsc, - TP_PROTO(u32 portnum, u32 portsc), - TP_ARGS(portnum, portsc), + TP_PROTO(struct xhci_port *port, u32 portsc), + TP_ARGS(port, portsc), TP_STRUCT__entry( + __field(u32, busnum) __field(u32, portnum) __field(u32, portsc) ), TP_fast_assign( - __entry->portnum = portnum; + __entry->busnum = port->rhub->hcd->self.busnum; + __entry->portnum = port->hcd_portnum; __entry->portsc = portsc; ), - TP_printk("port-%d: %s", + TP_printk("port %d-%d: %s", + __entry->busnum, __entry->portnum, xhci_decode_portsc(__get_buf(XHCI_MSG_MAX), __entry->portsc) ) ); DEFINE_EVENT(xhci_log_portsc, xhci_handle_port_status, - TP_PROTO(u32 portnum, u32 portsc), - TP_ARGS(portnum, portsc) + TP_PROTO(struct xhci_port *port, u32 portsc), + TP_ARGS(port, portsc) ); DEFINE_EVENT(xhci_log_portsc, xhci_get_port_status, - TP_PROTO(u32 portnum, u32 portsc), - TP_ARGS(portnum, portsc) + TP_PROTO(struct xhci_port *port, u32 portsc), + TP_ARGS(port, portsc) ); DEFINE_EVENT(xhci_log_portsc, xhci_hub_status_data, - TP_PROTO(u32 portnum, u32 portsc), - TP_ARGS(portnum, portsc) + TP_PROTO(struct xhci_port *port, u32 portsc), + TP_ARGS(port, portsc) ); DECLARE_EVENT_CLASS(xhci_log_doorbell, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e1b1b64a0723..884b0898d9c9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -81,6 +81,29 @@ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us) return ret; } +/* + * xhci_handshake_check_state - same as xhci_handshake but takes an additional + * exit_state parameter, and bails out with an error immediately when xhc_state + * has exit_state flag set. + */ +int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr, + u32 mask, u32 done, int usec, unsigned int exit_state) +{ + u32 result; + int ret; + + ret = readl_poll_timeout_atomic(ptr, result, + (result & mask) == done || + result == U32_MAX || + xhci->xhc_state & exit_state, + 1, usec); + + if (result == U32_MAX || xhci->xhc_state & exit_state) + return -ENODEV; + + return ret; +} + /* * Disable interrupts and begin the xHCI halting process. */ @@ -201,7 +224,8 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us) if (xhci->quirks & XHCI_INTEL_HOST) udelay(1000); - ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us); + ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command, + CMD_RESET, 0, timeout_us, XHCI_STATE_REMOVING); if (ret) return ret; @@ -520,7 +544,7 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_run"); temp_64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue); - temp_64 &= ~ERST_PTR_MASK; + temp_64 &= ERST_PTR_MASK; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "ERST deq = 64'h%0lx", (long unsigned int) temp_64); @@ -968,6 +992,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg) int retval = 0; bool comp_timer_running = false; bool pending_portevent = false; + bool suspended_usb3_devs = false; bool reinit_xhc = false; if (!hcd->state) @@ -1115,10 +1140,17 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg) /* * Resume roothubs only if there are pending events. * USB 3 devices resend U3 LFPS wake after a 100ms delay if - * the first wake signalling failed, give it that chance. + * the first wake signalling failed, give it that chance if + * there are suspended USB 3 devices. */ + if (xhci->usb3_rhub.bus_state.suspended_ports || + xhci->usb3_rhub.bus_state.bus_suspended) + suspended_usb3_devs = true; + pending_portevent = xhci_pending_portevent(xhci); - if (!pending_portevent && msg.event == PM_EVENT_AUTO_RESUME) { + + if (suspended_usb3_devs && !pending_portevent && + msg.event == PM_EVENT_AUTO_RESUME) { msleep(120); pending_portevent = xhci_pending_portevent(xhci); } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3d0451f5880a..3ea5c092bba7 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -525,7 +525,7 @@ struct xhci_intr_reg { * a work queue (or delayed service routine)? */ #define ERST_EHB (1 << 3) -#define ERST_PTR_MASK (0xf) +#define ERST_PTR_MASK (GENMASK_ULL(63, 4)) /** * struct xhci_run_regs @@ -558,33 +558,6 @@ struct xhci_doorbell_array { #define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16)) #define DB_VALUE_HOST 0x00000000 -/** - * struct xhci_protocol_caps - * @revision: major revision, minor revision, capability ID, - * and next capability pointer. - * @name_string: Four ASCII characters to say which spec this xHC - * follows, typically "USB ". - * @port_info: Port offset, count, and protocol-defined information. - */ -struct xhci_protocol_caps { - u32 revision; - u32 name_string; - u32 port_info; -}; - -#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff) -#define XHCI_EXT_PORT_MINOR(x) (((x) >> 16) & 0xff) -#define XHCI_EXT_PORT_PSIC(x) (((x) >> 28) & 0x0f) -#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff) -#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff) - -#define XHCI_EXT_PORT_PSIV(x) (((x) >> 0) & 0x0f) -#define XHCI_EXT_PORT_PSIE(x) (((x) >> 4) & 0x03) -#define XHCI_EXT_PORT_PLT(x) (((x) >> 6) & 0x03) -#define XHCI_EXT_PORT_PFD(x) (((x) >> 8) & 0x01) -#define XHCI_EXT_PORT_LP(x) (((x) >> 14) & 0x03) -#define XHCI_EXT_PORT_PSIM(x) (((x) >> 16) & 0xffff) - #define PLT_MASK (0x03 << 6) #define PLT_SYM (0x00 << 6) #define PLT_ASYM_RX (0x02 << 6) @@ -1545,6 +1518,7 @@ struct xhci_segment { union xhci_trb *trbs; /* private to HCD */ struct xhci_segment *next; + unsigned int num; dma_addr_t dma; /* Max packet sized bounce buffer for td-fragmant alignment */ dma_addr_t bounce_dma; @@ -1669,12 +1643,8 @@ struct urb_priv { struct xhci_td td[] __counted_by(num_tds); }; -/* - * Each segment table entry is 4*32bits long. 1K seems like an ok size: - * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, - * meaning 64 ring segments. - * Initial allocated size of the ERST, in number of entries */ -#define ERST_NUM_SEGS 1 +/* Reasonable limit for number of Event Ring segments (spec allows 32k) */ +#define ERST_MAX_SEGS 2 /* Poll every 60 seconds */ #define POLL_TIMEOUT 60 /* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */ @@ -2078,13 +2048,8 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, unsigned int num_trbs, gfp_t flags); -int xhci_alloc_erst(struct xhci_hcd *xhci, - struct xhci_ring *evt_ring, - struct xhci_erst *erst, - gfp_t flags); void xhci_initialize_ring_info(struct xhci_ring *ring, unsigned int cycle_state); -void xhci_free_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); void xhci_free_endpoint_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index); @@ -2119,6 +2084,8 @@ void xhci_free_container_ctx(struct xhci_hcd *xhci, /* xHCI host controller glue */ typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us); +int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr, + u32 mask, u32 done, int usec, unsigned int exit_state); void xhci_quiesce(struct xhci_hcd *xhci); int xhci_halt(struct xhci_hcd *xhci); int xhci_start(struct xhci_hcd *xhci); diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 99b15b77dfd5..c510af7baa0d 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -165,6 +165,19 @@ config APPLE_MFI_FASTCHARGE It is safe to say M here. +config USB_LJCA + tristate "Intel La Jolla Cove Adapter support" + select AUXILIARY_BUS + depends on USB && ACPI + help + This adds support for Intel La Jolla Cove USB-I2C/SPI/GPIO + Master Adapter (LJCA). Additional drivers such as I2C_LJCA, + GPIO_LJCA and SPI_LJCA must be enabled in order to use the + functionality of the device. + + This driver can also be built as a module. If so, the module + will be called usb-ljca. + source "drivers/usb/misc/sisusbvga/Kconfig" config USB_LD diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 1992cc284d8a..0bc732bcb162 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_USB_EMI26) += emi26.o obj-$(CONFIG_USB_EMI62) += emi62.o obj-$(CONFIG_USB_EZUSB_FX2) += ezusb.o obj-$(CONFIG_APPLE_MFI_FASTCHARGE) += apple-mfi-fastcharge.o +obj-$(CONFIG_USB_LJCA) += usb-ljca.o obj-$(CONFIG_USB_IDMOUSE) += idmouse.o obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c index 57bbe1309094..a341b2fbb7b4 100644 --- a/drivers/usb/misc/onboard_usb_hub.c +++ b/drivers/usb/misc/onboard_usb_hub.c @@ -240,7 +240,6 @@ static void onboard_hub_attach_usb_driver(struct work_struct *work) static int onboard_hub_probe(struct platform_device *pdev) { - const struct of_device_id *of_id; struct device *dev = &pdev->dev; struct onboard_hub *hub; unsigned int i; @@ -250,11 +249,7 @@ static int onboard_hub_probe(struct platform_device *pdev) if (!hub) return -ENOMEM; - of_id = of_match_device(onboard_hub_match, &pdev->dev); - if (!of_id) - return -ENODEV; - - hub->pdata = of_id->data; + hub->pdata = device_get_match_data(&pdev->dev); if (!hub->pdata) return -EINVAL; diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_hub.h index 2a4ab5ac0ebe..c4e24a7b9290 100644 --- a/drivers/usb/misc/onboard_usb_hub.h +++ b/drivers/usb/misc/onboard_usb_hub.h @@ -57,6 +57,7 @@ static const struct of_device_id onboard_hub_match[] = { { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, { .compatible = "usb5e3,610", .data = &genesys_gl852g_data, }, { .compatible = "usb5e3,620", .data = &genesys_gl852g_data, }, + { .compatible = "usb5e3,626", .data = &genesys_gl852g_data, }, { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,414", .data = &realtek_rts5411_data, }, diff --git a/drivers/usb/misc/usb-ljca.c b/drivers/usb/misc/usb-ljca.c new file mode 100644 index 000000000000..c9decd0396d4 --- /dev/null +++ b/drivers/usb/misc/usb-ljca.c @@ -0,0 +1,902 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel La Jolla Cove Adapter USB driver + * + * Copyright (c) 2023, Intel Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* command flags */ +#define LJCA_ACK_FLAG BIT(0) +#define LJCA_RESP_FLAG BIT(1) +#define LJCA_CMPL_FLAG BIT(2) + +#define LJCA_MAX_PACKET_SIZE 64u +#define LJCA_MAX_PAYLOAD_SIZE \ + (LJCA_MAX_PACKET_SIZE - sizeof(struct ljca_msg)) + +#define LJCA_WRITE_TIMEOUT_MS 200 +#define LJCA_WRITE_ACK_TIMEOUT_MS 500 +#define LJCA_ENUM_CLIENT_TIMEOUT_MS 20 + +/* ljca client type */ +enum ljca_client_type { + LJCA_CLIENT_MNG = 1, + LJCA_CLIENT_GPIO = 3, + LJCA_CLIENT_I2C = 4, + LJCA_CLIENT_SPI = 5, +}; + +/* MNG client commands */ +enum ljca_mng_cmd { + LJCA_MNG_RESET = 2, + LJCA_MNG_ENUM_GPIO = 4, + LJCA_MNG_ENUM_I2C = 5, + LJCA_MNG_ENUM_SPI = 8, +}; + +/* ljca client acpi _ADR */ +enum ljca_client_acpi_adr { + LJCA_GPIO_ACPI_ADR, + LJCA_I2C1_ACPI_ADR, + LJCA_I2C2_ACPI_ADR, + LJCA_SPI1_ACPI_ADR, + LJCA_SPI2_ACPI_ADR, + LJCA_CLIENT_ACPI_ADR_MAX, +}; + +/* ljca cmd message structure */ +struct ljca_msg { + u8 type; + u8 cmd; + u8 flags; + u8 len; + u8 data[] __counted_by(len); +} __packed; + +struct ljca_i2c_ctr_info { + u8 id; + u8 capacity; + u8 intr_pin; +} __packed; + +struct ljca_i2c_descriptor { + u8 num; + struct ljca_i2c_ctr_info info[] __counted_by(num); +} __packed; + +struct ljca_spi_ctr_info { + u8 id; + u8 capacity; + u8 intr_pin; +} __packed; + +struct ljca_spi_descriptor { + u8 num; + struct ljca_spi_ctr_info info[] __counted_by(num); +} __packed; + +struct ljca_bank_descriptor { + u8 bank_id; + u8 pin_num; + + /* 1 bit for each gpio, 1 means valid */ + __le32 valid_pins; +} __packed; + +struct ljca_gpio_descriptor { + u8 pins_per_bank; + u8 bank_num; + struct ljca_bank_descriptor bank_desc[] __counted_by(bank_num); +} __packed; + +/** + * struct ljca_adapter - represent a ljca adapter + * + * @intf: the usb interface for this ljca adapter + * @usb_dev: the usb device for this ljca adapter + * @dev: the specific device info of the usb interface + * @rx_pipe: bulk in pipe for receive data from firmware + * @tx_pipe: bulk out pipe for send data to firmware + * @rx_urb: urb used for the bulk in pipe + * @rx_buf: buffer used to receive command response and event + * @rx_len: length of rx buffer + * @ex_buf: external buffer to save command response + * @ex_buf_len: length of external buffer + * @actual_length: actual length of data copied to external buffer + * @tx_buf: buffer used to download command to firmware + * @tx_buf_len: length of tx buffer + * @lock: spinlock to protect tx_buf and ex_buf + * @cmd_completion: completion object as the command receives ack + * @mutex: mutex to avoid command download concurrently + * @client_list: client device list + * @disconnect: usb disconnect ongoing or not + * @reset_id: used to reset firmware + */ +struct ljca_adapter { + struct usb_interface *intf; + struct usb_device *usb_dev; + struct device *dev; + + unsigned int rx_pipe; + unsigned int tx_pipe; + + struct urb *rx_urb; + void *rx_buf; + unsigned int rx_len; + + u8 *ex_buf; + u8 ex_buf_len; + u8 actual_length; + + void *tx_buf; + u8 tx_buf_len; + + spinlock_t lock; + + struct completion cmd_completion; + struct mutex mutex; + + struct list_head client_list; + + bool disconnect; + + u32 reset_id; +}; + +struct ljca_match_ids_walk_data { + const struct acpi_device_id *ids; + const char *uid; + struct acpi_device *adev; +}; + +static const struct acpi_device_id ljca_gpio_hids[] = { + { "INTC1074" }, + { "INTC1096" }, + { "INTC100B" }, + { "INTC10D1" }, + {}, +}; + +static const struct acpi_device_id ljca_i2c_hids[] = { + { "INTC1075" }, + { "INTC1097" }, + { "INTC100C" }, + { "INTC10D2" }, + {}, +}; + +static const struct acpi_device_id ljca_spi_hids[] = { + { "INTC1091" }, + { "INTC1098" }, + { "INTC100D" }, + { "INTC10D3" }, + {}, +}; + +static void ljca_handle_event(struct ljca_adapter *adap, + struct ljca_msg *header) +{ + struct ljca_client *client; + + list_for_each_entry(client, &adap->client_list, link) { + /* + * Currently only GPIO register event callback, but + * firmware message structure should include id when + * multiple same type clients register event callback. + */ + if (client->type == header->type) { + unsigned long flags; + + spin_lock_irqsave(&client->event_cb_lock, flags); + client->event_cb(client->context, header->cmd, + header->data, header->len); + spin_unlock_irqrestore(&client->event_cb_lock, flags); + + break; + } + } +} + +/* process command ack and received data if available */ +static void ljca_handle_cmd_ack(struct ljca_adapter *adap, struct ljca_msg *header) +{ + struct ljca_msg *tx_header = adap->tx_buf; + u8 ibuf_len, actual_len = 0; + unsigned long flags; + u8 *ibuf; + + spin_lock_irqsave(&adap->lock, flags); + + if (tx_header->type != header->type || tx_header->cmd != header->cmd) { + spin_unlock_irqrestore(&adap->lock, flags); + dev_err(adap->dev, "cmd ack mismatch error\n"); + return; + } + + ibuf_len = adap->ex_buf_len; + ibuf = adap->ex_buf; + + if (ibuf && ibuf_len) { + actual_len = min(header->len, ibuf_len); + + /* copy received data to external buffer */ + memcpy(ibuf, header->data, actual_len); + } + /* update copied data length */ + adap->actual_length = actual_len; + + spin_unlock_irqrestore(&adap->lock, flags); + + complete(&adap->cmd_completion); +} + +static void ljca_recv(struct urb *urb) +{ + struct ljca_msg *header = urb->transfer_buffer; + struct ljca_adapter *adap = urb->context; + int ret; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ENOENT: + /* + * directly complete the possible ongoing transfer + * during disconnect + */ + if (adap->disconnect) + complete(&adap->cmd_completion); + return; + case -ECONNRESET: + case -ESHUTDOWN: + case -EPIPE: + /* rx urb is terminated */ + dev_dbg(adap->dev, "rx urb terminated with status: %d\n", + urb->status); + return; + default: + dev_dbg(adap->dev, "rx urb error: %d\n", urb->status); + goto resubmit; + } + + if (header->len + sizeof(*header) != urb->actual_length) + goto resubmit; + + if (header->flags & LJCA_ACK_FLAG) + ljca_handle_cmd_ack(adap, header); + else + ljca_handle_event(adap, header); + +resubmit: + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret && ret != -EPERM) + dev_err(adap->dev, "resubmit rx urb error %d\n", ret); +} + +static int ljca_send(struct ljca_adapter *adap, u8 type, u8 cmd, + const u8 *obuf, u8 obuf_len, u8 *ibuf, u8 ibuf_len, + bool ack, unsigned long timeout) +{ + unsigned int msg_len = sizeof(struct ljca_msg) + obuf_len; + struct ljca_msg *header = adap->tx_buf; + unsigned int transferred; + unsigned long flags; + int ret; + + if (adap->disconnect) + return -ENODEV; + + if (msg_len > adap->tx_buf_len) + return -EINVAL; + + mutex_lock(&adap->mutex); + + spin_lock_irqsave(&adap->lock, flags); + + header->type = type; + header->cmd = cmd; + header->len = obuf_len; + if (obuf) + memcpy(header->data, obuf, obuf_len); + + header->flags = LJCA_CMPL_FLAG | (ack ? LJCA_ACK_FLAG : 0); + + adap->ex_buf = ibuf; + adap->ex_buf_len = ibuf_len; + adap->actual_length = 0; + + spin_unlock_irqrestore(&adap->lock, flags); + + reinit_completion(&adap->cmd_completion); + + ret = usb_autopm_get_interface(adap->intf); + if (ret < 0) + goto out; + + ret = usb_bulk_msg(adap->usb_dev, adap->tx_pipe, header, + msg_len, &transferred, LJCA_WRITE_TIMEOUT_MS); + + usb_autopm_put_interface(adap->intf); + + if (ret < 0) + goto out; + if (transferred != msg_len) { + ret = -EIO; + goto out; + } + + if (ack) { + ret = wait_for_completion_timeout(&adap->cmd_completion, + timeout); + if (!ret) { + ret = -ETIMEDOUT; + goto out; + } + } + ret = adap->actual_length; + +out: + spin_lock_irqsave(&adap->lock, flags); + adap->ex_buf = NULL; + adap->ex_buf_len = 0; + + memset(header, 0, sizeof(*header)); + spin_unlock_irqrestore(&adap->lock, flags); + + mutex_unlock(&adap->mutex); + + return ret; +} + +int ljca_transfer(struct ljca_client *client, u8 cmd, const u8 *obuf, + u8 obuf_len, u8 *ibuf, u8 ibuf_len) +{ + return ljca_send(client->adapter, client->type, cmd, + obuf, obuf_len, ibuf, ibuf_len, true, + LJCA_WRITE_ACK_TIMEOUT_MS); +} +EXPORT_SYMBOL_NS_GPL(ljca_transfer, LJCA); + +int ljca_transfer_noack(struct ljca_client *client, u8 cmd, const u8 *obuf, + u8 obuf_len) +{ + return ljca_send(client->adapter, client->type, cmd, obuf, + obuf_len, NULL, 0, false, LJCA_WRITE_ACK_TIMEOUT_MS); +} +EXPORT_SYMBOL_NS_GPL(ljca_transfer_noack, LJCA); + +int ljca_register_event_cb(struct ljca_client *client, ljca_event_cb_t event_cb, + void *context) +{ + unsigned long flags; + + if (!event_cb) + return -EINVAL; + + spin_lock_irqsave(&client->event_cb_lock, flags); + + if (client->event_cb) { + spin_unlock_irqrestore(&client->event_cb_lock, flags); + return -EALREADY; + } + + client->event_cb = event_cb; + client->context = context; + + spin_unlock_irqrestore(&client->event_cb_lock, flags); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(ljca_register_event_cb, LJCA); + +void ljca_unregister_event_cb(struct ljca_client *client) +{ + unsigned long flags; + + spin_lock_irqsave(&client->event_cb_lock, flags); + + client->event_cb = NULL; + client->context = NULL; + + spin_unlock_irqrestore(&client->event_cb_lock, flags); +} +EXPORT_SYMBOL_NS_GPL(ljca_unregister_event_cb, LJCA); + +static int ljca_match_device_ids(struct acpi_device *adev, void *data) +{ + struct ljca_match_ids_walk_data *wd = data; + const char *uid = acpi_device_uid(adev); + + if (acpi_match_device_ids(adev, wd->ids)) + return 0; + + if (!wd->uid) + goto match; + + if (!uid) + /* + * Some DSDTs have only one ACPI companion for the two I2C + * controllers and they don't set a UID at all (e.g. Dell + * Latitude 9420). On these platforms only the first I2C + * controller is used, so if a HID match has no UID we use + * "0" as the UID and assign ACPI companion to the first + * I2C controller. + */ + uid = "0"; + else + uid = strchr(uid, wd->uid[0]); + + if (!uid || strcmp(uid, wd->uid)) + return 0; + +match: + wd->adev = adev; + + return 1; +} + +/* bind auxiliary device to acpi device */ +static void ljca_auxdev_acpi_bind(struct ljca_adapter *adap, + struct auxiliary_device *auxdev, + u64 adr, u8 id) +{ + struct ljca_match_ids_walk_data wd = { 0 }; + struct acpi_device *parent, *adev; + struct device *dev = adap->dev; + char uid[4]; + + parent = ACPI_COMPANION(dev); + if (!parent) + return; + + /* + * get auxdev ACPI handle from the ACPI device directly + * under the parent that matches _ADR. + */ + adev = acpi_find_child_device(parent, adr, false); + if (adev) { + ACPI_COMPANION_SET(&auxdev->dev, adev); + return; + } + + /* + * _ADR is a grey area in the ACPI specification, some + * platforms use _HID to distinguish children devices. + */ + switch (adr) { + case LJCA_GPIO_ACPI_ADR: + wd.ids = ljca_gpio_hids; + break; + case LJCA_I2C1_ACPI_ADR: + case LJCA_I2C2_ACPI_ADR: + snprintf(uid, sizeof(uid), "%d", id); + wd.uid = uid; + wd.ids = ljca_i2c_hids; + break; + case LJCA_SPI1_ACPI_ADR: + case LJCA_SPI2_ACPI_ADR: + wd.ids = ljca_spi_hids; + break; + default: + dev_warn(dev, "unsupported _ADR\n"); + return; + } + + acpi_dev_for_each_child(parent, ljca_match_device_ids, &wd); + if (wd.adev) { + ACPI_COMPANION_SET(&auxdev->dev, wd.adev); + return; + } + + parent = ACPI_COMPANION(dev->parent->parent); + if (!parent) + return; + + acpi_dev_for_each_child(parent, ljca_match_device_ids, &wd); + if (wd.adev) + ACPI_COMPANION_SET(&auxdev->dev, wd.adev); +} + +static void ljca_auxdev_release(struct device *dev) +{ + struct auxiliary_device *auxdev = to_auxiliary_dev(dev); + + kfree(auxdev->dev.platform_data); +} + +static int ljca_new_client_device(struct ljca_adapter *adap, u8 type, u8 id, + char *name, void *data, u64 adr) +{ + struct auxiliary_device *auxdev; + struct ljca_client *client; + int ret; + + client = kzalloc(sizeof *client, GFP_KERNEL); + if (!client) + return -ENOMEM; + + client->type = type; + client->id = id; + client->adapter = adap; + spin_lock_init(&client->event_cb_lock); + + auxdev = &client->auxdev; + auxdev->name = name; + auxdev->id = id; + + auxdev->dev.parent = adap->dev; + auxdev->dev.platform_data = data; + auxdev->dev.release = ljca_auxdev_release; + + ret = auxiliary_device_init(auxdev); + if (ret) + goto err_free; + + ljca_auxdev_acpi_bind(adap, auxdev, adr, id); + + ret = auxiliary_device_add(auxdev); + if (ret) + goto err_uninit; + + list_add_tail(&client->link, &adap->client_list); + + return 0; + +err_uninit: + auxiliary_device_uninit(auxdev); + +err_free: + kfree(client); + + return ret; +} + +static int ljca_enumerate_gpio(struct ljca_adapter *adap) +{ + u32 valid_pin[LJCA_MAX_GPIO_NUM / BITS_PER_TYPE(u32)]; + struct ljca_gpio_descriptor *desc; + struct ljca_gpio_info *gpio_info; + u8 buf[LJCA_MAX_PAYLOAD_SIZE]; + int ret, gpio_num; + unsigned int i; + + ret = ljca_send(adap, LJCA_CLIENT_MNG, LJCA_MNG_ENUM_GPIO, NULL, 0, buf, + sizeof(buf), true, LJCA_ENUM_CLIENT_TIMEOUT_MS); + if (ret < 0) + return ret; + + /* check firmware response */ + desc = (struct ljca_gpio_descriptor *)buf; + if (ret != struct_size(desc, bank_desc, desc->bank_num)) + return -EINVAL; + + gpio_num = desc->pins_per_bank * desc->bank_num; + if (gpio_num > LJCA_MAX_GPIO_NUM) + return -EINVAL; + + /* construct platform data */ + gpio_info = kzalloc(sizeof *gpio_info, GFP_KERNEL); + if (!gpio_info) + return -ENOMEM; + gpio_info->num = gpio_num; + + for (i = 0; i < desc->bank_num; i++) + valid_pin[i] = get_unaligned_le32(&desc->bank_desc[i].valid_pins); + bitmap_from_arr32(gpio_info->valid_pin_map, valid_pin, gpio_num); + + ret = ljca_new_client_device(adap, LJCA_CLIENT_GPIO, 0, "ljca-gpio", + gpio_info, LJCA_GPIO_ACPI_ADR); + if (ret) + kfree(gpio_info); + + return ret; +} + +static int ljca_enumerate_i2c(struct ljca_adapter *adap) +{ + struct ljca_i2c_descriptor *desc; + struct ljca_i2c_info *i2c_info; + u8 buf[LJCA_MAX_PAYLOAD_SIZE]; + unsigned int i; + int ret; + + ret = ljca_send(adap, LJCA_CLIENT_MNG, LJCA_MNG_ENUM_I2C, NULL, 0, buf, + sizeof(buf), true, LJCA_ENUM_CLIENT_TIMEOUT_MS); + if (ret < 0) + return ret; + + /* check firmware response */ + desc = (struct ljca_i2c_descriptor *)buf; + if (ret != struct_size(desc, info, desc->num)) + return -EINVAL; + + for (i = 0; i < desc->num; i++) { + /* construct platform data */ + i2c_info = kzalloc(sizeof *i2c_info, GFP_KERNEL); + if (!i2c_info) + return -ENOMEM; + + i2c_info->id = desc->info[i].id; + i2c_info->capacity = desc->info[i].capacity; + i2c_info->intr_pin = desc->info[i].intr_pin; + + ret = ljca_new_client_device(adap, LJCA_CLIENT_I2C, i, + "ljca-i2c", i2c_info, + LJCA_I2C1_ACPI_ADR + i); + if (ret) { + kfree(i2c_info); + return ret; + } + } + + return 0; +} + +static int ljca_enumerate_spi(struct ljca_adapter *adap) +{ + struct ljca_spi_descriptor *desc; + struct ljca_spi_info *spi_info; + u8 buf[LJCA_MAX_PAYLOAD_SIZE]; + unsigned int i; + int ret; + + ret = ljca_send(adap, LJCA_CLIENT_MNG, LJCA_MNG_ENUM_SPI, NULL, 0, buf, + sizeof(buf), true, LJCA_ENUM_CLIENT_TIMEOUT_MS); + if (ret < 0) + return ret; + + /* check firmware response */ + desc = (struct ljca_spi_descriptor *)buf; + if (ret != struct_size(desc, info, desc->num)) + return -EINVAL; + + for (i = 0; i < desc->num; i++) { + /* construct platform data */ + spi_info = kzalloc(sizeof *spi_info, GFP_KERNEL); + if (!spi_info) + return -ENOMEM; + + spi_info->id = desc->info[i].id; + spi_info->capacity = desc->info[i].capacity; + + ret = ljca_new_client_device(adap, LJCA_CLIENT_SPI, i, + "ljca-spi", spi_info, + LJCA_SPI1_ACPI_ADR + i); + if (ret) { + kfree(spi_info); + return ret; + } + } + + return 0; +} + +static int ljca_reset_handshake(struct ljca_adapter *adap) +{ + __le32 reset_id = cpu_to_le32(adap->reset_id); + __le32 reset_id_ret = 0; + int ret; + + adap->reset_id++; + + ret = ljca_send(adap, LJCA_CLIENT_MNG, LJCA_MNG_RESET, (u8 *)&reset_id, + sizeof(__le32), (u8 *)&reset_id_ret, sizeof(__le32), + true, LJCA_WRITE_ACK_TIMEOUT_MS); + if (ret < 0) + return ret; + + if (reset_id_ret != reset_id) + return -EINVAL; + + return 0; +} + +static int ljca_enumerate_clients(struct ljca_adapter *adap) +{ + struct ljca_client *client, *next; + int ret; + + ret = ljca_reset_handshake(adap); + if (ret) + goto err_kill; + + ret = ljca_enumerate_gpio(adap); + if (ret) { + dev_err(adap->dev, "enumerate GPIO error\n"); + goto err_kill; + } + + ret = ljca_enumerate_i2c(adap); + if (ret) { + dev_err(adap->dev, "enumerate I2C error\n"); + goto err_kill; + } + + ret = ljca_enumerate_spi(adap); + if (ret) { + dev_err(adap->dev, "enumerate SPI error\n"); + goto err_kill; + } + + return 0; + +err_kill: + adap->disconnect = true; + + usb_kill_urb(adap->rx_urb); + + list_for_each_entry_safe_reverse(client, next, &adap->client_list, link) { + auxiliary_device_delete(&client->auxdev); + auxiliary_device_uninit(&client->auxdev); + + list_del_init(&client->link); + kfree(client); + } + + return ret; +} + +static int ljca_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *usb_dev = interface_to_usbdev(interface); + struct usb_host_interface *alt = interface->cur_altsetting; + struct usb_endpoint_descriptor *ep_in, *ep_out; + struct device *dev = &interface->dev; + struct ljca_adapter *adap; + int ret; + + adap = devm_kzalloc(dev, sizeof(*adap), GFP_KERNEL); + if (!adap) + return -ENOMEM; + + /* separate tx buffer allocation for alignment */ + adap->tx_buf = devm_kzalloc(dev, LJCA_MAX_PACKET_SIZE, GFP_KERNEL); + if (!adap->tx_buf) + return -ENOMEM; + adap->tx_buf_len = LJCA_MAX_PACKET_SIZE; + + mutex_init(&adap->mutex); + spin_lock_init(&adap->lock); + init_completion(&adap->cmd_completion); + INIT_LIST_HEAD(&adap->client_list); + + adap->intf = usb_get_intf(interface); + adap->usb_dev = usb_dev; + adap->dev = dev; + + /* + * find the first bulk in and out endpoints. + * ignore any others. + */ + ret = usb_find_common_endpoints(alt, &ep_in, &ep_out, NULL, NULL); + if (ret) { + dev_err(dev, "bulk endpoints not found\n"); + goto err_put; + } + adap->rx_pipe = usb_rcvbulkpipe(usb_dev, usb_endpoint_num(ep_in)); + adap->tx_pipe = usb_sndbulkpipe(usb_dev, usb_endpoint_num(ep_out)); + + /* setup rx buffer */ + adap->rx_len = usb_endpoint_maxp(ep_in); + adap->rx_buf = devm_kzalloc(dev, adap->rx_len, GFP_KERNEL); + if (!adap->rx_buf) { + ret = -ENOMEM; + goto err_put; + } + + /* alloc rx urb */ + adap->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adap->rx_urb) { + ret = -ENOMEM; + goto err_put; + } + usb_fill_bulk_urb(adap->rx_urb, usb_dev, adap->rx_pipe, + adap->rx_buf, adap->rx_len, ljca_recv, adap); + + usb_set_intfdata(interface, adap); + + /* submit rx urb before enumerate clients */ + ret = usb_submit_urb(adap->rx_urb, GFP_KERNEL); + if (ret) { + dev_err(dev, "submit rx urb failed: %d\n", ret); + goto err_free; + } + + ret = ljca_enumerate_clients(adap); + if (ret) + goto err_free; + + usb_enable_autosuspend(usb_dev); + + return 0; + +err_free: + usb_free_urb(adap->rx_urb); + +err_put: + usb_put_intf(adap->intf); + + mutex_destroy(&adap->mutex); + + return ret; +} + +static void ljca_disconnect(struct usb_interface *interface) +{ + struct ljca_adapter *adap = usb_get_intfdata(interface); + struct ljca_client *client, *next; + + adap->disconnect = true; + + usb_kill_urb(adap->rx_urb); + + list_for_each_entry_safe_reverse(client, next, &adap->client_list, link) { + auxiliary_device_delete(&client->auxdev); + auxiliary_device_uninit(&client->auxdev); + + list_del_init(&client->link); + kfree(client); + } + + usb_free_urb(adap->rx_urb); + + usb_put_intf(adap->intf); + + mutex_destroy(&adap->mutex); +} + +static int ljca_suspend(struct usb_interface *interface, pm_message_t message) +{ + struct ljca_adapter *adap = usb_get_intfdata(interface); + + usb_kill_urb(adap->rx_urb); + + return 0; +} + +static int ljca_resume(struct usb_interface *interface) +{ + struct ljca_adapter *adap = usb_get_intfdata(interface); + + return usb_submit_urb(adap->rx_urb, GFP_KERNEL); +} + +static const struct usb_device_id ljca_table[] = { + { USB_DEVICE(0x8086, 0x0b63) }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(usb, ljca_table); + +static struct usb_driver ljca_driver = { + .name = "ljca", + .id_table = ljca_table, + .probe = ljca_probe, + .disconnect = ljca_disconnect, + .suspend = ljca_suspend, + .resume = ljca_resume, + .supports_autosuspend = 1, +}; +module_usb_driver(ljca_driver); + +MODULE_AUTHOR("Wentong Wu "); +MODULE_AUTHOR("Zhifeng Wang "); +MODULE_AUTHOR("Lixu Zhang "); +MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index ac0d75ac2d2f..caf65f8294db 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -705,7 +705,7 @@ static int is_good_config(struct usbtest_dev *tdev, int len) { struct usb_config_descriptor *config; - if (len < sizeof(*config)) + if (len < (int)sizeof(*config)) return 0; config = (struct usb_config_descriptor *) tdev->buf; diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 9812d102a005..824904abe76f 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -81,15 +81,12 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r) static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb) { unsigned long flags; - struct list_head *pos; struct mon_reader *r; spin_lock_irqsave(&mbus->lock, flags); mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); + list_for_each_entry(r, &mbus->r_list, r_link) r->rnf_submit(r->r_data, urb); - } spin_unlock_irqrestore(&mbus->lock, flags); } @@ -108,15 +105,12 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error) { unsigned long flags; - struct list_head *pos; struct mon_reader *r; spin_lock_irqsave(&mbus->lock, flags); mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); + list_for_each_entry(r, &mbus->r_list, r_link) r->rnf_error(r->r_data, urb, error); - } spin_unlock_irqrestore(&mbus->lock, flags); } @@ -135,15 +129,12 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, int status) { unsigned long flags; - struct list_head *pos; struct mon_reader *r; spin_lock_irqsave(&mbus->lock, flags); mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); + list_for_each_entry(r, &mbus->r_list, r_link) r->rnf_complete(r->r_data, urb, status); - } spin_unlock_irqrestore(&mbus->lock, flags); } @@ -165,11 +156,9 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status) static void mon_stop(struct mon_bus *mbus) { struct usb_bus *ubus; - struct list_head *p; if (mbus == &mon_bus0) { - list_for_each (p, &mon_buses) { - mbus = list_entry(p, struct mon_bus, bus_link); + list_for_each_entry(mbus, &mon_buses, bus_link) { /* * We do not change nreaders here, so rely on mon_lock. */ @@ -332,14 +321,12 @@ static void mon_bus0_init(void) */ struct mon_bus *mon_bus_lookup(unsigned int num) { - struct list_head *p; struct mon_bus *mbus; if (num == 0) { return &mon_bus0; } - list_for_each (p, &mon_buses) { - mbus = list_entry(p, struct mon_bus, bus_link); + list_for_each_entry(mbus, &mon_buses, bus_link) { if (mbus->u_bus->busnum == num) { return mbus; } diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index 6f264b129243..6858ed9fc3b2 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -451,7 +451,7 @@ comm_init_err: return ret; } -static int mtu3_remove(struct platform_device *pdev) +static void mtu3_remove(struct platform_device *pdev) { struct ssusb_mtk *ssusb = platform_get_drvdata(pdev); @@ -469,8 +469,16 @@ static int mtu3_remove(struct platform_device *pdev) ssusb_gadget_exit(ssusb); ssusb_host_exit(ssusb); break; - default: - return -EINVAL; + case USB_DR_MODE_UNKNOWN: + /* + * This cannot happen because with dr_mode == + * USB_DR_MODE_UNKNOWN, .probe() doesn't succeed and so + * .remove() wouldn't be called at all. However (little + * surprising) the compiler isn't smart enough to see that, so + * we explicitly have this case item to not make the compiler + * wail about an unhandled enumeration value. + */ + break; } ssusb_rscs_exit(ssusb); @@ -478,8 +486,6 @@ static int mtu3_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - - return 0; } static int resume_ip_and_ports(struct ssusb_mtk *ssusb, pm_message_t msg) @@ -615,7 +621,7 @@ MODULE_DEVICE_TABLE(of, mtu3_of_match); static struct platform_driver mtu3_driver = { .probe = mtu3_probe, - .remove = mtu3_remove, + .remove_new = mtu3_remove, .driver = { .name = MTU3_DRIVER_NAME, .pm = DEV_PM_OPS, diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 912e32b78ac6..8abf3a567e30 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 98b42dc04dee..9c7a8bbc0542 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -849,7 +849,7 @@ static int dsps_setup_optional_vbus_irq(struct platform_device *pdev, error = devm_request_threaded_irq(glue->dev, glue->vbus_irq, NULL, dsps_vbus_threaded_irq, - IRQF_ONESHOT, + IRQF_SHARED, "vbus", glue); if (error) { glue->vbus_irq = 0; diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index d73282c0ec50..4d3b49e5b87a 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -54,12 +54,12 @@ static int uas_find_endpoints(struct usb_host_interface *alt, static int uas_use_uas_driver(struct usb_interface *intf, const struct usb_device_id *id, - unsigned long *flags_ret) + u64 *flags_ret) { struct usb_host_endpoint *eps[4] = { }; struct usb_device *udev = interface_to_usbdev(intf); struct usb_hcd *hcd = bus_to_hcd(udev->bus); - unsigned long flags = id->driver_info; + u64 flags = id->driver_info; struct usb_host_interface *alt; int r; diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 2583ee9815c5..696bb0b23599 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -37,7 +37,7 @@ struct uas_dev_info { struct usb_anchor cmd_urbs; struct usb_anchor sense_urbs; struct usb_anchor data_urbs; - unsigned long flags; + u64 flags; int qdepth, resetting; unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; @@ -988,7 +988,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) struct Scsi_Host *shost = NULL; struct uas_dev_info *devinfo; struct usb_device *udev = interface_to_usbdev(intf); - unsigned long dev_flags; + u64 dev_flags; if (!uas_use_uas_driver(intf, id, &dev_flags)) return -ENODEV; diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h index 0547daf116a2..5df40759d77a 100644 --- a/drivers/usb/storage/unusual_cypress.h +++ b/drivers/usb/storage/unusual_cypress.h @@ -19,7 +19,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, "Cypress ISD-300LP", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, +UNUSUAL_DEV( 0x14cd, 0x6116, 0x0150, 0x0160, "Super Top", "USB 2.0 SATA BRIDGE", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 7b36a3334fb3..d1ad6a2509ab 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -110,17 +110,6 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); .useTransport = use_transport, \ } -#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \ - vendor_name, product_name, use_protocol, use_transport, \ - init_function, Flags) \ -{ \ - .vendorName = vendor_name, \ - .productName = product_name, \ - .useProtocol = use_protocol, \ - .useTransport = use_transport, \ - .initFunction = init_function, \ -} - static const struct us_unusual_dev us_unusual_dev_list[] = { # include "unusual_devs.h" { } /* Terminating entry */ @@ -132,7 +121,6 @@ static const struct us_unusual_dev for_dynamic_ids = #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV -#undef UNUSUAL_VENDOR_INTF #ifdef CONFIG_LOCKDEP @@ -472,13 +460,13 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) #define TOLOWER(x) ((x) | 0x20) /* Adjust device flags based on the "quirks=" module parameter */ -void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) +void usb_stor_adjust_quirks(struct usb_device *udev, u64 *fflags) { char *p; u16 vid = le16_to_cpu(udev->descriptor.idVendor); u16 pid = le16_to_cpu(udev->descriptor.idProduct); - unsigned f = 0; - unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE | + u64 f = 0; + u64 mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE | US_FL_FIX_CAPACITY | US_FL_IGNORE_UAS | US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE | US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | @@ -617,7 +605,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id, us->fflags &= ~US_FL_GO_SLOW; if (us->fflags) - dev_info(pdev, "Quirks match for vid %04x pid %04x: %lx\n", + dev_info(pdev, "Quirks match for vid %04x pid %04x: %llx\n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct), us->fflags); diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index fd3f32670873..97c6196d639b 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -95,7 +95,7 @@ struct us_data { struct usb_interface *pusb_intf; /* this interface */ const struct us_unusual_dev *unusual_dev; /* device-filter entry */ - unsigned long fflags; /* fixed flags from filter */ + u64 fflags; /* fixed flags from filter */ unsigned long dflags; /* dynamic atomic bitflags */ unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int recv_bulk_pipe; @@ -192,7 +192,7 @@ extern int usb_stor_probe2(struct us_data *us); extern void usb_stor_disconnect(struct usb_interface *intf); extern void usb_stor_adjust_quirks(struct usb_device *dev, - unsigned long *fflags); + u64 *fflags); #define module_usb_stor_driver(__driver, __sht, __name) \ static int __init __driver##_init(void) \ diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index 529512827d8f..a26029e43dfd 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c @@ -19,27 +19,13 @@ vendorName, productName, useProtocol, useTransport, \ initFunction, flags) \ { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ - .driver_info = (flags) } + .driver_info = (kernel_ulong_t)(flags) } #define COMPLIANT_DEV UNUSUAL_DEV #define USUAL_DEV(useProto, useTrans) \ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } -/* Define the device is matched with Vendor ID and interface descriptors */ -#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \ - vendorName, productName, useProtocol, useTransport, \ - initFunction, flags) \ -{ \ - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ - | USB_DEVICE_ID_MATCH_VENDOR, \ - .idVendor = (id_vendor), \ - .bInterfaceClass = (cl), \ - .bInterfaceSubClass = (sc), \ - .bInterfaceProtocol = (pr), \ - .driver_info = (flags) \ -} - const struct usb_device_id usb_storage_usb_ids[] = { # include "unusual_devs.h" { } /* Terminating entry */ @@ -49,7 +35,6 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV -#undef UNUSUAL_VENDOR_INTF /* * The table of devices to ignore diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index aea9d2fd0e76..f81bec0c7b86 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -86,8 +86,11 @@ static int dp_altmode_notify(struct dp_altmode *dp) static int dp_altmode_configure(struct dp_altmode *dp, u8 con) { - u32 conf = DP_CONF_SIGNALING_DP; /* Only DP signaling supported */ u8 pin_assign = 0; + u32 conf; + + /* DP Signalling */ + conf = (dp->data.conf & DP_CONF_SIGNALLING_MASK) >> DP_CONF_SIGNALLING_SHIFT; switch (con) { case DP_STATUS_CON_DISABLED: diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c index 221604f933a4..b12a07edc71b 100644 --- a/drivers/usb/typec/anx7411.c +++ b/drivers/usb/typec/anx7411.c @@ -1550,8 +1550,7 @@ static void anx7411_i2c_remove(struct i2c_client *client) if (plat->workqueue) destroy_workqueue(plat->workqueue); - if (plat->spi_client) - i2c_unregister_device(plat->spi_client); + i2c_unregister_device(plat->spi_client); if (plat->typec.role_sw) usb_role_switch_put(plat->typec.role_sw); diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 9c1dbf3c00e0..2e0451bd336e 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "bus.h" #include "class.h" @@ -681,6 +682,33 @@ const struct device_type typec_partner_dev_type = { .release = typec_partner_release, }; +static void typec_partner_link_device(struct typec_partner *partner, struct device *dev) +{ + int ret; + + ret = sysfs_create_link(&dev->kobj, &partner->dev.kobj, "typec"); + if (ret) + return; + + ret = sysfs_create_link(&partner->dev.kobj, &dev->kobj, dev_name(dev)); + if (ret) { + sysfs_remove_link(&dev->kobj, "typec"); + return; + } + + if (partner->attach) + partner->attach(partner, dev); +} + +static void typec_partner_unlink_device(struct typec_partner *partner, struct device *dev) +{ + sysfs_remove_link(&partner->dev.kobj, dev_name(dev)); + sysfs_remove_link(&dev->kobj, "typec"); + + if (partner->deattach) + partner->deattach(partner, dev); +} + /** * typec_partner_set_identity - Report result from Discover Identity command * @partner: The partner updated identity values @@ -865,6 +893,8 @@ struct typec_partner *typec_register_partner(struct typec_port *port, partner->num_altmodes = -1; partner->pd_revision = desc->pd_revision; partner->svdm_version = port->cap->svdm_version; + partner->attach = desc->attach; + partner->deattach = desc->deattach; if (desc->identity) { /* @@ -887,6 +917,11 @@ struct typec_partner *typec_register_partner(struct typec_port *port, return ERR_PTR(ret); } + if (port->usb2_dev) + typec_partner_link_device(partner, port->usb2_dev); + if (port->usb3_dev) + typec_partner_link_device(partner, port->usb3_dev); + return partner; } EXPORT_SYMBOL_GPL(typec_register_partner); @@ -899,8 +934,19 @@ EXPORT_SYMBOL_GPL(typec_register_partner); */ void typec_unregister_partner(struct typec_partner *partner) { - if (!IS_ERR_OR_NULL(partner)) - device_unregister(&partner->dev); + struct typec_port *port; + + if (IS_ERR_OR_NULL(partner)) + return; + + port = to_typec_port(partner->dev.parent); + + if (port->usb2_dev) + typec_partner_unlink_device(partner, port->usb2_dev); + if (port->usb3_dev) + typec_partner_unlink_device(partner, port->usb3_dev); + + device_unregister(&partner->dev); } EXPORT_SYMBOL_GPL(typec_unregister_partner); @@ -1775,6 +1821,50 @@ static int partner_match(struct device *dev, void *data) return is_typec_partner(dev); } +static struct typec_partner *typec_get_partner(struct typec_port *port) +{ + struct device *dev; + + dev = device_find_child(&port->dev, NULL, partner_match); + if (!dev) + return NULL; + + return to_typec_partner(dev); +} + +static void typec_partner_attach(struct typec_connector *con, struct device *dev) +{ + struct typec_port *port = container_of(con, struct typec_port, con); + struct typec_partner *partner = typec_get_partner(port); + struct usb_device *udev = to_usb_device(dev); + + if (udev->speed < USB_SPEED_SUPER) + port->usb2_dev = dev; + else + port->usb3_dev = dev; + + if (partner) { + typec_partner_link_device(partner, dev); + put_device(&partner->dev); + } +} + +static void typec_partner_deattach(struct typec_connector *con, struct device *dev) +{ + struct typec_port *port = container_of(con, struct typec_port, con); + struct typec_partner *partner = typec_get_partner(port); + + if (partner) { + typec_partner_unlink_device(partner, dev); + put_device(&partner->dev); + } + + if (port->usb2_dev == dev) + port->usb2_dev = NULL; + else if (port->usb3_dev == dev) + port->usb3_dev = NULL; +} + /** * typec_set_data_role - Report data role change * @port: The USB Type-C Port where the role was changed @@ -1784,7 +1874,7 @@ static int partner_match(struct device *dev, void *data) */ void typec_set_data_role(struct typec_port *port, enum typec_data_role role) { - struct device *partner_dev; + struct typec_partner *partner; if (port->data_role == role) return; @@ -1793,14 +1883,14 @@ void typec_set_data_role(struct typec_port *port, enum typec_data_role role) sysfs_notify(&port->dev.kobj, NULL, "data_role"); kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); - partner_dev = device_find_child(&port->dev, NULL, partner_match); - if (!partner_dev) + partner = typec_get_partner(port); + if (!partner) return; - if (to_typec_partner(partner_dev)->identity) - typec_product_type_notify(partner_dev); + if (partner->identity) + typec_product_type_notify(&partner->dev); - put_device(partner_dev); + put_device(&partner->dev); } EXPORT_SYMBOL_GPL(typec_set_data_role); @@ -2251,6 +2341,8 @@ struct typec_port *typec_register_port(struct device *parent, port->ops = cap->ops; port->port_type = cap->type; port->prefer_role = cap->prefer_role; + port->con.attach = typec_partner_attach; + port->con.deattach = typec_partner_deattach; device_initialize(&port->dev); port->dev.class = &typec_class; diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index 673b2952b074..c36761ba3f59 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -8,6 +8,7 @@ struct typec_mux; struct typec_switch; +struct usb_device; struct typec_plug { struct device dev; @@ -35,6 +36,9 @@ struct typec_partner { enum usb_pd_svdm_ver svdm_version; struct usb_power_delivery *pd; + + void (*attach)(struct typec_partner *partner, struct device *dev); + void (*deattach)(struct typec_partner *partner, struct device *dev); }; struct typec_port { @@ -59,6 +63,18 @@ struct typec_port { const struct typec_capability *cap; const struct typec_operations *ops; + + struct typec_connector con; + + /* + * REVISIT: Only USB devices for now. If there are others, these need to + * be converted into a list. + * + * NOTE: These may be registered first before the typec_partner, so they + * will always have to be kept here instead of struct typec_partner. + */ + struct device *usb2_dev; + struct device *usb3_dev; }; #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index 65da61150ba7..816b9bd08355 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -46,4 +46,14 @@ config TYPEC_MUX_NB7VPQ904M Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C redriver chip found on some devices with a Type-C port. +config TYPEC_MUX_PTN36502 + tristate "NXP PTN36502 Type-C redriver driver" + depends on I2C + depends on DRM || DRM=n + select DRM_PANEL_BRIDGE if DRM + select REGMAP_I2C + help + Say Y or M if your system has a NXP PTN36502 Type-C redriver chip + found on some devices with a Type-C port. + endmenu diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile index 76196096ef41..9d6a5557b0bd 100644 --- a/drivers/usb/typec/mux/Makefile +++ b/drivers/usb/typec/mux/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_MUX_GPIO_SBU) += gpio-sbu-mux.o obj-$(CONFIG_TYPEC_MUX_PI3USB30532) += pi3usb30532.o obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) += intel_pmc_mux.o obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o +obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c index e0ee1f621abb..cb7cdf90cb0a 100644 --- a/drivers/usb/typec/mux/fsa4480.c +++ b/drivers/usb/typec/mux/fsa4480.c @@ -60,6 +60,7 @@ struct fsa4480 { unsigned int svid; u8 cur_enable; + bool swap_sbu_lanes; }; static const struct regmap_config fsa4480_regmap_config = { @@ -76,6 +77,9 @@ static int fsa4480_set(struct fsa4480 *fsa) u8 enable = FSA4480_ENABLE_DEVICE; u8 sel = 0; + if (fsa->swap_sbu_lanes) + reverse = !reverse; + /* USB Mode */ if (fsa->mode < TYPEC_STATE_MODAL || (!fsa->svid && (fsa->mode == TYPEC_MODE_USB2 || @@ -179,12 +183,75 @@ static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *st return ret; } +enum { + NORMAL_LANE_MAPPING, + INVERT_LANE_MAPPING, +}; + +#define DATA_LANES_COUNT 2 + +static const int supported_data_lane_mapping[][DATA_LANES_COUNT] = { + [NORMAL_LANE_MAPPING] = { 0, 1 }, + [INVERT_LANE_MAPPING] = { 1, 0 }, +}; + +static int fsa4480_parse_data_lanes_mapping(struct fsa4480 *fsa) +{ + struct fwnode_handle *ep; + u32 data_lanes[DATA_LANES_COUNT]; + int ret, i, j; + + ep = fwnode_graph_get_next_endpoint(dev_fwnode(&fsa->client->dev), NULL); + if (!ep) + return 0; + + ret = fwnode_property_read_u32_array(ep, "data-lanes", data_lanes, DATA_LANES_COUNT); + if (ret == -EINVAL) + /* Property isn't here, consider default mapping */ + goto out_done; + if (ret) { + dev_err(&fsa->client->dev, "invalid data-lanes property: %d\n", ret); + goto out_error; + } + + for (i = 0; i < ARRAY_SIZE(supported_data_lane_mapping); i++) { + for (j = 0; j < DATA_LANES_COUNT; j++) { + if (data_lanes[j] != supported_data_lane_mapping[i][j]) + break; + } + + if (j == DATA_LANES_COUNT) + break; + } + + switch (i) { + case NORMAL_LANE_MAPPING: + break; + case INVERT_LANE_MAPPING: + fsa->swap_sbu_lanes = true; + break; + default: + dev_err(&fsa->client->dev, "invalid data-lanes mapping\n"); + ret = -EINVAL; + goto out_error; + } + +out_done: + ret = 0; + +out_error: + fwnode_handle_put(ep); + + return ret; +} + static int fsa4480_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct typec_switch_desc sw_desc = { }; struct typec_mux_desc mux_desc = { }; struct fsa4480 *fsa; + int ret; fsa = devm_kzalloc(dev, sizeof(*fsa), GFP_KERNEL); if (!fsa) @@ -193,6 +260,10 @@ static int fsa4480_probe(struct i2c_client *client) fsa->client = client; mutex_init(&fsa->lock); + ret = fsa4480_parse_data_lanes_mapping(fsa); + if (ret) + return ret; + fsa->regmap = devm_regmap_init_i2c(client, &fsa4480_regmap_config); if (IS_ERR(fsa->regmap)) return dev_err_probe(dev, PTR_ERR(fsa->regmap), "failed to initialize regmap\n"); diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c index 60ed1f809130..56989a0d0f43 100644 --- a/drivers/usb/typec/mux/intel_pmc_mux.c +++ b/drivers/usb/typec/mux/intel_pmc_mux.c @@ -191,6 +191,12 @@ static int hsl_orientation(struct pmc_usb_port *port) return port->orientation - 1; } +static bool is_pmc_mux_tbt(struct acpi_device *adev) +{ + return acpi_dev_hid_uid_match(adev, "INTC1072", NULL) || + acpi_dev_hid_uid_match(adev, "INTC1079", NULL); +} + static int pmc_usb_send_command(struct intel_scu_ipc_dev *ipc, u8 *msg, u32 len) { u8 response[4]; @@ -293,6 +299,24 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state) req.mode_data |= (state->mode - TYPEC_STATE_MODAL) << PMC_USB_ALTMODE_DP_MODE_SHIFT; + if (!is_pmc_mux_tbt(port->pmc->iom_adev)) { + u8 cable_speed = (data->conf & DP_CONF_SIGNALLING_MASK) >> + DP_CONF_SIGNALLING_SHIFT; + + u8 cable_type = (data->conf & DP_CONF_CABLE_TYPE_MASK) >> + DP_CONF_CABLE_TYPE_SHIFT; + + req.mode_data |= PMC_USB_ALTMODE_CABLE_SPD(cable_speed); + + if (cable_type == DP_CONF_CABLE_TYPE_OPTICAL) + req.mode_data |= PMC_USB_ALTMODE_CABLE_TYPE; + else if (cable_type == DP_CONF_CABLE_TYPE_RE_TIMER) + req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE | + PMC_USB_ALTMODE_RETIMER_CABLE; + else if (cable_type == DP_CONF_CABLE_TYPE_RE_DRIVER) + req.mode_data |= PMC_USB_ALTMODE_ACTIVE_CABLE; + } + ret = pmc_usb_command(port, (void *)&req, sizeof(req)); if (ret) return ret; @@ -599,6 +623,7 @@ static int pmc_usb_register_port(struct pmc_usb *pmc, int index, desc.driver_data = port; desc.name = fwnode_get_name(fwnode); desc.set = pmc_usb_set_role; + desc.allow_userspace_control = true; port->usb_sw = usb_role_switch_register(pmc->dev, &desc); if (IS_ERR(port->usb_sw)) { diff --git a/drivers/usb/typec/mux/ptn36502.c b/drivers/usb/typec/mux/ptn36502.c new file mode 100644 index 000000000000..72ae38a1b2be --- /dev/null +++ b/drivers/usb/typec/mux/ptn36502.c @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NXP PTN36502 Type-C driver + * + * Copyright (C) 2023 Luca Weiss + * + * Based on NB7VPQ904M driver: + * Copyright (C) 2023 Dmitry Baryshkov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTN36502_CHIP_ID_REG 0x00 +#define PTN36502_CHIP_ID 0x02 + +#define PTN36502_CHIP_REVISION_REG 0x01 +#define PTN36502_CHIP_REVISION_BASE_MASK GENMASK(7, 4) +#define PTN36502_CHIP_REVISION_METAL_MASK GENMASK(3, 0) + +#define PTN36502_DP_LINK_CTRL_REG 0x06 +#define PTN36502_DP_LINK_CTRL_LANES_MASK GENMASK(3, 2) +#define PTN36502_DP_LINK_CTRL_LANES_2 (2) +#define PTN36502_DP_LINK_CTRL_LANES_4 (3) +#define PTN36502_DP_LINK_CTRL_LINK_RATE_MASK GENMASK(1, 0) +#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS (2) + +/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */ +#define PTN36502_DP_LANE_CTRL_REG(n) (0x07 + (n)) +#define PTN36502_DP_LANE_CTRL_RX_GAIN_MASK GENMASK(6, 4) +#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB (2) +#define PTN36502_DP_LANE_CTRL_TX_SWING_MASK GENMASK(3, 2) +#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD (2) +#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_MASK GENMASK(1, 0) +#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB (1) + +#define PTN36502_MODE_CTRL1_REG 0x0b +#define PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK GENMASK(5, 5) +#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE (1) +#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_MASK GENMASK(3, 3) +#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON (1) +#define PTN36502_MODE_CTRL1_MODE_MASK GENMASK(2, 0) +#define PTN36502_MODE_CTRL1_MODE_OFF (0) +#define PTN36502_MODE_CTRL1_MODE_USB_ONLY (1) +#define PTN36502_MODE_CTRL1_MODE_USB_DP (2) +#define PTN36502_MODE_CTRL1_MODE_DP (3) + +#define PTN36502_DEVICE_CTRL_REG 0x0d +#define PTN36502_DEVICE_CTRL_AUX_MONITORING_MASK GENMASK(7, 7) +#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN (1) + +struct ptn36502 { + struct i2c_client *client; + struct regulator *vdd18_supply; + struct regmap *regmap; + struct typec_switch_dev *sw; + struct typec_retimer *retimer; + + struct typec_switch *typec_switch; + + struct drm_bridge bridge; + + struct mutex lock; /* protect non-concurrent retimer & switch */ + + enum typec_orientation orientation; + unsigned long mode; + unsigned int svid; +}; + +static int ptn36502_set(struct ptn36502 *ptn) +{ + bool reverse = (ptn->orientation == TYPEC_ORIENTATION_REVERSE); + unsigned int ctrl1_val = 0; + unsigned int lane_ctrl_val = 0; + unsigned int link_ctrl_val = 0; + + switch (ptn->mode) { + case TYPEC_STATE_SAFE: + /* Deep power saving state */ + regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, + FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, + PTN36502_MODE_CTRL1_MODE_OFF)); + return 0; + + case TYPEC_STATE_USB: + /* + * Normal Orientation (CC1) + * A -> USB RX + * B -> USB TX + * C -> X + * D -> X + * Flipped Orientation (CC2) + * A -> X + * B -> X + * C -> USB TX + * D -> USB RX + */ + + /* USB 3.1 Gen 1 only */ + ctrl1_val = FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, + PTN36502_MODE_CTRL1_MODE_USB_ONLY); + if (reverse) + ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK, + PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE); + + regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, ctrl1_val); + return 0; + + default: + if (ptn->svid != USB_TYPEC_DP_SID) + return -EINVAL; + + break; + } + + /* DP Altmode Setup */ + + switch (ptn->mode) { + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + /* + * Normal Orientation (CC1) + * A -> DP3 + * B -> DP2 + * C -> DP1 + * D -> DP0 + * Flipped Orientation (CC2) + * A -> DP0 + * B -> DP1 + * C -> DP2 + * D -> DP3 + */ + + /* 4-lane DP */ + ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, + PTN36502_MODE_CTRL1_MODE_DP); + link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LANES_MASK, + PTN36502_DP_LINK_CTRL_LANES_4); + break; + + case TYPEC_DP_STATE_D: + case TYPEC_DP_STATE_F: /* State F is deprecated */ + /* + * Normal Orientation (CC1) + * A -> USB RX + * B -> USB TX + * C -> DP1 + * D -> DP0 + * Flipped Orientation (CC2) + * A -> DP0 + * B -> DP1 + * C -> USB TX + * D -> USB RX + */ + + /* USB 3.1 Gen 1 and 2-lane DP */ + ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_MODE_MASK, + PTN36502_MODE_CTRL1_MODE_USB_DP); + link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LANES_MASK, + PTN36502_DP_LINK_CTRL_LANES_2); + break; + + default: + return -EOPNOTSUPP; + } + + /* Enable AUX monitoring */ + regmap_write(ptn->regmap, PTN36502_DEVICE_CTRL_REG, + FIELD_PREP(PTN36502_DEVICE_CTRL_AUX_MONITORING_MASK, + PTN36502_DEVICE_CTRL_AUX_MONITORING_EN)); + + /* Enable AUX switch path */ + ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_AUX_CROSSBAR_MASK, + PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON); + if (reverse) + ctrl1_val |= FIELD_PREP(PTN36502_MODE_CTRL1_PLUG_ORIENT_MASK, + PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE); + regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG, ctrl1_val); + + /* DP Link rate: 5.4 Gbps (HBR2) */ + link_ctrl_val |= FIELD_PREP(PTN36502_DP_LINK_CTRL_LINK_RATE_MASK, + PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS); + regmap_write(ptn->regmap, PTN36502_DP_LINK_CTRL_REG, link_ctrl_val); + + /* + * For all lanes: + * - Rx equivalization gain: 3 dB + * - TX output swing control: 800 mVppd + * - Pre-emphasis control: 3.5 dB + */ + lane_ctrl_val = FIELD_PREP(PTN36502_DP_LANE_CTRL_RX_GAIN_MASK, + PTN36502_DP_LANE_CTRL_RX_GAIN_3DB) | + FIELD_PREP(PTN36502_DP_LANE_CTRL_TX_SWING_MASK, + PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD) | + FIELD_PREP(PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_MASK, + PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB); + regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(0), lane_ctrl_val); + regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(1), lane_ctrl_val); + regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(2), lane_ctrl_val); + regmap_write(ptn->regmap, PTN36502_DP_LANE_CTRL_REG(3), lane_ctrl_val); + + return 0; +} + +static int ptn36502_sw_set(struct typec_switch_dev *sw, enum typec_orientation orientation) +{ + struct ptn36502 *ptn = typec_switch_get_drvdata(sw); + int ret; + + ret = typec_switch_set(ptn->typec_switch, orientation); + if (ret) + return ret; + + mutex_lock(&ptn->lock); + + if (ptn->orientation != orientation) { + ptn->orientation = orientation; + + ret = ptn36502_set(ptn); + } + + mutex_unlock(&ptn->lock); + + return ret; +} + +static int ptn36502_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state) +{ + struct ptn36502 *ptn = typec_retimer_get_drvdata(retimer); + int ret = 0; + + mutex_lock(&ptn->lock); + + if (ptn->mode != state->mode) { + ptn->mode = state->mode; + + if (state->alt) + ptn->svid = state->alt->svid; + else + ptn->svid = 0; // No SVID + + ret = ptn36502_set(ptn); + } + + mutex_unlock(&ptn->lock); + + return ret; +} + +static int ptn36502_detect(struct ptn36502 *ptn) +{ + struct device *dev = &ptn->client->dev; + unsigned int reg_val; + int ret; + + ret = regmap_read(ptn->regmap, PTN36502_CHIP_ID_REG, + ®_val); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read chip ID\n"); + + if (reg_val != PTN36502_CHIP_ID) + return dev_err_probe(dev, -ENODEV, "Unexpected chip ID: %x\n", reg_val); + + ret = regmap_read(ptn->regmap, PTN36502_CHIP_REVISION_REG, + ®_val); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read chip revision\n"); + + dev_dbg(dev, "Chip revision: base layer version %lx, metal layer version %lx\n", + FIELD_GET(PTN36502_CHIP_REVISION_BASE_MASK, reg_val), + FIELD_GET(PTN36502_CHIP_REVISION_METAL_MASK, reg_val)); + + return 0; +} + +#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) +static int ptn36502_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct ptn36502 *ptn = container_of(bridge, struct ptn36502, bridge); + struct drm_bridge *next_bridge; + + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) + return -EINVAL; + + next_bridge = devm_drm_of_get_bridge(&ptn->client->dev, ptn->client->dev.of_node, 0, 0); + if (IS_ERR(next_bridge)) { + dev_err(&ptn->client->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); + return PTR_ERR(next_bridge); + } + + return drm_bridge_attach(bridge->encoder, next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); +} + +static const struct drm_bridge_funcs ptn36502_bridge_funcs = { + .attach = ptn36502_bridge_attach, +}; + +static int ptn36502_register_bridge(struct ptn36502 *ptn) +{ + ptn->bridge.funcs = &ptn36502_bridge_funcs; + ptn->bridge.of_node = ptn->client->dev.of_node; + + return devm_drm_bridge_add(&ptn->client->dev, &ptn->bridge); +} +#else +static int ptn36502_register_bridge(struct ptn36502 *ptn) +{ + return 0; +} +#endif + +static const struct regmap_config ptn36502_regmap = { + .max_register = 0x0d, + .reg_bits = 8, + .val_bits = 8, +}; + +static int ptn36502_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct typec_switch_desc sw_desc = { }; + struct typec_retimer_desc retimer_desc = { }; + struct ptn36502 *ptn; + int ret; + + ptn = devm_kzalloc(dev, sizeof(*ptn), GFP_KERNEL); + if (!ptn) + return -ENOMEM; + + ptn->client = client; + + ptn->regmap = devm_regmap_init_i2c(client, &ptn36502_regmap); + if (IS_ERR(ptn->regmap)) { + dev_err(&client->dev, "Failed to allocate register map\n"); + return PTR_ERR(ptn->regmap); + } + + ptn->mode = TYPEC_STATE_SAFE; + ptn->orientation = TYPEC_ORIENTATION_NONE; + + mutex_init(&ptn->lock); + + ptn->vdd18_supply = devm_regulator_get_optional(dev, "vdd18"); + if (IS_ERR(ptn->vdd18_supply)) + return PTR_ERR(ptn->vdd18_supply); + + ptn->typec_switch = fwnode_typec_switch_get(dev->fwnode); + if (IS_ERR(ptn->typec_switch)) + return dev_err_probe(dev, PTR_ERR(ptn->typec_switch), + "Failed to acquire orientation-switch\n"); + + ret = regulator_enable(ptn->vdd18_supply); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable vdd18\n"); + + ret = ptn36502_detect(ptn); + if (ret) + goto err_disable_regulator; + + ret = ptn36502_register_bridge(ptn); + if (ret) + goto err_disable_regulator; + + sw_desc.drvdata = ptn; + sw_desc.fwnode = dev->fwnode; + sw_desc.set = ptn36502_sw_set; + + ptn->sw = typec_switch_register(dev, &sw_desc); + if (IS_ERR(ptn->sw)) { + ret = dev_err_probe(dev, PTR_ERR(ptn->sw), + "Failed to register typec switch\n"); + goto err_disable_regulator; + } + + retimer_desc.drvdata = ptn; + retimer_desc.fwnode = dev->fwnode; + retimer_desc.set = ptn36502_retimer_set; + + ptn->retimer = typec_retimer_register(dev, &retimer_desc); + if (IS_ERR(ptn->retimer)) { + ret = dev_err_probe(dev, PTR_ERR(ptn->retimer), + "Failed to register typec retimer\n"); + goto err_switch_unregister; + } + + return 0; + +err_switch_unregister: + typec_switch_unregister(ptn->sw); + +err_disable_regulator: + regulator_disable(ptn->vdd18_supply); + + return ret; +} + +static void ptn36502_remove(struct i2c_client *client) +{ + struct ptn36502 *ptn = i2c_get_clientdata(client); + + typec_retimer_unregister(ptn->retimer); + typec_switch_unregister(ptn->sw); + + regulator_disable(ptn->vdd18_supply); +} + +static const struct i2c_device_id ptn36502_table[] = { + { "ptn36502" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ptn36502_table); + +static const struct of_device_id ptn36502_of_table[] = { + { .compatible = "nxp,ptn36502" }, + { } +}; +MODULE_DEVICE_TABLE(of, ptn36502_of_table); + +static struct i2c_driver ptn36502_driver = { + .driver = { + .name = "ptn36502", + .of_match_table = ptn36502_of_table, + }, + .probe = ptn36502_probe, + .remove = ptn36502_remove, + .id_table = ptn36502_table, +}; +module_i2c_driver(ptn36502_driver); + +MODULE_AUTHOR("Luca Weiss "); +MODULE_DESCRIPTION("NXP PTN36502 Type-C driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/typec/pd.c b/drivers/usb/typec/pd.c index 8cc66e4467c4..85d015cdbe1f 100644 --- a/drivers/usb/typec/pd.c +++ b/drivers/usb/typec/pd.c @@ -83,14 +83,12 @@ unchunked_extended_messages_supported_show(struct device *dev, } static DEVICE_ATTR_RO(unchunked_extended_messages_supported); -/* - * REVISIT: Peak Current requires access also to the RDO. static ssize_t peak_current_show(struct device *dev, struct device_attribute *attr, char *buf) { - ... + return sysfs_emit(buf, "%u\n", (to_pdo(dev)->pdo >> PDO_FIXED_PEAK_CURR_SHIFT) & 3); } -*/ +static DEVICE_ATTR_RO(peak_current); static ssize_t fast_role_swap_current_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -135,7 +133,7 @@ static struct attribute *source_fixed_supply_attrs[] = { &dev_attr_usb_communication_capable.attr, &dev_attr_dual_role_data.attr, &dev_attr_unchunked_extended_messages_supported.attr, - /*&dev_attr_peak_current.attr,*/ + &dev_attr_peak_current.attr, &dev_attr_voltage.attr, &maximum_current_attr.attr, NULL @@ -144,7 +142,7 @@ static struct attribute *source_fixed_supply_attrs[] = { static umode_t fixed_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { if (to_pdo(kobj_to_dev(kobj))->object_position && - /*attr != &dev_attr_peak_current.attr &&*/ + attr != &dev_attr_peak_current.attr && attr != &dev_attr_voltage.attr && attr != &maximum_current_attr.attr && attr != &operational_current_attr.attr) diff --git a/drivers/usb/typec/port-mapper.c b/drivers/usb/typec/port-mapper.c index a929e000d0e2..d42da5720a25 100644 --- a/drivers/usb/typec/port-mapper.c +++ b/drivers/usb/typec/port-mapper.c @@ -8,17 +8,22 @@ #include #include +#include #include "class.h" static int typec_aggregate_bind(struct device *dev) { - return component_bind_all(dev, NULL); + struct typec_port *port = to_typec_port(dev); + + return component_bind_all(dev, &port->con); } static void typec_aggregate_unbind(struct device *dev) { - component_unbind_all(dev, NULL); + struct typec_port *port = to_typec_port(dev); + + component_unbind_all(dev, &port->con); } static const struct component_master_ops typec_aggregate_ops = { diff --git a/drivers/usb/typec/tcpm/tcpci_rt1711h.c b/drivers/usb/typec/tcpm/tcpci_rt1711h.c index 17ebc5fb684f..67422d45eb54 100644 --- a/drivers/usb/typec/tcpm/tcpci_rt1711h.c +++ b/drivers/usb/typec/tcpm/tcpci_rt1711h.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -51,13 +52,19 @@ /* 1b0 as fixed rx threshold of rd/rp 0.55V, 1b1 depends on RTCRTL4[0] */ #define BMCIO_RXDZEN BIT(0) +struct rt1711h_chip_info { + u32 rxdz_sel; + u16 did; + bool enable_pd30_extended_message; +}; + struct rt1711h_chip { struct tcpci_data data; struct tcpci *tcpci; struct device *dev; struct regulator *vbus; + const struct rt1711h_chip_info *info; bool src_en; - u16 did; }; static int rt1711h_read16(struct rt1711h_chip *chip, unsigned int reg, u16 *val) @@ -105,7 +112,7 @@ static int rt1711h_init(struct tcpci *tcpci, struct tcpci_data *tdata) return ret; /* Enable PD30 extended message for RT1715 */ - if (chip->did == RT1715_DID) { + if (chip->info->enable_pd30_extended_message) { ret = regmap_update_bits(regmap, RT1711H_RTCTRL8, RT1711H_ENEXTMSG, RT1711H_ENEXTMSG); if (ret < 0) @@ -200,10 +207,7 @@ static inline int rt1711h_init_cc_params(struct rt1711h_chip *chip, u8 status) if ((cc1 >= TYPEC_CC_RP_1_5 && cc2 < TYPEC_CC_RP_DEF) || (cc2 >= TYPEC_CC_RP_1_5 && cc1 < TYPEC_CC_RP_DEF)) { rxdz_en = BMCIO_RXDZEN; - if (chip->did == RT1715_DID) - rxdz_sel = RT1711H_BMCIO_RXDZSEL; - else - rxdz_sel = 0; + rxdz_sel = chip->info->rxdz_sel; } else { rxdz_en = 0; rxdz_sel = RT1711H_BMCIO_RXDZSEL; @@ -319,7 +323,7 @@ static int rt1711h_check_revision(struct i2c_client *i2c, struct rt1711h_chip *c ret = i2c_smbus_read_word_data(i2c, TCPC_BCD_DEV); if (ret < 0) return ret; - if (ret != chip->did) { + if (ret != chip->info->did) { dev_err(&i2c->dev, "did is not correct, 0x%04x\n", ret); return -ENODEV; } @@ -336,7 +340,7 @@ static int rt1711h_probe(struct i2c_client *client) if (!chip) return -ENOMEM; - chip->did = (size_t)device_get_match_data(&client->dev); + chip->info = i2c_get_match_data(client); ret = rt1711h_check_revision(client, chip); if (ret < 0) { @@ -391,26 +395,34 @@ static void rt1711h_remove(struct i2c_client *client) tcpci_unregister_port(chip->tcpci); } +static const struct rt1711h_chip_info rt1711h = { + .did = RT1711H_DID, +}; + +static const struct rt1711h_chip_info rt1715 = { + .rxdz_sel = RT1711H_BMCIO_RXDZSEL, + .did = RT1715_DID, + .enable_pd30_extended_message = true, +}; + static const struct i2c_device_id rt1711h_id[] = { - { "rt1711h", 0 }, - { "rt1715", 0 }, - { } + { "rt1711h", (kernel_ulong_t)&rt1711h }, + { "rt1715", (kernel_ulong_t)&rt1715 }, + {} }; MODULE_DEVICE_TABLE(i2c, rt1711h_id); -#ifdef CONFIG_OF static const struct of_device_id rt1711h_of_match[] = { - { .compatible = "richtek,rt1711h", .data = (void *)RT1711H_DID }, - { .compatible = "richtek,rt1715", .data = (void *)RT1715_DID }, - {}, + { .compatible = "richtek,rt1711h", .data = &rt1711h }, + { .compatible = "richtek,rt1715", .data = &rt1715 }, + {} }; MODULE_DEVICE_TABLE(of, rt1711h_of_match); -#endif static struct i2c_driver rt1711h_i2c_driver = { .driver = { .name = "rt1711h", - .of_match_table = of_match_ptr(rt1711h_of_match), + .of_match_table = rt1711h_of_match, }, .probe = rt1711h_probe, .remove = rt1711h_remove, diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index d962f67c95ae..058d5b853b57 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -517,9 +517,9 @@ static const char * const pd_rev[] = { ((cc) == TYPEC_CC_RP_DEF || (cc) == TYPEC_CC_RP_1_5 || \ (cc) == TYPEC_CC_RP_3_0) +/* As long as cc is pulled up, we can consider it as sink. */ #define tcpm_port_is_sink(port) \ - ((tcpm_cc_is_sink((port)->cc1) && !tcpm_cc_is_sink((port)->cc2)) || \ - (tcpm_cc_is_sink((port)->cc2) && !tcpm_cc_is_sink((port)->cc1))) + (tcpm_cc_is_sink((port)->cc1) || tcpm_cc_is_sink((port)->cc2)) #define tcpm_cc_is_source(cc) ((cc) == TYPEC_CC_RD) #define tcpm_cc_is_audio(cc) ((cc) == TYPEC_CC_RA) @@ -1625,6 +1625,9 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, if (PD_VDO_VID(p[0]) != USB_SID_PD) break; + if (IS_ERR_OR_NULL(port->partner)) + break; + if (PD_VDO_SVDM_VER(p[0]) < svdm_version) { typec_partner_set_svdm_version(port->partner, PD_VDO_SVDM_VER(p[0])); @@ -3903,6 +3906,8 @@ static void run_state_machine(struct tcpm_port *port) port->potential_contaminant = ((port->enter_state == SRC_ATTACH_WAIT && port->state == SRC_UNATTACHED) || (port->enter_state == SNK_ATTACH_WAIT && + port->state == SNK_UNATTACHED) || + (port->enter_state == SNK_DEBOUNCED && port->state == SNK_UNATTACHED)); port->enter_state = port->state; diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 37b56ce75f39..0e867f531d34 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "tps6598x.h" #include "trace.h" @@ -36,13 +37,33 @@ #define TPS_REG_STATUS 0x1a #define TPS_REG_SYSTEM_CONF 0x28 #define TPS_REG_CTRL_CONF 0x29 +#define TPS_REG_BOOT_STATUS 0x2D #define TPS_REG_POWER_STATUS 0x3f +#define TPS_REG_PD_STATUS 0x40 #define TPS_REG_RX_IDENTITY_SOP 0x48 #define TPS_REG_DATA_STATUS 0x5f +#define TPS_REG_SLEEP_CONF 0x70 /* TPS_REG_SYSTEM_CONF bits */ #define TPS_SYSCONF_PORTINFO(c) ((c) & 7) +/* + * BPMs task timeout, recommended 5 seconds + * pg.48 TPS2575 Host Interface Technical Reference + * Manual (Rev. A) + * https://www.ti.com/lit/ug/slvuc05a/slvuc05a.pdf + */ +#define TPS_BUNDLE_TIMEOUT 0x32 + +/* BPMs return code */ +#define TPS_TASK_BPMS_INVALID_BUNDLE_SIZE 0x4 +#define TPS_TASK_BPMS_INVALID_SLAVE_ADDR 0x5 +#define TPS_TASK_BPMS_INVALID_TIMEOUT 0x6 + +/* PBMc data out */ +#define TPS_PBMC_RC 0 /* Return code */ +#define TPS_PBMC_DPCS 2 /* device patch complete status */ + enum { TPS_PORTINFO_SINK, TPS_PORTINFO_SINK_ACCESSORY, @@ -68,6 +89,7 @@ enum { TPS_MODE_BOOT, TPS_MODE_BIST, TPS_MODE_DISC, + TPS_MODE_PTCH, }; static const char *const modes[] = { @@ -75,11 +97,22 @@ static const char *const modes[] = { [TPS_MODE_BOOT] = "BOOT", [TPS_MODE_BIST] = "BIST", [TPS_MODE_DISC] = "DISC", + [TPS_MODE_PTCH] = "PTCH", }; /* Unrecognized commands will be replaced with "!CMD" */ #define INVALID_CMD(_cmd_) (_cmd_ == 0x444d4321) +struct tps6598x; + +struct tipd_data { + irq_handler_t irq_handler; + int (*register_port)(struct tps6598x *tps, struct fwnode_handle *node); + void (*trace_power_status)(u16 status); + void (*trace_status)(u32 status); + int (*apply_patch)(struct tps6598x *tps); +}; + struct tps6598x { struct device *dev; struct regmap *regmap; @@ -97,9 +130,11 @@ struct tps6598x { enum power_supply_usb_type usb_type; int wakeup; + u32 status; /* status reg */ u16 pwr_status; struct delayed_work wq_poll; - irq_handler_t irq_handler; + + const struct tipd_data *data; }; static enum power_supply_property tps6598x_psy_props[] = { @@ -180,6 +215,11 @@ static inline int tps6598x_read64(struct tps6598x *tps, u8 reg, u64 *val) return tps6598x_block_read(tps, reg, val, sizeof(u64)); } +static inline int tps6598x_write8(struct tps6598x *tps, u8 reg, u8 val) +{ + return tps6598x_block_write(tps, reg, &val, sizeof(u8)); +} + static inline int tps6598x_write64(struct tps6598x *tps, u8 reg, u64 val) { return tps6598x_block_write(tps, reg, &val, sizeof(u64)); @@ -282,9 +322,10 @@ static void tps6598x_disconnect(struct tps6598x *tps, u32 status) power_supply_changed(tps->psy); } -static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, +static int tps6598x_exec_cmd_tmo(struct tps6598x *tps, const char *cmd, size_t in_len, u8 *in_data, - size_t out_len, u8 *out_data) + size_t out_len, u8 *out_data, + u32 cmd_timeout_ms, u32 res_delay_ms) { unsigned long timeout; u32 val; @@ -307,8 +348,7 @@ static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, if (ret < 0) return ret; - /* XXX: Using 1s for now, but it may not be enough for every command. */ - timeout = jiffies + msecs_to_jiffies(1000); + timeout = jiffies + msecs_to_jiffies(cmd_timeout_ms); do { ret = tps6598x_read32(tps, TPS_REG_CMD1, &val); @@ -321,6 +361,9 @@ static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, return -ETIMEDOUT; } while (val); + /* some commands require delay for the result to be available */ + mdelay(res_delay_ms); + if (out_len) { ret = tps6598x_block_read(tps, TPS_REG_DATA1, out_data, out_len); @@ -345,6 +388,14 @@ static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, return 0; } +static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd, + size_t in_len, u8 *in_data, + size_t out_len, u8 *out_data) +{ + return tps6598x_exec_cmd_tmo(tps, cmd, in_len, in_data, + out_len, out_data, 1000, 0); +} + static int tps6598x_dr_set(struct typec_port *port, enum typec_data_role role) { const char *cmd = (role == TYPEC_DEVICE) ? "SWUF" : "SWDF"; @@ -419,7 +470,9 @@ static bool tps6598x_read_status(struct tps6598x *tps, u32 *status) dev_err(tps->dev, "%s: failed to read status\n", __func__); return false; } - trace_tps6598x_status(*status); + + if (tps->data->trace_status) + tps->data->trace_status(*status); return true; } @@ -450,7 +503,9 @@ static bool tps6598x_read_power_status(struct tps6598x *tps) return false; } tps->pwr_status = pwr_status; - trace_tps6598x_power_status(pwr_status); + + if (tps->data->trace_power_status) + tps->data->trace_power_status(pwr_status); return true; } @@ -513,6 +568,65 @@ err_unlock: return IRQ_NONE; } +static bool tps6598x_has_role_changed(struct tps6598x *tps, u32 status) +{ + status ^= tps->status; + + return status & (TPS_STATUS_PORTROLE | TPS_STATUS_DATAROLE); +} + +static irqreturn_t tps25750_interrupt(int irq, void *data) +{ + struct tps6598x *tps = data; + u64 event[2] = { }; + u32 status; + int ret; + + mutex_lock(&tps->lock); + + ret = tps6598x_block_read(tps, TPS_REG_INT_EVENT1, event, 11); + if (ret) { + dev_err(tps->dev, "%s: failed to read events\n", __func__); + goto err_unlock; + } + trace_tps25750_irq(event[0]); + + if (!(event[0] | event[1])) + goto err_unlock; + + if (!tps6598x_read_status(tps, &status)) + goto err_clear_ints; + + if ((event[0] | event[1]) & TPS_REG_INT_POWER_STATUS_UPDATE) + if (!tps6598x_read_power_status(tps)) + goto err_clear_ints; + + if ((event[0] | event[1]) & TPS_REG_INT_DATA_STATUS_UPDATE) + if (!tps6598x_read_data_status(tps)) + goto err_clear_ints; + + /* + * data/port roles could be updated independently after + * a plug event. Therefore, we need to check + * for pr/dr status change to set TypeC dr/pr accordingly. + */ + if ((event[0] | event[1]) & TPS_REG_INT_PLUG_EVENT || + tps6598x_has_role_changed(tps, status)) + tps6598x_handle_plug_event(tps, status); + + tps->status = status; + +err_clear_ints: + tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event, 11); + +err_unlock: + mutex_unlock(&tps->lock); + + if (event[0] | event[1]) + return IRQ_HANDLED; + return IRQ_NONE; +} + static irqreturn_t tps6598x_interrupt(int irq, void *data) { struct tps6598x *tps = data; @@ -568,7 +682,7 @@ static void tps6598x_poll_work(struct work_struct *work) struct tps6598x *tps = container_of(to_delayed_work(work), struct tps6598x, wq_poll); - tps->irq_handler(0, tps); + tps->data->irq_handler(0, tps); queue_delayed_work(system_power_efficient_wq, &tps->wq_poll, msecs_to_jiffies(POLL_INTERVAL)); } @@ -582,12 +696,15 @@ static int tps6598x_check_mode(struct tps6598x *tps) if (ret) return ret; - switch (match_string(modes, ARRAY_SIZE(modes), mode)) { + ret = match_string(modes, ARRAY_SIZE(modes), mode); + + switch (ret) { case TPS_MODE_APP: - return 0; + case TPS_MODE_PTCH: + return ret; case TPS_MODE_BOOT: dev_warn(tps->dev, "dead-battery condition\n"); - return 0; + return ret; case TPS_MODE_BIST: case TPS_MODE_DISC: default: @@ -697,95 +814,16 @@ static int devm_tps6598_psy_register(struct tps6598x *tps) return PTR_ERR_OR_ZERO(tps->psy); } -static int tps6598x_probe(struct i2c_client *client) +static int +tps6598x_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode) { - irq_handler_t irq_handler = tps6598x_interrupt; - struct device_node *np = client->dev.of_node; - struct typec_capability typec_cap = { }; - struct tps6598x *tps; - struct fwnode_handle *fwnode; - u32 status; - u32 conf; - u32 vid; int ret; - u64 mask1; - - tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); - if (!tps) - return -ENOMEM; - - mutex_init(&tps->lock); - tps->dev = &client->dev; - - tps->regmap = devm_regmap_init_i2c(client, &tps6598x_regmap_config); - if (IS_ERR(tps->regmap)) - return PTR_ERR(tps->regmap); - - ret = tps6598x_read32(tps, TPS_REG_VID, &vid); - if (ret < 0 || !vid) - return -ENODEV; - - /* - * Checking can the adapter handle SMBus protocol. If it can not, the - * driver needs to take care of block reads separately. - */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - tps->i2c_protocol = true; - - if (np && of_device_is_compatible(np, "apple,cd321x")) { - /* Switch CD321X chips to the correct system power state */ - ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0); - if (ret) - return ret; - - /* CD321X chips have all interrupts masked initially */ - mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE | - APPLE_CD_REG_INT_DATA_STATUS_UPDATE | - APPLE_CD_REG_INT_PLUG_EVENT; - - irq_handler = cd321x_interrupt; - } else { - /* Enable power status, data status and plug event interrupts */ - mask1 = TPS_REG_INT_POWER_STATUS_UPDATE | - TPS_REG_INT_DATA_STATUS_UPDATE | - TPS_REG_INT_PLUG_EVENT; - } - - tps->irq_handler = irq_handler; - /* Make sure the controller has application firmware running */ - ret = tps6598x_check_mode(tps); - if (ret) - return ret; - - ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1); - if (ret) - return ret; - - ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); - if (ret < 0) - goto err_clear_mask; - trace_tps6598x_status(status); + u32 conf; + struct typec_capability typec_cap = { }; ret = tps6598x_read32(tps, TPS_REG_SYSTEM_CONF, &conf); - if (ret < 0) - goto err_clear_mask; - - /* - * This fwnode has a "compatible" property, but is never populated as a - * struct device. Instead we simply parse it to read the properties. - * This breaks fw_devlink=on. To maintain backward compatibility - * with existing DT files, we work around this by deleting any - * fwnode_links to/from this fwnode. - */ - fwnode = device_get_named_child_node(&client->dev, "connector"); - if (fwnode) - fw_devlink_purge_absent_suppliers(fwnode); - - tps->role_sw = fwnode_usb_role_switch_get(fwnode); - if (IS_ERR(tps->role_sw)) { - ret = PTR_ERR(tps->role_sw); - goto err_fwnode_put; - } + if (ret) + return ret; typec_cap.revision = USB_TYPEC_REV_1_2; typec_cap.pd_revision = 0x200; @@ -818,19 +856,424 @@ static int tps6598x_probe(struct i2c_client *client) typec_cap.data = TYPEC_PORT_DFP; break; default: + return -ENODEV; + } + + tps->port = typec_register_port(tps->dev, &typec_cap); + if (IS_ERR(tps->port)) + return PTR_ERR(tps->port); + + return 0; +} + +static int +tps25750_write_firmware(struct tps6598x *tps, + u8 bpms_addr, const u8 *data, size_t len) +{ + struct i2c_client *client = to_i2c_client(tps->dev); + int ret; + u8 slave_addr; + int timeout; + + slave_addr = client->addr; + timeout = client->adapter->timeout; + + /* + * binary configuration size is around ~16Kbytes + * which might take some time to finish writing it + */ + client->adapter->timeout = msecs_to_jiffies(5000); + client->addr = bpms_addr; + + ret = regmap_raw_write(tps->regmap, data[0], &data[1], len - 1); + + client->addr = slave_addr; + client->adapter->timeout = timeout; + + return ret; +} + +static int +tps25750_exec_pbms(struct tps6598x *tps, u8 *in_data, size_t in_len) +{ + int ret; + u8 rc; + + ret = tps6598x_exec_cmd_tmo(tps, "PBMs", in_len, in_data, + sizeof(rc), &rc, 4000, 0); + if (ret) + return ret; + + switch (rc) { + case TPS_TASK_BPMS_INVALID_BUNDLE_SIZE: + dev_err(tps->dev, "%s: invalid fw size\n", __func__); + return -EINVAL; + case TPS_TASK_BPMS_INVALID_SLAVE_ADDR: + dev_err(tps->dev, "%s: invalid slave address\n", __func__); + return -EINVAL; + case TPS_TASK_BPMS_INVALID_TIMEOUT: + dev_err(tps->dev, "%s: timed out\n", __func__); + return -ETIMEDOUT; + default: + break; + } + + return 0; +} + +static int tps25750_abort_patch_process(struct tps6598x *tps) +{ + int ret; + + ret = tps6598x_exec_cmd(tps, "PBMe", 0, NULL, 0, NULL); + if (ret) + return ret; + + ret = tps6598x_check_mode(tps); + if (ret != TPS_MODE_PTCH) + dev_err(tps->dev, "failed to switch to \"PTCH\" mode\n"); + + return ret; +} + +static int tps25750_start_patch_burst_mode(struct tps6598x *tps) +{ + int ret; + const struct firmware *fw; + const char *firmware_name; + struct { + u32 fw_size; + u8 addr; + u8 timeout; + } __packed bpms_data; + u32 addr; + struct device_node *np = tps->dev->of_node; + + ret = device_property_read_string(tps->dev, "firmware-name", + &firmware_name); + if (ret) + return ret; + + ret = request_firmware(&fw, firmware_name, tps->dev); + if (ret) { + dev_err(tps->dev, "failed to retrieve \"%s\"\n", firmware_name); + return ret; + } + + if (fw->size == 0) { + ret = -EINVAL; + goto release_fw; + } + + ret = of_property_match_string(np, "reg-names", "patch-address"); + if (ret < 0) { + dev_err(tps->dev, "failed to get patch-address %d\n", ret); + return ret; + } + + ret = of_property_read_u32_index(np, "reg", ret, &addr); + if (ret) + return ret; + + if (addr == 0 || (addr >= 0x20 && addr <= 0x23)) { + dev_err(tps->dev, "wrong patch address %u\n", addr); + return -EINVAL; + } + + bpms_data.addr = (u8)addr; + bpms_data.fw_size = fw->size; + bpms_data.timeout = TPS_BUNDLE_TIMEOUT; + + ret = tps25750_exec_pbms(tps, (u8 *)&bpms_data, sizeof(bpms_data)); + if (ret) + goto release_fw; + + ret = tps25750_write_firmware(tps, bpms_data.addr, fw->data, fw->size); + if (ret) { + dev_err(tps->dev, "Failed to write patch %s of %zu bytes\n", + firmware_name, fw->size); + goto release_fw; + } + + /* + * A delay of 500us is required after the firmware is written + * based on pg.62 in tps6598x Host Interface Technical + * Reference Manual + * https://www.ti.com/lit/ug/slvuc05a/slvuc05a.pdf + */ + udelay(500); + +release_fw: + release_firmware(fw); + + return ret; +} + +static int tps25750_complete_patch_process(struct tps6598x *tps) +{ + int ret; + u8 out_data[40]; + u8 dummy[2] = { }; + + /* + * Without writing something to DATA_IN, this command would + * return an error + */ + ret = tps6598x_exec_cmd_tmo(tps, "PBMc", sizeof(dummy), dummy, + sizeof(out_data), out_data, 2000, 20); + if (ret) + return ret; + + if (out_data[TPS_PBMC_RC]) { + dev_err(tps->dev, + "%s: pbmc failed: %u\n", __func__, + out_data[TPS_PBMC_RC]); + return -EIO; + } + + if (out_data[TPS_PBMC_DPCS]) { + dev_err(tps->dev, + "%s: failed device patch complete status: %u\n", + __func__, out_data[TPS_PBMC_DPCS]); + return -EIO; + } + + return 0; +} + +static int tps25750_apply_patch(struct tps6598x *tps) +{ + int ret; + unsigned long timeout; + u64 status = 0; + + ret = tps6598x_block_read(tps, TPS_REG_BOOT_STATUS, &status, 5); + if (ret) + return ret; + /* + * Nothing to be done if the configuration + * is being loaded from EERPOM + */ + if (status & TPS_BOOT_STATUS_I2C_EEPROM_PRESENT) + goto wait_for_app; + + ret = tps25750_start_patch_burst_mode(tps); + if (ret) { + tps25750_abort_patch_process(tps); + return ret; + } + + ret = tps25750_complete_patch_process(tps); + if (ret) + return ret; + +wait_for_app: + timeout = jiffies + msecs_to_jiffies(1000); + + do { + ret = tps6598x_check_mode(tps); + if (ret < 0) + return ret; + + if (time_is_before_jiffies(timeout)) + return -ETIMEDOUT; + + } while (ret != TPS_MODE_APP); + + /* + * The dead battery flag may be triggered when the controller + * port is connected to a device that can source power and + * attempts to power up both the controller and the board it is on. + * To restore controller functionality, it is necessary to clear + * this flag + */ + if (status & TPS_BOOT_STATUS_DEAD_BATTERY_FLAG) { + ret = tps6598x_exec_cmd(tps, "DBfg", 0, NULL, 0, NULL); + if (ret) { + dev_err(tps->dev, "failed to clear dead battery %d\n", ret); + return ret; + } + } + + dev_info(tps->dev, "controller switched to \"APP\" mode\n"); + + return 0; +}; + +static int tps25750_init(struct tps6598x *tps) +{ + int ret; + + ret = tps->data->apply_patch(tps); + if (ret) + return ret; + + ret = tps6598x_write8(tps, TPS_REG_SLEEP_CONF, + TPS_SLEEP_CONF_SLEEP_MODE_ALLOWED); + if (ret) + dev_warn(tps->dev, + "%s: failed to enable sleep mode: %d\n", + __func__, ret); + + return 0; +} + +static int +tps25750_register_port(struct tps6598x *tps, struct fwnode_handle *fwnode) +{ + struct typec_capability typec_cap = { }; + const char *data_role; + u8 pd_status; + int ret; + + ret = tps6598x_read8(tps, TPS_REG_PD_STATUS, &pd_status); + if (ret) + return ret; + + ret = fwnode_property_read_string(fwnode, "data-role", &data_role); + if (ret) { + dev_err(tps->dev, "data-role not found: %d\n", ret); + return ret; + } + + ret = typec_find_port_data_role(data_role); + if (ret < 0) { + dev_err(tps->dev, "unknown data-role: %s\n", data_role); + return ret; + } + + typec_cap.data = ret; + typec_cap.revision = USB_TYPEC_REV_1_3; + typec_cap.pd_revision = 0x300; + typec_cap.driver_data = tps; + typec_cap.ops = &tps6598x_ops; + typec_cap.fwnode = fwnode; + typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE; + + switch (TPS_PD_STATUS_PORT_TYPE(pd_status)) { + case TPS_PD_STATUS_PORT_TYPE_SINK_SOURCE: + case TPS_PD_STATUS_PORT_TYPE_SOURCE_SINK: + typec_cap.type = TYPEC_PORT_DRP; + break; + case TPS_PD_STATUS_PORT_TYPE_SINK: + typec_cap.type = TYPEC_PORT_SNK; + break; + case TPS_PD_STATUS_PORT_TYPE_SOURCE: + typec_cap.type = TYPEC_PORT_SRC; + break; + default: + return -ENODEV; + } + + tps->port = typec_register_port(tps->dev, &typec_cap); + if (IS_ERR(tps->port)) + return PTR_ERR(tps->port); + + return 0; +} + +static int tps6598x_probe(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + struct tps6598x *tps; + struct fwnode_handle *fwnode; + u32 status; + u32 vid; + int ret; + u64 mask1; + bool is_tps25750; + + tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); + if (!tps) + return -ENOMEM; + + mutex_init(&tps->lock); + tps->dev = &client->dev; + + tps->regmap = devm_regmap_init_i2c(client, &tps6598x_regmap_config); + if (IS_ERR(tps->regmap)) + return PTR_ERR(tps->regmap); + + is_tps25750 = device_is_compatible(tps->dev, "ti,tps25750"); + if (!is_tps25750) { + ret = tps6598x_read32(tps, TPS_REG_VID, &vid); + if (ret < 0 || !vid) + return -ENODEV; + } + + /* + * Checking can the adapter handle SMBus protocol. If it can not, the + * driver needs to take care of block reads separately. + */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + tps->i2c_protocol = true; + + if (np && of_device_is_compatible(np, "apple,cd321x")) { + /* Switch CD321X chips to the correct system power state */ + ret = cd321x_switch_power_state(tps, TPS_SYSTEM_POWER_STATE_S0); + if (ret) + return ret; + + /* CD321X chips have all interrupts masked initially */ + mask1 = APPLE_CD_REG_INT_POWER_STATUS_UPDATE | + APPLE_CD_REG_INT_DATA_STATUS_UPDATE | + APPLE_CD_REG_INT_PLUG_EVENT; + + } else { + /* Enable power status, data status and plug event interrupts */ + mask1 = TPS_REG_INT_POWER_STATUS_UPDATE | + TPS_REG_INT_DATA_STATUS_UPDATE | + TPS_REG_INT_PLUG_EVENT; + } + + tps->data = device_get_match_data(tps->dev); + if (!tps->data) + return -EINVAL; + + /* Make sure the controller has application firmware running */ + ret = tps6598x_check_mode(tps); + if (ret < 0) + return ret; + + if (is_tps25750 && ret == TPS_MODE_PTCH) { + ret = tps25750_init(tps); + if (ret) + return ret; + } + + ret = tps6598x_write64(tps, TPS_REG_INT_MASK1, mask1); + if (ret) + goto err_reset_controller; + + if (!tps6598x_read_status(tps, &status)) { ret = -ENODEV; - goto err_role_put; + goto err_clear_mask; + } + + /* + * This fwnode has a "compatible" property, but is never populated as a + * struct device. Instead we simply parse it to read the properties. + * This breaks fw_devlink=on. To maintain backward compatibility + * with existing DT files, we work around this by deleting any + * fwnode_links to/from this fwnode. + */ + fwnode = device_get_named_child_node(&client->dev, "connector"); + if (fwnode) + fw_devlink_purge_absent_suppliers(fwnode); + + tps->role_sw = fwnode_usb_role_switch_get(fwnode); + if (IS_ERR(tps->role_sw)) { + ret = PTR_ERR(tps->role_sw); + goto err_fwnode_put; } ret = devm_tps6598_psy_register(tps); if (ret) goto err_role_put; - tps->port = typec_register_port(&client->dev, &typec_cap); - if (IS_ERR(tps->port)) { - ret = PTR_ERR(tps->port); + ret = tps->data->register_port(tps, fwnode); + if (ret) goto err_role_put; - } if (status & TPS_STATUS_PLUG_PRESENT) { ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status); @@ -845,7 +1288,7 @@ static int tps6598x_probe(struct i2c_client *client) if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, - irq_handler, + tps->data->irq_handler, IRQF_SHARED | IRQF_ONESHOT, dev_name(&client->dev), tps); } else { @@ -879,6 +1322,10 @@ err_fwnode_put: fwnode_handle_put(fwnode); err_clear_mask: tps6598x_write64(tps, TPS_REG_INT_MASK1, 0); +err_reset_controller: + /* Reset PD controller to remove any applied patch */ + if (is_tps25750) + tps6598x_exec_cmd_tmo(tps, "GAID", 0, NULL, 0, NULL, 2000, 0); return ret; } @@ -889,9 +1336,14 @@ static void tps6598x_remove(struct i2c_client *client) if (!client->irq) cancel_delayed_work_sync(&tps->wq_poll); + devm_free_irq(tps->dev, client->irq, tps); tps6598x_disconnect(tps, 0); typec_unregister_port(tps->port); usb_role_switch_put(tps->role_sw); + + /* Reset PD controller to remove any applied patch */ + if (device_is_compatible(tps->dev, "ti,tps25750")) + tps6598x_exec_cmd_tmo(tps, "GAID", 0, NULL, 0, NULL, 2000, 0); } static int __maybe_unused tps6598x_suspend(struct device *dev) @@ -914,6 +1366,17 @@ static int __maybe_unused tps6598x_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct tps6598x *tps = i2c_get_clientdata(client); + int ret; + + ret = tps6598x_check_mode(tps); + if (ret < 0) + return ret; + + if (device_is_compatible(tps->dev, "ti,tps25750") && ret == TPS_MODE_PTCH) { + ret = tps25750_init(tps); + if (ret) + return ret; + } if (tps->wakeup) { disable_irq_wake(client->irq); @@ -931,9 +1394,32 @@ static const struct dev_pm_ops tps6598x_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(tps6598x_suspend, tps6598x_resume) }; +static const struct tipd_data cd321x_data = { + .irq_handler = cd321x_interrupt, + .register_port = tps6598x_register_port, + .trace_power_status = trace_tps6598x_power_status, + .trace_status = trace_tps6598x_status, +}; + +static const struct tipd_data tps6598x_data = { + .irq_handler = tps6598x_interrupt, + .register_port = tps6598x_register_port, + .trace_power_status = trace_tps6598x_power_status, + .trace_status = trace_tps6598x_status, +}; + +static const struct tipd_data tps25750_data = { + .irq_handler = tps25750_interrupt, + .register_port = tps25750_register_port, + .trace_power_status = trace_tps25750_power_status, + .trace_status = trace_tps25750_status, + .apply_patch = tps25750_apply_patch, +}; + static const struct of_device_id tps6598x_of_match[] = { - { .compatible = "ti,tps6598x", }, - { .compatible = "apple,cd321x", }, + { .compatible = "ti,tps6598x", &tps6598x_data}, + { .compatible = "apple,cd321x", &cd321x_data}, + { .compatible = "ti,tps25750", &tps25750_data}, {} }; MODULE_DEVICE_TABLE(of, tps6598x_of_match); diff --git a/drivers/usb/typec/tipd/tps6598x.h b/drivers/usb/typec/tipd/tps6598x.h index 527857549d69..01609bf509e4 100644 --- a/drivers/usb/typec/tipd/tps6598x.h +++ b/drivers/usb/typec/tipd/tps6598x.h @@ -161,6 +161,25 @@ #define TPS_POWER_STATUS_BC12_STATUS_CDP 2 #define TPS_POWER_STATUS_BC12_STATUS_DCP 3 +/* TPS25750_REG_POWER_STATUS bits */ +#define TPS25750_POWER_STATUS_CHARGER_DETECT_STATUS_MASK GENMASK(7, 4) +#define TPS25750_POWER_STATUS_CHARGER_DETECT_STATUS(p) \ + TPS_FIELD_GET(TPS25750_POWER_STATUS_CHARGER_DETECT_STATUS_MASK, (p)) +#define TPS25750_POWER_STATUS_CHARGER_ADVERTISE_STATUS_MASK GENMASK(9, 8) +#define TPS25750_POWER_STATUS_CHARGER_ADVERTISE_STATUS(p) \ + TPS_FIELD_GET(TPS25750_POWER_STATUS_CHARGER_ADVERTISE_STATUS_MASK, (p)) + +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DISABLED 0 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_IN_PROGRESS 1 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_NONE 2 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_SPD 3 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_BC_1_2_CPD 4 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_BC_1_2_DPD 5 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_1_DCP 6 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_2_DCP 7 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_3_DCP 8 +#define TPS25750_POWER_STATUS_CHARGER_DET_STATUS_1_2V_DCP 9 + /* TPS_REG_DATA_STATUS bits */ #define TPS_DATA_STATUS_DATA_CONNECTION BIT(0) #define TPS_DATA_STATUS_UPSIDE_DOWN BIT(1) @@ -199,4 +218,21 @@ #define TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_A BIT(2) #define TPS_DATA_STATUS_DP_SPEC_PIN_ASSIGNMENT_B (BIT(2) | BIT(1)) +/* BOOT STATUS REG*/ +#define TPS_BOOT_STATUS_DEAD_BATTERY_FLAG BIT(2) +#define TPS_BOOT_STATUS_I2C_EEPROM_PRESENT BIT(3) + +/* PD STATUS REG */ +#define TPS_REG_PD_STATUS_PORT_TYPE_MASK GENMASK(5, 4) +#define TPS_PD_STATUS_PORT_TYPE(x) \ + TPS_FIELD_GET(TPS_REG_PD_STATUS_PORT_TYPE_MASK, x) + +#define TPS_PD_STATUS_PORT_TYPE_SINK_SOURCE 0 +#define TPS_PD_STATUS_PORT_TYPE_SINK 1 +#define TPS_PD_STATUS_PORT_TYPE_SOURCE 2 +#define TPS_PD_STATUS_PORT_TYPE_SOURCE_SINK 3 + +/* SLEEP CONF REG */ +#define TPS_SLEEP_CONF_SLEEP_MODE_ALLOWED BIT(0) + #endif /* __TPS6598X_H__ */ diff --git a/drivers/usb/typec/tipd/trace.h b/drivers/usb/typec/tipd/trace.h index 12cad1bde7cc..0669cca12ea1 100644 --- a/drivers/usb/typec/tipd/trace.h +++ b/drivers/usb/typec/tipd/trace.h @@ -74,6 +74,13 @@ { APPLE_CD_REG_INT_DATA_STATUS_UPDATE, "DATA_STATUS_UPDATE" }, \ { APPLE_CD_REG_INT_STATUS_UPDATE, "STATUS_UPDATE" }) +#define show_tps25750_irq_flags(flags) \ + __print_flags_u64(flags, "|", \ + { TPS_REG_INT_PLUG_EVENT, "PLUG_EVENT" }, \ + { TPS_REG_INT_POWER_STATUS_UPDATE, "POWER_STATUS_UPDATE" }, \ + { TPS_REG_INT_STATUS_UPDATE, "STATUS_UPDATE" }, \ + { TPS_REG_INT_PD_STATUS_UPDATE, "PD_STATUS_UPDATE" }) + #define TPS6598X_STATUS_FLAGS_MASK (GENMASK(31, 0) ^ (TPS_STATUS_CONN_STATE_MASK | \ TPS_STATUS_PP_5V0_SWITCH_MASK | \ TPS_STATUS_PP_HV_SWITCH_MASK | \ @@ -84,6 +91,14 @@ TPS_STATUS_USB_HOST_PRESENT_MASK | \ TPS_STATUS_LEGACY_MASK)) +#define TPS25750_STATUS_FLAGS_MASK (GENMASK(31, 0) ^ (TPS_STATUS_CONN_STATE_MASK | \ + GENMASK(19, 7) | \ + TPS_STATUS_VBUS_STATUS_MASK | \ + TPS_STATUS_USB_HOST_PRESENT_MASK | \ + TPS_STATUS_LEGACY_MASK | \ + BIT(26) | \ + GENMASK(31, 28))) + #define show_status_conn_state(status) \ __print_symbolic(TPS_STATUS_CONN_STATE((status)), \ { TPS_STATUS_CONN_STATE_CONN_WITH_R_A, "conn-Ra" }, \ @@ -141,6 +156,14 @@ { TPS_STATUS_HIGH_VOLAGE_WARNING, "HIGH_VOLAGE_WARNING" }, \ { TPS_STATUS_HIGH_LOW_VOLTAGE_WARNING, "HIGH_LOW_VOLTAGE_WARNING" }) +#define show_tps25750_status_flags(flags) \ + __print_flags((flags & TPS25750_STATUS_FLAGS_MASK), "|", \ + { TPS_STATUS_PLUG_PRESENT, "PLUG_PRESENT" }, \ + { TPS_STATUS_PLUG_UPSIDE_DOWN, "UPSIDE_DOWN" }, \ + { TPS_STATUS_PORTROLE, "PORTROLE" }, \ + { TPS_STATUS_DATAROLE, "DATAROLE" }, \ + { TPS_STATUS_BIST, "BIST" }) + #define show_power_status_source_sink(power_status) \ __print_symbolic(TPS_POWER_STATUS_SOURCESINK(power_status), \ { 1, "sink" }, \ @@ -159,6 +182,19 @@ { TPS_POWER_STATUS_BC12_STATUS_CDP, "cdp" }, \ { TPS_POWER_STATUS_BC12_STATUS_SDP, "sdp" }) +#define show_tps25750_power_status_charger_detect_status(power_status) \ + __print_symbolic(TPS25750_POWER_STATUS_CHARGER_DETECT_STATUS(power_status), \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DISABLED, "disabled"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_IN_PROGRESS, "in progress"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_NONE, "none"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_SPD, "spd"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_BC_1_2_CPD, "cpd"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_BC_1_2_DPD, "dpd"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_1_DCP, "divider 1 dcp"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_2_DCP, "divider 2 dcp"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_DIV_3_DCP, "divider 3 dpc"}, \ + { TPS25750_POWER_STATUS_CHARGER_DET_STATUS_1_2V_DCP, "1.2V dpc"}) + #define TPS_DATA_STATUS_FLAGS_MASK (GENMASK(31, 0) ^ (TPS_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK | \ TPS_DATA_STATUS_TBT_CABLE_SPEED_MASK | \ TPS_DATA_STATUS_TBT_CABLE_GEN_MASK)) @@ -230,6 +266,21 @@ TRACE_EVENT(cd321x_irq, show_cd321x_irq_flags(__entry->event)) ); +TRACE_EVENT(tps25750_irq, + TP_PROTO(u64 event), + TP_ARGS(event), + + TP_STRUCT__entry( + __field(u64, event) + ), + + TP_fast_assign( + __entry->event = event; + ), + + TP_printk("event=%s", show_tps25750_irq_flags(__entry->event)) +); + TRACE_EVENT(tps6598x_status, TP_PROTO(u32 status), TP_ARGS(status), @@ -257,6 +308,27 @@ TRACE_EVENT(tps6598x_status, ) ); +TRACE_EVENT(tps25750_status, + TP_PROTO(u32 status), + TP_ARGS(status), + + TP_STRUCT__entry( + __field(u32, status) + ), + + TP_fast_assign( + __entry->status = status; + ), + + TP_printk("conn: %s, vbus: %s, usb-host: %s, legacy: %s, flags: %s", + show_status_conn_state(__entry->status), + show_status_vbus_status(__entry->status), + show_status_usb_host_present(__entry->status), + show_status_legacy(__entry->status), + show_tps25750_status_flags(__entry->status) + ) +); + TRACE_EVENT(tps6598x_power_status, TP_PROTO(u16 power_status), TP_ARGS(power_status), @@ -277,6 +349,26 @@ TRACE_EVENT(tps6598x_power_status, ) ); +TRACE_EVENT(tps25750_power_status, + TP_PROTO(u16 power_status), + TP_ARGS(power_status), + + TP_STRUCT__entry( + __field(u16, power_status) + ), + + TP_fast_assign( + __entry->power_status = power_status; + ), + + TP_printk("conn: %d, pwr-role: %s, typec: %s, charger detect: %s", + !!TPS_POWER_STATUS_CONNECTION(__entry->power_status), + show_power_status_source_sink(__entry->power_status), + show_power_status_typec_status(__entry->power_status), + show_tps25750_power_status_charger_detect_status(__entry->power_status) + ) +); + TRACE_EVENT(tps6598x_data_status, TP_PROTO(u32 data_status), TP_ARGS(data_status), diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/displayport.c index 73cd5bf35047..d9d3c91125ca 100644 --- a/drivers/usb/typec/ucsi/displayport.c +++ b/drivers/usb/typec/ucsi/displayport.c @@ -315,7 +315,7 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, struct ucsi_dp *dp; /* We can't rely on the firmware with the capabilities. */ - desc->vdo |= DP_CAP_DP_SIGNALING | DP_CAP_RECEPTACLE; + desc->vdo |= DP_CAP_DP_SIGNALLING(0) | DP_CAP_RECEPTACLE; /* Claiming that we support all pin assignments */ desc->vdo |= all_assignments << 8; diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 607061a37eca..449c125f6f87 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -501,8 +501,8 @@ static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc, case NVIDIA_FTB_DP_OFFSET: if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DBG_VDO) alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DP_VDO | - DP_CAP_DP_SIGNALING | DP_CAP_USB | - DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_E)); + DP_CAP_DP_SIGNALLING(0) | DP_CAP_USB | + DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_E)); break; case NVIDIA_FTB_DBG_OFFSET: if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DP_VDO) diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c index bb1854b3311d..db6e248f8208 100644 --- a/drivers/usb/typec/ucsi/ucsi_glink.c +++ b/drivers/usb/typec/ucsi/ucsi_glink.c @@ -8,9 +8,13 @@ #include #include #include +#include +#include #include #include "ucsi.h" +#define PMIC_GLINK_MAX_PORTS 2 + #define UCSI_BUF_SIZE 48 #define MSG_TYPE_REQ_RESP 1 @@ -52,6 +56,9 @@ struct ucsi_notify_ind_msg { struct pmic_glink_ucsi { struct device *dev; + struct gpio_desc *port_orientation[PMIC_GLINK_MAX_PORTS]; + struct typec_switch *port_switch[PMIC_GLINK_MAX_PORTS]; + struct pmic_glink_client *client; struct ucsi *ucsi; @@ -220,8 +227,20 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) } con_num = UCSI_CCI_CONNECTOR(cci); - if (con_num) + if (con_num) { + if (con_num < PMIC_GLINK_MAX_PORTS && + ucsi->port_orientation[con_num - 1]) { + int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]); + + if (orientation >= 0) { + typec_switch_set(ucsi->port_switch[con_num - 1], + orientation ? TYPEC_ORIENTATION_REVERSE + : TYPEC_ORIENTATION_NORMAL); + } + } + ucsi_connector_change(ucsi->ucsi, con_num); + } if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) { ucsi->sync_val = -EBUSY; @@ -282,6 +301,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, { struct pmic_glink_ucsi *ucsi; struct device *dev = &adev->dev; + struct fwnode_handle *fwnode; int ret; ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL); @@ -309,6 +329,38 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, ucsi_set_drvdata(ucsi->ucsi, ucsi); + device_for_each_child_node(dev, fwnode) { + struct gpio_desc *desc; + u32 port; + + ret = fwnode_property_read_u32(fwnode, "reg", &port); + if (ret < 0) { + dev_err(dev, "missing reg property of %pOFn\n", fwnode); + return ret; + } + + if (port >= PMIC_GLINK_MAX_PORTS) { + dev_warn(dev, "invalid connector number, ignoring\n"); + continue; + } + + desc = devm_gpiod_get_index_optional(&adev->dev, "orientation", port, GPIOD_IN); + + /* If GPIO isn't found, continue */ + if (!desc) + continue; + + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), + "unable to acquire orientation gpio\n"); + ucsi->port_orientation[port] = desc; + + ucsi->port_switch[port] = fwnode_typec_switch_get(fwnode); + if (IS_ERR(ucsi->port_switch[port])) + return dev_err_probe(dev, PTR_ERR(ucsi->port_switch[port]), + "failed to acquire orientation-switch\n"); + } + ucsi->client = devm_pmic_glink_register_client(dev, PMIC_GLINK_OWNER_USBC, pmic_glink_ucsi_callback, diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 9c6954aad6c8..ce625b1ce9a5 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -464,8 +464,13 @@ static void stub_disconnect(struct usb_device *udev) /* release port */ rc = usb_hub_release_port(udev->parent, udev->portnum, (struct usb_dev_state *) udev); - if (rc) { - dev_dbg(&udev->dev, "unable to release port\n"); + /* + * NOTE: If a HUB disconnect triggered disconnect of the down stream + * device usb_hub_release_port will return -ENODEV so we can safely ignore + * that error here. + */ + if (rc && (rc != -ENODEV)) { + dev_dbg(&udev->dev, "unable to release port (%i)\n", rc); return; } diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 37d1fc34e8a5..82650c11e451 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1140,6 +1140,7 @@ static int hcd_name_to_id(const char *name) static int vhci_setup(struct usb_hcd *hcd) { struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller)); + if (usb_hcd_is_primary_hcd(hcd)) { vhci->vhci_hcd_hs = hcd_to_vhci_hcd(hcd); vhci->vhci_hcd_hs->vhci = vhci; @@ -1493,13 +1494,10 @@ static struct platform_driver vhci_driver = { static void del_platform_devices(void) { - struct platform_device *pdev; int i; for (i = 0; i < vhci_num_controllers; i++) { - pdev = vhcis[i].pdev; - if (pdev != NULL) - platform_device_unregister(pdev); + platform_device_unregister(vhcis[i].pdev); vhcis[i].pdev = NULL; } sysfs_remove_link(&platform_bus.kobj, driver_name); @@ -1519,45 +1517,33 @@ static int __init vhci_hcd_init(void) if (vhcis == NULL) return -ENOMEM; - for (i = 0; i < vhci_num_controllers; i++) { - vhcis[i].pdev = platform_device_alloc(driver_name, i); - if (!vhcis[i].pdev) { - i--; - while (i >= 0) - platform_device_put(vhcis[i--].pdev); - ret = -ENOMEM; - goto err_device_alloc; - } - } - for (i = 0; i < vhci_num_controllers; i++) { - void *vhci = &vhcis[i]; - ret = platform_device_add_data(vhcis[i].pdev, &vhci, sizeof(void *)); - if (ret) - goto err_driver_register; - } - ret = platform_driver_register(&vhci_driver); if (ret) goto err_driver_register; for (i = 0; i < vhci_num_controllers; i++) { - ret = platform_device_add(vhcis[i].pdev); + void *vhci = &vhcis[i]; + struct platform_device_info pdevinfo = { + .name = driver_name, + .id = i, + .data = &vhci, + .size_data = sizeof(void *), + }; + + vhcis[i].pdev = platform_device_register_full(&pdevinfo); + ret = PTR_ERR_OR_ZERO(vhcis[i].pdev); if (ret < 0) { - i--; - while (i >= 0) - platform_device_del(vhcis[i--].pdev); + while (i--) + platform_device_unregister(vhcis[i].pdev); goto err_add_hcd; } } - return ret; + return 0; err_add_hcd: platform_driver_unregister(&vhci_driver); err_driver_register: - for (i = 0; i < vhci_num_controllers; i++) - platform_device_put(vhcis[i].pdev); -err_device_alloc: kfree(vhcis); return ret; } diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 30577b1d3de5..83c2d7329ca5 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -7,9 +7,9 @@ menu "Console display driver support" config VGA_CONSOLE bool "VGA text console" if EXPERT || !X86 - depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC && !SUPERH && \ - (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ - !ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML + depends on ALPHA || IA64 || X86 || \ + (ARM && ARCH_FOOTBRIDGE) || \ + (MIPS && (MIPS_MALTA || SIBYTE_BCM112X || SIBYTE_SB1250 || SIBYTE_BCM1x80 || SNI_RM)) select APERTURE_HELPERS if (DRM || FB || VFIO_PCI_CORE) default y help @@ -52,7 +52,7 @@ config DUMMY_CONSOLE config DUMMY_CONSOLE_COLUMNS int "Initial number of console screen columns" - depends on DUMMY_CONSOLE && !ARM + depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE default 160 if PARISC default 80 help @@ -62,8 +62,9 @@ config DUMMY_CONSOLE_COLUMNS config DUMMY_CONSOLE_ROWS int "Initial number of console screen rows" - depends on DUMMY_CONSOLE && !ARM + depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE default 64 if PARISC + default 30 if ARM default 25 help On PA-RISC, the default value is 64, which should fit a 1280x1024 diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index f1711b2f9ff0..14af5d9e13b0 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -18,9 +18,10 @@ * Dummy console driver */ -#if defined(__arm__) -#define DUMMY_COLUMNS screen_info.orig_video_cols -#define DUMMY_ROWS screen_info.orig_video_lines +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_VGA_CONSOLE) +#include +#define DUMMY_COLUMNS vgacon_screen_info.orig_video_cols +#define DUMMY_ROWS vgacon_screen_info.orig_video_lines #else /* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ #define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7ad047bcae17..8ef1579fa57f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -89,6 +89,8 @@ static int vga_video_font_height; static int vga_scan_lines __read_mostly; static unsigned int vga_rolled_over; /* last vc_origin offset before wrap */ +static struct screen_info *vga_si; + static bool vga_hardscroll_enabled; static bool vga_hardscroll_user_enable = true; @@ -153,8 +155,9 @@ static const char *vgacon_startup(void) u16 saved1, saved2; volatile u16 *p; - if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB || - screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) { + if (!vga_si || + vga_si->orig_video_isVGA == VIDEO_TYPE_VLFB || + vga_si->orig_video_isVGA == VIDEO_TYPE_EFI) { no_vga: #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -164,29 +167,29 @@ static const char *vgacon_startup(void) #endif } - /* boot_params.screen_info reasonably initialized? */ - if ((screen_info.orig_video_lines == 0) || - (screen_info.orig_video_cols == 0)) + /* vga_si reasonably initialized? */ + if ((vga_si->orig_video_lines == 0) || + (vga_si->orig_video_cols == 0)) goto no_vga; /* VGA16 modes are not handled by VGACON */ - if ((screen_info.orig_video_mode == 0x0D) || /* 320x200/4 */ - (screen_info.orig_video_mode == 0x0E) || /* 640x200/4 */ - (screen_info.orig_video_mode == 0x10) || /* 640x350/4 */ - (screen_info.orig_video_mode == 0x12) || /* 640x480/4 */ - (screen_info.orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */ + if ((vga_si->orig_video_mode == 0x0D) || /* 320x200/4 */ + (vga_si->orig_video_mode == 0x0E) || /* 640x200/4 */ + (vga_si->orig_video_mode == 0x10) || /* 640x350/4 */ + (vga_si->orig_video_mode == 0x12) || /* 640x480/4 */ + (vga_si->orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */ goto no_vga; - vga_video_num_lines = screen_info.orig_video_lines; - vga_video_num_columns = screen_info.orig_video_cols; + vga_video_num_lines = vga_si->orig_video_lines; + vga_video_num_columns = vga_si->orig_video_cols; vgastate.vgabase = NULL; - if (screen_info.orig_video_mode == 7) { + if (vga_si->orig_video_mode == 7) { /* Monochrome display */ vga_vram_base = 0xb0000; vga_video_port_reg = VGA_CRT_IM; vga_video_port_val = VGA_CRT_DM; - if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { + if ((vga_si->orig_video_ega_bx & 0xff) != 0x10) { static struct resource ega_console_resource = { .name = "ega", .flags = IORESOURCE_IO, @@ -223,12 +226,12 @@ static const char *vgacon_startup(void) vga_vram_base = 0xb8000; vga_video_port_reg = VGA_CRT_IC; vga_video_port_val = VGA_CRT_DC; - if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { + if ((vga_si->orig_video_ega_bx & 0xff) != 0x10) { int i; vga_vram_size = 0x8000; - if (!screen_info.orig_video_isVGA) { + if (!vga_si->orig_video_isVGA) { static struct resource ega_console_resource = { .name = "ega", .flags = IORESOURCE_IO, @@ -319,14 +322,14 @@ static const char *vgacon_startup(void) || vga_video_type == VIDEO_TYPE_VGAC || vga_video_type == VIDEO_TYPE_EGAM) { vga_hardscroll_enabled = vga_hardscroll_user_enable; - vga_default_font_height = screen_info.orig_video_points; - vga_video_font_height = screen_info.orig_video_points; + vga_default_font_height = vga_si->orig_video_points; + vga_video_font_height = vga_si->orig_video_points; /* This may be suboptimal but is a safe bet - go with it */ vga_scan_lines = vga_video_font_height * vga_video_num_lines; } - vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH; + vgacon_xres = vga_si->orig_video_cols * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; return display_desc; @@ -371,7 +374,7 @@ static void vgacon_init(struct vc_data *c, int init) /* Only set the default if the user didn't deliberately override it */ if (global_cursor_default == -1) global_cursor_default = - !(screen_info.flags & VIDEO_FLAGS_NOCURSOR); + !(vga_si->flags & VIDEO_FLAGS_NOCURSOR); } static void vgacon_deinit(struct vc_data *c) @@ -589,7 +592,7 @@ static int vgacon_switch(struct vc_data *c) { int x = c->vc_cols * VGA_FONTWIDTH; int y = c->vc_rows * c->vc_cell_height; - int rows = screen_info.orig_video_lines * vga_default_font_height/ + int rows = vga_si->orig_video_lines * vga_default_font_height/ c->vc_cell_height; /* * We need to save screen size here as it's the only way @@ -609,7 +612,7 @@ static int vgacon_switch(struct vc_data *c) if ((vgacon_xres != x || vgacon_yres != y) && (!(vga_video_num_columns % 2) && - vga_video_num_columns <= screen_info.orig_video_cols && + vga_video_num_columns <= vga_si->orig_video_cols && vga_video_num_lines <= rows)) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -1056,13 +1059,13 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, * Ho ho! Someone (svgatextmode, eh?) may have reprogrammed * the video mode! Set the new defaults then and go away. */ - screen_info.orig_video_cols = width; - screen_info.orig_video_lines = height; + vga_si->orig_video_cols = width; + vga_si->orig_video_lines = height; vga_default_font_height = c->vc_cell_height; return 0; } - if (width % 2 || width > screen_info.orig_video_cols || - height > (screen_info.orig_video_lines * vga_default_font_height)/ + if (width % 2 || width > vga_si->orig_video_cols || + height > (vga_si->orig_video_lines * vga_default_font_height)/ c->vc_cell_height) return -EINVAL; @@ -1092,8 +1095,8 @@ static void vgacon_save_screen(struct vc_data *c) * console initialization routines. */ vga_bootup_console = 1; - c->state.x = screen_info.orig_x; - c->state.y = screen_info.orig_y; + c->state.x = vga_si->orig_x; + c->state.y = vga_si->orig_y; } /* We can't copy in more than the size of the video buffer, @@ -1186,4 +1189,13 @@ const struct consw vga_con = { }; EXPORT_SYMBOL(vga_con); +void vgacon_register_screen(struct screen_info *si) +{ + if (!si || vga_si) + return; + + conswitchp = &vga_con; + vga_si = si; +} + MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 96fdc7301481..53693c826ebd 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -364,7 +364,7 @@ config FB_IMSTT config FB_VGA16 tristate "VGA 16-color graphics support" - depends on FB && (X86 || PPC) + depends on FB && X86 select APERTURE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 2e27c6bd8044..bf59daf862fc 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1010,7 +1010,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) goto getmem_done; } pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); - } else { + } else if (IS_ENABLED(CONFIG_SYSFB)) { base = screen_info.lfb_base; size = screen_info.lfb_size; } @@ -1056,13 +1056,13 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) getmem_done: aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); - if (gen2vm) { + if (!gen2vm) { + pci_dev_put(pdev); + } else if (IS_ENABLED(CONFIG_SYSFB)) { /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ screen_info.lfb_size = 0; screen_info.lfb_base = 0; screen_info.orig_video_isVGA = 0; - } else { - pci_dev_put(pdev); } return 0; diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index ac21942d5311..b485e9198201 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -185,8 +185,6 @@ static inline void setindex(int index) /* Check if the video mode is supported by the driver */ static inline int check_mode_supported(const struct screen_info *si) { - /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ -#if defined(CONFIG_X86) /* only EGA and VGA in 16 color graphic mode are supported */ if (si->orig_video_isVGA != VIDEO_TYPE_EGAC && si->orig_video_isVGA != VIDEO_TYPE_VGAC) @@ -197,7 +195,7 @@ static inline int check_mode_supported(const struct screen_info *si) si->orig_video_mode != 0x10 && /* 640x350/4 (EGA) */ si->orig_video_mode != 0x12) /* 640x480/4 (VGA) */ return -ENODEV; -#endif + return 0; } @@ -1340,12 +1338,7 @@ static int vga16fb_probe(struct platform_device *dev) printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); par = info->par; -#if defined(CONFIG_X86) par->isVGA = si->orig_video_isVGA == VIDEO_TYPE_VGAC; -#else - /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ - par->isVGA = si->orig_video_isVGA; -#endif par->palette_blanked = 0; par->vesa_blanked = 0; diff --git a/include/linux/console.h b/include/linux/console.h index e4fc6f7c1496..779d388af8a0 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -101,6 +101,13 @@ extern const struct consw dummy_con; /* dummy console buffer */ extern const struct consw vga_con; /* VGA text console */ extern const struct consw newport_con; /* SGI Newport console */ +struct screen_info; +#ifdef CONFIG_VGA_CONSOLE +void vgacon_register_screen(struct screen_info *si); +#else +static inline void vgacon_register_screen(struct screen_info *si) { } +#endif + int con_is_bound(const struct consw *csw); int do_unregister_con_driver(const struct consw *csw); int do_take_over_console(const struct consw *sw, int first, int last, int deflt); @@ -469,7 +476,7 @@ enum con_flush_mode { CONSOLE_REPLAY_ALL, }; -extern int add_preferred_console(char *name, int idx, char *options); +extern int add_preferred_console(const char *name, const short idx, char *options); extern void console_force_preferred_locked(struct console *con); extern void register_console(struct console *); extern int unregister_console(struct console *); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c3656e590213..3df70d6131c8 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -517,8 +517,6 @@ static inline const char *dma_chan_name(struct dma_chan *chan) return dev_name(&chan->dev->device); } -void dma_chan_cleanup(struct kref *kref); - /** * typedef dma_filter_fn - callback filter for dma_request_channel * @chan: channel to be reviewed diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index aa3c28781248..f458469c5ce5 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -956,4 +956,8 @@ struct cdx_device_id { __u32 override_only; }; +struct vchiq_device_id { + char name[32]; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bb6f073bc159..89f7b6c63598 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -588,6 +588,85 @@ struct uart_port { void *private_data; /* generic platform data pointer */ }; +/** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock(struct uart_port *up) +{ + spin_lock(&up->lock); +} + +/** + * uart_port_lock_irq - Lock the UART port and disable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock_irq(struct uart_port *up) +{ + spin_lock_irq(&up->lock); +} + +/** + * uart_port_lock_irqsave - Lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + */ +static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) +{ + spin_lock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_trylock - Try to lock the UART port + * @up: Pointer to UART port structure + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock(struct uart_port *up) +{ + return spin_trylock(&up->lock); +} + +/** + * uart_port_trylock_irqsave - Try to lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) +{ + return spin_trylock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_unlock - Unlock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock(struct uart_port *up) +{ + spin_unlock(&up->lock); +} + +/** + * uart_port_unlock_irq - Unlock the UART port and re-enable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock_irq(struct uart_port *up) +{ + spin_unlock_irq(&up->lock); +} + +/** + * uart_port_unlock_irqrestore - Unlock the UART port, restore interrupts + * @up: Pointer to UART port structure + * @flags: The saved interrupt flags for restore + */ +static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) +{ + spin_unlock_irqrestore(&up->lock, flags); +} + static inline int serial_port_in(struct uart_port *up, int offset) { return up->serial_in(up, offset); @@ -956,14 +1035,14 @@ static inline void uart_unlock_and_check_sysrq(struct uart_port *port) u8 sysrq_ch; if (!port->has_sysrq) { - spin_unlock(&port->lock); + uart_port_unlock(port); return; } sysrq_ch = port->sysrq_ch; port->sysrq_ch = 0; - spin_unlock(&port->lock); + uart_port_unlock(port); if (sysrq_ch) handle_sysrq(sysrq_ch); @@ -975,14 +1054,14 @@ static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port u8 sysrq_ch; if (!port->has_sysrq) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } sysrq_ch = port->sysrq_ch; port->sysrq_ch = 0; - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (sysrq_ch) handle_sysrq(sysrq_ch); @@ -998,12 +1077,12 @@ static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch) } static inline void uart_unlock_and_check_sysrq(struct uart_port *port) { - spin_unlock(&port->lock); + uart_port_unlock(port); } static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port, unsigned long flags) { - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } #endif /* CONFIG_MAGIC_SYSRQ_SERIAL */ diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index 02333f47c994..6151c210d987 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -175,7 +175,7 @@ void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir); * enum tb_link_width - Thunderbolt/USB4 link width * @TB_LINK_WIDTH_SINGLE: Single lane link * @TB_LINK_WIDTH_DUAL: Dual lane symmetric link - * @TB_LINK_WIDTH_ASYM_TX: Dual lane asymmetric Gen 4 link with 3 trasmitters + * @TB_LINK_WIDTH_ASYM_TX: Dual lane asymmetric Gen 4 link with 3 transmitters * @TB_LINK_WIDTH_ASYM_RX: Dual lane asymmetric Gen 4 link with 3 receivers */ enum tb_link_width { diff --git a/include/linux/tty.h b/include/linux/tty.h index f002d0f25db7..4b6340ac2af2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -390,14 +390,12 @@ int vcs_init(void); extern const struct class tty_class; /** - * tty_kref_get - get a tty reference - * @tty: tty device + * tty_kref_get - get a tty reference + * @tty: tty device * - * Return a new reference to a tty object. The caller must hold - * sufficient locks/counts to ensure that their existing reference cannot - * go away + * Returns: a new reference to a tty object. The caller must hold sufficient + * locks/counts to ensure that their existing reference cannot go away */ - static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) { if (tty) @@ -416,8 +414,8 @@ unsigned int tty_chars_in_buffer(struct tty_struct *tty); unsigned int tty_write_room(struct tty_struct *tty); void tty_driver_flush_buffer(struct tty_struct *tty); void tty_unthrottle(struct tty_struct *tty); -int tty_throttle_safe(struct tty_struct *tty); -int tty_unthrottle_safe(struct tty_struct *tty); +bool tty_throttle_safe(struct tty_struct *tty); +bool tty_unthrottle_safe(struct tty_struct *tty); int tty_do_resize(struct tty_struct *tty, struct winsize *ws); int tty_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -435,14 +433,13 @@ void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); /** - * tty_get_baud_rate - get tty bit rates - * @tty: tty to query + * tty_get_baud_rate - get tty bit rates + * @tty: tty to query * - * Returns the baud rate as an integer for this terminal. The - * termios lock must be held by the caller and the terminal bit - * flags may be updated. + * Returns: the baud rate as an integer for this terminal. The termios lock + * must be held by the caller and the terminal bit flags may be updated. * - * Locking: none + * Locking: none */ static inline speed_t tty_get_baud_rate(struct tty_struct *tty) { diff --git a/include/linux/usb.h b/include/linux/usb.h index a21074861f91..8c61643acd49 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1823,22 +1823,6 @@ void *usb_alloc_coherent(struct usb_device *dev, size_t size, void usb_free_coherent(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma); -#if 0 -struct urb *usb_buffer_map(struct urb *urb); -void usb_buffer_dmasync(struct urb *urb); -void usb_buffer_unmap(struct urb *urb); -#endif - -struct scatterlist; -int usb_buffer_map_sg(const struct usb_device *dev, int is_in, - struct scatterlist *sg, int nents); -#if 0 -void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, - struct scatterlist *sg, int n_hw_ents); -#endif -void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, - struct scatterlist *sg, int n_hw_ents); - /*-------------------------------------------------------------------* * SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 0b4f2d5faa08..5a7f96684ea2 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -64,6 +64,7 @@ struct ci_hdrc_platform_data { #define CI_HDRC_PMQOS BIT(15) #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) +#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18) enum usb_dr_mode dr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 6014340ba980..af3cd2aae4bc 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -35,6 +35,14 @@ * are ready. The control transfer will then be kept from completing till * all the function drivers that requested for USB_GADGET_DELAYED_STAUS * invoke usb_composite_setup_continue(). + * + * NOTE: USB_GADGET_DELAYED_STATUS must not be used in UDC drivers: they + * must delay completing the status stage for 0-length control transfers + * regardless of the whether USB_GADGET_DELAYED_STATUS is returned from + * the gadget driver's setup() callback. + * Currently, a number of UDC drivers rely on USB_GADGET_DELAYED_STATUS, + * which is a bug. These drivers must be fixed and USB_GADGET_DELAYED_STATUS + * must be contained within the composite framework. */ #define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 75bda0783395..6532beb587b1 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -711,6 +711,15 @@ static inline int usb_gadget_check_config(struct usb_gadget *gadget) * get_interface. Setting a configuration (or interface) is where * endpoints should be activated or (config 0) shut down. * + * The gadget driver's setup() callback does not have to queue a response to + * ep0 within the setup() call, the driver can do it after setup() returns. + * The UDC driver must wait until such a response is queued before proceeding + * with the data/status stages of the control transfer. + * + * NOTE: Currently, a number of UDC drivers rely on USB_GADGET_DELAYED_STATUS + * being returned from the setup() callback, which is a bug. See the comment + * next to USB_GADGET_DELAYED_STATUS for details. + * * (Note that only the default control endpoint is supported. Neither * hosts nor devices generally support control traffic except to ep0.) * diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 61d4f0b793dc..00724b4f6e12 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -484,8 +484,25 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev, extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); +#ifdef CONFIG_USB_PCI_AMD extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); +static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev, + const struct hc_driver *driver) +{ + if (!usb_hcd_amd_remote_wakeup_quirk(dev)) + return false; + if (driver->flags & (HCD_USB11 | HCD_USB3)) + return true; + return false; +} +#else /* CONFIG_USB_PCI_AMD */ +static inline bool usb_hcd_amd_resume_bug(struct pci_dev *dev, + const struct hc_driver *driver) +{ + return false; +} +#endif extern const struct dev_pm_ops usb_hcd_pci_pm_ops; #endif /* CONFIG_USB_PCI */ diff --git a/include/linux/usb/ljca.h b/include/linux/usb/ljca.h new file mode 100644 index 000000000000..47661feda96c --- /dev/null +++ b/include/linux/usb/ljca.h @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Intel Corporation. All rights reserved. + */ +#ifndef _LINUX_USB_LJCA_H_ +#define _LINUX_USB_LJCA_H_ + +#include +#include +#include +#include + +#define LJCA_MAX_GPIO_NUM 64 + +#define auxiliary_dev_to_ljca_client(auxiliary_dev) \ + container_of(auxiliary_dev, struct ljca_client, auxdev) + +struct ljca_adapter; + +/** + * typedef ljca_event_cb_t - event callback function signature + * + * @context: the execution context of who registered this callback + * @cmd: the command from device for this event + * @evt_data: the event data payload + * @len: the event data payload length + * + * The callback function is called in interrupt context and the data payload is + * only valid during the call. If the user needs later access of the data, it + * must copy it. + */ +typedef void (*ljca_event_cb_t)(void *context, u8 cmd, const void *evt_data, int len); + +/** + * struct ljca_client - represent a ljca client device + * + * @type: ljca client type + * @id: ljca client id within same client type + * @link: ljca client on the same ljca adapter + * @auxdev: auxiliary device object + * @adapter: ljca adapter the ljca client sit on + * @context: the execution context of the event callback + * @event_cb: ljca client driver register this callback to get + * firmware asynchronous rx buffer pending notifications + * @event_cb_lock: spinlock to protect event callback + */ +struct ljca_client { + u8 type; + u8 id; + struct list_head link; + struct auxiliary_device auxdev; + struct ljca_adapter *adapter; + + void *context; + ljca_event_cb_t event_cb; + /* lock to protect event_cb */ + spinlock_t event_cb_lock; +}; + +/** + * struct ljca_gpio_info - ljca gpio client device info + * + * @num: ljca gpio client device pin number + * @valid_pin_map: ljca gpio client device valid pin mapping + */ +struct ljca_gpio_info { + unsigned int num; + DECLARE_BITMAP(valid_pin_map, LJCA_MAX_GPIO_NUM); +}; + +/** + * struct ljca_i2c_info - ljca i2c client device info + * + * @id: ljca i2c client device identification number + * @capacity: ljca i2c client device capacity + * @intr_pin: ljca i2c client device interrupt pin number if exists + */ +struct ljca_i2c_info { + u8 id; + u8 capacity; + u8 intr_pin; +}; + +/** + * struct ljca_spi_info - ljca spi client device info + * + * @id: ljca spi client device identification number + * @capacity: ljca spi client device capacity + */ +struct ljca_spi_info { + u8 id; + u8 capacity; +}; + +/** + * ljca_register_event_cb - register a callback function to receive events + * + * @client: ljca client device + * @event_cb: callback function + * @context: execution context of event callback + * + * Return: 0 in case of success, negative value in case of error + */ +int ljca_register_event_cb(struct ljca_client *client, ljca_event_cb_t event_cb, void *context); + +/** + * ljca_unregister_event_cb - unregister the callback function for an event + * + * @client: ljca client device + */ +void ljca_unregister_event_cb(struct ljca_client *client); + +/** + * ljca_transfer - issue a LJCA command and wait for a response + * + * @client: ljca client device + * @cmd: the command to be sent to the device + * @obuf: the buffer to be sent to the device; it can be NULL if the user + * doesn't need to transmit data with this command + * @obuf_len: the size of the buffer to be sent to the device; it should + * be 0 when obuf is NULL + * @ibuf: any data associated with the response will be copied here; it can be + * NULL if the user doesn't need the response data + * @ibuf_len: must be initialized to the input buffer size + * + * Return: the actual length of response data for success, negative value for errors + */ +int ljca_transfer(struct ljca_client *client, u8 cmd, const u8 *obuf, + u8 obuf_len, u8 *ibuf, u8 ibuf_len); + +/** + * ljca_transfer_noack - issue a LJCA command without a response + * + * @client: ljca client device + * @cmd: the command to be sent to the device + * @obuf: the buffer to be sent to the device; it can be NULL if the user + * doesn't need to transmit data with this command + * @obuf_len: the size of the buffer to be sent to the device + * + * Return: 0 for success, negative value for errors + */ +int ljca_transfer_noack(struct ljca_client *client, u8 cmd, const u8 *obuf, + u8 obuf_len); + +#endif diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index c59fb79a42e8..eb626af0e4e7 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -228,6 +228,7 @@ enum pd_pdo_type { #define PDO_FIXED_UNCHUNK_EXT BIT(24) /* Unchunked Extended Message supported (Source) */ #define PDO_FIXED_FRS_CURR_MASK (BIT(24) | BIT(23)) /* FR_Swap Current (Sink) */ #define PDO_FIXED_FRS_CURR_SHIFT 23 +#define PDO_FIXED_PEAK_CURR_SHIFT 20 #define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ #define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ diff --git a/include/linux/usb/pd_vdo.h b/include/linux/usb/pd_vdo.h index b057250704e8..3a747938cdab 100644 --- a/include/linux/usb/pd_vdo.h +++ b/include/linux/usb/pd_vdo.h @@ -376,6 +376,7 @@ | ((vbm) & 0x3) << 9 | (sbu) << 8 | (sbut) << 7 | ((cur) & 0x3) << 5 \ | (vbt) << 4 | (sopp) << 3 | ((spd) & 0x7)) +#define VDO_TYPEC_CABLE_SPEED(vdo) ((vdo) & 0x7) #define VDO_TYPEC_CABLE_TYPE(vdo) (((vdo) >> 18) & 0x3) /* diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index d418c55523a7..372898d9eeb0 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -5,16 +5,6 @@ * Copyright (C) 2011 Renesas Solutions Corp. * Copyright (C) 2019 Renesas Electronics Corporation * Kuninori Morimoto - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * */ #ifndef RENESAS_USB_H #define RENESAS_USB_H diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 8fa781207970..a05d6f6f2536 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -202,6 +202,8 @@ struct typec_cable_desc { * @accessory: Audio, Debug or none. * @identity: Discover Identity command data * @pd_revision: USB Power Delivery Specification Revision if supported + * @attach: Notification about attached USB device + * @deattach: Notification about removed USB device * * Details about a partner that is attached to USB Type-C port. If @identity * member exists when partner is registered, a directory named "identity" is @@ -217,6 +219,9 @@ struct typec_partner_desc { enum typec_accessory accessory; struct usb_pd_identity *identity; u16 pd_revision; /* 0300H = "3.0" */ + + void (*attach)(struct typec_partner *partner, struct device *dev); + void (*deattach)(struct typec_partner *partner, struct device *dev); }; /** @@ -335,4 +340,36 @@ int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_ int typec_partner_set_usb_power_delivery(struct typec_partner *partner, struct usb_power_delivery *pd); +/** + * struct typec_connector - Representation of Type-C port for external drivers + * @attach: notification about device removal + * @deattach: notification about device removal + * + * Drivers that control the USB and other ports (DisplayPorts, etc.), that are + * connected to the Type-C connectors, can use these callbacks to inform the + * Type-C connector class about connections and disconnections. That information + * can then be used by the typec-port drivers to power on or off parts that are + * needed or not needed - as an example, in USB mode if USB2 device is + * enumerated, USB3 components (retimers, phys, and what have you) do not need + * to be powered on. + * + * The attached (enumerated) devices will be liked with the typec-partner device. + */ +struct typec_connector { + void (*attach)(struct typec_connector *con, struct device *dev); + void (*deattach)(struct typec_connector *con, struct device *dev); +}; + +static inline void typec_attach(struct typec_connector *con, struct device *dev) +{ + if (con && con->attach) + con->attach(con, dev); +} + +static inline void typec_deattach(struct typec_connector *con, struct device *dev) +{ + if (con && con->deattach) + con->deattach(con, dev); +} + #endif /* __LINUX_USB_TYPEC_H */ diff --git a/include/linux/usb/typec_dp.h b/include/linux/usb/typec_dp.h index 8d09c2f0a9b8..1f358098522d 100644 --- a/include/linux/usb/typec_dp.h +++ b/include/linux/usb/typec_dp.h @@ -67,8 +67,10 @@ enum { #define DP_CAP_UFP_D 1 #define DP_CAP_DFP_D 2 #define DP_CAP_DFP_D_AND_UFP_D 3 -#define DP_CAP_DP_SIGNALING BIT(2) /* Always set */ -#define DP_CAP_GEN2 BIT(3) /* Reserved after v1.0b */ +#define DP_CAP_DP_SIGNALLING(_cap_) (((_cap_) & GENMASK(5, 2)) >> 2) +#define DP_CAP_SIGNALLING_HBR3 1 +#define DP_CAP_SIGNALLING_UHBR10 2 +#define DP_CAP_SIGNALLING_UHBR20 3 #define DP_CAP_RECEPTACLE BIT(6) #define DP_CAP_USB BIT(7) #define DP_CAP_DFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(15, 8)) >> 8) @@ -78,6 +80,13 @@ enum { DP_CAP_UFP_D_PIN_ASSIGN(_cap_) : DP_CAP_DFP_D_PIN_ASSIGN(_cap_)) #define DP_CAP_PIN_ASSIGN_DFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \ DP_CAP_DFP_D_PIN_ASSIGN(_cap_) : DP_CAP_UFP_D_PIN_ASSIGN(_cap_)) +#define DP_CAP_UHBR_13_5_SUPPORT BIT(26) +#define DP_CAP_CABLE_TYPE(_cap_) (((_cap_) & GENMASK(29, 28)) >> 28) +#define DP_CAP_CABLE_TYPE_PASSIVE 0 +#define DP_CAP_CABLE_TYPE_RE_TIMER 1 +#define DP_CAP_CABLE_TYPE_RE_DRIVER 2 +#define DP_CAP_CABLE_TYPE_OPTICAL 3 +#define DP_CAP_DPAM_VERSION BIT(30) /* DisplayPort Status Update VDO bits */ #define DP_STATUS_CONNECTION(_status_) ((_status_) & 3) @@ -97,13 +106,24 @@ enum { #define DP_CONF_CURRENTLY(_conf_) ((_conf_) & 3) #define DP_CONF_UFP_U_AS_DFP_D BIT(0) #define DP_CONF_UFP_U_AS_UFP_D BIT(1) -#define DP_CONF_SIGNALING_DP BIT(2) -#define DP_CONF_SIGNALING_GEN_2 BIT(3) /* Reserved after v1.0b */ +#define DP_CONF_SIGNALLING_MASK GENMASK(5, 2) +#define DP_CONF_SIGNALLING_SHIFT 2 +#define DP_CONF_SIGNALLING_HBR3 1 +#define DP_CONF_SIGNALLING_UHBR10 2 +#define DP_CONF_SIGNALLING_UHBR20 3 #define DP_CONF_PIN_ASSIGNEMENT_SHIFT 8 #define DP_CONF_PIN_ASSIGNEMENT_MASK GENMASK(15, 8) /* Helper for setting/getting the pin assignment value to the configuration */ #define DP_CONF_SET_PIN_ASSIGN(_a_) ((_a_) << 8) #define DP_CONF_GET_PIN_ASSIGN(_conf_) (((_conf_) & GENMASK(15, 8)) >> 8) +#define DP_CONF_UHBR13_5_SUPPORT BIT(26) +#define DP_CONF_CABLE_TYPE_MASK GENMASK(29, 28) +#define DP_CONF_CABLE_TYPE_SHIFT 28 +#define DP_CONF_CABLE_TYPE_PASSIVE 0 +#define DP_CONF_CABLE_TYPE_RE_TIMER 1 +#define DP_CONF_CABLE_TYPE_RE_DRIVER 2 +#define DP_CONF_CABLE_TYPE_OPTICAL 3 +#define DP_CONF_DPAM_VERSION BIT(30) #endif /* __USB_TYPEC_DP_H */ diff --git a/include/linux/usb/typec_tbt.h b/include/linux/usb/typec_tbt.h index 63dd44b72e0c..c7a2153bd6f5 100644 --- a/include/linux/usb/typec_tbt.h +++ b/include/linux/usb/typec_tbt.h @@ -46,6 +46,7 @@ struct typec_thunderbolt_data { #define TBT_CABLE_OPTICAL BIT(21) #define TBT_CABLE_RETIMER BIT(22) #define TBT_CABLE_LINK_TRAINING BIT(23) +#define TBT_CABLE_ACTIVE_PASSIVE BIT(25) #define TBT_SET_CABLE_SPEED(_s_) (((_s_) & GENMASK(2, 0)) << 16) #define TBT_SET_CABLE_ROUNDED(_g_) (((_g_) & GENMASK(1, 0)) << 19) diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index 4c878d84dbda..3a93f17ca943 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (c) 2022/23 Siemens Mobility GmbH */ #ifndef _LINUX_GSMMUX_H #define _LINUX_GSMMUX_H diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h index 606b52e88ce3..3d1987e1bb2d 100644 --- a/include/uapi/linux/idxd.h +++ b/include/uapi/linux/idxd.h @@ -31,6 +31,7 @@ enum idxd_scmd_stat { IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, IDXD_SCMD_DEV_EVL_ERR = 0x80120000, + IDXD_SCMD_WQ_NO_DRV_NAME = 0x80200000, }; #define IDXD_SCMD_SOFTERR_MASK 0x80000000 diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index add349889d0a..9c007a106330 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -1,22 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* - * linux/drivers/char/serial_core.h - * * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _UAPILINUX_SERIAL_CORE_H #define _UAPILINUX_SERIAL_CORE_H @@ -27,6 +11,8 @@ * The type definitions. These are from Ted Ts'o's serial.h * By historical reasons the values from 0 to 13 are defined * in the include/uapi/linux/serial.h, do not define them here. + * Values 0 to 19 are used by setserial from busybox and must never + * be modified. */ #define PORT_NS16550A 14 #define PORT_XSCALE 15 @@ -245,4 +231,7 @@ /* Sunplus UART */ #define PORT_SUNPLUS 123 +/* Generic type identifier for ports which type is not important to userspace. */ +#define PORT_GENERIC (-1) + #endif /* _UAPILINUX_SERIAL_CORE_H */ diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index 08b3527e1b93..9c987b04e2d0 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -49,6 +49,7 @@ #define UART_IIR_FIFO_ENABLED_8250 0x00 /* 8250: no FIFO */ #define UART_IIR_FIFO_ENABLED_16550 0x80 /* 16550: (broken/unusable) FIFO */ #define UART_IIR_FIFO_ENABLED_16550A 0xc0 /* 16550A: FIFO enabled */ +#define UART_IIR_FIFO_ENABLED_16750 0xe0 /* 16750: 64 bytes FIFO enabled */ #define UART_FCR 2 /* Out: FIFO Control Register */ #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ diff --git a/include/uapi/linux/usb/raw_gadget.h b/include/uapi/linux/usb/raw_gadget.h index c7d2199134d7..f0224a8dc858 100644 --- a/include/uapi/linux/usb/raw_gadget.h +++ b/include/uapi/linux/usb/raw_gadget.h @@ -44,6 +44,16 @@ enum usb_raw_event_type { /* This event is queued when a new control request arrived to ep0. */ USB_RAW_EVENT_CONTROL = 2, + /* + * These events are queued when the gadget driver is suspended, + * resumed, reset, or disconnected. Note that some UDCs (e.g. dwc2) + * report a disconnect event instead of a reset. + */ + USB_RAW_EVENT_SUSPEND = 3, + USB_RAW_EVENT_RESUME = 4, + USB_RAW_EVENT_RESET = 5, + USB_RAW_EVENT_DISCONNECT = 6, + /* The list might grow in the future. */ }; @@ -54,8 +64,8 @@ enum usb_raw_event_type { * actual length of the fetched event data. * @data: A buffer to store the fetched event data. * - * Currently the fetched data buffer is empty for USB_RAW_EVENT_CONNECT, - * and contains struct usb_ctrlrequest for USB_RAW_EVENT_CONTROL. + * The fetched event data buffer contains struct usb_ctrlrequest for + * USB_RAW_EVENT_CONTROL and is empty for other events. */ struct usb_raw_event { __u32 type; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e50ec9362da9..afd1dcd2a0de 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2386,12 +2386,20 @@ static void set_user_specified(struct console_cmdline *c, bool user_specified) console_set_on_cmdline = 1; } -static int __add_preferred_console(char *name, int idx, char *options, +static int __add_preferred_console(const char *name, const short idx, char *options, char *brl_options, bool user_specified) { struct console_cmdline *c; int i; + /* + * We use a signed short index for struct console for device drivers to + * indicate a not yet assigned index or port. However, a negative index + * value is not valid for preferred console. + */ + if (idx < 0) + return -EINVAL; + /* * See if this tty is not yet registered, and * if we have a slot free. @@ -2495,7 +2503,7 @@ __setup("console=", console_setup); * commonly to provide a default console (ie from PROM variables) when * the user has not supplied one. */ -int add_preferred_console(char *name, int idx, char *options) +int add_preferred_console(const char *name, const short idx, char *options) { return __add_preferred_console(name, idx, options, NULL, false); } diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 7a659aa3114a..e91a3c38143b 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -271,5 +271,8 @@ int main(void) DEVID_FIELD(cdx_device_id, class_mask); DEVID_FIELD(cdx_device_id, override_only); + DEVID(vchiq_device_id); + DEVID_FIELD(vchiq_device_id, name); + return 0; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 2b28faca9585..5bc02ce92958 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1486,6 +1486,14 @@ static int do_cdx_entry(const char *filename, void *symval, return 1; } +static int do_vchiq_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, vchiq_device_id, name); + sprintf(alias, "vchiq:%s", *name); + + return 1; +} + /* Does namelen bytes of name exactly match the symbol? */ static bool sym_is(const char *name, unsigned namelen, const char *symbol) { @@ -1566,6 +1574,7 @@ static const struct devtable devtable[] = { {"dfl", SIZE_dfl_device_id, do_dfl_entry}, {"ishtp", SIZE_ishtp_device_id, do_ishtp_entry}, {"cdx", SIZE_cdx_device_id, do_cdx_entry}, + {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, }; /* Create MODULE_ALIAS() statements.