Pull networking updates from David Miller: "Highlights: 1) Maintain the TCP retransmit queue using an rbtree, with 1GB windows at 100Gb this really has become necessary. From Eric Dumazet. 2) Multi-program support for cgroup+bpf, from Alexei Starovoitov. 3) Perform broadcast flooding in hardware in mv88e6xxx, from Andrew Lunn. 4) Add meter action support to openvswitch, from Andy Zhou. 5) Add a data meta pointer for BPF accessible packets, from Daniel Borkmann. 6) Namespace-ify almost all TCP sysctl knobs, from Eric Dumazet. 7) Turn on Broadcom Tags in b53 driver, from Florian Fainelli. 8) More work to move the RTNL mutex down, from Florian Westphal. 9) Add 'bpftool' utility, to help with bpf program introspection. From Jakub Kicinski. 10) Add new 'cpumap' type for XDP_REDIRECT action, from Jesper Dangaard Brouer. 11) Support 'blocks' of transformations in the packet scheduler which can span multiple network devices, from Jiri Pirko. 12) TC flower offload support in cxgb4, from Kumar Sanghvi. 13) Priority based stream scheduler for SCTP, from Marcelo Ricardo Leitner. 14) Thunderbolt networking driver, from Amir Levy and Mika Westerberg. 15) Add RED qdisc offloadability, and use it in mlxsw driver. From Nogah Frankel. 16) eBPF based device controller for cgroup v2, from Roman Gushchin. 17) Add some fundamental tracepoints for TCP, from Song Liu. 18) Remove garbage collection from ipv6 route layer, this is a significant accomplishment. From Wei Wang. 19) Add multicast route offload support to mlxsw, from Yotam Gigi" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2177 commits) tcp: highest_sack fix geneve: fix fill_info when link down bpf: fix lockdep splat net: cdc_ncm: GetNtbFormat endian fix openvswitch: meter: fix NULL pointer dereference in ovs_meter_cmd_reply_start netem: remove unnecessary 64 bit modulus netem: use 64 bit divide by rate tcp: Namespace-ify sysctl_tcp_default_congestion_control net: Protect iterations over net::fib_notifier_ops in fib_seq_sum() ipv6: set all.accept_dad to 0 by default uapi: fix linux/tls.h userspace compilation error usbnet: ipheth: prevent TX queue timeouts when device not ready vhost_net: conditionally enable tx polling uapi: fix linux/rxrpc.h userspace compilation errors net: stmmac: fix LPI transitioning for dwmac4 atm: horizon: Fix irq release error net-sysfs: trigger netlink notification on ifalias change via sysfs openvswitch: Using kfree_rcu() to simplify the code openvswitch: Make local function ovs_nsh_key_attr_size() static openvswitch: Fix return value check in ovs_meter_cmd_features() ...
Unified · Split
| @@ -110,3 +110,51 @@ Description: When new NVM image is written to the non-active NVM · 109 unmodified lines | ||
| 110 | 110 | is directly the status value from the DMA configuration |
| 111 | 111 | based mailbox before the device is power cycled. Writing |
| 112 | 112 | 0 here clears the status. |
| 113 | + | |
| 114 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/key | |
| 115 | +Date: Jan 2018 | |
| 116 | +KernelVersion: 4.15 | |
| 117 | +Contact: thunderbolt-software@lists.01.org | |
| 118 | +Description: This contains name of the property directory the XDomain | |
| 119 | + service exposes. This entry describes the protocol in | |
| 120 | + question. Following directories are already reserved by | |
| 121 | + the Apple XDomain specification: | |
| 122 | + | |
| 123 | + network: IP/ethernet over Thunderbolt | |
| 124 | + targetdm: Target disk mode protocol over Thunderbolt | |
| 125 | + extdisp: External display mode protocol over Thunderbolt | |
| 126 | + | |
| 127 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/modalias | |
| 128 | +Date: Jan 2018 | |
| 129 | +KernelVersion: 4.15 | |
| 130 | +Contact: thunderbolt-software@lists.01.org | |
| 131 | +Description: Stores the same MODALIAS value emitted by uevent for | |
| 132 | + the XDomain service. Format: tbtsvc:kSpNvNrN | |
| 133 | + | |
| 134 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/prtcid | |
| 135 | +Date: Jan 2018 | |
| 136 | +KernelVersion: 4.15 | |
| 137 | +Contact: thunderbolt-software@lists.01.org | |
| 138 | +Description: This contains XDomain protocol identifier the XDomain | |
| 139 | + service supports. | |
| 140 | + | |
| 141 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/prtcvers | |
| 142 | +Date: Jan 2018 | |
| 143 | +KernelVersion: 4.15 | |
| 144 | +Contact: thunderbolt-software@lists.01.org | |
| 145 | +Description: This contains XDomain protocol version the XDomain | |
| 146 | + service supports. | |
| 147 | + | |
| 148 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/prtcrevs | |
| 149 | +Date: Jan 2018 | |
| 150 | +KernelVersion: 4.15 | |
| 151 | +Contact: thunderbolt-software@lists.01.org | |
| 152 | +Description: This contains XDomain software version the XDomain | |
| 153 | + service supports. | |
| 154 | + | |
| 155 | +What: /sys/bus/thunderbolt/devices/<xdomain>.<service>/prtcstns | |
| 156 | +Date: Jan 2018 | |
| 157 | +KernelVersion: 4.15 | |
| 158 | +Contact: thunderbolt-software@lists.01.org | |
| 159 | +Description: This contains XDomain service specific settings as | |
| 160 | + bitmask. Format: %x | |
| @@ -197,3 +197,27 @@ information is missing. · 196 unmodified lines | ||
| 197 | 197 | |
| 198 | 198 | To recover from this mode, one needs to flash a valid NVM image to the |
| 199 | 199 | host host controller in the same way it is done in the previous chapter. |
| 200 | + | |
| 201 | +Networking over Thunderbolt cable | |
| 202 | +--------------------------------- | |
| 203 | +Thunderbolt technology allows software communication across two hosts | |
| 204 | +connected by a Thunderbolt cable. | |
| 205 | + | |
| 206 | +It is possible to tunnel any kind of traffic over Thunderbolt link but | |
| 207 | +currently we only support Apple ThunderboltIP protocol. | |
| 208 | + | |
| 209 | +If the other host is running Windows or macOS only thing you need to | |
| 210 | +do is to connect Thunderbolt cable between the two hosts, the | |
| 211 | +``thunderbolt-net`` is loaded automatically. If the other host is also | |
| 212 | +Linux you should load ``thunderbolt-net`` manually on one host (it does | |
| 213 | +not matter which one):: | |
| 214 | + | |
| 215 | + # modprobe thunderbolt-net | |
| 216 | + | |
| 217 | +This triggers module load on the other host automatically. If the driver | |
| 218 | +is built-in to the kernel image, there is no need to do anything. | |
| 219 | + | |
| 220 | +The driver will create one virtual ethernet interface per Thunderbolt | |
| 221 | +port which are named like ``thunderbolt0`` and so on. From this point | |
| 222 | +you can either use standard userspace tools like ``ifconfig`` to | |
| 223 | +configure the interface or let your GUI to handle it automatically. | |
| @@ -0,0 +1,156 @@ | ||
| 1 | +BPF extensibility and applicability to networking, tracing, security | |
| 2 | +in the linux kernel and several user space implementations of BPF | |
| 3 | +virtual machine led to a number of misunderstanding on what BPF actually is. | |
| 4 | +This short QA is an attempt to address that and outline a direction | |
| 5 | +of where BPF is heading long term. | |
| 6 | + | |
| 7 | +Q: Is BPF a generic instruction set similar to x64 and arm64? | |
| 8 | +A: NO. | |
| 9 | + | |
| 10 | +Q: Is BPF a generic virtual machine ? | |
| 11 | +A: NO. | |
| 12 | + | |
| 13 | +BPF is generic instruction set _with_ C calling convention. | |
| 14 | + | |
| 15 | +Q: Why C calling convention was chosen? | |
| 16 | +A: Because BPF programs are designed to run in the linux kernel | |
| 17 | + which is written in C, hence BPF defines instruction set compatible | |
| 18 | + with two most used architectures x64 and arm64 (and takes into | |
| 19 | + consideration important quirks of other architectures) and | |
| 20 | + defines calling convention that is compatible with C calling | |
| 21 | + convention of the linux kernel on those architectures. | |
| 22 | + | |
| 23 | +Q: can multiple return values be supported in the future? | |
| 24 | +A: NO. BPF allows only register R0 to be used as return value. | |
| 25 | + | |
| 26 | +Q: can more than 5 function arguments be supported in the future? | |
| 27 | +A: NO. BPF calling convention only allows registers R1-R5 to be used | |
| 28 | + as arguments. BPF is not a standalone instruction set. | |
| 29 | + (unlike x64 ISA that allows msft, cdecl and other conventions) | |
| 30 | + | |
| 31 | +Q: can BPF programs access instruction pointer or return address? | |
| 32 | +A: NO. | |
| 33 | + | |
| 34 | +Q: can BPF programs access stack pointer ? | |
| 35 | +A: NO. Only frame pointer (register R10) is accessible. | |
| 36 | + From compiler point of view it's necessary to have stack pointer. | |
| 37 | + For example LLVM defines register R11 as stack pointer in its | |
| 38 | + BPF backend, but it makes sure that generated code never uses it. | |
| 39 | + | |
| 40 | +Q: Does C-calling convention diminishes possible use cases? | |
| 41 | +A: YES. BPF design forces addition of major functionality in the form | |
| 42 | + of kernel helper functions and kernel objects like BPF maps with | |
| 43 | + seamless interoperability between them. It lets kernel call into | |
| 44 | + BPF programs and programs call kernel helpers with zero overhead. | |
| 45 | + As all of them were native C code. That is particularly the case | |
| 46 | + for JITed BPF programs that are indistinguishable from | |
| 47 | + native kernel C code. | |
| 48 | + | |
| 49 | +Q: Does it mean that 'innovative' extensions to BPF code are disallowed? | |
| 50 | +A: Soft yes. At least for now until BPF core has support for | |
| 51 | + bpf-to-bpf calls, indirect calls, loops, global variables, | |
| 52 | + jump tables, read only sections and all other normal constructs | |
| 53 | + that C code can produce. | |
| 54 | + | |
| 55 | +Q: Can loops be supported in a safe way? | |
| 56 | +A: It's not clear yet. BPF developers are trying to find a way to | |
| 57 | + support bounded loops where the verifier can guarantee that | |
| 58 | + the program terminates in less than 4096 instructions. | |
| 59 | + | |
| 60 | +Q: How come LD_ABS and LD_IND instruction are present in BPF whereas | |
| 61 | + C code cannot express them and has to use builtin intrinsics? | |
| 62 | +A: This is artifact of compatibility with classic BPF. Modern | |
| 63 | + networking code in BPF performs better without them. | |
| 64 | + See 'direct packet access'. | |
| 65 | + | |
| 66 | +Q: It seems not all BPF instructions are one-to-one to native CPU. | |
| 67 | + For example why BPF_JNE and other compare and jumps are not cpu-like? | |
| 68 | +A: This was necessary to avoid introducing flags into ISA which are | |
| 69 | + impossible to make generic and efficient across CPU architectures. | |
| 70 | + | |
| 71 | +Q: why BPF_DIV instruction doesn't map to x64 div? | |
| 72 | +A: Because if we picked one-to-one relationship to x64 it would have made | |
| 73 | + it more complicated to support on arm64 and other archs. Also it | |
| 74 | + needs div-by-zero runtime check. | |
| 75 | + | |
| 76 | +Q: why there is no BPF_SDIV for signed divide operation? | |
| 77 | +A: Because it would be rarely used. llvm errors in such case and | |
| 78 | + prints a suggestion to use unsigned divide instead | |
| 79 | + | |
| 80 | +Q: Why BPF has implicit prologue and epilogue? | |
| 81 | +A: Because architectures like sparc have register windows and in general | |
| 82 | + there are enough subtle differences between architectures, so naive | |
| 83 | + store return address into stack won't work. Another reason is BPF has | |
| 84 | + to be safe from division by zero (and legacy exception path | |
| 85 | + of LD_ABS insn). Those instructions need to invoke epilogue and | |
| 86 | + return implicitly. | |
| 87 | + | |
| 88 | +Q: Why BPF_JLT and BPF_JLE instructions were not introduced in the beginning? | |
| 89 | +A: Because classic BPF didn't have them and BPF authors felt that compiler | |
| 90 | + workaround would be acceptable. Turned out that programs lose performance | |
| 91 | + due to lack of these compare instructions and they were added. | |
| 92 | + These two instructions is a perfect example what kind of new BPF | |
| 93 | + instructions are acceptable and can be added in the future. | |
| 94 | + These two already had equivalent instructions in native CPUs. | |
| 95 | + New instructions that don't have one-to-one mapping to HW instructions | |
| 96 | + will not be accepted. | |
| 97 | + | |
| 98 | +Q: BPF 32-bit subregisters have a requirement to zero upper 32-bits of BPF | |
| 99 | + registers which makes BPF inefficient virtual machine for 32-bit | |
| 100 | + CPU architectures and 32-bit HW accelerators. Can true 32-bit registers | |
| 101 | + be added to BPF in the future? | |
| 102 | +A: NO. The first thing to improve performance on 32-bit archs is to teach | |
| 103 | + LLVM to generate code that uses 32-bit subregisters. Then second step | |
| 104 | + is to teach verifier to mark operations where zero-ing upper bits | |
| 105 | + is unnecessary. Then JITs can take advantage of those markings and | |
| 106 | + drastically reduce size of generated code and improve performance. | |
| 107 | + | |
| 108 | +Q: Does BPF have a stable ABI? | |
| 109 | +A: YES. BPF instructions, arguments to BPF programs, set of helper | |
| 110 | + functions and their arguments, recognized return codes are all part | |
| 111 | + of ABI. However when tracing programs are using bpf_probe_read() helper | |
| 112 | + to walk kernel internal datastructures and compile with kernel | |
| 113 | + internal headers these accesses can and will break with newer | |
| 114 | + kernels. The union bpf_attr -> kern_version is checked at load time | |
| 115 | + to prevent accidentally loading kprobe-based bpf programs written | |
| 116 | + for a different kernel. Networking programs don't do kern_version check. | |
| 117 | + | |
| 118 | +Q: How much stack space a BPF program uses? | |
| 119 | +A: Currently all program types are limited to 512 bytes of stack | |
| 120 | + space, but the verifier computes the actual amount of stack used | |
| 121 | + and both interpreter and most JITed code consume necessary amount. | |
| 122 | + | |
| 123 | +Q: Can BPF be offloaded to HW? | |
| 124 | +A: YES. BPF HW offload is supported by NFP driver. | |
| 125 | + | |
| 126 | +Q: Does classic BPF interpreter still exist? | |
| 127 | +A: NO. Classic BPF programs are converted into extend BPF instructions. | |
| 128 | + | |
| 129 | +Q: Can BPF call arbitrary kernel functions? | |
| 130 | +A: NO. BPF programs can only call a set of helper functions which | |
| 131 | + is defined for every program type. | |
| 132 | + | |
| 133 | +Q: Can BPF overwrite arbitrary kernel memory? | |
| 134 | +A: NO. Tracing bpf programs can _read_ arbitrary memory with bpf_probe_read() | |
| 135 | + and bpf_probe_read_str() helpers. Networking programs cannot read | |
| 136 | + arbitrary memory, since they don't have access to these helpers. | |
| 137 | + Programs can never read or write arbitrary memory directly. | |
| 138 | + | |
| 139 | +Q: Can BPF overwrite arbitrary user memory? | |
| 140 | +A: Sort-of. Tracing BPF programs can overwrite the user memory | |
| 141 | + of the current task with bpf_probe_write_user(). Every time such | |
| 142 | + program is loaded the kernel will print warning message, so | |
| 143 | + this helper is only useful for experiments and prototypes. | |
| 144 | + Tracing BPF programs are root only. | |
| 145 | + | |
| 146 | +Q: When bpf_trace_printk() helper is used the kernel prints nasty | |
| 147 | + warning message. Why is that? | |
| 148 | +A: This is done to nudge program authors into better interfaces when | |
| 149 | + programs need to pass data to user space. Like bpf_perf_event_output() | |
| 150 | + can be used to efficiently stream data via perf ring buffer. | |
| 151 | + BPF maps can be used for asynchronous data sharing between kernel | |
| 152 | + and user space. bpf_trace_printk() should only be used for debugging. | |
| 153 | + | |
| 154 | +Q: Can BPF functionality such as new program or map types, new | |
| 155 | + helpers, etc be added out of kernel module code? | |
| 156 | +A: NO. | |
| @@ -0,0 +1,5 @@ | ||
| 1 | +The following properties are common to the Bluetooth controllers: | |
| 2 | + | |
| 3 | +- local-bd-address: array of 6 bytes, specifies the BD address that was | |
| 4 | + uniquely assigned to the Bluetooth device, formatted with least significant | |
| 5 | + byte first (little-endian). | |
| @@ -52,7 +52,7 @@ I2C managed mode: · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | port@1 { /* external port 1 */ |
| 54 | 54 | reg = <1>; |
| 55 | − label = "lan1; | |
| 55 | + label = "lan1"; | |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | 58 | port@2 { /* external port 2 */ |
| @@ -89,7 +89,7 @@ MDIO managed mode: · 30 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | port@1 { /* external port 1 */ |
| 91 | 91 | reg = <1>; |
| 92 | − label = "lan1; | |
| 92 | + label = "lan1"; | |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | 95 | port@2 { /* external port 2 */ |
| @@ -34,6 +34,19 @@ Optional properties: · 33 unmodified lines | ||
| 34 | 34 | - fsl,err006687-workaround-present: If present indicates that the system has |
| 35 | 35 | the hardware workaround for ERR006687 applied and does not need a software |
| 36 | 36 | workaround. |
| 37 | + -interrupt-names: names of the interrupts listed in interrupts property in | |
| 38 | + the same order. The defaults if not specified are | |
| 39 | + __Number of interrupts__ __Default__ | |
| 40 | + 1 "int0" | |
| 41 | + 2 "int0", "pps" | |
| 42 | + 3 "int0", "int1", "int2" | |
| 43 | + 4 "int0", "int1", "int2", "pps" | |
| 44 | + The order may be changed as long as they correspond to the interrupts | |
| 45 | + property. Currently, only i.mx7 uses "int1" and "int2". They correspond to | |
| 46 | + tx/rx queues 1 and 2. "int0" will be used for queue 0 and ENET_MII interrupts. | |
| 47 | + For imx6sx, "int0" handles all 3 queues and ENET_MII. "pps" is for the pulse | |
| 48 | + per second interrupt associated with 1588 precision time protocol(PTP). | |
| 49 | + | |
| 37 | 50 | |
| 38 | 51 | Optional subnodes: |
| 39 | 52 | - mdio : specifies the mdio bus in the FEC, used as a container for phy nodes |
| @@ -17,6 +17,8 @@ Required properties: · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | - "renesas,etheravb-r8a7795" for the R8A7795 SoC. |
| 19 | 19 | - "renesas,etheravb-r8a7796" for the R8A7796 SoC. |
| 20 | + - "renesas,etheravb-r8a77970" for the R8A77970 SoC. | |
| 21 | + - "renesas,etheravb-r8a77995" for the R8A77995 SoC. | |
| 20 | 22 | - "renesas,etheravb-rcar-gen3" as a fallback for the above |
| 21 | 23 | R-Car Gen3 devices. |
| 22 | 24 | |
| @@ -40,7 +42,7 @@ Optional properties: · 17 unmodified lines | ||
| 40 | 42 | - interrupt-parent: the phandle for the interrupt controller that services |
| 41 | 43 | interrupts for this device. |
| 42 | 44 | - interrupt-names: A list of interrupt names. |
| 43 | − For the R8A779[56] SoCs this property is mandatory; | |
| 45 | + For the R-Car Gen 3 SoCs this property is mandatory; | |
| 44 | 46 | it should include one entry per channel, named "ch%u", |
| 45 | 47 | where %u is the channel number ranging from 0 to 24. |
| 46 | 48 | For other SoCs this property is optional; if present |
| @@ -4,7 +4,8 @@ This file provides information on what the device node for the SH EtherMAC · 3 unmodified lines | ||
| 4 | 4 | interface contains. |
| 5 | 5 | |
| 6 | 6 | Required properties: |
| 7 | −- compatible: "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC. | |
| 7 | +- compatible: Must contain one or more of the following: | |
| 8 | + "renesas,gether-r8a7740" if the device is a part of R8A7740 SoC. | |
| 8 | 9 | "renesas,ether-r8a7743" if the device is a part of R8A7743 SoC. |
| 9 | 10 | "renesas,ether-r8a7745" if the device is a part of R8A7745 SoC. |
| 10 | 11 | "renesas,ether-r8a7778" if the device is a part of R8A7778 SoC. |
| @@ -14,6 +15,14 @@ Required properties: · 3 unmodified lines | ||
| 14 | 15 | "renesas,ether-r8a7793" if the device is a part of R8A7793 SoC. |
| 15 | 16 | "renesas,ether-r8a7794" if the device is a part of R8A7794 SoC. |
| 16 | 17 | "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC. |
| 18 | + "renesas,rcar-gen1-ether" for a generic R-Car Gen1 device. | |
| 19 | + "renesas,rcar-gen2-ether" for a generic R-Car Gen2 or RZ/G1 | |
| 20 | + device. | |
| 21 | + | |
| 22 | + When compatible with the generic version, nodes must list | |
| 23 | + the SoC-specific version corresponding to the platform | |
| 24 | + first followed by the generic version. | |
| 25 | + | |
| 17 | 26 | - reg: offset and length of (1) the E-DMAC/feLic register block (required), |
| 18 | 27 | (2) the TSU register block (optional). |
| 19 | 28 | - interrupts: interrupt specifier for the sole interrupt. |
| @@ -36,7 +45,8 @@ Optional properties: · 16 unmodified lines | ||
| 36 | 45 | Example (Lager board): |
| 37 | 46 | |
| 38 | 47 | ethernet@ee700000 { |
| 39 | − compatible = "renesas,ether-r8a7790"; | |
| 48 | + compatible = "renesas,ether-r8a7790", | |
| 49 | + "renesas,rcar-gen2-ether"; | |
| 40 | 50 | reg = <0 0xee700000 0 0x400>; |
| 41 | 51 | interrupt-parent = <&gic>; |
| 42 | 52 | interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -12,7 +12,7 @@ Required properties: · 11 unmodified lines | ||
| 12 | 12 | Valid interrupt names are: |
| 13 | 13 | - "macirq" (combined signal for various interrupt events) |
| 14 | 14 | - "eth_wake_irq" (the interrupt to manage the remote wake-up packet detection) |
| 15 | − - "eth_lpi" (the interrupt that occurs when Tx or Rx enters/exits LPI state) | |
| 15 | + - "eth_lpi" (the interrupt that occurs when Rx exits the LPI state) | |
| 16 | 16 | - phy-mode: See ethernet.txt file in the same directory. |
| 17 | 17 | - snps,reset-gpio gpio number for phy reset. |
| 18 | 18 | - snps,reset-active-low boolean flag to indicate if phy reset is active low. |
| @@ -37,6 +37,11 @@ The following properties are defined to the bluetooth node: · 36 unmodified lines | ||
| 37 | 37 | Definition: must be: |
| 38 | 38 | "qcom,wcnss-bt" |
| 39 | 39 | |
| 40 | +- local-bd-address: | |
| 41 | + Usage: optional | |
| 42 | + Value type: <u8 array> | |
| 43 | + Definition: see Documentation/devicetree/bindings/net/bluetooth.txt | |
| 44 | + | |
| 40 | 45 | == WiFi |
| 41 | 46 | The following properties are defined to the WiFi node: |
| 42 | 47 | |
| @@ -91,6 +96,9 @@ smd { · 48 unmodified lines | ||
| 91 | 96 | |
| 92 | 97 | bt { |
| 93 | 98 | compatible = "qcom,wcnss-bt"; |
| 99 | + | |
| 100 | + /* BD address 00:11:22:33:44:55 */ | |
| 101 | + local-bd-address = [ 55 44 33 22 11 00 ]; | |
| 94 | 102 | }; |
| 95 | 103 | |
| 96 | 104 | wlan { |
| @@ -299,9 +299,6 @@ Data path helpers · 298 unmodified lines | ||
| 299 | 299 | .. kernel-doc:: include/net/cfg80211.h |
| 300 | 300 | :functions: ieee80211_data_to_8023 |
| 301 | 301 | |
| 302 | −.. kernel-doc:: include/net/cfg80211.h | |
| 303 | − :functions: ieee80211_data_from_8023 | |
| 304 | − | |
| 305 | 302 | .. kernel-doc:: include/net/cfg80211.h |
| 306 | 303 | :functions: ieee80211_amsdu_to_8023s |
| 307 | 304 | |
| @@ -0,0 +1,37 @@ | ||
| 1 | +LAN9303 Ethernet switch driver | |
| 2 | +============================== | |
| 3 | + | |
| 4 | +The LAN9303 is a three port 10/100 Mbps ethernet switch with integrated phys for | |
| 5 | +the two external ethernet ports. The third port is an RMII/MII interface to a | |
| 6 | +host master network interface (e.g. fixed link). | |
| 7 | + | |
| 8 | + | |
| 9 | +Driver details | |
| 10 | +============== | |
| 11 | + | |
| 12 | +The driver is implemented as a DSA driver, see | |
| 13 | +Documentation/networking/dsa/dsa.txt. | |
| 14 | + | |
| 15 | +See Documentation/devicetree/bindings/net/dsa/lan9303.txt for device tree | |
| 16 | +binding. | |
| 17 | + | |
| 18 | +The LAN9303 can be managed both via MDIO and I2C, both supported by this driver. | |
| 19 | + | |
| 20 | +At startup the driver configures the device to provide two separate network | |
| 21 | +interfaces (which is the default state of a DSA device). Due to HW limitations, | |
| 22 | +no HW MAC learning takes place in this mode. | |
| 23 | + | |
| 24 | +When both user ports are joined to the same bridge, the normal HW MAC learning | |
| 25 | +is enabled. This means that unicast traffic is forwarded in HW. Broadcast and | |
| 26 | +multicast is flooded in HW. STP is also supported in this mode. The driver | |
| 27 | +support fdb/mdb operations as well, meaning IGMP snooping is supported. | |
| 28 | + | |
| 29 | +If one of the user ports leave the bridge, the ports goes back to the initial | |
| 30 | +separated operation. | |
| 31 | + | |
| 32 | + | |
| 33 | +Driver limitations | |
| 34 | +================== | |
| 35 | + | |
| 36 | + - Support for VLAN filtering is not implemented | |
| 37 | + - The HW does not support VLAN-specific fdb entries | |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | The Linux kernel GTP tunneling module |
| 2 | 2 | ====================================================================== |
| 3 | −Documentation by Harald Welte <laforge@gnumonks.org> | |
| 3 | +Documentation by Harald Welte <laforge@gnumonks.org> and | |
| 4 | + Andreas Schultz <aschultz@tpip.net> | |
| 4 | 5 | |
| 5 | 6 | In 'drivers/net/gtp.c' you are finding a kernel-level implementation |
| 6 | 7 | of a GTP tunnel endpoint. |
| @@ -91,9 +92,13 @@ http://git.osmocom.org/libgtpnl/ · 84 unmodified lines | ||
| 91 | 92 | |
| 92 | 93 | == Protocol Versions == |
| 93 | 94 | |
| 94 | −There are two different versions of GTP-U: v0 and v1. Both are | |
| 95 | −implemented in the Kernel GTP module. Version 0 is a legacy version, | |
| 96 | −and deprecated from recent 3GPP specifications. | |
| 95 | +There are two different versions of GTP-U: v0 [GSM TS 09.60] and v1 | |
| 96 | +[3GPP TS 29.281]. Both are implemented in the Kernel GTP module. | |
| 97 | +Version 0 is a legacy version, and deprecated from recent 3GPP | |
| 98 | +specifications. | |
| 99 | + | |
| 100 | +GTP-U uses UDP for transporting PDUs. The receiving UDP port is 2151 | |
| 101 | +for GTPv1-U and 3386 for GTPv0-U. | |
| 97 | 102 | |
| 98 | 103 | There are three versions of GTP-C: v0, v1, and v2. As the kernel |
| 99 | 104 | doesn't implement GTP-C, we don't have to worry about this. It's the |
| @@ -133,3 +138,93 @@ doe to a lack of user interest, it never got merged. · 33 unmodified lines | ||
| 133 | 138 | In 2015, Andreas Schultz came to the rescue and fixed lots more bugs, |
| 134 | 139 | extended it with new features and finally pushed all of us to get it |
| 135 | 140 | mainline, where it was merged in 4.7.0. |
| 141 | + | |
| 142 | +== Architectural Details == | |
| 143 | + | |
| 144 | +=== Local GTP-U entity and tunnel identification === | |
| 145 | + | |
| 146 | +GTP-U uses UDP for transporting PDU's. The receiving UDP port is 2152 | |
| 147 | +for GTPv1-U and 3386 for GTPv0-U. | |
| 148 | + | |
| 149 | +There is only one GTP-U entity (and therefor SGSN/GGSN/S-GW/PDN-GW | |
| 150 | +instance) per IP address. Tunnel Endpoint Identifier (TEID) are unique | |
| 151 | +per GTP-U entity. | |
| 152 | + | |
| 153 | +A specific tunnel is only defined by the destination entity. Since the | |
| 154 | +destination port is constant, only the destination IP and TEID define | |
| 155 | +a tunnel. The source IP and Port have no meaning for the tunnel. | |
| 156 | + | |
| 157 | +Therefore: | |
| 158 | + | |
| 159 | + * when sending, the remote entity is defined by the remote IP and | |
| 160 | + the tunnel endpoint id. The source IP and port have no meaning and | |
| 161 | + can be changed at any time. | |
| 162 | + | |
| 163 | + * when receiving the local entity is defined by the local | |
| 164 | + destination IP and the tunnel endpoint id. The source IP and port | |
| 165 | + have no meaning and can change at any time. | |
| 166 | + | |
| 167 | +[3GPP TS 29.281] Section 4.3.0 defines this so: | |
| 168 | + | |
| 169 | +> The TEID in the GTP-U header is used to de-multiplex traffic | |
| 170 | +> incoming from remote tunnel endpoints so that it is delivered to the | |
| 171 | +> User plane entities in a way that allows multiplexing of different | |
| 172 | +> users, different packet protocols and different QoS levels. | |
| 173 | +> Therefore no two remote GTP-U endpoints shall send traffic to a | |
| 174 | +> GTP-U protocol entity using the same TEID value except | |
| 175 | +> for data forwarding as part of mobility procedures. | |
| 176 | + | |
| 177 | +The definition above only defines that two remote GTP-U endpoints | |
| 178 | +*should not* send to the same TEID, it *does not* forbid or exclude | |
| 179 | +such a scenario. In fact, the mentioned mobility procedures make it | |
| 180 | +necessary that the GTP-U entity accepts traffic for TEIDs from | |
| 181 | +multiple or unknown peers. | |
| 182 | + | |
| 183 | +Therefore, the receiving side identifies tunnels exclusively based on | |
| 184 | +TEIDs, not based on the source IP! | |
| 185 | + | |
| 186 | +== APN vs. Network Device == | |
| 187 | + | |
| 188 | +The GTP-U driver creates a Linux network device for each Gi/SGi | |
| 189 | +interface. | |
| 190 | + | |
| 191 | +[3GPP TS 29.281] calls the Gi/SGi reference point an interface. This | |
| 192 | +may lead to the impression that the GGSN/P-GW can have only one such | |
| 193 | +interface. | |
| 194 | + | |
| 195 | +Correct is that the Gi/SGi reference point defines the interworking | |
| 196 | +between +the 3GPP packet domain (PDN) based on GTP-U tunnel and IP | |
| 197 | +based networks. | |
| 198 | + | |
| 199 | +There is no provision in any of the 3GPP documents that limits the | |
| 200 | +number of Gi/SGi interfaces implemented by a GGSN/P-GW. | |
| 201 | + | |
| 202 | +[3GPP TS 29.061] Section 11.3 makes it clear that the selection of a | |
| 203 | +specific Gi/SGi interfaces is made through the Access Point Name | |
| 204 | +(APN): | |
| 205 | + | |
| 206 | +> 2. each private network manages its own addressing. In general this | |
| 207 | +> will result in different private networks having overlapping | |
| 208 | +> address ranges. A logically separate connection (e.g. an IP in IP | |
| 209 | +> tunnel or layer 2 virtual circuit) is used between the GGSN/P-GW | |
| 210 | +> and each private network. | |
| 211 | +> | |
| 212 | +> In this case the IP address alone is not necessarily unique. The | |
| 213 | +> pair of values, Access Point Name (APN) and IPv4 address and/or | |
| 214 | +> IPv6 prefixes, is unique. | |
| 215 | + | |
| 216 | +In order to support the overlapping address range use case, each APN | |
| 217 | +is mapped to a separate Gi/SGi interface (network device). | |
| 218 | + | |
| 219 | +NOTE: The Access Point Name is purely a control plane (GTP-C) concept. | |
| 220 | +At the GTP-U level, only Tunnel Endpoint Identifiers are present in | |
| 221 | +GTP-U packets and network devices are known | |
| 222 | + | |
| 223 | +Therefore for a given UE the mapping in IP to PDN network is: | |
| 224 | + * network device + MS IP -> Peer IP + Peer TEID, | |
| 225 | + | |
| 226 | +and from PDN to IP network: | |
| 227 | + * local GTP-U IP + TEID -> network device | |
| 228 | + | |
| 229 | +Furthermore, before a received T-PDU is injected into the network | |
| 230 | +device the MS IP is checked against the IP recorded in PDP context. | |
| @@ -0,0 +1,285 @@ | ||
| 1 | +Identifier Locator Addressing (ILA) | |
| 2 | + | |
| 3 | + | |
| 4 | +Introduction | |
| 5 | +============ | |
| 6 | + | |
| 7 | +Identifier-locator addressing (ILA) is a technique used with IPv6 that | |
| 8 | +differentiates between location and identity of a network node. Part of an | |
| 9 | +address expresses the immutable identity of the node, and another part | |
| 10 | +indicates the location of the node which can be dynamic. Identifier-locator | |
| 11 | +addressing can be used to efficiently implement overlay networks for | |
| 12 | +network virtualization as well as solutions for use cases in mobility. | |
| 13 | + | |
| 14 | +ILA can be thought of as means to implement an overlay network without | |
| 15 | +encapsulation. This is accomplished by performing network address | |
| 16 | +translation on destination addresses as a packet traverses a network. To | |
| 17 | +the network, an ILA translated packet appears to be no different than any | |
| 18 | +other IPv6 packet. For instance, if the transport protocol is TCP then an | |
| 19 | +ILA translated packet looks like just another TCP/IPv6 packet. The | |
| 20 | +advantage of this is that ILA is transparent to the network so that | |
| 21 | +optimizations in the network, such as ECMP, RSS, GRO, GSO, etc., just work. | |
| 22 | + | |
| 23 | +The ILA protocol is described in Internet-Draft draft-herbert-intarea-ila. | |
| 24 | + | |
| 25 | + | |
| 26 | +ILA terminology | |
| 27 | +=============== | |
| 28 | + | |
| 29 | + - Identifier A number that identifies an addressable node in the network | |
| 30 | + independent of its location. ILA identifiers are sixty-four | |
| 31 | + bit values. | |
| 32 | + | |
| 33 | + - Locator A network prefix that routes to a physical host. Locators | |
| 34 | + provide the topological location of an addressed node. ILA | |
| 35 | + locators are sixty-four bit prefixes. | |
| 36 | + | |
| 37 | + - ILA mapping | |
| 38 | + A mapping of an ILA identifier to a locator (or to a | |
| 39 | + locator and meta data). An ILA domain maintains a database | |
| 40 | + that contains mappings for all destinations in the domain. | |
| 41 | + | |
| 42 | + - SIR address | |
| 43 | + An IPv6 address composed of a SIR prefix (upper sixty- | |
| 44 | + four bits) and an identifier (lower sixty-four bits). | |
| 45 | + SIR addresses are visible to applications and provide a | |
| 46 | + means for them to address nodes independent of their | |
| 47 | + location. | |
| 48 | + | |
| 49 | + - ILA address | |
| 50 | + An IPv6 address composed of a locator (upper sixty-four | |
| 51 | + bits) and an identifier (low order sixty-four bits). ILA | |
| 52 | + addresses are never visible to an application. | |
| 53 | + | |
| 54 | + - ILA host An end host that is capable of performing ILA translations | |
| 55 | + on transmit or receive. | |
| 56 | + | |
| 57 | + - ILA router A network node that performs ILA translation and forwarding | |
| 58 | + of translated packets. | |
| 59 | + | |
| 60 | + - ILA forwarding cache | |
| 61 | + A type of ILA router that only maintains a working set | |
| 62 | + cache of mappings. | |
| 63 | + | |
| 64 | + - ILA node A network node capable of performing ILA translations. This | |
| 65 | + can be an ILA router, ILA forwarding cache, or ILA host. | |
| 66 | + | |
| 67 | + | |
| 68 | +Operation | |
| 69 | +========= | |
| 70 | + | |
| 71 | +There are two fundamental operations with ILA: | |
| 72 | + | |
| 73 | + - Translate a SIR address to an ILA address. This is performed on ingress | |
| 74 | + to an ILA overlay. | |
| 75 | + | |
| 76 | + - Translate an ILA address to a SIR address. This is performed on egress | |
| 77 | + from the ILA overlay. | |
| 78 | + | |
| 79 | +ILA can be deployed either on end hosts or intermediate devices in the | |
| 80 | +network; these are provided by "ILA hosts" and "ILA routers" respectively. | |
| 81 | +Configuration and datapath for these two points of deployment is somewhat | |
| 82 | +different. | |
| 83 | + | |
| 84 | +The diagram below illustrates the flow of packets through ILA as well | |
| 85 | +as showing ILA hosts and routers. | |
| 86 | + | |
| 87 | + +--------+ +--------+ | |
| 88 | + | Host A +-+ +--->| Host B | | |
| 89 | + | | | (2) ILA (') | | | |
| 90 | + +--------+ | ...addressed.... ( ) +--------+ | |
| 91 | + V +---+--+ . packet . +---+--+ (_) | |
| 92 | + (1) SIR | | ILA |----->-------->---->| ILA | | (3) SIR | |
| 93 | + addressed +->|router| . . |router|->-+ addressed | |
| 94 | + packet +---+--+ . IPv6 . +---+--+ packet | |
| 95 | + / . Network . | |
| 96 | + / . . +--+-++--------+ | |
| 97 | + +--------+ / . . |ILA || Host | | |
| 98 | + | Host +--+ . .- -|host|| | | |
| 99 | + | | . . +--+-++--------+ | |
| 100 | + +--------+ ................ | |
| 101 | + | |
| 102 | + | |
| 103 | +Transport checksum handling | |
| 104 | +=========================== | |
| 105 | + | |
| 106 | +When an address is translated by ILA, an encapsulated transport checksum | |
| 107 | +that includes the translated address in a pseudo header may be rendered | |
| 108 | +incorrect on the wire. This is a problem for intermediate devices, | |
| 109 | +including checksum offload in NICs, that process the checksum. There are | |
| 110 | +three options to deal with this: | |
| 111 | + | |
| 112 | +- no action Allow the checksum to be incorrect on the wire. Before | |
| 113 | + a receiver verifies a checksum the ILA to SIR address | |
| 114 | + translation must be done. | |
| 115 | + | |
| 116 | +- adjust transport checksum | |
| 117 | + When ILA translation is performed the packet is parsed | |
| 118 | + and if a transport layer checksum is found then it is | |
| 119 | + adjusted to reflect the correct checksum per the | |
| 120 | + translated address. | |
| 121 | + | |
| 122 | +- checksum neutral mapping | |
| 123 | + When an address is translated the difference can be offset | |
| 124 | + elsewhere in a part of the packet that is covered by the | |
| 125 | + the checksum. The low order sixteen bits of the identifier | |
| 126 | + are used. This method is preferred since it doesn't require | |
| 127 | + parsing a packet beyond the IP header and in most cases the | |
| 128 | + adjustment can be precomputed and saved with the mapping. | |
| 129 | + | |
| 130 | +Note that the checksum neutral adjustment affects the low order sixteen | |
| 131 | +bits of the identifier. When ILA to SIR address translation is done on | |
| 132 | +egress the low order bits are restored to the original value which | |
| 133 | +restores the identifier as it was originally sent. | |
| 134 | + | |
| 135 | + | |
| 136 | +Identifier types | |
| 137 | +================ | |
| 138 | + | |
| 139 | +ILA defines different types of identifiers for different use cases. | |
| 140 | + | |
| 141 | +The defined types are: | |
| 142 | + | |
| 143 | + 0: interface identifier | |
| 144 | + | |
| 145 | + 1: locally unique identifier | |
| 146 | + | |
| 147 | + 2: virtual networking identifier for IPv4 address | |
| 148 | + | |
| 149 | + 3: virtual networking identifier for IPv6 unicast address | |
| 150 | + | |
| 151 | + 4: virtual networking identifier for IPv6 multicast address | |
| 152 | + | |
| 153 | + 5: non-local address identifier | |
| 154 | + | |
| 155 | +In the current implementation of kernel ILA only locally unique identifiers | |
| 156 | +(LUID) are supported. LUID allows for a generic, unformatted 64 bit | |
| 157 | +identifier. | |
| 158 | + | |
| 159 | + | |
| 160 | +Identifier formats | |
| 161 | +================== | |
| 162 | + | |
| 163 | +Kernel ILA supports two optional fields in an identifier for formatting: | |
| 164 | +"C-bit" and "identifier type". The presence of these fields is determined | |
| 165 | +by configuration as demonstrated below. | |
| 166 | + | |
| 167 | +If the identifier type is present it occupies the three highest order | |
| 168 | +bits of an identifier. The possible values are given in the above list. | |
| 169 | + | |
| 170 | +If the C-bit is present, this is used as an indication that checksum | |
| 171 | +neutral mapping has been done. The C-bit can only be set in an | |
| 172 | +ILA address, never a SIR address. | |
| 173 | + | |
| 174 | +In the simplest format the identifier types, C-bit, and checksum | |
| 175 | +adjustment value are not present so an identifier is considered an | |
| 176 | +unstructured sixty-four bit value. | |
| 177 | + | |
| 178 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 179 | + | Identifier | | |
| 180 | + + + | |
| 181 | + | | | |
| 182 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 183 | + | |
| 184 | +The checksum neutral adjustment may be configured to always be | |
| 185 | +present using neutral-map-auto. In this case there is no C-bit, but the | |
| 186 | +checksum adjustment is in the low order 16 bits. The identifier is | |
| 187 | +still sixty-four bits. | |
| 188 | + | |
| 189 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 190 | + | Identifier | | |
| 191 | + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 192 | + | | Checksum-neutral adjustment | | |
| 193 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 194 | + | |
| 195 | +The C-bit may used to explicitly indicate that checksum neutral | |
| 196 | +mapping has been applied to an ILA address. The format is: | |
| 197 | + | |
| 198 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 199 | + | |C| Identifier | | |
| 200 | + | +-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 201 | + | | Checksum-neutral adjustment | | |
| 202 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 203 | + | |
| 204 | +The identifier type field may be present to indicate the identifier | |
| 205 | +type. If it is not present then the type is inferred based on mapping | |
| 206 | +configuration. The checksum neutral adjustment may automatically | |
| 207 | +used with the identifier type as illustrated below. | |
| 208 | + | |
| 209 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 210 | + | Type| Identifier | | |
| 211 | + +-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 212 | + | | Checksum-neutral adjustment | | |
| 213 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 214 | + | |
| 215 | +If the identifier type and the C-bit can be present simultaneously so | |
| 216 | +the identifier format would be: | |
| 217 | + | |
| 218 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 219 | + | Type|C| Identifier | | |
| 220 | + +-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 221 | + | | Checksum-neutral adjustment | | |
| 222 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 223 | + | |
| 224 | + | |
| 225 | +Configuration | |
| 226 | +============= | |
| 227 | + | |
| 228 | +There are two methods to configure ILA mappings. One is by using LWT routes | |
| 229 | +and the other is ila_xlat (called from NFHOOK PREROUTING hook). ila_xlat | |
| 230 | +is intended to be used in the receive path for ILA hosts . | |
| 231 | + | |
| 232 | +An ILA router has also been implemented in XDP. Description of that is | |
| 233 | +outside the scope of this document. | |
| 234 | + | |
| 235 | +The usage of for ILA LWT routes is: | |
| 236 | + | |
| 237 | +ip route add DEST/128 encap ila LOC csum-mode MODE ident-type TYPE via ADDR | |
| 238 | + | |
| 239 | +Destination (DEST) can either be a SIR address (for an ILA host or ingress | |
| 240 | +ILA router) or an ILA address (egress ILA router). LOC is the sixty-four | |
| 241 | +bit locator (with format W:X:Y:Z) that overwrites the upper sixty-four | |
| 242 | +bits of the destination address. Checksum MODE is one of "no-action", | |
| 243 | +"adj-transport", "neutral-map", and "neutral-map-auto". If neutral-map is | |
| 244 | +set then the C-bit will be present. Identifier TYPE one of "luid" or | |
| 245 | +"use-format." In the case of use-format, the identifier type field is | |
| 246 | +present and the effective type is taken from that. | |
| 247 | + | |
| 248 | +The usage of ila_xlat is: | |
| 249 | + | |
| 250 | +ip ila add loc_match MATCH loc LOC csum-mode MODE ident-type TYPE | |
| 251 | + | |
| 252 | +MATCH indicates the incoming locator that must be matched to apply | |
| 253 | +a the translaiton. LOC is the locator that overwrites the upper | |
| 254 | +sixty-four bits of the destination address. MODE and TYPE have the | |
| 255 | +same meanings as described above. | |
| 256 | + | |
| 257 | + | |
| 258 | +Some examples | |
| 259 | +============= | |
| 260 | + | |
| 261 | +# Configure an ILA route that uses checksum neutral mapping as well | |
| 262 | +# as type field. Note that the type field is set in the SIR address | |
| 263 | +# (the 2000 implies type is 1 which is LUID). | |
| 264 | +ip route add 3333:0:0:1:2000:0:1:87/128 encap ila 2001:0:87:0 \ | |
| 265 | + csum-mode neutral-map ident-type use-format | |
| 266 | + | |
| 267 | +# Configure an ILA LWT route that uses auto checksum neutral mapping | |
| 268 | +# (no C-bit) and configure identifier type to be LUID so that the | |
| 269 | +# identifier type field will not be present. | |
| 270 | +ip route add 3333:0:0:1:2000:0:2:87/128 encap ila 2001:0:87:1 \ | |
| 271 | + csum-mode neutral-map-auto ident-type luid | |
| 272 | + | |
| 273 | +ila_xlat configuration | |
| 274 | + | |
| 275 | +# Configure an ILA to SIR mapping that matches a locator and overwrites | |
| 276 | +# it with a SIR address (3333:0:0:1 in this example). The C-bit and | |
| 277 | +# identifier field are used. | |
| 278 | +ip ila add loc_match 2001:0:119:0 loc 3333:0:0:1 \ | |
| 279 | + csum-mode neutral-map-auto ident-type use-format | |
| 280 | + | |
| 281 | +# Configure an ILA to SIR mapping where checksum neutral is automatically | |
| 282 | +# set without the C-bit and the identifier type is configured to be LUID | |
| 283 | +# so that the identifier type field is not present. | |
| 284 | +ip ila add loc_match 2001:0:119:0 loc 3333:0:0:1 \ | |
| 285 | + csum-mode neutral-map-auto ident-type use-format | |
| @@ -289,8 +289,7 @@ tcp_ecn_fallback - BOOLEAN · 288 unmodified lines | ||
| 289 | 289 | Default: 1 (fallback enabled) |
| 290 | 290 | |
| 291 | 291 | tcp_fack - BOOLEAN |
| 292 | − Enable FACK congestion avoidance and fast retransmission. | |
| 293 | − The value is not used, if tcp_sack is not enabled. | |
| 292 | + This is a legacy option, it has no effect anymore. | |
| 294 | 293 | |
| 295 | 294 | tcp_fin_timeout - INTEGER |
| 296 | 295 | The length of time an orphaned (no longer referenced by any |
| @@ -454,6 +453,7 @@ tcp_recovery - INTEGER · 157 unmodified lines | ||
| 454 | 453 | |
| 455 | 454 | RACK: 0x1 enables the RACK loss detection for fast detection of lost |
| 456 | 455 | retransmissions and tail drops. |
| 456 | + RACK: 0x2 makes RACK's reordering window static (min_rtt/4). | |
| 457 | 457 | |
| 458 | 458 | Default: 0x1 |
| 459 | 459 | |
| @@ -1385,6 +1385,30 @@ mld_qrv - INTEGER · 925 unmodified lines | ||
| 1385 | 1385 | Default: 2 (as specified by RFC3810 9.1) |
| 1386 | 1386 | Minimum: 1 (as specified by RFC6636 4.5) |
| 1387 | 1387 | |
| 1388 | +max_dst_opts_cnt - INTEGER | |
| 1389 | + Maximum number of non-padding TLVs allowed in a Destination | |
| 1390 | + options extension header. If this value is less than zero | |
| 1391 | + then unknown options are disallowed and the number of known | |
| 1392 | + TLVs allowed is the absolute value of this number. | |
| 1393 | + Default: 8 | |
| 1394 | + | |
| 1395 | +max_hbh_opts_cnt - INTEGER | |
| 1396 | + Maximum number of non-padding TLVs allowed in a Hop-by-Hop | |
| 1397 | + options extension header. If this value is less than zero | |
| 1398 | + then unknown options are disallowed and the number of known | |
| 1399 | + TLVs allowed is the absolute value of this number. | |
| 1400 | + Default: 8 | |
| 1401 | + | |
| 1402 | +max dst_opts_len - INTEGER | |
| 1403 | + Maximum length allowed for a Destination options extension | |
| 1404 | + header. | |
| 1405 | + Default: INT_MAX (unlimited) | |
| 1406 | + | |
| 1407 | +max hbh_opts_len - INTEGER | |
| 1408 | + Maximum length allowed for a Hop-by-Hop options extension | |
| 1409 | + header. | |
| 1410 | + Default: INT_MAX (unlimited) | |
| 1411 | + | |
| 1388 | 1412 | IPv6 Fragmentation: |
| 1389 | 1413 | |
| 1390 | 1414 | ip6frag_high_thresh - INTEGER |
| @@ -1707,6 +1731,15 @@ ndisc_notify - BOOLEAN · 316 unmodified lines | ||
| 1707 | 1731 | 1 - Generate unsolicited neighbour advertisements when device is brought |
| 1708 | 1732 | up or hardware address changes. |
| 1709 | 1733 | |
| 1734 | +ndisc_tclass - INTEGER | |
| 1735 | + The IPv6 Traffic Class to use by default when sending IPv6 Neighbor | |
| 1736 | + Discovery (Router Solicitation, Router Advertisement, Neighbor | |
| 1737 | + Solicitation, Neighbor Advertisement, Redirect) messages. | |
| 1738 | + These 8 bits can be interpreted as 6 high order bits holding the DSCP | |
| 1739 | + value and 2 low order bits representing ECN (which you probably want | |
| 1740 | + to leave cleared). | |
| 1741 | + 0 - (default) | |
| 1742 | + | |
| 1710 | 1743 | mldv1_unsolicited_report_interval - INTEGER |
| 1711 | 1744 | The interval in milliseconds in which the next unsolicited |
| 1712 | 1745 | MLDv1 report retransmit will take place. |
| @@ -22,9 +22,21 @@ The driver can be built into the kernel (CONFIG_IPVLAN=y) or as a module · 21 unmodified lines | ||
| 22 | 22 | There are no module parameters for this driver and it can be configured |
| 23 | 23 | using IProute2/ip utility. |
| 24 | 24 | |
| 25 | − ip link add link <master-dev> name <slave-dev> type ipvlan mode { l2 | l3 | l3s } | |
| 26 | − | |
| 27 | − e.g. ip link add link eth0 name ipvl0 type ipvlan mode l2 | |
| 25 | + ip link add link <master> name <slave> type ipvlan [ mode MODE ] [ FLAGS ] | |
| 26 | + where | |
| 27 | + MODE: l3 (default) | l3s | l2 | |
| 28 | + FLAGS: bridge (default) | private | vepa | |
| 29 | + | |
| 30 | + e.g. | |
| 31 | + (a) Following will create IPvlan link with eth0 as master in | |
| 32 | + L3 bridge mode | |
| 33 | + bash# ip link add link eth0 name ipvl0 type ipvlan | |
| 34 | + (b) This command will create IPvlan link in L2 bridge mode. | |
| 35 | + bash# ip link add link eth0 name ipvl0 type ipvlan mode l2 bridge | |
| 36 | + (c) This command will create an IPvlan device in L2 private mode. | |
| 37 | + bash# ip link add link eth0 name ipvlan type ipvlan mode l2 private | |
| 38 | + (d) This command will create an IPvlan device in L2 vepa mode. | |
| 39 | + bash# ip link add link eth0 name ipvlan type ipvlan mode l2 vepa | |
| 28 | 40 | |
| 29 | 41 | |
| 30 | 42 | 4. Operating modes: |
| @@ -54,7 +66,29 @@ works in this mode and hence it is L3-symmetric (L3s). This will have slightly l · 23 unmodified lines | ||
| 54 | 66 | performance but that shouldn't matter since you are choosing this mode over plain-L3 |
| 55 | 67 | mode to make conn-tracking work. |
| 56 | 68 | |
| 57 | −5. What to choose (macvlan vs. ipvlan)? | |
| 69 | +5. Mode flags: | |
| 70 | + At this time following mode flags are available | |
| 71 | + | |
| 72 | +5.1 bridge: | |
| 73 | + This is the default option. To configure the IPvlan port in this mode, | |
| 74 | +user can choose to either add this option on the command-line or don't specify | |
| 75 | +anything. This is the traditional mode where slaves can cross-talk among | |
| 76 | +themseleves apart from talking through the master device. | |
| 77 | + | |
| 78 | +5.2 private: | |
| 79 | + If this option is added to the command-line, the port is set in private | |
| 80 | +mode. i.e. port wont allow cross communication between slaves. | |
| 81 | + | |
| 82 | +5.3 vepa: | |
| 83 | + If this is added to the command-line, the port is set in VEPA mode. | |
| 84 | +i.e. port will offload switching functionality to the external entity as | |
| 85 | +described in 802.1Qbg | |
| 86 | +Note: VEPA mode in IPvlan has limitations. IPvlan uses the mac-address of the | |
| 87 | +master-device, so the packets which are emitted in this mode for the adjacent | |
| 88 | +neighbor will have source and destination mac same. This will make the switch / | |
| 89 | +router send the redirect message. | |
| 90 | + | |
| 91 | +6. What to choose (macvlan vs. ipvlan)? | |
| 58 | 92 | These two devices are very similar in many regards and the specific use |
| 59 | 93 | case could very well define which device to choose. if one of the following |
| 60 | 94 | situations defines your use case then you can choose to use ipvlan - |
| @@ -64,7 +64,10 @@ A: To understand this, you need to know a bit of background information · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | If you aren't subscribed to netdev and/or are simply unsure if net-next |
| 66 | 66 | has re-opened yet, simply check the net-next git repository link above for |
| 67 | − any new networking-related commits. | |
| 67 | + any new networking-related commits. You may also check the following | |
| 68 | + website for the current status: | |
| 69 | + | |
| 70 | + http://vger.kernel.org/~davem/net-next.html | |
| 68 | 71 | |
| 69 | 72 | The "net" tree continues to collect fixes for the vX.Y content, and |
| 70 | 73 | is fed back to Linus at regular (~weekly) intervals. Meaning that the |
| @@ -19,12 +19,12 @@ Features · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | Receive Side Scaling |
| 21 | 21 | -------------------- |
| 22 | − Hyper-V supports receive side scaling. For TCP, packets are | |
| 23 | − distributed among available queues based on IP address and port | |
| 22 | + Hyper-V supports receive side scaling. For TCP & UDP, packets can | |
| 23 | + be distributed among available queues based on IP address and port | |
| 24 | 24 | number. |
| 25 | 25 | |
| 26 | − For UDP, we can switch UDP hash level between L3 and L4 by ethtool | |
| 27 | − command. UDP over IPv4 and v6 can be set differently. The default | |
| 26 | + For TCP & UDP, we can switch hash level between L3 and L4 by ethtool | |
| 27 | + command. TCP/UDP over IPv4 and v6 can be set differently. The default | |
| 28 | 28 | hash level is L4. We currently only allow switching TX hash level |
| 29 | 29 | from within the guests. |
| 30 | 30 | |
| @@ -19,6 +19,14 @@ core regulatory domain all wireless devices should adhere to. · 18 unmodified lines | ||
| 19 | 19 | How to get regulatory domains to the kernel |
| 20 | 20 | ------------------------------------------- |
| 21 | 21 | |
| 22 | +When the regulatory domain is first set up, the kernel will request a | |
| 23 | +database file (regulatory.db) containing all the regulatory rules. It | |
| 24 | +will then use that database when it needs to look up the rules for a | |
| 25 | +given country. | |
| 26 | + | |
| 27 | +How to get regulatory domains to the kernel (old CRDA solution) | |
| 28 | +--------------------------------------------------------------- | |
| 29 | + | |
| 22 | 30 | Userspace gets a regulatory domain in the kernel by having |
| 23 | 31 | a userspace agent build it and send it via nl80211. Only |
| 24 | 32 | expected regulatory domains will be respected by the kernel. |
| @@ -192,23 +200,5 @@ Then in some part of your code after your wiphy has been registered: · 167 unmodified lines | ||
| 192 | 200 | Statically compiled regulatory database |
| 193 | 201 | --------------------------------------- |
| 194 | 202 | |
| 195 | −In most situations the userland solution using CRDA as described | |
| 196 | −above is the preferred solution. However in some cases a set of | |
| 197 | −rules built into the kernel itself may be desirable. To account | |
| 198 | −for this situation, a configuration option has been provided | |
| 199 | −(i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled, | |
| 200 | −the wireless database information contained in net/wireless/db.txt is | |
| 201 | −used to generate a data structure encoded in net/wireless/regdb.c. | |
| 202 | −That option also enables code in net/wireless/reg.c which queries | |
| 203 | −the data in regdb.c as an alternative to using CRDA. | |
| 204 | − | |
| 205 | −The file net/wireless/db.txt should be kept up-to-date with the db.txt | |
| 206 | −file available in the git repository here: | |
| 207 | − | |
| 208 | − git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git | |
| 209 | − | |
| 210 | −Again, most users in most situations should be using the CRDA package | |
| 211 | −provided with their distribution, and in most other situations users | |
| 212 | −should be building and using CRDA on their own rather than using | |
| 213 | −this option. If you are not absolutely sure that you should be using | |
| 214 | −CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_. | |
| 203 | +When a database should be fixed into the kernel, it can be provided as a | |
| 204 | +firmware file at build time that is then linked into the kernel. | |
| @@ -280,6 +280,18 @@ Interaction with the user of the RxRPC socket: · 279 unmodified lines | ||
| 280 | 280 | nominated by a socket option. |
| 281 | 281 | |
| 282 | 282 | |
| 283 | +Notes on sendmsg: | |
| 284 | + | |
| 285 | + (*) MSG_WAITALL can be set to tell sendmsg to ignore signals if the peer is | |
| 286 | + making progress at accepting packets within a reasonable time such that we | |
| 287 | + manage to queue up all the data for transmission. This requires the | |
| 288 | + client to accept at least one packet per 2*RTT time period. | |
| 289 | + | |
| 290 | + If this isn't set, sendmsg() will return immediately, either returning | |
| 291 | + EINTR/ERESTARTSYS if nothing was consumed or returning the amount of data | |
| 292 | + consumed. | |
| 293 | + | |
| 294 | + | |
| 283 | 295 | Notes on recvmsg: |
| 284 | 296 | |
| 285 | 297 | (*) If there's a sequence of data messages belonging to a particular call on |
| @@ -782,7 +794,9 @@ The kernel interface functions are as follows: · 496 unmodified lines | ||
| 782 | 794 | struct key *key, |
| 783 | 795 | unsigned long user_call_ID, |
| 784 | 796 | s64 tx_total_len, |
| 785 | − gfp_t gfp); | |
| 797 | + gfp_t gfp, | |
| 798 | + rxrpc_notify_rx_t notify_rx, | |
| 799 | + bool upgrade); | |
| 786 | 800 | |
| 787 | 801 | This allocates the infrastructure to make a new RxRPC call and assigns |
| 788 | 802 | call and connection numbers. The call will be made on the UDP port that |
| @@ -803,6 +817,13 @@ The kernel interface functions are as follows: · 14 unmodified lines | ||
| 803 | 817 | allows the kernel to encrypt directly to the packet buffers, thereby |
| 804 | 818 | saving a copy. The value may not be less than -1. |
| 805 | 819 | |
| 820 | + notify_rx is a pointer to a function to be called when events such as | |
| 821 | + incoming data packets or remote aborts happen. | |
| 822 | + | |
| 823 | + upgrade should be set to true if a client operation should request that | |
| 824 | + the server upgrade the service to a better one. The resultant service ID | |
| 825 | + is returned by rxrpc_kernel_recv_data(). | |
| 826 | + | |
| 806 | 827 | If this function is successful, an opaque reference to the RxRPC call is |
| 807 | 828 | returned. The caller now holds a reference on this and it must be |
| 808 | 829 | properly ended. |
| @@ -850,7 +871,8 @@ The kernel interface functions are as follows: · 41 unmodified lines | ||
| 850 | 871 | size_t size, |
| 851 | 872 | size_t *_offset, |
| 852 | 873 | bool want_more, |
| 853 | − u32 *_abort) | |
| 874 | + u32 *_abort, | |
| 875 | + u16 *_service) | |
| 854 | 876 | |
| 855 | 877 | This is used to receive data from either the reply part of a client call |
| 856 | 878 | or the request part of a service call. buf and size specify how much |
| @@ -873,6 +895,9 @@ The kernel interface functions are as follows: · 16 unmodified lines | ||
| 873 | 895 | If a remote ABORT is detected, the abort code received will be stored in |
| 874 | 896 | *_abort and ECONNABORTED will be returned. |
| 875 | 897 | |
| 898 | + The service ID that the call ended up with is returned into *_service. | |
| 899 | + This can be used to see if a call got a service upgrade. | |
| 900 | + | |
| 876 | 901 | (*) Abort a call. |
| 877 | 902 | |
| 878 | 903 | void rxrpc_kernel_abort_call(struct socket *sock, |
| @@ -1020,6 +1045,30 @@ The kernel interface functions are as follows: · 141 unmodified lines | ||
| 1020 | 1045 | |
| 1021 | 1046 | It returns 0 if the call was requeued and an error otherwise. |
| 1022 | 1047 | |
| 1048 | + (*) Get call RTT. | |
| 1049 | + | |
| 1050 | + u64 rxrpc_kernel_get_rtt(struct socket *sock, struct rxrpc_call *call); | |
| 1051 | + | |
| 1052 | + Get the RTT time to the peer in use by a call. The value returned is in | |
| 1053 | + nanoseconds. | |
| 1054 | + | |
| 1055 | + (*) Check call still alive. | |
| 1056 | + | |
| 1057 | + u32 rxrpc_kernel_check_life(struct socket *sock, | |
| 1058 | + struct rxrpc_call *call); | |
| 1059 | + | |
| 1060 | + This returns a number that is updated when ACKs are received from the peer | |
| 1061 | + (notably including PING RESPONSE ACKs which we can elicit by sending PING | |
| 1062 | + ACKs to see if the call still exists on the server). The caller should | |
| 1063 | + compare the numbers of two calls to see if the call is still alive after | |
| 1064 | + waiting for a suitable interval. | |
| 1065 | + | |
| 1066 | + This allows the caller to work out if the server is still contactable and | |
| 1067 | + if the call is still alive on the server whilst waiting for the server to | |
| 1068 | + process a client operation. | |
| 1069 | + | |
| 1070 | + This function may transmit a PING ACK. | |
| 1071 | + | |
| 1023 | 1072 | |
| 1024 | 1073 | ======================= |
| 1025 | 1074 | CONFIGURABLE PARAMETERS |
| @@ -71,7 +71,12 @@ Setup · 70 unmodified lines | ||
| 71 | 71 | ip ru add iif vrf-blue table 10 |
| 72 | 72 | |
| 73 | 73 | 3. Set the default route for the table (and hence default route for the VRF). |
| 74 | − ip route add table 10 unreachable default | |
| 74 | + ip route add table 10 unreachable default metric 4278198272 | |
| 75 | + | |
| 76 | + This high metric value ensures that the default unreachable route can | |
| 77 | + be overridden by a routing protocol suite. FRRouting interprets | |
| 78 | + kernel metrics as a combined admin distance (upper byte) and priority | |
| 79 | + (lower 3 bytes). Thus the above metric translates to [255/8192]. | |
| 75 | 80 | |
| 76 | 81 | 4. Enslave L3 interfaces to a VRF device. |
| 77 | 82 | ip link set dev eth1 master vrf-blue |
| @@ -256,7 +261,7 @@ older form without it. · 178 unmodified lines | ||
| 256 | 261 | |
| 257 | 262 | For example: |
| 258 | 263 | $ ip route show vrf red |
| 259 | − prohibit default | |
| 264 | + unreachable default metric 4278198272 | |
| 260 | 265 | broadcast 10.2.1.0 dev eth1 proto kernel scope link src 10.2.1.2 |
| 261 | 266 | 10.2.1.0/24 dev eth1 proto kernel scope link src 10.2.1.2 |
| 262 | 267 | local 10.2.1.2 dev eth1 proto kernel scope host src 10.2.1.2 |
| @@ -282,7 +287,7 @@ older form without it. · 19 unmodified lines | ||
| 282 | 287 | ff00::/8 dev red metric 256 pref medium |
| 283 | 288 | ff00::/8 dev eth1 metric 256 pref medium |
| 284 | 289 | ff00::/8 dev eth2 metric 256 pref medium |
| 285 | − | |
| 290 | + unreachable default dev lo metric 4278198272 error -101 pref medium | |
| 286 | 291 | |
| 287 | 292 | 8. Route Lookup for a VRF |
| 288 | 293 | |
| @@ -331,7 +336,7 @@ function vrf_create · 42 unmodified lines | ||
| 331 | 336 | ip link add ${VRF} type vrf table ${TBID} |
| 332 | 337 | |
| 333 | 338 | if [ "${VRF}" != "mgmt" ]; then |
| 334 | − ip route add table ${TBID} unreachable default | |
| 339 | + ip route add table ${TBID} unreachable default metric 4278198272 | |
| 335 | 340 | fi |
| 336 | 341 | ip link set dev ${VRF} up |
| 337 | 342 | } |
| @@ -695,9 +695,9 @@ F: include/linux/altera_uart.h · 694 unmodified lines | ||
| 695 | 695 | F: include/linux/altera_jtaguart.h |
| 696 | 696 | |
| 697 | 697 | AMAZON ETHERNET DRIVERS |
| 698 | −M: Netanel Belgazal <netanel@annapurnalabs.com> | |
| 699 | −R: Saeed Bishara <saeed@annapurnalabs.com> | |
| 700 | −R: Zorik Machulsky <zorik@annapurnalabs.com> | |
| 698 | +M: Netanel Belgazal <netanel@amazon.com> | |
| 699 | +R: Saeed Bishara <saeedb@amazon.com> | |
| 700 | +R: Zorik Machulsky <zorik@amazon.com> | |
| 701 | 701 | L: netdev@vger.kernel.org |
| 702 | 702 | S: Supported |
| 703 | 703 | F: Documentation/networking/ena.txt |
| @@ -2712,6 +2712,7 @@ L: linux-kernel@vger.kernel.org · 2008 unmodified lines | ||
| 2712 | 2712 | S: Supported |
| 2713 | 2713 | F: arch/x86/net/bpf_jit* |
| 2714 | 2714 | F: Documentation/networking/filter.txt |
| 2715 | +F: Documentation/bpf/ | |
| 2715 | 2716 | F: include/linux/bpf* |
| 2716 | 2717 | F: include/linux/filter.h |
| 2717 | 2718 | F: include/uapi/linux/bpf* |
| @@ -2724,7 +2725,7 @@ F: net/core/filter.c · 6 unmodified lines | ||
| 2724 | 2725 | F: net/sched/act_bpf.c |
| 2725 | 2726 | F: net/sched/cls_bpf.c |
| 2726 | 2727 | F: samples/bpf/ |
| 2727 | −F: tools/net/bpf* | |
| 2728 | +F: tools/bpf/ | |
| 2728 | 2729 | F: tools/testing/selftests/bpf/ |
| 2729 | 2730 | |
| 2730 | 2731 | BROADCOM B44 10/100 ETHERNET DRIVER |
| @@ -2903,6 +2904,7 @@ S: Maintained · 172 unmodified lines | ||
| 2903 | 2904 | F: drivers/phy/broadcom/phy-brcm-usb* |
| 2904 | 2905 | |
| 2905 | 2906 | BROADCOM GENET ETHERNET DRIVER |
| 2907 | +M: Doug Berger <opendmb@gmail.com> | |
| 2906 | 2908 | M: Florian Fainelli <f.fainelli@gmail.com> |
| 2907 | 2909 | L: netdev@vger.kernel.org |
| 2908 | 2910 | S: Supported |
| @@ -3088,7 +3090,6 @@ F: arch/c6x/ · 179 unmodified lines | ||
| 3088 | 3090 | |
| 3089 | 3091 | CA8210 IEEE-802.15.4 RADIO DRIVER |
| 3090 | 3092 | M: Harry Morris <h.morris@cascoda.com> |
| 3091 | −M: linuxdev@cascoda.com | |
| 3092 | 3093 | L: linux-wpan@vger.kernel.org |
| 3093 | 3094 | W: https://github.com/Cascoda/ca8210-linux.git |
| 3094 | 3095 | S: Maintained |
| @@ -3335,17 +3336,22 @@ S: Maintained · 240 unmodified lines | ||
| 3335 | 3336 | F: drivers/auxdisplay/cfag12864bfb.c |
| 3336 | 3337 | F: include/linux/cfag12864b.h |
| 3337 | 3338 | |
| 3338 | −CFG80211 and NL80211 | |
| 3339 | +802.11 (including CFG80211/NL80211) | |
| 3339 | 3340 | M: Johannes Berg <johannes@sipsolutions.net> |
| 3340 | 3341 | L: linux-wireless@vger.kernel.org |
| 3341 | 3342 | W: http://wireless.kernel.org/ |
| 3342 | 3343 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git |
| 3343 | 3344 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git |
| 3344 | 3345 | S: Maintained |
| 3346 | +F: net/wireless/ | |
| 3345 | 3347 | F: include/uapi/linux/nl80211.h |
| 3348 | +F: include/linux/ieee80211.h | |
| 3349 | +F: include/net/wext.h | |
| 3346 | 3350 | F: include/net/cfg80211.h |
| 3347 | −F: net/wireless/* | |
| 3348 | −X: net/wireless/wext* | |
| 3351 | +F: include/net/iw_handler.h | |
| 3352 | +F: include/net/ieee80211_radiotap.h | |
| 3353 | +F: Documentation/driver-api/80211/cfg80211.rst | |
| 3354 | +F: Documentation/networking/regulatory.txt | |
| 3349 | 3355 | |
| 3350 | 3356 | CHAR and MISC DRIVERS |
| 3351 | 3357 | M: Arnd Bergmann <arnd@arndb.de> |
| @@ -3421,7 +3427,7 @@ F: drivers/scsi/snic/ · 69 unmodified lines | ||
| 3421 | 3427 | CISCO VIC ETHERNET NIC DRIVER |
| 3422 | 3428 | M: Christian Benvenuti <benve@cisco.com> |
| 3423 | 3429 | M: Govindarajulu Varadarajan <_govind@gmx.com> |
| 3424 | −M: Neel Patel <neepatel@cisco.com> | |
| 3430 | +M: Parvi Kaustubhi <pkaustub@cisco.com> | |
| 3425 | 3431 | S: Supported |
| 3426 | 3432 | F: drivers/net/ethernet/cisco/enic/ |
| 3427 | 3433 | |
| @@ -8231,6 +8237,7 @@ F: Documentation/networking/mac80211-injection.txt · 4803 unmodified lines | ||
| 8231 | 8237 | F: include/net/mac80211.h |
| 8232 | 8238 | F: net/mac80211/ |
| 8233 | 8239 | F: drivers/net/wireless/mac80211_hwsim.[ch] |
| 8240 | +F: Documentation/networking/mac80211_hwsim/README | |
| 8234 | 8241 | |
| 8235 | 8242 | MAILBOX API |
| 8236 | 8243 | M: Jassi Brar <jassisinghbrar@gmail.com> |
| @@ -9425,6 +9432,7 @@ M: Florian Fainelli <f.fainelli@gmail.com> · 1188 unmodified lines | ||
| 9425 | 9432 | S: Maintained |
| 9426 | 9433 | F: net/dsa/ |
| 9427 | 9434 | F: include/net/dsa.h |
| 9435 | +F: include/linux/dsa/ | |
| 9428 | 9436 | F: drivers/net/dsa/ |
| 9429 | 9437 | |
| 9430 | 9438 | NETWORKING [GENERAL] |
| @@ -9445,8 +9453,8 @@ F: include/uapi/linux/in.h · 14 unmodified lines | ||
| 9445 | 9453 | F: include/uapi/linux/net.h |
| 9446 | 9454 | F: include/uapi/linux/netdevice.h |
| 9447 | 9455 | F: include/uapi/linux/net_namespace.h |
| 9448 | −F: tools/net/ | |
| 9449 | 9456 | F: tools/testing/selftests/net/ |
| 9457 | +F: lib/net_utils.c | |
| 9450 | 9458 | F: lib/random32.c |
| 9451 | 9459 | |
| 9452 | 9460 | NETWORKING [IPSEC] |
| @@ -11520,6 +11528,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git · 2067 unmodified lines | ||
| 11520 | 11528 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git |
| 11521 | 11529 | S: Maintained |
| 11522 | 11530 | F: Documentation/rfkill.txt |
| 11531 | +F: Documentation/ABI/stable/sysfs-class-rfkill | |
| 11523 | 11532 | F: net/rfkill/ |
| 11524 | 11533 | |
| 11525 | 11534 | RHASHTABLE |
| @@ -13343,6 +13352,15 @@ M: Mika Westerberg <mika.westerberg@linux.intel.com> · 1817 unmodified lines | ||
| 13343 | 13352 | M: Yehezkel Bernat <yehezkel.bernat@intel.com> |
| 13344 | 13353 | S: Maintained |
| 13345 | 13354 | F: drivers/thunderbolt/ |
| 13355 | +F: include/linux/thunderbolt.h | |
| 13356 | + | |
| 13357 | +THUNDERBOLT NETWORK DRIVER | |
| 13358 | +M: Michael Jamet <michael.jamet@intel.com> | |
| 13359 | +M: Mika Westerberg <mika.westerberg@linux.intel.com> | |
| 13360 | +M: Yehezkel Bernat <yehezkel.bernat@intel.com> | |
| 13361 | +L: netdev@vger.kernel.org | |
| 13362 | +S: Maintained | |
| 13363 | +F: drivers/net/thunderbolt.c | |
| 13346 | 13364 | |
| 13347 | 13365 | THUNDERX GPIO DRIVER |
| 13348 | 13366 | M: David Daney <david.daney@cavium.com> |
| @@ -14322,12 +14340,15 @@ S: Maintained · 973 unmodified lines | ||
| 14322 | 14340 | F: include/linux/virtio_vsock.h |
| 14323 | 14341 | F: include/uapi/linux/virtio_vsock.h |
| 14324 | 14342 | F: include/uapi/linux/vsockmon.h |
| 14343 | +F: include/uapi/linux/vm_sockets_diag.h | |
| 14344 | +F: net/vmw_vsock/diag.c | |
| 14325 | 14345 | F: net/vmw_vsock/af_vsock_tap.c |
| 14326 | 14346 | F: net/vmw_vsock/virtio_transport_common.c |
| 14327 | 14347 | F: net/vmw_vsock/virtio_transport.c |
| 14328 | 14348 | F: drivers/net/vsockmon.c |
| 14329 | 14349 | F: drivers/vhost/vsock.c |
| 14330 | 14350 | F: drivers/vhost/vsock.h |
| 14351 | +F: tools/testing/vsock/ | |
| 14331 | 14352 | |
| 14332 | 14353 | VIRTIO CONSOLE DRIVER |
| 14333 | 14354 | M: Amit Shah <amit@kernel.org> |
| @@ -14591,7 +14612,6 @@ L: wil6210@qca.qualcomm.com · 257 unmodified lines | ||
| 14591 | 14612 | S: Supported |
| 14592 | 14613 | W: http://wireless.kernel.org/en/users/Drivers/wil6210 |
| 14593 | 14614 | F: drivers/net/wireless/ath/wil6210/ |
| 14594 | −F: include/uapi/linux/wil6210_uapi.h | |
| 14595 | 14615 | |
| 14596 | 14616 | WIMAX STACK |
| 14597 | 14617 | M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/dpmc.h> |
| 26 | 26 | #include <asm/bfin_sdh.h> |
| 27 | 27 | #include <linux/spi/ad7877.h> |
| 28 | −#include <net/dsa.h> | |
| 29 | 28 | |
| 30 | 29 | /* |
| 31 | 30 | * Name the Board for the /proc/cpuinfo |
| @@ -105,11 +104,7 @@ static const unsigned short bfin_mac_peripherals[] = { · 73 unmodified lines | ||
| 105 | 104 | |
| 106 | 105 | static struct bfin_phydev_platform_data bfin_phydev_data[] = { |
| 107 | 106 | { |
| 108 | −#if IS_ENABLED(CONFIG_NET_DSA_KSZ8893M) | |
| 109 | − .addr = 3, | |
| 110 | −#else | |
| 111 | 107 | .addr = 1, |
| 112 | −#endif | |
| 113 | 108 | .irq = IRQ_MAC_PHYINT, |
| 114 | 109 | }, |
| 115 | 110 | }; |
| @@ -119,9 +114,6 @@ static struct bfin_mii_bus_platform_data bfin_mii_bus_data = { · 3 unmodified lines | ||
| 119 | 114 | .phydev_data = bfin_phydev_data, |
| 120 | 115 | .phy_mode = PHY_INTERFACE_MODE_MII, |
| 121 | 116 | .mac_peripherals = bfin_mac_peripherals, |
| 122 | −#if IS_ENABLED(CONFIG_NET_DSA_KSZ8893M) | |
| 123 | − .phy_mask = 0xfff7, /* Only probe the port phy connect to the on chip MAC */ | |
| 124 | −#endif | |
| 125 | 117 | .vlan1_mask = 1, |
| 126 | 118 | .vlan2_mask = 2, |
| 127 | 119 | }; |
| @@ -140,29 +132,6 @@ static struct platform_device bfin_mac_device = { · 12 unmodified lines | ||
| 140 | 132 | } |
| 141 | 133 | }; |
| 142 | 134 | |
| 143 | −#if IS_ENABLED(CONFIG_NET_DSA_KSZ8893M) | |
| 144 | −static struct dsa_chip_data ksz8893m_switch_chip_data = { | |
| 145 | − .mii_bus = &bfin_mii_bus.dev, | |
| 146 | − .port_names = { | |
| 147 | − NULL, | |
| 148 | − "eth%d", | |
| 149 | − "eth%d", | |
| 150 | − "cpu", | |
| 151 | − }, | |
| 152 | −}; | |
| 153 | −static struct dsa_platform_data ksz8893m_switch_data = { | |
| 154 | − .nr_chips = 1, | |
| 155 | − .netdev = &bfin_mac_device.dev, | |
| 156 | − .chip = &ksz8893m_switch_chip_data, | |
| 157 | −}; | |
| 158 | − | |
| 159 | −static struct platform_device ksz8893m_switch_device = { | |
| 160 | − .name = "dsa", | |
| 161 | − .id = 0, | |
| 162 | − .num_resources = 0, | |
| 163 | − .dev.platform_data = &ksz8893m_switch_data, | |
| 164 | −}; | |
| 165 | −#endif | |
| 166 | 135 | #endif |
| 167 | 136 | |
| 168 | 137 | #if IS_ENABLED(CONFIG_MTD_M25P80) |
| @@ -228,19 +197,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { · 59 unmodified lines | ||
| 228 | 197 | }, |
| 229 | 198 | #endif |
| 230 | 199 | |
| 231 | −#if IS_ENABLED(CONFIG_BFIN_MAC) | |
| 232 | −#if IS_ENABLED(CONFIG_NET_DSA_KSZ8893M) | |
| 233 | − { | |
| 234 | − .modalias = "ksz8893m", | |
| 235 | − .max_speed_hz = 5000000, | |
| 236 | − .bus_num = 0, | |
| 237 | − .chip_select = 1, | |
| 238 | − .platform_data = NULL, | |
| 239 | − .mode = SPI_MODE_3, | |
| 240 | − }, | |
| 241 | −#endif | |
| 242 | −#endif | |
| 243 | − | |
| 244 | 200 | #if IS_ENABLED(CONFIG_MMC_SPI) |
| 245 | 201 | { |
| 246 | 202 | .modalias = "mmc_spi", |
| @@ -714,9 +670,6 @@ static struct platform_device *stamp_devices[] __initdata = { · 467 unmodified lines | ||
| 714 | 670 | #if IS_ENABLED(CONFIG_BFIN_MAC) |
| 715 | 671 | &bfin_mii_bus, |
| 716 | 672 | &bfin_mac_device, |
| 717 | −#if IS_ENABLED(CONFIG_NET_DSA_KSZ8893M) | |
| 718 | − &ksz8893m_switch_device, | |
| 719 | −#endif | |
| 720 | 673 | #endif |
| 721 | 674 | |
| 722 | 675 | #if IS_ENABLED(CONFIG_SPI_BFIN5XX) |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/dpmc.h> |
| 26 | 26 | #include <asm/bfin_sdh.h> |
| 27 | 27 | #include <linux/spi/ad7877.h> |
| 28 | −#include <net/dsa.h> | |
| 29 | 28 | |
| 30 | 29 | /* |
| 31 | 30 | * Name the Board for the /proc/cpuinfo |
| @@ -168,7 +168,6 @@ static int uml_net_open(struct net_device *dev) · 167 unmodified lines | ||
| 168 | 168 | goto out_close; |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | − lp->tl.data = (unsigned long) &lp->user; | |
| 172 | 171 | netif_start_queue(dev); |
| 173 | 172 | |
| 174 | 173 | /* clear buffer - it can happen that the host side of the interface |
| @@ -278,10 +277,11 @@ static const struct ethtool_ops uml_net_ethtool_ops = { · 103 unmodified lines | ||
| 278 | 277 | .get_ts_info = ethtool_op_get_ts_info, |
| 279 | 278 | }; |
| 280 | 279 | |
| 281 | −static void uml_net_user_timer_expire(unsigned long _conn) | |
| 280 | +static void uml_net_user_timer_expire(struct timer_list *t) | |
| 282 | 281 | { |
| 283 | 282 | #ifdef undef |
| 284 | − struct connection *conn = (struct connection *)_conn; | |
| 283 | + struct uml_net_private *lp = from_timer(lp, t, tl); | |
| 284 | + struct connection *conn = &lp->user; | |
| 285 | 285 | |
| 286 | 286 | dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn); |
| 287 | 287 | do_connect(conn); |
| @@ -458,9 +458,8 @@ static void eth_configure(int n, void *init, char *mac, · 170 unmodified lines | ||
| 458 | 458 | .add_address = transport->user->add_address, |
| 459 | 459 | .delete_address = transport->user->delete_address }); |
| 460 | 460 | |
| 461 | − init_timer(&lp->tl); | |
| 461 | + timer_setup(&lp->tl, uml_net_user_timer_expire, 0); | |
| 462 | 462 | spin_lock_init(&lp->lock); |
| 463 | − lp->tl.function = uml_net_user_timer_expire; | |
| 464 | 463 | memcpy(lp->mac, dev->dev_addr, sizeof(lp->mac)); |
| 465 | 464 | |
| 466 | 465 | if ((transport->user->init != NULL) && |
| @@ -358,26 +358,33 @@ fore200e_shutdown(struct fore200e* fore200e) · 357 unmodified lines | ||
| 358 | 358 | case FORE200E_STATE_COMPLETE: |
| 359 | 359 | kfree(fore200e->stats); |
| 360 | 360 | |
| 361 | + /* fall through */ | |
| 361 | 362 | case FORE200E_STATE_IRQ: |
| 362 | 363 | free_irq(fore200e->irq, fore200e->atm_dev); |
| 363 | 364 | |
| 365 | + /* fall through */ | |
| 364 | 366 | case FORE200E_STATE_ALLOC_BUF: |
| 365 | 367 | fore200e_free_rx_buf(fore200e); |
| 366 | 368 | |
| 369 | + /* fall through */ | |
| 367 | 370 | case FORE200E_STATE_INIT_BSQ: |
| 368 | 371 | fore200e_uninit_bs_queue(fore200e); |
| 369 | 372 | |
| 373 | + /* fall through */ | |
| 370 | 374 | case FORE200E_STATE_INIT_RXQ: |
| 371 | 375 | fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.status); |
| 372 | 376 | fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd); |
| 373 | 377 | |
| 378 | + /* fall through */ | |
| 374 | 379 | case FORE200E_STATE_INIT_TXQ: |
| 375 | 380 | fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status); |
| 376 | 381 | fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd); |
| 377 | 382 | |
| 383 | + /* fall through */ | |
| 378 | 384 | case FORE200E_STATE_INIT_CMDQ: |
| 379 | 385 | fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status); |
| 380 | 386 | |
| 387 | + /* fall through */ | |
| 381 | 388 | case FORE200E_STATE_INITIALIZE: |
| 382 | 389 | /* nothing to do for that state */ |
| 383 | 390 | |
| @@ -390,6 +397,7 @@ fore200e_shutdown(struct fore200e* fore200e) · 6 unmodified lines | ||
| 390 | 397 | case FORE200E_STATE_MAP: |
| 391 | 398 | fore200e->bus->unmap(fore200e); |
| 392 | 399 | |
| 400 | + /* fall through */ | |
| 393 | 401 | case FORE200E_STATE_CONFIGURE: |
| 394 | 402 | /* nothing to do for that state */ |
| 395 | 403 | |
| @@ -2803,7 +2803,7 @@ out: · 2802 unmodified lines | ||
| 2803 | 2803 | return err; |
| 2804 | 2804 | |
| 2805 | 2805 | out_free_irq: |
| 2806 | − free_irq(dev->irq, dev); | |
| 2806 | + free_irq(irq, dev); | |
| 2807 | 2807 | out_free: |
| 2808 | 2808 | kfree(dev); |
| 2809 | 2809 | out_release: |
| @@ -306,11 +306,9 @@ static int idt77105_start(struct atm_dev *dev) · 305 unmodified lines | ||
| 306 | 306 | if (start_timer) { |
| 307 | 307 | start_timer = 0; |
| 308 | 308 | |
| 309 | − setup_timer(&stats_timer, idt77105_stats_timer_func, 0UL); | |
| 310 | 309 | stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD; |
| 311 | 310 | add_timer(&stats_timer); |
| 312 | 311 | |
| 313 | − setup_timer(&restart_timer, idt77105_restart_timer_func, 0UL); | |
| 314 | 312 | restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD; |
| 315 | 313 | add_timer(&restart_timer); |
| 316 | 314 | } |
| @@ -2073,21 +2073,19 @@ idt77252_rate_logindex(struct idt77252_dev *card, int pcr) · 2072 unmodified lines | ||
| 2073 | 2073 | } |
| 2074 | 2074 | |
| 2075 | 2075 | static void |
| 2076 | −idt77252_est_timer(unsigned long data) | |
| 2076 | +idt77252_est_timer(struct timer_list *t) | |
| 2077 | 2077 | { |
| 2078 | − struct vc_map *vc = (struct vc_map *)data; | |
| 2078 | + struct rate_estimator *est = from_timer(est, t, timer); | |
| 2079 | + struct vc_map *vc = est->vc; | |
| 2079 | 2080 | struct idt77252_dev *card = vc->card; |
| 2080 | − struct rate_estimator *est; | |
| 2081 | 2081 | unsigned long flags; |
| 2082 | 2082 | u32 rate, cps; |
| 2083 | 2083 | u64 ncells; |
| 2084 | 2084 | u8 lacr; |
| 2085 | 2085 | |
| 2086 | 2086 | spin_lock_irqsave(&vc->lock, flags); |
| 2087 | − est = vc->estimator; | |
| 2088 | − if (!est) | |
| 2087 | + if (!vc->estimator) | |
| 2089 | 2088 | goto out; |
| 2090 | − | |
| 2091 | 2089 | ncells = est->cells; |
| 2092 | 2090 | |
| 2093 | 2091 | rate = ((u32)(ncells - est->last_cells)) << (7 - est->interval); |
| @@ -2126,10 +2124,11 @@ idt77252_init_est(struct vc_map *vc, int pcr) · 32 unmodified lines | ||
| 2126 | 2124 | est->maxcps = pcr < 0 ? -pcr : pcr; |
| 2127 | 2125 | est->cps = est->maxcps; |
| 2128 | 2126 | est->avcps = est->cps << 5; |
| 2127 | + est->vc = vc; | |
| 2129 | 2128 | |
| 2130 | 2129 | est->interval = 2; /* XXX: make this configurable */ |
| 2131 | 2130 | est->ewma_log = 2; /* XXX: make this configurable */ |
| 2132 | − setup_timer(&est->timer, idt77252_est_timer, (unsigned long)vc); | |
| 2131 | + timer_setup(&est->timer, idt77252_est_timer, 0); | |
| 2133 | 2132 | mod_timer(&est->timer, jiffies + ((HZ / 4) << est->interval)); |
| 2134 | 2133 | |
| 2135 | 2134 | return est; |
| @@ -2209,16 +2208,20 @@ static int · 73 unmodified lines | ||
| 2209 | 2208 | idt77252_init_ubr(struct idt77252_dev *card, struct vc_map *vc, |
| 2210 | 2209 | struct atm_vcc *vcc, struct atm_qos *qos) |
| 2211 | 2210 | { |
| 2211 | + struct rate_estimator *est = NULL; | |
| 2212 | 2212 | unsigned long flags; |
| 2213 | 2213 | int tcr; |
| 2214 | 2214 | |
| 2215 | 2215 | spin_lock_irqsave(&vc->lock, flags); |
| 2216 | 2216 | if (vc->estimator) { |
| 2217 | − del_timer(&vc->estimator->timer); | |
| 2218 | − kfree(vc->estimator); | |
| 2217 | + est = vc->estimator; | |
| 2219 | 2218 | vc->estimator = NULL; |
| 2220 | 2219 | } |
| 2221 | 2220 | spin_unlock_irqrestore(&vc->lock, flags); |
| 2221 | + if (est) { | |
| 2222 | + del_timer_sync(&est->timer); | |
| 2223 | + kfree(est); | |
| 2224 | + } | |
| 2222 | 2225 | |
| 2223 | 2226 | tcr = atm_pcr_goal(&qos->txtp); |
| 2224 | 2227 | if (tcr == 0) |
| @@ -184,6 +184,8 @@ struct aal1 { · 183 unmodified lines | ||
| 184 | 184 | unsigned char sequence; |
| 185 | 185 | }; |
| 186 | 186 | |
| 187 | +struct vc_map; | |
| 188 | + | |
| 187 | 189 | struct rate_estimator { |
| 188 | 190 | struct timer_list timer; |
| 189 | 191 | unsigned int interval; |
| @@ -193,6 +195,7 @@ struct rate_estimator { · 3 unmodified lines | ||
| 193 | 195 | long avcps; |
| 194 | 196 | u32 cps; |
| 195 | 197 | u32 maxcps; |
| 198 | + struct vc_map *vc; | |
| 196 | 199 | }; |
| 197 | 200 | |
| 198 | 201 | struct vc_map { |
| @@ -880,7 +880,7 @@ static void ia_phy_write(struct iadev_priv *iadev, · 879 unmodified lines | ||
| 880 | 880 | |
| 881 | 881 | static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev) |
| 882 | 882 | { |
| 883 | − static const struct ia_reg suni_ds3_init [] = { | |
| 883 | + static const struct ia_reg suni_ds3_init[] = { | |
| 884 | 884 | { SUNI_DS3_FRM_INTR_ENBL, 0x17 }, |
| 885 | 885 | { SUNI_DS3_FRM_CFG, 0x01 }, |
| 886 | 886 | { SUNI_DS3_TRAN_CFG, 0x01 }, |
| @@ -898,7 +898,7 @@ static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev) · 11 unmodified lines | ||
| 898 | 898 | |
| 899 | 899 | static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev) |
| 900 | 900 | { |
| 901 | − static const struct ia_reg suni_e3_init [] = { | |
| 901 | + static const struct ia_reg suni_e3_init[] = { | |
| 902 | 902 | { SUNI_E3_FRM_FRAM_OPTIONS, 0x04 }, |
| 903 | 903 | { SUNI_E3_FRM_MAINT_OPTIONS, 0x20 }, |
| 904 | 904 | { SUNI_E3_FRM_FRAM_INTR_ENBL, 0x1d }, |
| @@ -918,7 +918,7 @@ static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev) · 13 unmodified lines | ||
| 918 | 918 | |
| 919 | 919 | static void ia_suni_pm7345_init(struct iadev_priv *iadev) |
| 920 | 920 | { |
| 921 | − static const struct ia_reg suni_init [] = { | |
| 921 | + static const struct ia_reg suni_init[] = { | |
| 922 | 922 | /* Enable RSOP loss of signal interrupt. */ |
| 923 | 923 | { SUNI_INTR_ENBL, 0x28 }, |
| 924 | 924 | /* Clear error counters. */ |
| @@ -53,7 +53,7 @@ static DEFINE_SPINLOCK(sunis_lock); · 52 unmodified lines | ||
| 53 | 53 | if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX); |
| 54 | 54 | |
| 55 | 55 | |
| 56 | −static void suni_hz(unsigned long from_timer) | |
| 56 | +static void suni_hz(struct timer_list *timer) | |
| 57 | 57 | { |
| 58 | 58 | struct suni_priv *walk; |
| 59 | 59 | struct atm_dev *dev; |
| @@ -85,7 +85,7 @@ static void suni_hz(unsigned long from_timer) · 25 unmodified lines | ||
| 85 | 85 | ((GET(TACP_TCC) & 0xff) << 8) | |
| 86 | 86 | ((GET(TACP_TCCM) & 7) << 16)); |
| 87 | 87 | } |
| 88 | − if (from_timer) mod_timer(&poll_timer,jiffies+HZ); | |
| 88 | + if (timer) mod_timer(&poll_timer,jiffies+HZ); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | |
| @@ -322,13 +322,11 @@ static int suni_start(struct atm_dev *dev) · 230 unmodified lines | ||
| 322 | 322 | printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, |
| 323 | 323 | dev->number); |
| 324 | 324 | PRIV(dev)->loop_mode = ATM_LM_NONE; |
| 325 | − suni_hz(0); /* clear SUNI counters */ | |
| 325 | + suni_hz(NULL); /* clear SUNI counters */ | |
| 326 | 326 | (void) fetch_stats(dev,NULL,1); /* clear kernel counters */ |
| 327 | 327 | if (first) { |
| 328 | − init_timer(&poll_timer); | |
| 328 | + timer_setup(&poll_timer, suni_hz, 0); | |
| 329 | 329 | poll_timer.expires = jiffies+HZ; |
| 330 | − poll_timer.function = suni_hz; | |
| 331 | − poll_timer.data = 1; | |
| 332 | 330 | #if 0 |
| 333 | 331 | printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.list.prev, |
| 334 | 332 | (unsigned long) poll_timer.list.next); |
| @@ -11,14 +11,15 @@ menuconfig BCMA · 10 unmodified lines | ||
| 11 | 11 | Bus driver for Broadcom specific Advanced Microcontroller Bus |
| 12 | 12 | Architecture. |
| 13 | 13 | |
| 14 | +if BCMA | |
| 15 | + | |
| 14 | 16 | # Support for Block-I/O. SELECT this from the driver that needs it. |
| 15 | 17 | config BCMA_BLOCKIO |
| 16 | 18 | bool |
| 17 | − depends on BCMA | |
| 18 | 19 | |
| 19 | 20 | config BCMA_HOST_PCI_POSSIBLE |
| 20 | 21 | bool |
| 21 | − depends on BCMA && PCI = y | |
| 22 | + depends on PCI = y | |
| 22 | 23 | default y |
| 23 | 24 | |
| 24 | 25 | config BCMA_HOST_PCI |
| @@ -29,7 +30,6 @@ config BCMA_HOST_PCI · 4 unmodified lines | ||
| 29 | 30 | |
| 30 | 31 | config BCMA_HOST_SOC |
| 31 | 32 | bool "Support for BCMA in a SoC" |
| 32 | − depends on BCMA | |
| 33 | 33 | help |
| 34 | 34 | Host interface for a Broadcom AIX bus directly mapped into |
| 35 | 35 | the memory. This only works with the Broadcom SoCs from the |
| @@ -39,7 +39,7 @@ config BCMA_HOST_SOC · 3 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | config BCMA_DRIVER_PCI |
| 41 | 41 | bool "BCMA Broadcom PCI core driver" |
| 42 | − depends on BCMA && PCI | |
| 42 | + depends on PCI | |
| 43 | 43 | default y |
| 44 | 44 | help |
| 45 | 45 | BCMA bus may have many versions of PCIe core. This driver |
| @@ -55,13 +55,13 @@ config BCMA_DRIVER_PCI · 9 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | config BCMA_DRIVER_PCI_HOSTMODE |
| 57 | 57 | bool "Driver for PCI core working in hostmode" |
| 58 | − depends on BCMA && MIPS && BCMA_DRIVER_PCI | |
| 58 | + depends on MIPS && BCMA_DRIVER_PCI | |
| 59 | 59 | help |
| 60 | 60 | PCI core hostmode operation (external PCI bus). |
| 61 | 61 | |
| 62 | 62 | config BCMA_DRIVER_MIPS |
| 63 | 63 | bool "BCMA Broadcom MIPS core driver" |
| 64 | − depends on BCMA && MIPS | |
| 64 | + depends on MIPS | |
| 65 | 65 | help |
| 66 | 66 | Driver for the Broadcom MIPS core attached to Broadcom specific |
| 67 | 67 | Advanced Microcontroller Bus. |
| @@ -92,7 +92,6 @@ config BCMA_NFLASH · 24 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | config BCMA_DRIVER_GMAC_CMN |
| 94 | 94 | bool "BCMA Broadcom GBIT MAC COMMON core driver" |
| 95 | − depends on BCMA | |
| 96 | 95 | help |
| 97 | 96 | Driver for the Broadcom GBIT MAC COMMON core attached to Broadcom |
| 98 | 97 | specific Advanced Microcontroller Bus. |
| @@ -101,7 +100,7 @@ config BCMA_DRIVER_GMAC_CMN · 2 unmodified lines | ||
| 101 | 100 | |
| 102 | 101 | config BCMA_DRIVER_GPIO |
| 103 | 102 | bool "BCMA GPIO driver" |
| 104 | − depends on BCMA && GPIOLIB | |
| 103 | + depends on GPIOLIB | |
| 105 | 104 | select GPIOLIB_IRQCHIP if BCMA_HOST_SOC |
| 106 | 105 | help |
| 107 | 106 | Driver to provide access to the GPIO pins of the bcma bus. |
| @@ -110,8 +109,9 @@ config BCMA_DRIVER_GPIO · 2 unmodified lines | ||
| 110 | 109 | |
| 111 | 110 | config BCMA_DEBUG |
| 112 | 111 | bool "BCMA debugging" |
| 113 | − depends on BCMA | |
| 114 | 112 | help |
| 115 | 113 | This turns on additional debugging messages. |
| 116 | 114 | |
| 117 | 115 | If unsure, say N |
| 116 | + | |
| 117 | +endif # BCMA | |
| @@ -184,10 +184,14 @@ static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq) · 183 unmodified lines | ||
| 184 | 184 | { |
| 185 | 185 | int i; |
| 186 | 186 | static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; |
| 187 | − printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); | |
| 188 | − for (i = 0; i <= 6; i++) | |
| 189 | − printk(" %s%s", irq_name[i], i == irq ? "*" : " "); | |
| 190 | − printk("\n"); | |
| 187 | + char interrupts[20]; | |
| 188 | + char *ints = interrupts; | |
| 189 | + | |
| 190 | + for (i = 0; i < ARRAY_SIZE(irq_name); i++) | |
| 191 | + ints += sprintf(ints, " %s%c", | |
| 192 | + irq_name[i], i == irq ? '*' : ' '); | |
| 193 | + | |
| 194 | + bcma_debug(dev->bus, "core 0x%04x, irq:%s\n", dev->id.id, interrupts); | |
| 191 | 195 | } |
| 192 | 196 | |
| 193 | 197 | static void bcma_core_mips_dump_irq(struct bcma_bus *bus) |
| @@ -66,6 +66,7 @@ config BT_HCIBTSDIO · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | config BT_HCIUART |
| 68 | 68 | tristate "HCI UART driver" |
| 69 | + depends on SERIAL_DEV_BUS || !SERIAL_DEV_BUS | |
| 69 | 70 | depends on TTY |
| 70 | 71 | help |
| 71 | 72 | Bluetooth HCI UART driver. |
| @@ -80,7 +81,6 @@ config BT_HCIUART · 8 unmodified lines | ||
| 80 | 81 | config BT_HCIUART_SERDEV |
| 81 | 82 | bool |
| 82 | 83 | depends on SERIAL_DEV_BUS && BT_HCIUART |
| 83 | − depends on SERIAL_DEV_BUS=y || SERIAL_DEV_BUS=BT_HCIUART | |
| 84 | 84 | default y |
| 85 | 85 | |
| 86 | 86 | config BT_HCIUART_H4 |
| @@ -170,6 +170,7 @@ config BT_HCIUART_BCM · 83 unmodified lines | ||
| 170 | 170 | bool "Broadcom protocol support" |
| 171 | 171 | depends on BT_HCIUART |
| 172 | 172 | depends on BT_HCIUART_SERDEV |
| 173 | + depends on (!ACPI || SERIAL_DEV_CTRL_TTYPORT) | |
| 173 | 174 | select BT_HCIUART_H4 |
| 174 | 175 | select BT_BCM |
| 175 | 176 | help |
| @@ -121,7 +121,7 @@ static void bcm203x_complete(struct urb *urb) · 120 unmodified lines | ||
| 121 | 121 | } |
| 122 | 122 | |
| 123 | 123 | data->state = BCM203X_LOAD_FIRMWARE; |
| 124 | − | |
| 124 | + /* fall through */ | |
| 125 | 125 | case BCM203X_LOAD_FIRMWARE: |
| 126 | 126 | if (data->fw_sent == data->fw_size) { |
| 127 | 127 | usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), |
| @@ -156,9 +156,9 @@ static void bluecard_detach(struct pcmcia_device *p_dev); · 155 unmodified lines | ||
| 156 | 156 | /* ======================== LED handling routines ======================== */ |
| 157 | 157 | |
| 158 | 158 | |
| 159 | −static void bluecard_activity_led_timeout(u_long arg) | |
| 159 | +static void bluecard_activity_led_timeout(struct timer_list *t) | |
| 160 | 160 | { |
| 161 | − struct bluecard_info *info = (struct bluecard_info *)arg; | |
| 161 | + struct bluecard_info *info = from_timer(info, t, timer); | |
| 162 | 162 | unsigned int iobase = info->p_dev->resource[0]->start; |
| 163 | 163 | |
| 164 | 164 | if (test_bit(CARD_ACTIVITY, &(info->hw_state))) { |
| @@ -691,8 +691,7 @@ static int bluecard_open(struct bluecard_info *info) · 526 unmodified lines | ||
| 691 | 691 | |
| 692 | 692 | spin_lock_init(&(info->lock)); |
| 693 | 693 | |
| 694 | − setup_timer(&(info->timer), &bluecard_activity_led_timeout, | |
| 695 | − (u_long)info); | |
| 694 | + timer_setup(&info->timer, bluecard_activity_led_timeout, 0); | |
| 696 | 695 | |
| 697 | 696 | skb_queue_head_init(&(info->txq)); |
| 698 | 697 | |
| @@ -117,7 +117,7 @@ static void bpa10x_rx_complete(struct urb *urb) · 116 unmodified lines | ||
| 117 | 117 | bpa10x_recv_pkts, |
| 118 | 118 | ARRAY_SIZE(bpa10x_recv_pkts)); |
| 119 | 119 | if (IS_ERR(data->rx_skb[idx])) { |
| 120 | − BT_ERR("%s corrupted event packet", hdev->name); | |
| 120 | + bt_dev_err(hdev, "corrupted event packet"); | |
| 121 | 121 | hdev->stat.err_rx++; |
| 122 | 122 | data->rx_skb[idx] = NULL; |
| 123 | 123 | } |
| @@ -127,8 +127,7 @@ static void bpa10x_rx_complete(struct urb *urb) · 3 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 129 | 129 | if (err < 0) { |
| 130 | − BT_ERR("%s urb %p failed to resubmit (%d)", | |
| 131 | − hdev->name, urb, -err); | |
| 130 | + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", urb, -err); | |
| 132 | 131 | usb_unanchor_urb(urb); |
| 133 | 132 | } |
| 134 | 133 | } |
| @@ -164,8 +163,7 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev) · 29 unmodified lines | ||
| 164 | 163 | |
| 165 | 164 | err = usb_submit_urb(urb, GFP_KERNEL); |
| 166 | 165 | if (err < 0) { |
| 167 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 168 | − hdev->name, urb, -err); | |
| 166 | + bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err); | |
| 169 | 167 | usb_unanchor_urb(urb); |
| 170 | 168 | } |
| 171 | 169 | |
| @@ -205,8 +203,7 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev) · 33 unmodified lines | ||
| 205 | 203 | |
| 206 | 204 | err = usb_submit_urb(urb, GFP_KERNEL); |
| 207 | 205 | if (err < 0) { |
| 208 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 209 | − hdev->name, urb, -err); | |
| 206 | + bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err); | |
| 210 | 207 | usb_unanchor_urb(urb); |
| 211 | 208 | } |
| 212 | 209 | |
| @@ -272,7 +269,7 @@ static int bpa10x_setup(struct hci_dev *hdev) · 59 unmodified lines | ||
| 272 | 269 | if (IS_ERR(skb)) |
| 273 | 270 | return PTR_ERR(skb); |
| 274 | 271 | |
| 275 | − BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); | |
| 272 | + bt_dev_info(hdev, "%s", (char *)(skb->data + 1)); | |
| 276 | 273 | |
| 277 | 274 | hci_set_fw_info(hdev, "%s", skb->data + 1); |
| 278 | 275 | |
| @@ -348,7 +345,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb) · 69 unmodified lines | ||
| 348 | 345 | |
| 349 | 346 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 350 | 347 | if (err < 0) { |
| 351 | − BT_ERR("%s urb %p submission failed", hdev->name, urb); | |
| 348 | + bt_dev_err(hdev, "urb %p submission failed", urb); | |
| 352 | 349 | kfree(urb->setup_packet); |
| 353 | 350 | usb_unanchor_urb(urb); |
| 354 | 351 | } |
| @@ -355,7 +355,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) · 354 unmodified lines | ||
| 355 | 355 | } else if ((stat & 0xff) != 0xff) { |
| 356 | 356 | if (stat & 0x0020) { |
| 357 | 357 | int status = bt3c_read(iobase, 0x7002) & 0x10; |
| 358 | − BT_INFO("%s: Antenna %s", info->hdev->name, | |
| 358 | + bt_dev_info(info->hdev, "Antenna %s", | |
| 359 | 359 | status ? "out" : "in"); |
| 360 | 360 | } |
| 361 | 361 | if (stat & 0x0001) |
| @@ -45,13 +45,12 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) · 44 unmodified lines | ||
| 45 | 45 | HCI_INIT_TIMEOUT); |
| 46 | 46 | if (IS_ERR(skb)) { |
| 47 | 47 | int err = PTR_ERR(skb); |
| 48 | − BT_ERR("%s: BCM: Reading device address failed (%d)", | |
| 49 | − hdev->name, err); | |
| 48 | + bt_dev_err(hdev, "BCM: Reading device address failed (%d)", err); | |
| 50 | 49 | return err; |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | 52 | if (skb->len != sizeof(*bda)) { |
| 54 | − BT_ERR("%s: BCM: Device address length mismatch", hdev->name); | |
| 53 | + bt_dev_err(hdev, "BCM: Device address length mismatch"); | |
| 55 | 54 | kfree_skb(skb); |
| 56 | 55 | return -EIO; |
| 57 | 56 | } |
| @@ -74,8 +73,8 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) · 16 unmodified lines | ||
| 74 | 73 | if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) || |
| 75 | 74 | !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || |
| 76 | 75 | !bacmp(&bda->bdaddr, BDADDR_BCM4330B1)) { |
| 77 | − BT_INFO("%s: BCM: Using default device address (%pMR)", | |
| 78 | − hdev->name, &bda->bdaddr); | |
| 76 | + bt_dev_info(hdev, "BCM: Using default device address (%pMR)", | |
| 77 | + &bda->bdaddr); | |
| 79 | 78 | set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); |
| 80 | 79 | } |
| 81 | 80 | |
| @@ -93,8 +92,7 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) · 11 unmodified lines | ||
| 93 | 92 | skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT); |
| 94 | 93 | if (IS_ERR(skb)) { |
| 95 | 94 | err = PTR_ERR(skb); |
| 96 | − BT_ERR("%s: BCM: Change address command failed (%d)", | |
| 97 | − hdev->name, err); | |
| 95 | + bt_dev_err(hdev, "BCM: Change address command failed (%d)", err); | |
| 98 | 96 | return err; |
| 99 | 97 | } |
| 100 | 98 | kfree_skb(skb); |
| @@ -116,8 +114,8 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) · 15 unmodified lines | ||
| 116 | 114 | skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); |
| 117 | 115 | if (IS_ERR(skb)) { |
| 118 | 116 | err = PTR_ERR(skb); |
| 119 | − BT_ERR("%s: BCM: Download Minidrv command failed (%d)", | |
| 120 | − hdev->name, err); | |
| 117 | + bt_dev_err(hdev, "BCM: Download Minidrv command failed (%d)", | |
| 118 | + err); | |
| 121 | 119 | goto done; |
| 122 | 120 | } |
| 123 | 121 | kfree_skb(skb); |
| @@ -136,7 +134,7 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) · 12 unmodified lines | ||
| 136 | 134 | fw_size -= sizeof(*cmd); |
| 137 | 135 | |
| 138 | 136 | if (fw_size < cmd->plen) { |
| 139 | − BT_ERR("%s: BCM: Patch is corrupted", hdev->name); | |
| 137 | + bt_dev_err(hdev, "BCM: Patch is corrupted"); | |
| 140 | 138 | err = -EINVAL; |
| 141 | 139 | goto done; |
| 142 | 140 | } |
| @@ -151,8 +149,8 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) · 8 unmodified lines | ||
| 151 | 149 | HCI_INIT_TIMEOUT); |
| 152 | 150 | if (IS_ERR(skb)) { |
| 153 | 151 | err = PTR_ERR(skb); |
| 154 | − BT_ERR("%s: BCM: Patch command %04x failed (%d)", | |
| 155 | − hdev->name, opcode, err); | |
| 152 | + bt_dev_err(hdev, "BCM: Patch command %04x failed (%d)", | |
| 153 | + opcode, err); | |
| 156 | 154 | goto done; |
| 157 | 155 | } |
| 158 | 156 | kfree_skb(skb); |
| @@ -173,7 +171,7 @@ static int btbcm_reset(struct hci_dev *hdev) · 14 unmodified lines | ||
| 173 | 171 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); |
| 174 | 172 | if (IS_ERR(skb)) { |
| 175 | 173 | int err = PTR_ERR(skb); |
| 176 | − BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err); | |
| 174 | + bt_dev_err(hdev, "BCM: Reset failed (%d)", err); | |
| 177 | 175 | return err; |
| 178 | 176 | } |
| 179 | 177 | kfree_skb(skb); |
| @@ -191,13 +189,13 @@ static struct sk_buff *btbcm_read_local_name(struct hci_dev *hdev) · 11 unmodified lines | ||
| 191 | 189 | skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL, |
| 192 | 190 | HCI_INIT_TIMEOUT); |
| 193 | 191 | if (IS_ERR(skb)) { |
| 194 | − BT_ERR("%s: BCM: Reading local name failed (%ld)", | |
| 195 | − hdev->name, PTR_ERR(skb)); | |
| 192 | + bt_dev_err(hdev, "BCM: Reading local name failed (%ld)", | |
| 193 | + PTR_ERR(skb)); | |
| 196 | 194 | return skb; |
| 197 | 195 | } |
| 198 | 196 | |
| 199 | 197 | if (skb->len != sizeof(struct hci_rp_read_local_name)) { |
| 200 | − BT_ERR("%s: BCM: Local name length mismatch", hdev->name); | |
| 198 | + bt_dev_err(hdev, "BCM: Local name length mismatch"); | |
| 201 | 199 | kfree_skb(skb); |
| 202 | 200 | return ERR_PTR(-EIO); |
| 203 | 201 | } |
| @@ -212,13 +210,13 @@ static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev) · 8 unmodified lines | ||
| 212 | 210 | skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, |
| 213 | 211 | HCI_INIT_TIMEOUT); |
| 214 | 212 | if (IS_ERR(skb)) { |
| 215 | − BT_ERR("%s: BCM: Reading local version info failed (%ld)", | |
| 216 | − hdev->name, PTR_ERR(skb)); | |
| 213 | + bt_dev_err(hdev, "BCM: Reading local version info failed (%ld)", | |
| 214 | + PTR_ERR(skb)); | |
| 217 | 215 | return skb; |
| 218 | 216 | } |
| 219 | 217 | |
| 220 | 218 | if (skb->len != sizeof(struct hci_rp_read_local_version)) { |
| 221 | − BT_ERR("%s: BCM: Local version length mismatch", hdev->name); | |
| 219 | + bt_dev_err(hdev, "BCM: Local version length mismatch"); | |
| 222 | 220 | kfree_skb(skb); |
| 223 | 221 | return ERR_PTR(-EIO); |
| 224 | 222 | } |
| @@ -232,13 +230,13 @@ static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev) · 7 unmodified lines | ||
| 232 | 230 | |
| 233 | 231 | skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT); |
| 234 | 232 | if (IS_ERR(skb)) { |
| 235 | − BT_ERR("%s: BCM: Read verbose config info failed (%ld)", | |
| 236 | − hdev->name, PTR_ERR(skb)); | |
| 233 | + bt_dev_err(hdev, "BCM: Read verbose config info failed (%ld)", | |
| 234 | + PTR_ERR(skb)); | |
| 237 | 235 | return skb; |
| 238 | 236 | } |
| 239 | 237 | |
| 240 | 238 | if (skb->len != 7) { |
| 241 | − BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name); | |
| 239 | + bt_dev_err(hdev, "BCM: Verbose config length mismatch"); | |
| 242 | 240 | kfree_skb(skb); |
| 243 | 241 | return ERR_PTR(-EIO); |
| 244 | 242 | } |
| @@ -252,14 +250,13 @@ static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev) · 7 unmodified lines | ||
| 252 | 250 | |
| 253 | 251 | skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT); |
| 254 | 252 | if (IS_ERR(skb)) { |
| 255 | − BT_ERR("%s: BCM: Read controller features failed (%ld)", | |
| 256 | − hdev->name, PTR_ERR(skb)); | |
| 253 | + bt_dev_err(hdev, "BCM: Read controller features failed (%ld)", | |
| 254 | + PTR_ERR(skb)); | |
| 257 | 255 | return skb; |
| 258 | 256 | } |
| 259 | 257 | |
| 260 | 258 | if (skb->len != 9) { |
| 261 | − BT_ERR("%s: BCM: Controller features length mismatch", | |
| 262 | − hdev->name); | |
| 259 | + bt_dev_err(hdev, "BCM: Controller features length mismatch"); | |
| 263 | 260 | kfree_skb(skb); |
| 264 | 261 | return ERR_PTR(-EIO); |
| 265 | 262 | } |
| @@ -273,13 +270,13 @@ static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev) · 7 unmodified lines | ||
| 273 | 270 | |
| 274 | 271 | skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT); |
| 275 | 272 | if (IS_ERR(skb)) { |
| 276 | − BT_ERR("%s: BCM: Read USB product info failed (%ld)", | |
| 277 | − hdev->name, PTR_ERR(skb)); | |
| 273 | + bt_dev_err(hdev, "BCM: Read USB product info failed (%ld)", | |
| 274 | + PTR_ERR(skb)); | |
| 278 | 275 | return skb; |
| 279 | 276 | } |
| 280 | 277 | |
| 281 | 278 | if (skb->len != 5) { |
| 282 | − BT_ERR("%s: BCM: USB product length mismatch", hdev->name); | |
| 279 | + bt_dev_err(hdev, "BCM: USB product length mismatch"); | |
| 283 | 280 | kfree_skb(skb); |
| 284 | 281 | return ERR_PTR(-EIO); |
| 285 | 282 | } |
| @@ -296,7 +293,7 @@ static int btbcm_read_info(struct hci_dev *hdev) · 10 unmodified lines | ||
| 296 | 293 | if (IS_ERR(skb)) |
| 297 | 294 | return PTR_ERR(skb); |
| 298 | 295 | |
| 299 | − BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]); | |
| 296 | + bt_dev_info(hdev, "BCM: chip id %u", skb->data[1]); | |
| 300 | 297 | kfree_skb(skb); |
| 301 | 298 | |
| 302 | 299 | /* Read Controller Features */ |
| @@ -304,7 +301,7 @@ static int btbcm_read_info(struct hci_dev *hdev) · 1 unmodified line | ||
| 304 | 301 | if (IS_ERR(skb)) |
| 305 | 302 | return PTR_ERR(skb); |
| 306 | 303 | |
| 307 | − BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]); | |
| 304 | + bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]); | |
| 308 | 305 | kfree_skb(skb); |
| 309 | 306 | |
| 310 | 307 | /* Read Local Name */ |
| @@ -312,7 +309,7 @@ static int btbcm_read_info(struct hci_dev *hdev) · 1 unmodified line | ||
| 312 | 309 | if (IS_ERR(skb)) |
| 313 | 310 | return PTR_ERR(skb); |
| 314 | 311 | |
| 315 | − BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); | |
| 312 | + bt_dev_info(hdev, "%s", (char *)(skb->data + 1)); | |
| 316 | 313 | kfree_skb(skb); |
| 317 | 314 | |
| 318 | 315 | return 0; |
| @@ -327,6 +324,8 @@ static const struct { · 8 unmodified lines | ||
| 327 | 324 | { 0x4406, "BCM4324B3" }, /* 002.004.006 */ |
| 328 | 325 | { 0x610c, "BCM4354" }, /* 003.001.012 */ |
| 329 | 326 | { 0x2209, "BCM43430A1" }, /* 001.002.009 */ |
| 327 | + { 0x6119, "BCM4345C0" }, /* 003.001.025 */ | |
| 328 | + { 0x230f, "BCM4356A2" }, /* 001.003.015 */ | |
| 330 | 329 | { } |
| 331 | 330 | }; |
| 332 | 331 | |
| @@ -361,6 +360,7 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len) · 28 unmodified lines | ||
| 361 | 360 | switch ((rev & 0xf000) >> 12) { |
| 362 | 361 | case 0: |
| 363 | 362 | case 1: |
| 363 | + case 2: | |
| 364 | 364 | case 3: |
| 365 | 365 | for (i = 0; bcm_uart_subver_table[i].name; i++) { |
| 366 | 366 | if (subver == bcm_uart_subver_table[i].subver) { |
| @@ -375,9 +375,9 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len) · 8 unmodified lines | ||
| 375 | 375 | return 0; |
| 376 | 376 | } |
| 377 | 377 | |
| 378 | − BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, | |
| 379 | − hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 380 | − (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 378 | + bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u", | |
| 379 | + hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 380 | + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 381 | 381 | |
| 382 | 382 | return 0; |
| 383 | 383 | } |
| @@ -405,9 +405,9 @@ int btbcm_finalize(struct hci_dev *hdev) · 21 unmodified lines | ||
| 405 | 405 | subver = le16_to_cpu(ver->lmp_subver); |
| 406 | 406 | kfree_skb(skb); |
| 407 | 407 | |
| 408 | − BT_INFO("%s: BCM (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, | |
| 409 | − (subver & 0xe000) >> 13, (subver & 0x1f00) >> 8, | |
| 410 | − (subver & 0x00ff), rev & 0x0fff); | |
| 408 | + bt_dev_info(hdev, "BCM (%3.3u.%3.3u.%3.3u) build %4.4u", | |
| 409 | + (subver & 0xe000) >> 13, (subver & 0x1f00) >> 8, | |
| 410 | + (subver & 0x00ff), rev & 0x0fff); | |
| 411 | 411 | |
| 412 | 412 | btbcm_check_bdaddr(hdev); |
| 413 | 413 | |
| @@ -502,13 +502,13 @@ int btbcm_setup_patchram(struct hci_dev *hdev) · 88 unmodified lines | ||
| 502 | 502 | return 0; |
| 503 | 503 | } |
| 504 | 504 | |
| 505 | − BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, | |
| 506 | − hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 507 | − (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 505 | + bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u", | |
| 506 | + hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 507 | + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 508 | 508 | |
| 509 | 509 | err = request_firmware(&fw, fw_name, &hdev->dev); |
| 510 | 510 | if (err < 0) { |
| 511 | − BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name); | |
| 511 | + bt_dev_info(hdev, "BCM: Patch %s not found", fw_name); | |
| 512 | 512 | goto done; |
| 513 | 513 | } |
| 514 | 514 | |
| @@ -531,16 +531,16 @@ int btbcm_setup_patchram(struct hci_dev *hdev) · 16 unmodified lines | ||
| 531 | 531 | subver = le16_to_cpu(ver->lmp_subver); |
| 532 | 532 | kfree_skb(skb); |
| 533 | 533 | |
| 534 | − BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, | |
| 535 | − hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 536 | − (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 534 | + bt_dev_info(hdev, "%s (%3.3u.%3.3u.%3.3u) build %4.4u", | |
| 535 | + hw_name ? : "BCM", (subver & 0xe000) >> 13, | |
| 536 | + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); | |
| 537 | 537 | |
| 538 | 538 | /* Read Local Name */ |
| 539 | 539 | skb = btbcm_read_local_name(hdev); |
| 540 | 540 | if (IS_ERR(skb)) |
| 541 | 541 | return PTR_ERR(skb); |
| 542 | 542 | |
| 543 | − BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); | |
| 543 | + bt_dev_info(hdev, "%s", (char *)(skb->data + 1)); | |
| 544 | 544 | kfree_skb(skb); |
| 545 | 545 | |
| 546 | 546 | done: |
| @@ -565,31 +565,31 @@ int btbcm_setup_apple(struct hci_dev *hdev) · 18 unmodified lines | ||
| 565 | 565 | /* Read Verbose Config Version Info */ |
| 566 | 566 | skb = btbcm_read_verbose_config(hdev); |
| 567 | 567 | if (!IS_ERR(skb)) { |
| 568 | − BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, | |
| 569 | − skb->data[1], get_unaligned_le16(skb->data + 5)); | |
| 568 | + bt_dev_info(hdev, "BCM: chip id %u build %4.4u", | |
| 569 | + skb->data[1], get_unaligned_le16(skb->data + 5)); | |
| 570 | 570 | kfree_skb(skb); |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | 573 | /* Read USB Product Info */ |
| 574 | 574 | skb = btbcm_read_usb_product(hdev); |
| 575 | 575 | if (!IS_ERR(skb)) { |
| 576 | − BT_INFO("%s: BCM: product %4.4x:%4.4x", hdev->name, | |
| 577 | − get_unaligned_le16(skb->data + 1), | |
| 578 | − get_unaligned_le16(skb->data + 3)); | |
| 576 | + bt_dev_info(hdev, "BCM: product %4.4x:%4.4x", | |
| 577 | + get_unaligned_le16(skb->data + 1), | |
| 578 | + get_unaligned_le16(skb->data + 3)); | |
| 579 | 579 | kfree_skb(skb); |
| 580 | 580 | } |
| 581 | 581 | |
| 582 | 582 | /* Read Controller Features */ |
| 583 | 583 | skb = btbcm_read_controller_features(hdev); |
| 584 | 584 | if (!IS_ERR(skb)) { |
| 585 | − BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]); | |
| 585 | + bt_dev_info(hdev, "BCM: features 0x%2.2x", skb->data[1]); | |
| 586 | 586 | kfree_skb(skb); |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | 589 | /* Read Local Name */ |
| 590 | 590 | skb = btbcm_read_local_name(hdev); |
| 591 | 591 | if (!IS_ERR(skb)) { |
| 592 | − BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); | |
| 592 | + bt_dev_info(hdev, "%s", (char *)(skb->data + 1)); | |
| 593 | 593 | kfree_skb(skb); |
| 594 | 594 | } |
| 595 | 595 | |
| @@ -43,13 +43,13 @@ int btintel_check_bdaddr(struct hci_dev *hdev) · 42 unmodified lines | ||
| 43 | 43 | HCI_INIT_TIMEOUT); |
| 44 | 44 | if (IS_ERR(skb)) { |
| 45 | 45 | int err = PTR_ERR(skb); |
| 46 | − BT_ERR("%s: Reading Intel device address failed (%d)", | |
| 47 | − hdev->name, err); | |
| 46 | + bt_dev_err(hdev, "Reading Intel device address failed (%d)", | |
| 47 | + err); | |
| 48 | 48 | return err; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | if (skb->len != sizeof(*bda)) { |
| 52 | − BT_ERR("%s: Intel device address length mismatch", hdev->name); | |
| 52 | + bt_dev_err(hdev, "Intel device address length mismatch"); | |
| 53 | 53 | kfree_skb(skb); |
| 54 | 54 | return -EIO; |
| 55 | 55 | } |
| @@ -62,8 +62,8 @@ int btintel_check_bdaddr(struct hci_dev *hdev) · 6 unmodified lines | ||
| 62 | 62 | * and that in turn can cause problems with Bluetooth operation. |
| 63 | 63 | */ |
| 64 | 64 | if (!bacmp(&bda->bdaddr, BDADDR_INTEL)) { |
| 65 | − BT_ERR("%s: Found Intel default device address (%pMR)", | |
| 66 | − hdev->name, &bda->bdaddr); | |
| 65 | + bt_dev_err(hdev, "Found Intel default device address (%pMR)", | |
| 66 | + &bda->bdaddr); | |
| 67 | 67 | set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); |
| 68 | 68 | } |
| 69 | 69 | |
| @@ -123,8 +123,8 @@ int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) · 53 unmodified lines | ||
| 123 | 123 | skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT); |
| 124 | 124 | if (IS_ERR(skb)) { |
| 125 | 125 | err = PTR_ERR(skb); |
| 126 | − BT_ERR("%s: Changing Intel device address failed (%d)", | |
| 127 | − hdev->name, err); | |
| 126 | + bt_dev_err(hdev, "Changing Intel device address failed (%d)", | |
| 127 | + err); | |
| 128 | 128 | return err; |
| 129 | 129 | } |
| 130 | 130 | kfree_skb(skb); |
| @@ -154,8 +154,8 @@ int btintel_set_diag(struct hci_dev *hdev, bool enable) · 23 unmodified lines | ||
| 154 | 154 | err = PTR_ERR(skb); |
| 155 | 155 | if (err == -ENODATA) |
| 156 | 156 | goto done; |
| 157 | − BT_ERR("%s: Changing Intel diagnostic mode failed (%d)", | |
| 158 | − hdev->name, err); | |
| 157 | + bt_dev_err(hdev, "Changing Intel diagnostic mode failed (%d)", | |
| 158 | + err); | |
| 159 | 159 | return err; |
| 160 | 160 | } |
| 161 | 161 | kfree_skb(skb); |
| @@ -189,30 +189,30 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code) · 27 unmodified lines | ||
| 189 | 189 | struct sk_buff *skb; |
| 190 | 190 | u8 type = 0x00; |
| 191 | 191 | |
| 192 | − BT_ERR("%s: Hardware error 0x%2.2x", hdev->name, code); | |
| 192 | + bt_dev_err(hdev, "Hardware error 0x%2.2x", code); | |
| 193 | 193 | |
| 194 | 194 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); |
| 195 | 195 | if (IS_ERR(skb)) { |
| 196 | − BT_ERR("%s: Reset after hardware error failed (%ld)", | |
| 197 | − hdev->name, PTR_ERR(skb)); | |
| 196 | + bt_dev_err(hdev, "Reset after hardware error failed (%ld)", | |
| 197 | + PTR_ERR(skb)); | |
| 198 | 198 | return; |
| 199 | 199 | } |
| 200 | 200 | kfree_skb(skb); |
| 201 | 201 | |
| 202 | 202 | skb = __hci_cmd_sync(hdev, 0xfc22, 1, &type, HCI_INIT_TIMEOUT); |
| 203 | 203 | if (IS_ERR(skb)) { |
| 204 | − BT_ERR("%s: Retrieving Intel exception info failed (%ld)", | |
| 205 | − hdev->name, PTR_ERR(skb)); | |
| 204 | + bt_dev_err(hdev, "Retrieving Intel exception info failed (%ld)", | |
| 205 | + PTR_ERR(skb)); | |
| 206 | 206 | return; |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | if (skb->len != 13) { |
| 210 | − BT_ERR("%s: Exception info size mismatch", hdev->name); | |
| 210 | + bt_dev_err(hdev, "Exception info size mismatch"); | |
| 211 | 211 | kfree_skb(skb); |
| 212 | 212 | return; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | − BT_ERR("%s: Exception info %s", hdev->name, (char *)(skb->data + 1)); | |
| 215 | + bt_dev_err(hdev, "Exception info %s", (char *)(skb->data + 1)); | |
| 216 | 216 | |
| 217 | 217 | kfree_skb(skb); |
| 218 | 218 | } |
| @@ -233,9 +233,10 @@ void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver) · 14 unmodified lines | ||
| 233 | 233 | return; |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | − BT_INFO("%s: %s revision %u.%u build %u week %u %u", hdev->name, | |
| 237 | − variant, ver->fw_revision >> 4, ver->fw_revision & 0x0f, | |
| 238 | − ver->fw_build_num, ver->fw_build_ww, 2000 + ver->fw_build_yy); | |
| 236 | + bt_dev_info(hdev, "%s revision %u.%u build %u week %u %u", | |
| 237 | + variant, ver->fw_revision >> 4, ver->fw_revision & 0x0f, | |
| 238 | + ver->fw_build_num, ver->fw_build_ww, | |
| 239 | + 2000 + ver->fw_build_yy); | |
| 239 | 240 | } |
| 240 | 241 | EXPORT_SYMBOL_GPL(btintel_version_info); |
| 241 | 242 | |
| @@ -321,8 +322,7 @@ int btintel_set_event_mask(struct hci_dev *hdev, bool debug) · 79 unmodified lines | ||
| 321 | 322 | skb = __hci_cmd_sync(hdev, 0xfc52, 8, mask, HCI_INIT_TIMEOUT); |
| 322 | 323 | if (IS_ERR(skb)) { |
| 323 | 324 | err = PTR_ERR(skb); |
| 324 | − BT_ERR("%s: Setting Intel event mask failed (%d)", | |
| 325 | − hdev->name, err); | |
| 325 | + bt_dev_err(hdev, "Setting Intel event mask failed (%d)", err); | |
| 326 | 326 | return err; |
| 327 | 327 | } |
| 328 | 328 | kfree_skb(skb); |
| @@ -64,7 +64,7 @@ static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv) · 63 unmodified lines | ||
| 64 | 64 | struct btmrvl_sdio_card *card = priv; |
| 65 | 65 | struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg; |
| 66 | 66 | |
| 67 | − pr_info("%s: wake by bt", __func__); | |
| 67 | + pr_info("%s: wake by bt\n", __func__); | |
| 68 | 68 | cfg->wake_by_bt = true; |
| 69 | 69 | disable_irq_nosync(irq); |
| 70 | 70 | |
| @@ -87,7 +87,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, · 16 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | if (!dev->of_node || |
| 89 | 89 | !of_match_node(btmrvl_sdio_of_match_table, dev->of_node)) { |
| 90 | − pr_err("sdio platform data not available"); | |
| 90 | + pr_err("sdio platform data not available\n"); | |
| 91 | 91 | return -1; |
| 92 | 92 | } |
| 93 | 93 | |
| @@ -99,7 +99,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, · 5 unmodified lines | ||
| 99 | 99 | if (cfg && card->plt_of_node) { |
| 100 | 100 | cfg->irq_bt = irq_of_parse_and_map(card->plt_of_node, 0); |
| 101 | 101 | if (!cfg->irq_bt) { |
| 102 | − dev_err(dev, "fail to parse irq_bt from device tree"); | |
| 102 | + dev_err(dev, "fail to parse irq_bt from device tree\n"); | |
| 103 | 103 | cfg->irq_bt = -1; |
| 104 | 104 | } else { |
| 105 | 105 | ret = devm_request_irq(dev, cfg->irq_bt, |
| @@ -287,7 +287,7 @@ static int rome_download_firmware(struct hci_dev *hdev, · 286 unmodified lines | ||
| 287 | 287 | const struct firmware *fw; |
| 288 | 288 | int ret; |
| 289 | 289 | |
| 290 | − BT_INFO("%s: ROME Downloading %s", hdev->name, config->fwname); | |
| 290 | + bt_dev_info(hdev, "ROME Downloading %s", config->fwname); | |
| 291 | 291 | |
| 292 | 292 | ret = request_firmware(&fw, config->fwname, &hdev->dev); |
| 293 | 293 | if (ret) { |
| @@ -351,7 +351,7 @@ int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate) · 57 unmodified lines | ||
| 351 | 351 | return err; |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | − BT_INFO("%s: ROME controller version 0x%08x", hdev->name, rome_ver); | |
| 354 | + bt_dev_info(hdev, "ROME controller version 0x%08x", rome_ver); | |
| 355 | 355 | |
| 356 | 356 | /* Download rampatch file */ |
| 357 | 357 | config.type = TLV_TYPE_PATCH; |
| @@ -380,7 +380,7 @@ int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate) · 22 unmodified lines | ||
| 380 | 380 | return err; |
| 381 | 381 | } |
| 382 | 382 | |
| 383 | − BT_INFO("%s: ROME setup on UART is completed", hdev->name); | |
| 383 | + bt_dev_info(hdev, "ROME setup on UART is completed"); | |
| 384 | 384 | |
| 385 | 385 | return 0; |
| 386 | 386 | } |
| @@ -15,6 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/module.h> |
| 16 | 16 | #include <linux/slab.h> |
| 17 | 17 | #include <linux/rpmsg.h> |
| 18 | +#include <linux/of.h> | |
| 19 | + | |
| 18 | 20 | #include <linux/soc/qcom/wcnss_ctrl.h> |
| 19 | 21 | #include <linux/platform_device.h> |
| 20 | 22 | |
| @@ -26,6 +28,7 @@ · 5 unmodified lines | ||
| 26 | 28 | struct btqcomsmd { |
| 27 | 29 | struct hci_dev *hdev; |
| 28 | 30 | |
| 31 | + bdaddr_t bdaddr; | |
| 29 | 32 | struct rpmsg_endpoint *acl_channel; |
| 30 | 33 | struct rpmsg_endpoint *cmd_channel; |
| 31 | 34 | }; |
| @@ -100,6 +103,38 @@ static int btqcomsmd_close(struct hci_dev *hdev) · 68 unmodified lines | ||
| 100 | 103 | return 0; |
| 101 | 104 | } |
| 102 | 105 | |
| 106 | +static int btqcomsmd_setup(struct hci_dev *hdev) | |
| 107 | +{ | |
| 108 | + struct btqcomsmd *btq = hci_get_drvdata(hdev); | |
| 109 | + struct sk_buff *skb; | |
| 110 | + int err; | |
| 111 | + | |
| 112 | + skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); | |
| 113 | + if (IS_ERR(skb)) | |
| 114 | + return PTR_ERR(skb); | |
| 115 | + kfree_skb(skb); | |
| 116 | + | |
| 117 | + /* Devices do not have persistent storage for BD address. If no | |
| 118 | + * BD address has been retrieved during probe, mark the device | |
| 119 | + * as having an invalid BD address. | |
| 120 | + */ | |
| 121 | + if (!bacmp(&btq->bdaddr, BDADDR_ANY)) { | |
| 122 | + set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); | |
| 123 | + return 0; | |
| 124 | + } | |
| 125 | + | |
| 126 | + /* When setting a configured BD address fails, mark the device | |
| 127 | + * as having an invalid BD address. | |
| 128 | + */ | |
| 129 | + err = qca_set_bdaddr_rome(hdev, &btq->bdaddr); | |
| 130 | + if (err) { | |
| 131 | + set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); | |
| 132 | + return 0; | |
| 133 | + } | |
| 134 | + | |
| 135 | + return 0; | |
| 136 | +} | |
| 137 | + | |
| 103 | 138 | static int btqcomsmd_probe(struct platform_device *pdev) |
| 104 | 139 | { |
| 105 | 140 | struct btqcomsmd *btq; |
| @@ -123,6 +158,15 @@ static int btqcomsmd_probe(struct platform_device *pdev) · 17 unmodified lines | ||
| 123 | 158 | if (IS_ERR(btq->cmd_channel)) |
| 124 | 159 | return PTR_ERR(btq->cmd_channel); |
| 125 | 160 | |
| 161 | + /* The local-bd-address property is usually injected by the | |
| 162 | + * bootloader which has access to the allocated BD address. | |
| 163 | + */ | |
| 164 | + if (!of_property_read_u8_array(pdev->dev.of_node, "local-bd-address", | |
| 165 | + (u8 *)&btq->bdaddr, sizeof(bdaddr_t))) { | |
| 166 | + dev_info(&pdev->dev, "BD address %pMR retrieved from device-tree", | |
| 167 | + &btq->bdaddr); | |
| 168 | + } | |
| 169 | + | |
| 126 | 170 | hdev = hci_alloc_dev(); |
| 127 | 171 | if (!hdev) |
| 128 | 172 | return -ENOMEM; |
| @@ -135,6 +179,7 @@ static int btqcomsmd_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 135 | 179 | hdev->open = btqcomsmd_open; |
| 136 | 180 | hdev->close = btqcomsmd_close; |
| 137 | 181 | hdev->send = btqcomsmd_send; |
| 182 | + hdev->setup = btqcomsmd_setup; | |
| 138 | 183 | hdev->set_bdaddr = qca_set_bdaddr_rome; |
| 139 | 184 | |
| 140 | 185 | ret = hci_register_dev(hdev); |
| @@ -55,8 +55,8 @@ static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) · 54 unmodified lines | ||
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | rom_version = (struct rtl_rom_version_evt *)skb->data; |
| 58 | − BT_INFO("%s: rom_version status=%x version=%x", | |
| 59 | − hdev->name, rom_version->status, rom_version->version); | |
| 58 | + bt_dev_info(hdev, "rom_version status=%x version=%x", | |
| 59 | + rom_version->status, rom_version->version); | |
| 60 | 60 | |
| 61 | 61 | *version = rom_version->version; |
| 62 | 62 | |
| @@ -273,7 +273,7 @@ static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff) · 210 unmodified lines | ||
| 273 | 273 | const struct firmware *fw; |
| 274 | 274 | int ret; |
| 275 | 275 | |
| 276 | − BT_INFO("%s: rtl: loading %s", hdev->name, name); | |
| 276 | + bt_dev_info(hdev, "rtl: loading %s", name); | |
| 277 | 277 | ret = request_firmware(&fw, name, &hdev->dev); |
| 278 | 278 | if (ret < 0) |
| 279 | 279 | return ret; |
| @@ -292,7 +292,7 @@ static int btrtl_setup_rtl8723a(struct hci_dev *hdev) · 12 unmodified lines | ||
| 292 | 292 | const struct firmware *fw; |
| 293 | 293 | int ret; |
| 294 | 294 | |
| 295 | − BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); | |
| 295 | + bt_dev_info(hdev, "rtl: loading rtl_bt/rtl8723a_fw.bin"); | |
| 296 | 296 | ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev); |
| 297 | 297 | if (ret < 0) { |
| 298 | 298 | BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); |
| @@ -363,7 +363,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, · 64 unmodified lines | ||
| 363 | 363 | } else |
| 364 | 364 | cfg_sz = 0; |
| 365 | 365 | |
| 366 | − BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); | |
| 366 | + bt_dev_info(hdev, "rtl: loading %s", fw_name); | |
| 367 | 367 | ret = request_firmware(&fw, fw_name, &hdev->dev); |
| 368 | 368 | if (ret < 0) { |
| 369 | 369 | BT_ERR("%s: Failed to load %s", hdev->name, fw_name); |
| @@ -390,7 +390,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, · 20 unmodified lines | ||
| 390 | 390 | fw_data = tbuff; |
| 391 | 391 | } |
| 392 | 392 | |
| 393 | − BT_INFO("cfg_sz %d, total size %d", cfg_sz, ret); | |
| 393 | + bt_dev_info(hdev, "cfg_sz %d, total size %d", cfg_sz, ret); | |
| 394 | 394 | |
| 395 | 395 | ret = rtl_download_firmware(hdev, fw_data, ret); |
| 396 | 396 | |
| @@ -436,9 +436,10 @@ int btrtl_setup_realtek(struct hci_dev *hdev) · 39 unmodified lines | ||
| 436 | 436 | return -PTR_ERR(skb); |
| 437 | 437 | |
| 438 | 438 | resp = (struct hci_rp_read_local_version *)skb->data; |
| 439 | − BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " | |
| 440 | − "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, | |
| 441 | − resp->lmp_ver, resp->lmp_subver); | |
| 439 | + bt_dev_info(hdev, "rtl: examining hci_ver=%02x hci_rev=%04x " | |
| 440 | + "lmp_ver=%02x lmp_subver=%04x", | |
| 441 | + resp->hci_ver, resp->hci_rev, | |
| 442 | + resp->lmp_ver, resp->lmp_subver); | |
| 442 | 443 | |
| 443 | 444 | lmp_subver = le16_to_cpu(resp->lmp_subver); |
| 444 | 445 | kfree_skb(skb); |
| @@ -466,7 +467,7 @@ int btrtl_setup_realtek(struct hci_dev *hdev) · 21 unmodified lines | ||
| 466 | 467 | return btrtl_setup_rtl8723b(hdev, lmp_subver, |
| 467 | 468 | "rtl_bt/rtl8822b_fw.bin"); |
| 468 | 469 | default: |
| 469 | − BT_INFO("rtl: assuming no firmware upload needed."); | |
| 470 | + bt_dev_info(hdev, "rtl: assuming no firmware upload needed"); | |
| 470 | 471 | return 0; |
| 471 | 472 | } |
| 472 | 473 | } |
| @@ -66,7 +66,6 @@ static struct usb_driver btusb_driver; · 65 unmodified lines | ||
| 66 | 66 | #define BTUSB_BCM2045 0x40000 |
| 67 | 67 | #define BTUSB_IFNUM_2 0x80000 |
| 68 | 68 | #define BTUSB_CW6622 0x100000 |
| 69 | −#define BTUSB_BCM_NO_PRODID 0x200000 | |
| 70 | 69 | |
| 71 | 70 | static const struct usb_device_id btusb_table[] = { |
| 72 | 71 | /* Generic Bluetooth USB device */ |
| @@ -171,10 +170,6 @@ static const struct usb_device_id btusb_table[] = { · 98 unmodified lines | ||
| 171 | 170 | { USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01), |
| 172 | 171 | .driver_info = BTUSB_BCM_PATCHRAM }, |
| 173 | 172 | |
| 174 | − /* Broadcom devices with missing product id */ | |
| 175 | − { USB_DEVICE_AND_INTERFACE_INFO(0x0000, 0x0000, 0xff, 0x01, 0x01), | |
| 176 | − .driver_info = BTUSB_BCM_PATCHRAM | BTUSB_BCM_NO_PRODID }, | |
| 177 | − | |
| 178 | 173 | /* Intel Bluetooth USB Bootloader (RAM module) */ |
| 179 | 174 | { USB_DEVICE(0x8087, 0x0a5a), |
| 180 | 175 | .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC }, |
| @@ -272,6 +267,7 @@ static const struct usb_device_id blacklist_table[] = { · 91 unmodified lines | ||
| 272 | 267 | { USB_DEVICE(0x0cf3, 0xe301), .driver_info = BTUSB_QCA_ROME }, |
| 273 | 268 | { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME }, |
| 274 | 269 | { USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME }, |
| 270 | + { USB_DEVICE(0x0489, 0xe09f), .driver_info = BTUSB_QCA_ROME }, | |
| 275 | 271 | { USB_DEVICE(0x0489, 0xe0a2), .driver_info = BTUSB_QCA_ROME }, |
| 276 | 272 | { USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME }, |
| 277 | 273 | { USB_DEVICE(0x04ca, 0x3016), .driver_info = BTUSB_QCA_ROME }, |
| @@ -401,6 +397,7 @@ struct btusb_data { · 123 unmodified lines | ||
| 401 | 397 | struct usb_interface *intf; |
| 402 | 398 | struct usb_interface *isoc; |
| 403 | 399 | struct usb_interface *diag; |
| 400 | + unsigned isoc_ifnum; | |
| 404 | 401 | |
| 405 | 402 | unsigned long flags; |
| 406 | 403 | |
| @@ -647,7 +644,7 @@ static void btusb_intr_complete(struct urb *urb) · 240 unmodified lines | ||
| 647 | 644 | |
| 648 | 645 | if (btusb_recv_intr(data, urb->transfer_buffer, |
| 649 | 646 | urb->actual_length) < 0) { |
| 650 | − BT_ERR("%s corrupted event packet", hdev->name); | |
| 647 | + bt_dev_err(hdev, "corrupted event packet"); | |
| 651 | 648 | hdev->stat.err_rx++; |
| 652 | 649 | } |
| 653 | 650 | } else if (urb->status == -ENOENT) { |
| @@ -667,8 +664,8 @@ static void btusb_intr_complete(struct urb *urb) · 13 unmodified lines | ||
| 667 | 664 | * -ENODEV: device got disconnected |
| 668 | 665 | */ |
| 669 | 666 | if (err != -EPERM && err != -ENODEV) |
| 670 | − BT_ERR("%s urb %p failed to resubmit (%d)", | |
| 671 | − hdev->name, urb, -err); | |
| 667 | + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", | |
| 668 | + urb, -err); | |
| 672 | 669 | usb_unanchor_urb(urb); |
| 673 | 670 | } |
| 674 | 671 | } |
| @@ -710,8 +707,8 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) · 35 unmodified lines | ||
| 710 | 707 | err = usb_submit_urb(urb, mem_flags); |
| 711 | 708 | if (err < 0) { |
| 712 | 709 | if (err != -EPERM && err != -ENODEV) |
| 713 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 714 | − hdev->name, urb, -err); | |
| 710 | + bt_dev_err(hdev, "urb %p submission failed (%d)", | |
| 711 | + urb, -err); | |
| 715 | 712 | usb_unanchor_urb(urb); |
| 716 | 713 | } |
| 717 | 714 | |
| @@ -737,7 +734,7 @@ static void btusb_bulk_complete(struct urb *urb) · 19 unmodified lines | ||
| 737 | 734 | |
| 738 | 735 | if (data->recv_bulk(data, urb->transfer_buffer, |
| 739 | 736 | urb->actual_length) < 0) { |
| 740 | − BT_ERR("%s corrupted ACL packet", hdev->name); | |
| 737 | + bt_dev_err(hdev, "corrupted ACL packet"); | |
| 741 | 738 | hdev->stat.err_rx++; |
| 742 | 739 | } |
| 743 | 740 | } else if (urb->status == -ENOENT) { |
| @@ -757,8 +754,8 @@ static void btusb_bulk_complete(struct urb *urb) · 13 unmodified lines | ||
| 757 | 754 | * -ENODEV: device got disconnected |
| 758 | 755 | */ |
| 759 | 756 | if (err != -EPERM && err != -ENODEV) |
| 760 | − BT_ERR("%s urb %p failed to resubmit (%d)", | |
| 761 | − hdev->name, urb, -err); | |
| 757 | + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", | |
| 758 | + urb, -err); | |
| 762 | 759 | usb_unanchor_urb(urb); |
| 763 | 760 | } |
| 764 | 761 | } |
| @@ -799,8 +796,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) · 34 unmodified lines | ||
| 799 | 796 | err = usb_submit_urb(urb, mem_flags); |
| 800 | 797 | if (err < 0) { |
| 801 | 798 | if (err != -EPERM && err != -ENODEV) |
| 802 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 803 | − hdev->name, urb, -err); | |
| 799 | + bt_dev_err(hdev, "urb %p submission failed (%d)", | |
| 800 | + urb, -err); | |
| 804 | 801 | usb_unanchor_urb(urb); |
| 805 | 802 | } |
| 806 | 803 | |
| @@ -833,7 +830,7 @@ static void btusb_isoc_complete(struct urb *urb) · 26 unmodified lines | ||
| 833 | 830 | |
| 834 | 831 | if (btusb_recv_isoc(data, urb->transfer_buffer + offset, |
| 835 | 832 | length) < 0) { |
| 836 | − BT_ERR("%s corrupted SCO packet", hdev->name); | |
| 833 | + bt_dev_err(hdev, "corrupted SCO packet"); | |
| 837 | 834 | hdev->stat.err_rx++; |
| 838 | 835 | } |
| 839 | 836 | } |
| @@ -853,8 +850,8 @@ static void btusb_isoc_complete(struct urb *urb) · 13 unmodified lines | ||
| 853 | 850 | * -ENODEV: device got disconnected |
| 854 | 851 | */ |
| 855 | 852 | if (err != -EPERM && err != -ENODEV) |
| 856 | − BT_ERR("%s urb %p failed to resubmit (%d)", | |
| 857 | − hdev->name, urb, -err); | |
| 853 | + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", | |
| 854 | + urb, -err); | |
| 858 | 855 | usb_unanchor_urb(urb); |
| 859 | 856 | } |
| 860 | 857 | } |
| @@ -921,8 +918,8 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) · 60 unmodified lines | ||
| 921 | 918 | err = usb_submit_urb(urb, mem_flags); |
| 922 | 919 | if (err < 0) { |
| 923 | 920 | if (err != -EPERM && err != -ENODEV) |
| 924 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 925 | − hdev->name, urb, -err); | |
| 921 | + bt_dev_err(hdev, "urb %p submission failed (%d)", | |
| 922 | + urb, -err); | |
| 926 | 923 | usb_unanchor_urb(urb); |
| 927 | 924 | } |
| 928 | 925 | |
| @@ -966,8 +963,8 @@ static void btusb_diag_complete(struct urb *urb) · 37 unmodified lines | ||
| 966 | 963 | * -ENODEV: device got disconnected |
| 967 | 964 | */ |
| 968 | 965 | if (err != -EPERM && err != -ENODEV) |
| 969 | − BT_ERR("%s urb %p failed to resubmit (%d)", | |
| 970 | − hdev->name, urb, -err); | |
| 966 | + bt_dev_err(hdev, "urb %p failed to resubmit (%d)", | |
| 967 | + urb, -err); | |
| 971 | 968 | usb_unanchor_urb(urb); |
| 972 | 969 | } |
| 973 | 970 | } |
| @@ -1008,8 +1005,8 @@ static int btusb_submit_diag_urb(struct hci_dev *hdev, gfp_t mem_flags) · 34 unmodified lines | ||
| 1008 | 1005 | err = usb_submit_urb(urb, mem_flags); |
| 1009 | 1006 | if (err < 0) { |
| 1010 | 1007 | if (err != -EPERM && err != -ENODEV) |
| 1011 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 1012 | − hdev->name, urb, -err); | |
| 1008 | + bt_dev_err(hdev, "urb %p submission failed (%d)", | |
| 1009 | + urb, -err); | |
| 1013 | 1010 | usb_unanchor_urb(urb); |
| 1014 | 1011 | } |
| 1015 | 1012 | |
| @@ -1270,8 +1267,8 @@ static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb) · 254 unmodified lines | ||
| 1270 | 1267 | err = usb_submit_urb(urb, GFP_KERNEL); |
| 1271 | 1268 | if (err < 0) { |
| 1272 | 1269 | if (err != -EPERM && err != -ENODEV) |
| 1273 | − BT_ERR("%s urb %p submission failed (%d)", | |
| 1274 | − hdev->name, urb, -err); | |
| 1270 | + bt_dev_err(hdev, "urb %p submission failed (%d)", | |
| 1271 | + urb, -err); | |
| 1275 | 1272 | kfree(urb->setup_packet); |
| 1276 | 1273 | usb_unanchor_urb(urb); |
| 1277 | 1274 | } else { |
| @@ -1364,9 +1361,9 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting) · 86 unmodified lines | ||
| 1364 | 1361 | if (!data->isoc) |
| 1365 | 1362 | return -ENODEV; |
| 1366 | 1363 | |
| 1367 | − err = usb_set_interface(data->udev, 1, altsetting); | |
| 1364 | + err = usb_set_interface(data->udev, data->isoc_ifnum, altsetting); | |
| 1368 | 1365 | if (err < 0) { |
| 1369 | − BT_ERR("%s setting interface failed (%d)", hdev->name, -err); | |
| 1366 | + bt_dev_err(hdev, "setting interface failed (%d)", -err); | |
| 1370 | 1367 | return err; |
| 1371 | 1368 | } |
| 1372 | 1369 | |
| @@ -1390,7 +1387,7 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting) · 17 unmodified lines | ||
| 1390 | 1387 | } |
| 1391 | 1388 | |
| 1392 | 1389 | if (!data->isoc_tx_ep || !data->isoc_rx_ep) { |
| 1393 | − BT_ERR("%s invalid SCO descriptors", hdev->name); | |
| 1390 | + bt_dev_err(hdev, "invalid SCO descriptors"); | |
| 1394 | 1391 | return -ENODEV; |
| 1395 | 1392 | } |
| 1396 | 1393 | |
| @@ -1485,7 +1482,7 @@ static int btusb_setup_bcm92035(struct hci_dev *hdev) · 88 unmodified lines | ||
| 1485 | 1482 | |
| 1486 | 1483 | skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT); |
| 1487 | 1484 | if (IS_ERR(skb)) |
| 1488 | − BT_ERR("BCM92035 command failed (%ld)", -PTR_ERR(skb)); | |
| 1485 | + bt_dev_err(hdev, "BCM92035 command failed (%ld)", PTR_ERR(skb)); | |
| 1489 | 1486 | else |
| 1490 | 1487 | kfree_skb(skb); |
| 1491 | 1488 | |
| @@ -1503,12 +1500,12 @@ static int btusb_setup_csr(struct hci_dev *hdev) · 11 unmodified lines | ||
| 1503 | 1500 | HCI_INIT_TIMEOUT); |
| 1504 | 1501 | if (IS_ERR(skb)) { |
| 1505 | 1502 | int err = PTR_ERR(skb); |
| 1506 | − BT_ERR("%s: CSR: Local version failed (%d)", hdev->name, err); | |
| 1503 | + bt_dev_err(hdev, "CSR: Local version failed (%d)", err); | |
| 1507 | 1504 | return err; |
| 1508 | 1505 | } |
| 1509 | 1506 | |
| 1510 | 1507 | if (skb->len != sizeof(struct hci_rp_read_local_version)) { |
| 1511 | − BT_ERR("%s: CSR: Local version length mismatch", hdev->name); | |
| 1508 | + bt_dev_err(hdev, "CSR: Local version length mismatch"); | |
| 1512 | 1509 | kfree_skb(skb); |
| 1513 | 1510 | return -EIO; |
| 1514 | 1511 | } |
| @@ -1570,7 +1567,7 @@ static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, · 55 unmodified lines | ||
| 1570 | 1567 | } |
| 1571 | 1568 | } |
| 1572 | 1569 | |
| 1573 | − BT_INFO("%s: Intel Bluetooth firmware file: %s", hdev->name, fwname); | |
| 1570 | + bt_dev_info(hdev, "Intel Bluetooth firmware file: %s", fwname); | |
| 1574 | 1571 | |
| 1575 | 1572 | return fw; |
| 1576 | 1573 | } |
| @@ -1726,18 +1723,18 @@ static int btusb_setup_intel(struct hci_dev *hdev) · 149 unmodified lines | ||
| 1726 | 1723 | if (err) |
| 1727 | 1724 | return err; |
| 1728 | 1725 | |
| 1729 | − BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x", | |
| 1730 | − hdev->name, ver.hw_platform, ver.hw_variant, ver.hw_revision, | |
| 1731 | − ver.fw_variant, ver.fw_revision, ver.fw_build_num, | |
| 1732 | − ver.fw_build_ww, ver.fw_build_yy, ver.fw_patch_num); | |
| 1726 | + bt_dev_info(hdev, "read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x", | |
| 1727 | + ver.hw_platform, ver.hw_variant, ver.hw_revision, | |
| 1728 | + ver.fw_variant, ver.fw_revision, ver.fw_build_num, | |
| 1729 | + ver.fw_build_ww, ver.fw_build_yy, ver.fw_patch_num); | |
| 1733 | 1730 | |
| 1734 | 1731 | /* fw_patch_num indicates the version of patch the device currently |
| 1735 | 1732 | * have. If there is no patch data in the device, it is always 0x00. |
| 1736 | 1733 | * So, if it is other than 0x00, no need to patch the device again. |
| 1737 | 1734 | */ |
| 1738 | 1735 | if (ver.fw_patch_num) { |
| 1739 | − BT_INFO("%s: Intel device is already patched. patch num: %02x", | |
| 1740 | − hdev->name, ver.fw_patch_num); | |
| 1736 | + bt_dev_info(hdev, "Intel device is already patched. " | |
| 1737 | + "patch num: %02x", ver.fw_patch_num); | |
| 1741 | 1738 | goto complete; |
| 1742 | 1739 | } |
| 1743 | 1740 | |
| @@ -1805,8 +1802,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) · 61 unmodified lines | ||
| 1805 | 1802 | if (err) |
| 1806 | 1803 | return err; |
| 1807 | 1804 | |
| 1808 | − BT_INFO("%s: Intel Bluetooth firmware patch completed and activated", | |
| 1809 | − hdev->name); | |
| 1805 | + bt_dev_info(hdev, "Intel firmware patch completed and activated"); | |
| 1810 | 1806 | |
| 1811 | 1807 | goto complete; |
| 1812 | 1808 | |
| @@ -1816,7 +1812,7 @@ exit_mfg_disable: · 3 unmodified lines | ||
| 1816 | 1812 | if (err) |
| 1817 | 1813 | return err; |
| 1818 | 1814 | |
| 1819 | − BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name); | |
| 1815 | + bt_dev_info(hdev, "Intel firmware patch completed"); | |
| 1820 | 1816 | |
| 1821 | 1817 | goto complete; |
| 1822 | 1818 | |
| @@ -1830,8 +1826,7 @@ exit_mfg_deactivate: · 7 unmodified lines | ||
| 1830 | 1826 | if (err) |
| 1831 | 1827 | return err; |
| 1832 | 1828 | |
| 1833 | − BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated", | |
| 1834 | − hdev->name); | |
| 1829 | + bt_dev_info(hdev, "Intel firmware patch completed and deactivated"); | |
| 1835 | 1830 | |
| 1836 | 1831 | complete: |
| 1837 | 1832 | /* Set the event mask for Intel specific vendor events. This enables |
| @@ -2112,24 +2107,24 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) · 274 unmodified lines | ||
| 2112 | 2107 | |
| 2113 | 2108 | params = (struct intel_boot_params *)skb->data; |
| 2114 | 2109 | |
| 2115 | − BT_INFO("%s: Device revision is %u", hdev->name, | |
| 2116 | − le16_to_cpu(params->dev_revid)); | |
| 2110 | + bt_dev_info(hdev, "Device revision is %u", | |
| 2111 | + le16_to_cpu(params->dev_revid)); | |
| 2117 | 2112 | |
| 2118 | − BT_INFO("%s: Secure boot is %s", hdev->name, | |
| 2119 | − params->secure_boot ? "enabled" : "disabled"); | |
| 2113 | + bt_dev_info(hdev, "Secure boot is %s", | |
| 2114 | + params->secure_boot ? "enabled" : "disabled"); | |
| 2120 | 2115 | |
| 2121 | − BT_INFO("%s: OTP lock is %s", hdev->name, | |
| 2122 | − params->otp_lock ? "enabled" : "disabled"); | |
| 2116 | + bt_dev_info(hdev, "OTP lock is %s", | |
| 2117 | + params->otp_lock ? "enabled" : "disabled"); | |
| 2123 | 2118 | |
| 2124 | − BT_INFO("%s: API lock is %s", hdev->name, | |
| 2125 | − params->api_lock ? "enabled" : "disabled"); | |
| 2119 | + bt_dev_info(hdev, "API lock is %s", | |
| 2120 | + params->api_lock ? "enabled" : "disabled"); | |
| 2126 | 2121 | |
| 2127 | − BT_INFO("%s: Debug lock is %s", hdev->name, | |
| 2128 | − params->debug_lock ? "enabled" : "disabled"); | |
| 2122 | + bt_dev_info(hdev, "Debug lock is %s", | |
| 2123 | + params->debug_lock ? "enabled" : "disabled"); | |
| 2129 | 2124 | |
| 2130 | − BT_INFO("%s: Minimum firmware build %u week %u %u", hdev->name, | |
| 2131 | − params->min_fw_build_nn, params->min_fw_build_cw, | |
| 2132 | − 2000 + params->min_fw_build_yy); | |
| 2125 | + bt_dev_info(hdev, "Minimum firmware build %u week %u %u", | |
| 2126 | + params->min_fw_build_nn, params->min_fw_build_cw, | |
| 2127 | + 2000 + params->min_fw_build_yy); | |
| 2133 | 2128 | |
| 2134 | 2129 | /* It is required that every single firmware fragment is acknowledged |
| 2135 | 2130 | * with a command complete event. If the boot parameters indicate |
| @@ -2146,24 +2141,49 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) · 10 unmodified lines | ||
| 2146 | 2141 | * also be no valid address for the operational firmware. |
| 2147 | 2142 | */ |
| 2148 | 2143 | if (!bacmp(¶ms->otp_bdaddr, BDADDR_ANY)) { |
| 2149 | − BT_INFO("%s: No device address configured", hdev->name); | |
| 2144 | + bt_dev_info(hdev, "No device address configured"); | |
| 2150 | 2145 | set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); |
| 2151 | 2146 | } |
| 2152 | 2147 | |
| 2153 | 2148 | /* With this Intel bootloader only the hardware variant and device |
| 2154 | − * revision information are used to select the right firmware. | |
| 2149 | + * revision information are used to select the right firmware for SfP | |
| 2150 | + * and WsP. | |
| 2155 | 2151 | * |
| 2156 | 2152 | * The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi. |
| 2157 | 2153 | * |
| 2158 | 2154 | * Currently the supported hardware variants are: |
| 2159 | 2155 | * 11 (0x0b) for iBT3.0 (LnP/SfP) |
| 2160 | 2156 | * 12 (0x0c) for iBT3.5 (WsP) |
| 2157 | + * | |
| 2158 | + * For ThP/JfP and for future SKU's, the FW name varies based on HW | |
| 2159 | + * variant, HW revision and FW revision, as these are dependent on CNVi | |
| 2160 | + * and RF Combination. | |
| 2161 | + * | |
| 2161 | 2162 | * 17 (0x11) for iBT3.5 (JfP) |
| 2162 | 2163 | * 18 (0x12) for iBT3.5 (ThP) |
| 2164 | + * | |
| 2165 | + * The firmware file name for these will be | |
| 2166 | + * ibt-<hw_variant>-<hw_revision>-<fw_revision>.sfi. | |
| 2167 | + * | |
| 2163 | 2168 | */ |
| 2164 | − snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi", | |
| 2165 | − le16_to_cpu(ver.hw_variant), | |
| 2166 | − le16_to_cpu(params->dev_revid)); | |
| 2169 | + switch (ver.hw_variant) { | |
| 2170 | + case 0x0b: /* SfP */ | |
| 2171 | + case 0x0c: /* WsP */ | |
| 2172 | + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi", | |
| 2173 | + le16_to_cpu(ver.hw_variant), | |
| 2174 | + le16_to_cpu(params->dev_revid)); | |
| 2175 | + break; | |
| 2176 | + case 0x11: /* JfP */ | |
| 2177 | + case 0x12: /* ThP */ | |
| 2178 | + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.sfi", | |
| 2179 | + le16_to_cpu(ver.hw_variant), | |
| 2180 | + le16_to_cpu(ver.hw_revision), | |
| 2181 | + le16_to_cpu(ver.fw_revision)); | |
| 2182 | + break; | |
| 2183 | + default: | |
| 2184 | + BT_ERR("%s: Unsupported Intel firmware naming", hdev->name); | |
| 2185 | + return -EINVAL; | |
| 2186 | + } | |
| 2167 | 2187 | |
| 2168 | 2188 | err = request_firmware(&fw, fwname, &hdev->dev); |
| 2169 | 2189 | if (err < 0) { |
| @@ -2173,14 +2193,29 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) · 3 unmodified lines | ||
| 2173 | 2193 | return err; |
| 2174 | 2194 | } |
| 2175 | 2195 | |
| 2176 | − BT_INFO("%s: Found device firmware: %s", hdev->name, fwname); | |
| 2196 | + bt_dev_info(hdev, "Found device firmware: %s", fwname); | |
| 2177 | 2197 | |
| 2178 | 2198 | /* Save the DDC file name for later use to apply once the firmware |
| 2179 | 2199 | * downloading is done. |
| 2180 | 2200 | */ |
| 2181 | − snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc", | |
| 2182 | − le16_to_cpu(ver.hw_variant), | |
| 2183 | − le16_to_cpu(params->dev_revid)); | |
| 2201 | + switch (ver.hw_variant) { | |
| 2202 | + case 0x0b: /* SfP */ | |
| 2203 | + case 0x0c: /* WsP */ | |
| 2204 | + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc", | |
| 2205 | + le16_to_cpu(ver.hw_variant), | |
| 2206 | + le16_to_cpu(params->dev_revid)); | |
| 2207 | + break; | |
| 2208 | + case 0x11: /* JfP */ | |
| 2209 | + case 0x12: /* ThP */ | |
| 2210 | + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u-%u.ddc", | |
| 2211 | + le16_to_cpu(ver.hw_variant), | |
| 2212 | + le16_to_cpu(ver.hw_revision), | |
| 2213 | + le16_to_cpu(ver.fw_revision)); | |
| 2214 | + break; | |
| 2215 | + default: | |
| 2216 | + BT_ERR("%s: Unsupported Intel firmware naming", hdev->name); | |
| 2217 | + return -EINVAL; | |
| 2218 | + } | |
| 2184 | 2219 | |
| 2185 | 2220 | kfree_skb(skb); |
| 2186 | 2221 | |
| @@ -2254,7 +2289,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) · 67 unmodified lines | ||
| 2254 | 2289 | |
| 2255 | 2290 | set_bit(BTUSB_FIRMWARE_LOADED, &data->flags); |
| 2256 | 2291 | |
| 2257 | − BT_INFO("%s: Waiting for firmware download to complete", hdev->name); | |
| 2292 | + bt_dev_info(hdev, "Waiting for firmware download to complete"); | |
| 2258 | 2293 | |
| 2259 | 2294 | /* Before switching the device into operational mode and with that |
| 2260 | 2295 | * booting the loaded firmware, wait for the bootloader notification |
| @@ -2291,7 +2326,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) · 30 unmodified lines | ||
| 2291 | 2326 | delta = ktime_sub(rettime, calltime); |
| 2292 | 2327 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
| 2293 | 2328 | |
| 2294 | − BT_INFO("%s: Firmware loaded in %llu usecs", hdev->name, duration); | |
| 2329 | + bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration); | |
| 2295 | 2330 | |
| 2296 | 2331 | done: |
| 2297 | 2332 | release_firmware(fw); |
| @@ -2317,7 +2352,7 @@ done: · 19 unmodified lines | ||
| 2317 | 2352 | * 1 second. However if that happens, then just fail the setup |
| 2318 | 2353 | * since something went wrong. |
| 2319 | 2354 | */ |
| 2320 | − BT_INFO("%s: Waiting for device to boot", hdev->name); | |
| 2355 | + bt_dev_info(hdev, "Waiting for device to boot"); | |
| 2321 | 2356 | |
| 2322 | 2357 | err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING, |
| 2323 | 2358 | TASK_INTERRUPTIBLE, |
| @@ -2337,7 +2372,7 @@ done: · 13 unmodified lines | ||
| 2337 | 2372 | delta = ktime_sub(rettime, calltime); |
| 2338 | 2373 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
| 2339 | 2374 | |
| 2340 | − BT_INFO("%s: Device booted in %llu usecs", hdev->name, duration); | |
| 2375 | + bt_dev_info(hdev, "Device booted in %llu usecs", duration); | |
| 2341 | 2376 | |
| 2342 | 2377 | clear_bit(BTUSB_BOOTLOADER, &data->flags); |
| 2343 | 2378 | |
| @@ -2440,8 +2475,8 @@ static int btusb_set_bdaddr_marvell(struct hci_dev *hdev, · 96 unmodified lines | ||
| 2440 | 2475 | skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT); |
| 2441 | 2476 | if (IS_ERR(skb)) { |
| 2442 | 2477 | ret = PTR_ERR(skb); |
| 2443 | − BT_ERR("%s: changing Marvell device address failed (%ld)", | |
| 2444 | − hdev->name, ret); | |
| 2478 | + bt_dev_err(hdev, "changing Marvell device address failed (%ld)", | |
| 2479 | + ret); | |
| 2445 | 2480 | return ret; |
| 2446 | 2481 | } |
| 2447 | 2482 | kfree_skb(skb); |
| @@ -2465,8 +2500,7 @@ static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, · 17 unmodified lines | ||
| 2465 | 2500 | skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); |
| 2466 | 2501 | if (IS_ERR(skb)) { |
| 2467 | 2502 | ret = PTR_ERR(skb); |
| 2468 | − BT_ERR("%s: Change address command failed (%ld)", | |
| 2469 | − hdev->name, ret); | |
| 2503 | + bt_dev_err(hdev, "Change address command failed (%ld)", ret); | |
| 2470 | 2504 | return ret; |
| 2471 | 2505 | } |
| 2472 | 2506 | kfree_skb(skb); |
| @@ -2532,7 +2566,7 @@ static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request, · 59 unmodified lines | ||
| 2532 | 2566 | err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN, |
| 2533 | 2567 | 0, 0, buf, size, USB_CTRL_SET_TIMEOUT); |
| 2534 | 2568 | if (err < 0) { |
| 2535 | − BT_ERR("%s: Failed to access otp area (%d)", hdev->name, err); | |
| 2569 | + bt_dev_err(hdev, "Failed to access otp area (%d)", err); | |
| 2536 | 2570 | goto done; |
| 2537 | 2571 | } |
| 2538 | 2572 | |
| @@ -2572,7 +2606,7 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev, · 33 unmodified lines | ||
| 2572 | 2606 | err = usb_control_msg(udev, pipe, QCA_DFU_DOWNLOAD, USB_TYPE_VENDOR, |
| 2573 | 2607 | 0, 0, buf, size, USB_CTRL_SET_TIMEOUT); |
| 2574 | 2608 | if (err < 0) { |
| 2575 | − BT_ERR("%s: Failed to send headers (%d)", hdev->name, err); | |
| 2609 | + bt_dev_err(hdev, "Failed to send headers (%d)", err); | |
| 2576 | 2610 | goto done; |
| 2577 | 2611 | } |
| 2578 | 2612 | |
| @@ -2588,13 +2622,13 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev, · 9 unmodified lines | ||
| 2588 | 2622 | err = usb_bulk_msg(udev, pipe, buf, size, &len, |
| 2589 | 2623 | QCA_DFU_TIMEOUT); |
| 2590 | 2624 | if (err < 0) { |
| 2591 | − BT_ERR("%s: Failed to send body at %zd of %zd (%d)", | |
| 2592 | − hdev->name, sent, firmware->size, err); | |
| 2625 | + bt_dev_err(hdev, "Failed to send body at %zd of %zd (%d)", | |
| 2626 | + sent, firmware->size, err); | |
| 2593 | 2627 | break; |
| 2594 | 2628 | } |
| 2595 | 2629 | |
| 2596 | 2630 | if (size != len) { |
| 2597 | − BT_ERR("%s: Failed to get bulk buffer", hdev->name); | |
| 2631 | + bt_dev_err(hdev, "Failed to get bulk buffer"); | |
| 2598 | 2632 | err = -EILSEQ; |
| 2599 | 2633 | break; |
| 2600 | 2634 | } |
| @@ -2626,24 +2660,23 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev, · 25 unmodified lines | ||
| 2626 | 2660 | |
| 2627 | 2661 | err = request_firmware(&fw, fwname, &hdev->dev); |
| 2628 | 2662 | if (err) { |
| 2629 | − BT_ERR("%s: failed to request rampatch file: %s (%d)", | |
| 2630 | − hdev->name, fwname, err); | |
| 2663 | + bt_dev_err(hdev, "failed to request rampatch file: %s (%d)", | |
| 2664 | + fwname, err); | |
| 2631 | 2665 | return err; |
| 2632 | 2666 | } |
| 2633 | 2667 | |
| 2634 | − BT_INFO("%s: using rampatch file: %s", hdev->name, fwname); | |
| 2668 | + bt_dev_info(hdev, "using rampatch file: %s", fwname); | |
| 2635 | 2669 | |
| 2636 | 2670 | rver = (struct qca_rampatch_version *)(fw->data + info->ver_offset); |
| 2637 | 2671 | rver_rom = le16_to_cpu(rver->rom_version); |
| 2638 | 2672 | rver_patch = le16_to_cpu(rver->patch_version); |
| 2639 | 2673 | |
| 2640 | − BT_INFO("%s: QCA: patch rome 0x%x build 0x%x, firmware rome 0x%x " | |
| 2641 | − "build 0x%x", hdev->name, rver_rom, rver_patch, ver_rom, | |
| 2642 | − ver_patch); | |
| 2674 | + bt_dev_info(hdev, "QCA: patch rome 0x%x build 0x%x, " | |
| 2675 | + "firmware rome 0x%x build 0x%x", | |
| 2676 | + rver_rom, rver_patch, ver_rom, ver_patch); | |
| 2643 | 2677 | |
| 2644 | 2678 | if (rver_rom != ver_rom || rver_patch <= ver_patch) { |
| 2645 | − BT_ERR("%s: rampatch file version did not match with firmware", | |
| 2646 | − hdev->name); | |
| 2679 | + bt_dev_err(hdev, "rampatch file version did not match with firmware"); | |
| 2647 | 2680 | err = -EINVAL; |
| 2648 | 2681 | goto done; |
| 2649 | 2682 | } |
| @@ -2669,12 +2702,12 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev, · 19 unmodified lines | ||
| 2669 | 2702 | |
| 2670 | 2703 | err = request_firmware(&fw, fwname, &hdev->dev); |
| 2671 | 2704 | if (err) { |
| 2672 | − BT_ERR("%s: failed to request NVM file: %s (%d)", | |
| 2673 | − hdev->name, fwname, err); | |
| 2705 | + bt_dev_err(hdev, "failed to request NVM file: %s (%d)", | |
| 2706 | + fwname, err); | |
| 2674 | 2707 | return err; |
| 2675 | 2708 | } |
| 2676 | 2709 | |
| 2677 | − BT_INFO("%s: using NVM file: %s", hdev->name, fwname); | |
| 2710 | + bt_dev_info(hdev, "using NVM file: %s", fwname); | |
| 2678 | 2711 | |
| 2679 | 2712 | err = btusb_setup_qca_download_fw(hdev, fw, info->nvm_hdr); |
| 2680 | 2713 | |
| @@ -2702,8 +2735,7 @@ static int btusb_setup_qca(struct hci_dev *hdev) · 21 unmodified lines | ||
| 2702 | 2735 | info = &qca_devices_table[i]; |
| 2703 | 2736 | } |
| 2704 | 2737 | if (!info) { |
| 2705 | − BT_ERR("%s: don't support firmware rome 0x%x", hdev->name, | |
| 2706 | − ver_rom); | |
| 2738 | + bt_dev_err(hdev, "don't support firmware rome 0x%x", ver_rom); | |
| 2707 | 2739 | return -ENODEV; |
| 2708 | 2740 | } |
| 2709 | 2741 | |
| @@ -2757,7 +2789,7 @@ static inline int __set_diag_interface(struct hci_dev *hdev) · 47 unmodified lines | ||
| 2757 | 2789 | } |
| 2758 | 2790 | |
| 2759 | 2791 | if (!data->diag_tx_ep || !data->diag_rx_ep) { |
| 2760 | − BT_ERR("%s invalid diagnostic descriptors", hdev->name); | |
| 2792 | + bt_dev_err(hdev, "invalid diagnostic descriptors"); | |
| 2761 | 2793 | return -ENODEV; |
| 2762 | 2794 | } |
| 2763 | 2795 | |
| @@ -2909,19 +2941,6 @@ static int btusb_probe(struct usb_interface *intf, · 145 unmodified lines | ||
| 2909 | 2941 | if (id->driver_info == BTUSB_IGNORE) |
| 2910 | 2942 | return -ENODEV; |
| 2911 | 2943 | |
| 2912 | − if (id->driver_info & BTUSB_BCM_NO_PRODID) { | |
| 2913 | − struct usb_device *udev = interface_to_usbdev(intf); | |
| 2914 | − | |
| 2915 | − /* For the broken Broadcom devices that show 0000:0000 | |
| 2916 | − * as USB vendor and product information, check that the | |
| 2917 | − * manufacturer string identifies them as Broadcom based | |
| 2918 | − * devices. | |
| 2919 | − */ | |
| 2920 | − if (!udev->manufacturer || | |
| 2921 | − strcmp(udev->manufacturer, "Broadcom Corp")) | |
| 2922 | − return -ENODEV; | |
| 2923 | − } | |
| 2924 | − | |
| 2925 | 2944 | if (id->driver_info & BTUSB_ATH3012) { |
| 2926 | 2945 | struct usb_device *udev = interface_to_usbdev(intf); |
| 2927 | 2946 | |
| @@ -3124,6 +3143,7 @@ static int btusb_probe(struct usb_interface *intf, · 196 unmodified lines | ||
| 3124 | 3143 | } else { |
| 3125 | 3144 | /* Interface orders are hardcoded in the specification */ |
| 3126 | 3145 | data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1); |
| 3146 | + data->isoc_ifnum = ifnum_base + 1; | |
| 3127 | 3147 | } |
| 3128 | 3148 | |
| 3129 | 3149 | if (!reset) |
| @@ -50,6 +50,17 @@ struct ath_struct { · 49 unmodified lines | ||
| 50 | 50 | struct work_struct ctxtsw; |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | +#define OP_WRITE_TAG 0x01 | |
| 54 | + | |
| 55 | +#define INDEX_BDADDR 0x01 | |
| 56 | + | |
| 57 | +struct ath_vendor_cmd { | |
| 58 | + __u8 opcode; | |
| 59 | + __le16 index; | |
| 60 | + __u8 len; | |
| 61 | + __u8 data[251]; | |
| 62 | +} __packed; | |
| 63 | + | |
| 53 | 64 | static int ath_wakeup_ar3k(struct tty_struct *tty) |
| 54 | 65 | { |
| 55 | 66 | int status = tty->driver->ops->tiocmget(tty); |
| @@ -144,30 +155,34 @@ static int ath_flush(struct hci_uart *hu) · 88 unmodified lines | ||
| 144 | 155 | return 0; |
| 145 | 156 | } |
| 146 | 157 | |
| 147 | −static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |
| 158 | +static int ath_vendor_cmd(struct hci_dev *hdev, uint8_t opcode, uint16_t index, | |
| 159 | + const void *data, size_t dlen) | |
| 148 | 160 | { |
| 149 | 161 | struct sk_buff *skb; |
| 150 | − u8 buf[10]; | |
| 151 | − int err; | |
| 152 | − | |
| 153 | − buf[0] = 0x01; | |
| 154 | − buf[1] = 0x01; | |
| 155 | − buf[2] = 0x00; | |
| 156 | − buf[3] = sizeof(bdaddr_t); | |
| 157 | − memcpy(buf + 4, bdaddr, sizeof(bdaddr_t)); | |
| 158 | − | |
| 159 | − skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); | |
| 160 | − if (IS_ERR(skb)) { | |
| 161 | − err = PTR_ERR(skb); | |
| 162 | − BT_ERR("%s: Change address command failed (%d)", | |
| 163 | − hdev->name, err); | |
| 164 | − return err; | |
| 165 | − } | |
| 162 | + struct ath_vendor_cmd cmd; | |
| 163 | + | |
| 164 | + if (dlen > sizeof(cmd.data)) | |
| 165 | + return -EINVAL; | |
| 166 | + | |
| 167 | + cmd.opcode = opcode; | |
| 168 | + cmd.index = cpu_to_le16(index); | |
| 169 | + cmd.len = dlen; | |
| 170 | + memcpy(cmd.data, data, dlen); | |
| 171 | + | |
| 172 | + skb = __hci_cmd_sync(hdev, 0xfc0b, dlen + 4, &cmd, HCI_INIT_TIMEOUT); | |
| 173 | + if (IS_ERR(skb)) | |
| 174 | + return PTR_ERR(skb); | |
| 166 | 175 | kfree_skb(skb); |
| 167 | 176 | |
| 168 | 177 | return 0; |
| 169 | 178 | } |
| 170 | 179 | |
| 180 | +static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |
| 181 | +{ | |
| 182 | + return ath_vendor_cmd(hdev, OP_WRITE_TAG, INDEX_BDADDR, bdaddr, | |
| 183 | + sizeof(*bdaddr)); | |
| 184 | +} | |
| 185 | + | |
| 171 | 186 | static int ath_setup(struct hci_uart *hu) |
| 172 | 187 | { |
| 173 | 188 | BT_DBG("hu %p", hu); |
| @@ -191,7 +206,7 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count) · 17 unmodified lines | ||
| 191 | 206 | ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts)); |
| 192 | 207 | if (IS_ERR(ath->rx_skb)) { |
| 193 | 208 | int err = PTR_ERR(ath->rx_skb); |
| 194 | − BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | |
| 209 | + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); | |
| 195 | 210 | ath->rx_skb = NULL; |
| 196 | 211 | return err; |
| 197 | 212 | } |
| @@ -52,11 +52,13 @@ · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | #define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */ |
| 54 | 54 | |
| 55 | −/* platform device driver resources */ | |
| 55 | +/* device driver resources */ | |
| 56 | 56 | struct bcm_device { |
| 57 | + /* Must be the first member, hci_serdev.c expects this. */ | |
| 58 | + struct hci_uart serdev_hu; | |
| 57 | 59 | struct list_head list; |
| 58 | 60 | |
| 59 | − struct platform_device *pdev; | |
| 61 | + struct device *dev; | |
| 60 | 62 | |
| 61 | 63 | const char *name; |
| 62 | 64 | struct gpio_desc *device_wakeup; |
| @@ -68,7 +70,7 @@ struct bcm_device { · 5 unmodified lines | ||
| 68 | 70 | u32 init_speed; |
| 69 | 71 | u32 oper_speed; |
| 70 | 72 | int irq; |
| 71 | − u8 irq_polarity; | |
| 73 | + bool irq_active_low; | |
| 72 | 74 | |
| 73 | 75 | #ifdef CONFIG_PM |
| 74 | 76 | struct hci_uart *hu; |
| @@ -76,11 +78,6 @@ struct bcm_device { · 1 unmodified line | ||
| 76 | 78 | #endif |
| 77 | 79 | }; |
| 78 | 80 | |
| 79 | −/* serdev driver resources */ | |
| 80 | −struct bcm_serdev { | |
| 81 | − struct hci_uart hu; | |
| 82 | −}; | |
| 83 | − | |
| 84 | 81 | /* generic bcm uart resources */ |
| 85 | 82 | struct bcm_data { |
| 86 | 83 | struct sk_buff *rx_skb; |
| @@ -155,6 +152,12 @@ static bool bcm_device_exists(struct bcm_device *device) · 68 unmodified lines | ||
| 155 | 152 | { |
| 156 | 153 | struct list_head *p; |
| 157 | 154 | |
| 155 | +#ifdef CONFIG_PM | |
| 156 | + /* Devices using serdev always exist */ | |
| 157 | + if (device && device->hu && device->hu->serdev) | |
| 158 | + return true; | |
| 159 | +#endif | |
| 160 | + | |
| 158 | 161 | list_for_each(p, &bcm_device_list) { |
| 159 | 162 | struct bcm_device *dev = list_entry(p, struct bcm_device, list); |
| 160 | 163 | |
| @@ -188,9 +191,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data) · 27 unmodified lines | ||
| 188 | 191 | |
| 189 | 192 | bt_dev_dbg(bdev, "Host wake IRQ"); |
| 190 | 193 | |
| 191 | − pm_runtime_get(&bdev->pdev->dev); | |
| 192 | − pm_runtime_mark_last_busy(&bdev->pdev->dev); | |
| 193 | − pm_runtime_put_autosuspend(&bdev->pdev->dev); | |
| 194 | + pm_runtime_get(bdev->dev); | |
| 195 | + pm_runtime_mark_last_busy(bdev->dev); | |
| 196 | + pm_runtime_put_autosuspend(bdev->dev); | |
| 194 | 197 | |
| 195 | 198 | return IRQ_HANDLED; |
| 196 | 199 | } |
| @@ -200,7 +203,6 @@ static int bcm_request_irq(struct bcm_data *bcm) · 3 unmodified lines | ||
| 200 | 203 | struct bcm_device *bdev = bcm->dev; |
| 201 | 204 | int err; |
| 202 | 205 | |
| 203 | − /* If this is not a platform device, do not enable PM functionalities */ | |
| 204 | 206 | mutex_lock(&bcm_device_lock); |
| 205 | 207 | if (!bcm_device_exists(bdev)) { |
| 206 | 208 | err = -ENODEV; |
| @@ -212,18 +214,20 @@ static int bcm_request_irq(struct bcm_data *bcm) · 5 unmodified lines | ||
| 212 | 214 | goto unlock; |
| 213 | 215 | } |
| 214 | 216 | |
| 215 | − err = devm_request_irq(&bdev->pdev->dev, bdev->irq, bcm_host_wake, | |
| 216 | − IRQF_TRIGGER_RISING, "host_wake", bdev); | |
| 217 | + err = devm_request_irq(bdev->dev, bdev->irq, bcm_host_wake, | |
| 218 | + bdev->irq_active_low ? IRQF_TRIGGER_FALLING : | |
| 219 | + IRQF_TRIGGER_RISING, | |
| 220 | + "host_wake", bdev); | |
| 217 | 221 | if (err) |
| 218 | 222 | goto unlock; |
| 219 | 223 | |
| 220 | − device_init_wakeup(&bdev->pdev->dev, true); | |
| 224 | + device_init_wakeup(bdev->dev, true); | |
| 221 | 225 | |
| 222 | − pm_runtime_set_autosuspend_delay(&bdev->pdev->dev, | |
| 226 | + pm_runtime_set_autosuspend_delay(bdev->dev, | |
| 223 | 227 | BCM_AUTOSUSPEND_DELAY); |
| 224 | − pm_runtime_use_autosuspend(&bdev->pdev->dev); | |
| 225 | − pm_runtime_set_active(&bdev->pdev->dev); | |
| 226 | − pm_runtime_enable(&bdev->pdev->dev); | |
| 228 | + pm_runtime_use_autosuspend(bdev->dev); | |
| 229 | + pm_runtime_set_active(bdev->dev); | |
| 230 | + pm_runtime_enable(bdev->dev); | |
| 227 | 231 | |
| 228 | 232 | unlock: |
| 229 | 233 | mutex_unlock(&bcm_device_lock); |
| @@ -253,7 +257,7 @@ static int bcm_setup_sleep(struct hci_uart *hu) · 23 unmodified lines | ||
| 253 | 257 | struct sk_buff *skb; |
| 254 | 258 | struct bcm_set_sleep_mode sleep_params = default_sleep_params; |
| 255 | 259 | |
| 256 | − sleep_params.host_wake_active = !bcm->dev->irq_polarity; | |
| 260 | + sleep_params.host_wake_active = !bcm->dev->irq_active_low; | |
| 257 | 261 | |
| 258 | 262 | skb = __hci_cmd_sync(hu->hdev, 0xfc27, sizeof(sleep_params), |
| 259 | 263 | &sleep_params, HCI_INIT_TIMEOUT); |
| @@ -311,18 +315,17 @@ static int bcm_open(struct hci_uart *hu) · 51 unmodified lines | ||
| 311 | 315 | |
| 312 | 316 | hu->priv = bcm; |
| 313 | 317 | |
| 314 | − /* If this is a serdev defined device, then only use | |
| 315 | − * serdev open primitive and skip the rest. | |
| 316 | − */ | |
| 318 | + mutex_lock(&bcm_device_lock); | |
| 319 | + | |
| 317 | 320 | if (hu->serdev) { |
| 318 | 321 | serdev_device_open(hu->serdev); |
| 322 | + bcm->dev = serdev_device_get_drvdata(hu->serdev); | |
| 319 | 323 | goto out; |
| 320 | 324 | } |
| 321 | 325 | |
| 322 | 326 | if (!hu->tty->dev) |
| 323 | 327 | goto out; |
| 324 | 328 | |
| 325 | − mutex_lock(&bcm_device_lock); | |
| 326 | 329 | list_for_each(p, &bcm_device_list) { |
| 327 | 330 | struct bcm_device *dev = list_entry(p, struct bcm_device, list); |
| 328 | 331 | |
| @@ -330,50 +333,56 @@ static int bcm_open(struct hci_uart *hu) · 1 unmodified line | ||
| 330 | 333 | * platform device (saved during device probe) and |
| 331 | 334 | * parent of tty device used by hci_uart |
| 332 | 335 | */ |
| 333 | − if (hu->tty->dev->parent == dev->pdev->dev.parent) { | |
| 336 | + if (hu->tty->dev->parent == dev->dev->parent) { | |
| 334 | 337 | bcm->dev = dev; |
| 335 | − hu->init_speed = dev->init_speed; | |
| 336 | − hu->oper_speed = dev->oper_speed; | |
| 337 | 338 | #ifdef CONFIG_PM |
| 338 | 339 | dev->hu = hu; |
| 339 | 340 | #endif |
| 340 | − bcm_gpio_set_power(bcm->dev, true); | |
| 341 | 341 | break; |
| 342 | 342 | } |
| 343 | 343 | } |
| 344 | 344 | |
| 345 | − mutex_unlock(&bcm_device_lock); | |
| 346 | 345 | out: |
| 346 | + if (bcm->dev) { | |
| 347 | + hu->init_speed = bcm->dev->init_speed; | |
| 348 | + hu->oper_speed = bcm->dev->oper_speed; | |
| 349 | + bcm_gpio_set_power(bcm->dev, true); | |
| 350 | + } | |
| 351 | + | |
| 352 | + mutex_unlock(&bcm_device_lock); | |
| 347 | 353 | return 0; |
| 348 | 354 | } |
| 349 | 355 | |
| 350 | 356 | static int bcm_close(struct hci_uart *hu) |
| 351 | 357 | { |
| 352 | 358 | struct bcm_data *bcm = hu->priv; |
| 353 | − struct bcm_device *bdev = bcm->dev; | |
| 359 | + struct bcm_device *bdev = NULL; | |
| 354 | 360 | |
| 355 | 361 | bt_dev_dbg(hu->hdev, "hu %p", hu); |
| 356 | 362 | |
| 357 | − /* If this is a serdev defined device, only use serdev | |
| 358 | − * close primitive and then continue as usual. | |
| 359 | − */ | |
| 360 | − if (hu->serdev) | |
| 361 | − serdev_device_close(hu->serdev); | |
| 362 | − | |
| 363 | 363 | /* Protect bcm->dev against removal of the device or driver */ |
| 364 | 364 | mutex_lock(&bcm_device_lock); |
| 365 | − if (bcm_device_exists(bdev)) { | |
| 365 | + | |
| 366 | + if (hu->serdev) { | |
| 367 | + serdev_device_close(hu->serdev); | |
| 368 | + bdev = serdev_device_get_drvdata(hu->serdev); | |
| 369 | + } else if (bcm_device_exists(bcm->dev)) { | |
| 370 | + bdev = bcm->dev; | |
| 371 | +#ifdef CONFIG_PM | |
| 372 | + bdev->hu = NULL; | |
| 373 | +#endif | |
| 374 | + } | |
| 375 | + | |
| 376 | + if (bdev) { | |
| 366 | 377 | bcm_gpio_set_power(bdev, false); |
| 367 | 378 | #ifdef CONFIG_PM |
| 368 | − pm_runtime_disable(&bdev->pdev->dev); | |
| 369 | − pm_runtime_set_suspended(&bdev->pdev->dev); | |
| 379 | + pm_runtime_disable(bdev->dev); | |
| 380 | + pm_runtime_set_suspended(bdev->dev); | |
| 370 | 381 | |
| 371 | − if (device_can_wakeup(&bdev->pdev->dev)) { | |
| 372 | − devm_free_irq(&bdev->pdev->dev, bdev->irq, bdev); | |
| 373 | − device_init_wakeup(&bdev->pdev->dev, false); | |
| 382 | + if (device_can_wakeup(bdev->dev)) { | |
| 383 | + devm_free_irq(bdev->dev, bdev->irq, bdev); | |
| 384 | + device_init_wakeup(bdev->dev, false); | |
| 374 | 385 | } |
| 375 | − | |
| 376 | − bdev->hu = NULL; | |
| 377 | 386 | #endif |
| 378 | 387 | } |
| 379 | 388 | mutex_unlock(&bcm_device_lock); |
| @@ -504,9 +513,9 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) · 124 unmodified lines | ||
| 504 | 513 | /* Delay auto-suspend when receiving completed packet */ |
| 505 | 514 | mutex_lock(&bcm_device_lock); |
| 506 | 515 | if (bcm->dev && bcm_device_exists(bcm->dev)) { |
| 507 | − pm_runtime_get(&bcm->dev->pdev->dev); | |
| 508 | − pm_runtime_mark_last_busy(&bcm->dev->pdev->dev); | |
| 509 | − pm_runtime_put_autosuspend(&bcm->dev->pdev->dev); | |
| 516 | + pm_runtime_get(bcm->dev->dev); | |
| 517 | + pm_runtime_mark_last_busy(bcm->dev->dev); | |
| 518 | + pm_runtime_put_autosuspend(bcm->dev->dev); | |
| 510 | 519 | } |
| 511 | 520 | mutex_unlock(&bcm_device_lock); |
| 512 | 521 | } |
| @@ -537,15 +546,15 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu) · 24 unmodified lines | ||
| 537 | 546 | |
| 538 | 547 | if (bcm_device_exists(bcm->dev)) { |
| 539 | 548 | bdev = bcm->dev; |
| 540 | − pm_runtime_get_sync(&bdev->pdev->dev); | |
| 549 | + pm_runtime_get_sync(bdev->dev); | |
| 541 | 550 | /* Shall be resumed here */ |
| 542 | 551 | } |
| 543 | 552 | |
| 544 | 553 | skb = skb_dequeue(&bcm->txq); |
| 545 | 554 | |
| 546 | 555 | if (bdev) { |
| 547 | − pm_runtime_mark_last_busy(&bdev->pdev->dev); | |
| 548 | − pm_runtime_put_autosuspend(&bdev->pdev->dev); | |
| 556 | + pm_runtime_mark_last_busy(bdev->dev); | |
| 557 | + pm_runtime_put_autosuspend(bdev->dev); | |
| 549 | 558 | } |
| 550 | 559 | |
| 551 | 560 | mutex_unlock(&bcm_device_lock); |
| @@ -556,7 +565,7 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu) · 4 unmodified lines | ||
| 556 | 565 | #ifdef CONFIG_PM |
| 557 | 566 | static int bcm_suspend_device(struct device *dev) |
| 558 | 567 | { |
| 559 | − struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev)); | |
| 568 | + struct bcm_device *bdev = dev_get_drvdata(dev); | |
| 560 | 569 | |
| 561 | 570 | bt_dev_dbg(bdev, ""); |
| 562 | 571 | |
| @@ -579,7 +588,7 @@ static int bcm_suspend_device(struct device *dev) · 16 unmodified lines | ||
| 579 | 588 | |
| 580 | 589 | static int bcm_resume_device(struct device *dev) |
| 581 | 590 | { |
| 582 | − struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev)); | |
| 591 | + struct bcm_device *bdev = dev_get_drvdata(dev); | |
| 583 | 592 | |
| 584 | 593 | bt_dev_dbg(bdev, ""); |
| 585 | 594 | |
| @@ -601,16 +610,18 @@ static int bcm_resume_device(struct device *dev) · 15 unmodified lines | ||
| 601 | 610 | #endif |
| 602 | 611 | |
| 603 | 612 | #ifdef CONFIG_PM_SLEEP |
| 604 | −/* Platform suspend callback */ | |
| 613 | +/* suspend callback */ | |
| 605 | 614 | static int bcm_suspend(struct device *dev) |
| 606 | 615 | { |
| 607 | − struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev)); | |
| 616 | + struct bcm_device *bdev = dev_get_drvdata(dev); | |
| 608 | 617 | int error; |
| 609 | 618 | |
| 610 | 619 | bt_dev_dbg(bdev, "suspend: is_suspended %d", bdev->is_suspended); |
| 611 | 620 | |
| 612 | − /* bcm_suspend can be called at any time as long as platform device is | |
| 613 | − * bound, so it should use bcm_device_lock to protect access to hci_uart | |
| 621 | + /* | |
| 622 | + * When used with a device instantiated as platform_device, bcm_suspend | |
| 623 | + * can be called at any time as long as the platform device is bound, | |
| 624 | + * so it should use bcm_device_lock to protect access to hci_uart | |
| 614 | 625 | * and device_wake-up GPIO. |
| 615 | 626 | */ |
| 616 | 627 | mutex_lock(&bcm_device_lock); |
| @@ -621,7 +632,7 @@ static int bcm_suspend(struct device *dev) · 4 unmodified lines | ||
| 621 | 632 | if (pm_runtime_active(dev)) |
| 622 | 633 | bcm_suspend_device(dev); |
| 623 | 634 | |
| 624 | − if (device_may_wakeup(&bdev->pdev->dev)) { | |
| 635 | + if (device_may_wakeup(dev)) { | |
| 625 | 636 | error = enable_irq_wake(bdev->irq); |
| 626 | 637 | if (!error) |
| 627 | 638 | bt_dev_dbg(bdev, "BCM irq: enabled"); |
| @@ -633,15 +644,17 @@ unlock: · 5 unmodified lines | ||
| 633 | 644 | return 0; |
| 634 | 645 | } |
| 635 | 646 | |
| 636 | −/* Platform resume callback */ | |
| 647 | +/* resume callback */ | |
| 637 | 648 | static int bcm_resume(struct device *dev) |
| 638 | 649 | { |
| 639 | − struct bcm_device *bdev = platform_get_drvdata(to_platform_device(dev)); | |
| 650 | + struct bcm_device *bdev = dev_get_drvdata(dev); | |
| 640 | 651 | |
| 641 | 652 | bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended); |
| 642 | 653 | |
| 643 | − /* bcm_resume can be called at any time as long as platform device is | |
| 644 | − * bound, so it should use bcm_device_lock to protect access to hci_uart | |
| 654 | + /* | |
| 655 | + * When used with a device instantiated as platform_device, bcm_resume | |
| 656 | + * can be called at any time as long as platform device is bound, | |
| 657 | + * so it should use bcm_device_lock to protect access to hci_uart | |
| 645 | 658 | * and device_wake-up GPIO. |
| 646 | 659 | */ |
| 647 | 660 | mutex_lock(&bcm_device_lock); |
| @@ -649,7 +662,7 @@ static int bcm_resume(struct device *dev) · 1 unmodified line | ||
| 649 | 662 | if (!bdev->hu) |
| 650 | 663 | goto unlock; |
| 651 | 664 | |
| 652 | − if (device_may_wakeup(&bdev->pdev->dev)) { | |
| 665 | + if (device_may_wakeup(dev)) { | |
| 653 | 666 | disable_irq_wake(bdev->irq); |
| 654 | 667 | bt_dev_dbg(bdev, "BCM irq: disabled"); |
| 655 | 668 | } |
| @@ -690,10 +703,8 @@ static const struct acpi_gpio_mapping acpi_bcm_int_first_gpios[] = { · 34 unmodified lines | ||
| 690 | 703 | }; |
| 691 | 704 | |
| 692 | 705 | #ifdef CONFIG_ACPI |
| 693 | −static u8 acpi_active_low = ACPI_ACTIVE_LOW; | |
| 694 | − | |
| 695 | 706 | /* IRQ polarity of some chipsets are not defined correctly in ACPI table. */ |
| 696 | −static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = { | |
| 707 | +static const struct dmi_system_id bcm_active_low_irq_dmi_table[] = { | |
| 697 | 708 | { |
| 698 | 709 | .ident = "Asus T100TA", |
| 699 | 710 | .matches = { |
| @@ -701,7 +712,6 @@ static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = { · 1 unmodified line | ||
| 701 | 712 | "ASUSTeK COMPUTER INC."), |
| 702 | 713 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), |
| 703 | 714 | }, |
| 704 | − .driver_data = &acpi_active_low, | |
| 705 | 715 | }, |
| 706 | 716 | { |
| 707 | 717 | .ident = "Asus T100CHI", |
| @@ -710,7 +720,6 @@ static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = { · 2 unmodified lines | ||
| 710 | 720 | "ASUSTeK COMPUTER INC."), |
| 711 | 721 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100CHI"), |
| 712 | 722 | }, |
| 713 | − .driver_data = &acpi_active_low, | |
| 714 | 723 | }, |
| 715 | 724 | { /* Handle ThinkPad 8 tablets with BCM2E55 chipset ACPI ID */ |
| 716 | 725 | .ident = "Lenovo ThinkPad 8", |
| @@ -718,7 +727,13 @@ static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = { · 1 unmodified line | ||
| 718 | 727 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 719 | 728 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 8"), |
| 720 | 729 | }, |
| 721 | − .driver_data = &acpi_active_low, | |
| 730 | + }, | |
| 731 | + { | |
| 732 | + .ident = "MINIX Z83-4", | |
| 733 | + .matches = { | |
| 734 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), | |
| 735 | + DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | |
| 736 | + }, | |
| 722 | 737 | }, |
| 723 | 738 | { } |
| 724 | 739 | }; |
| @@ -733,13 +748,13 @@ static int bcm_resource(struct acpi_resource *ares, void *data) · 8 unmodified lines | ||
| 733 | 748 | switch (ares->type) { |
| 734 | 749 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| 735 | 750 | irq = &ares->data.extended_irq; |
| 736 | − dev->irq_polarity = irq->polarity; | |
| 751 | + dev->irq_active_low = irq->polarity == ACPI_ACTIVE_LOW; | |
| 737 | 752 | break; |
| 738 | 753 | |
| 739 | 754 | case ACPI_RESOURCE_TYPE_GPIO: |
| 740 | 755 | gpio = &ares->data.gpio; |
| 741 | 756 | if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) |
| 742 | − dev->irq_polarity = gpio->polarity; | |
| 757 | + dev->irq_active_low = gpio->polarity == ACPI_ACTIVE_LOW; | |
| 743 | 758 | break; |
| 744 | 759 | |
| 745 | 760 | case ACPI_RESOURCE_TYPE_SERIAL_BUS: |
| @@ -754,36 +769,32 @@ static int bcm_resource(struct acpi_resource *ares, void *data) · 8 unmodified lines | ||
| 754 | 769 | break; |
| 755 | 770 | } |
| 756 | 771 | |
| 757 | − /* Always tell the ACPI core to skip this resource */ | |
| 758 | − return 1; | |
| 772 | + return 0; | |
| 759 | 773 | } |
| 760 | 774 | #endif /* CONFIG_ACPI */ |
| 761 | 775 | |
| 762 | −static int bcm_platform_probe(struct bcm_device *dev) | |
| 776 | +static int bcm_get_resources(struct bcm_device *dev) | |
| 763 | 777 | { |
| 764 | − struct platform_device *pdev = dev->pdev; | |
| 765 | − | |
| 766 | − dev->name = dev_name(&pdev->dev); | |
| 778 | + dev->name = dev_name(dev->dev); | |
| 767 | 779 | |
| 768 | − dev->clk = devm_clk_get(&pdev->dev, NULL); | |
| 780 | + dev->clk = devm_clk_get(dev->dev, NULL); | |
| 769 | 781 | |
| 770 | − dev->device_wakeup = devm_gpiod_get_optional(&pdev->dev, | |
| 782 | + dev->device_wakeup = devm_gpiod_get_optional(dev->dev, | |
| 771 | 783 | "device-wakeup", |
| 772 | 784 | GPIOD_OUT_LOW); |
| 773 | 785 | if (IS_ERR(dev->device_wakeup)) |
| 774 | 786 | return PTR_ERR(dev->device_wakeup); |
| 775 | 787 | |
| 776 | − dev->shutdown = devm_gpiod_get_optional(&pdev->dev, "shutdown", | |
| 788 | + dev->shutdown = devm_gpiod_get_optional(dev->dev, "shutdown", | |
| 777 | 789 | GPIOD_OUT_LOW); |
| 778 | 790 | if (IS_ERR(dev->shutdown)) |
| 779 | 791 | return PTR_ERR(dev->shutdown); |
| 780 | 792 | |
| 781 | 793 | /* IRQ can be declared in ACPI table as Interrupt or GpioInt */ |
| 782 | − dev->irq = platform_get_irq(pdev, 0); | |
| 783 | 794 | if (dev->irq <= 0) { |
| 784 | 795 | struct gpio_desc *gpio; |
| 785 | 796 | |
| 786 | − gpio = devm_gpiod_get_optional(&pdev->dev, "host-wakeup", | |
| 797 | + gpio = devm_gpiod_get_optional(dev->dev, "host-wakeup", | |
| 787 | 798 | GPIOD_IN); |
| 788 | 799 | if (IS_ERR(gpio)) |
| 789 | 800 | return PTR_ERR(gpio); |
| @@ -791,54 +802,48 @@ static int bcm_platform_probe(struct bcm_device *dev) · 1 unmodified line | ||
| 791 | 802 | dev->irq = gpiod_to_irq(gpio); |
| 792 | 803 | } |
| 793 | 804 | |
| 794 | − dev_info(&pdev->dev, "BCM irq: %d\n", dev->irq); | |
| 795 | − | |
| 796 | − /* Make sure at-least one of the GPIO is defined and that | |
| 797 | − * a name is specified for this instance | |
| 798 | − */ | |
| 799 | − if ((!dev->device_wakeup && !dev->shutdown) || !dev->name) { | |
| 800 | − dev_err(&pdev->dev, "invalid platform data\n"); | |
| 801 | − return -EINVAL; | |
| 802 | − } | |
| 803 | − | |
| 805 | + dev_info(dev->dev, "BCM irq: %d\n", dev->irq); | |
| 804 | 806 | return 0; |
| 805 | 807 | } |
| 806 | 808 | |
| 807 | 809 | #ifdef CONFIG_ACPI |
| 808 | 810 | static int bcm_acpi_probe(struct bcm_device *dev) |
| 809 | 811 | { |
| 810 | − struct platform_device *pdev = dev->pdev; | |
| 811 | 812 | LIST_HEAD(resources); |
| 812 | 813 | const struct dmi_system_id *dmi_id; |
| 813 | 814 | const struct acpi_gpio_mapping *gpio_mapping = acpi_bcm_int_last_gpios; |
| 814 | 815 | const struct acpi_device_id *id; |
| 816 | + struct resource_entry *entry; | |
| 815 | 817 | int ret; |
| 816 | 818 | |
| 817 | 819 | /* Retrieve GPIO data */ |
| 818 | − id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); | |
| 820 | + id = acpi_match_device(dev->dev->driver->acpi_match_table, dev->dev); | |
| 819 | 821 | if (id) |
| 820 | 822 | gpio_mapping = (const struct acpi_gpio_mapping *) id->driver_data; |
| 821 | 823 | |
| 822 | − ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, gpio_mapping); | |
| 823 | − if (ret) | |
| 824 | − return ret; | |
| 825 | − | |
| 826 | − ret = bcm_platform_probe(dev); | |
| 824 | + ret = devm_acpi_dev_add_driver_gpios(dev->dev, gpio_mapping); | |
| 827 | 825 | if (ret) |
| 828 | 826 | return ret; |
| 829 | 827 | |
| 830 | 828 | /* Retrieve UART ACPI info */ |
| 831 | − ret = acpi_dev_get_resources(ACPI_COMPANION(&dev->pdev->dev), | |
| 829 | + ret = acpi_dev_get_resources(ACPI_COMPANION(dev->dev), | |
| 832 | 830 | &resources, bcm_resource, dev); |
| 833 | 831 | if (ret < 0) |
| 834 | 832 | return ret; |
| 833 | + | |
| 834 | + resource_list_for_each_entry(entry, &resources) { | |
| 835 | + if (resource_type(entry->res) == IORESOURCE_IRQ) { | |
| 836 | + dev->irq = entry->res->start; | |
| 837 | + break; | |
| 838 | + } | |
| 839 | + } | |
| 835 | 840 | acpi_dev_free_resource_list(&resources); |
| 836 | 841 | |
| 837 | − dmi_id = dmi_first_match(bcm_wrong_irq_dmi_table); | |
| 842 | + dmi_id = dmi_first_match(bcm_active_low_irq_dmi_table); | |
| 838 | 843 | if (dmi_id) { |
| 839 | − bt_dev_warn(dev, "%s: Overwriting IRQ polarity to active low", | |
| 844 | + dev_warn(dev->dev, "%s: Overwriting IRQ polarity to active low", | |
| 840 | 845 | dmi_id->ident); |
| 841 | − dev->irq_polarity = *(u8 *)dmi_id->driver_data; | |
| 846 | + dev->irq_active_low = true; | |
| 842 | 847 | } |
| 843 | 848 | |
| 844 | 849 | return 0; |
| @@ -850,6 +855,12 @@ static int bcm_acpi_probe(struct bcm_device *dev) · 5 unmodified lines | ||
| 850 | 855 | } |
| 851 | 856 | #endif /* CONFIG_ACPI */ |
| 852 | 857 | |
| 858 | +static int bcm_of_probe(struct bcm_device *bdev) | |
| 859 | +{ | |
| 860 | + device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed); | |
| 861 | + return 0; | |
| 862 | +} | |
| 863 | + | |
| 853 | 864 | static int bcm_probe(struct platform_device *pdev) |
| 854 | 865 | { |
| 855 | 866 | struct bcm_device *dev; |
| @@ -859,12 +870,16 @@ static int bcm_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 859 | 870 | if (!dev) |
| 860 | 871 | return -ENOMEM; |
| 861 | 872 | |
| 862 | − dev->pdev = pdev; | |
| 873 | + dev->dev = &pdev->dev; | |
| 874 | + dev->irq = platform_get_irq(pdev, 0); | |
| 863 | 875 | |
| 864 | − if (has_acpi_companion(&pdev->dev)) | |
| 876 | + if (has_acpi_companion(&pdev->dev)) { | |
| 865 | 877 | ret = bcm_acpi_probe(dev); |
| 866 | − else | |
| 867 | − ret = bcm_platform_probe(dev); | |
| 878 | + if (ret) | |
| 879 | + return ret; | |
| 880 | + } | |
| 881 | + | |
| 882 | + ret = bcm_get_resources(dev); | |
| 868 | 883 | if (ret) |
| 869 | 884 | return ret; |
| 870 | 885 | |
| @@ -926,14 +941,16 @@ static const struct acpi_device_id bcm_acpi_match[] = { · 55 unmodified lines | ||
| 926 | 941 | { "BCM2E71", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, |
| 927 | 942 | { "BCM2E7B", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, |
| 928 | 943 | { "BCM2E7C", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, |
| 944 | + { "BCM2E7E", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, | |
| 929 | 945 | { "BCM2E95", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, |
| 930 | 946 | { "BCM2E96", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, |
| 947 | + { "BCM2EA4", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, | |
| 931 | 948 | { }, |
| 932 | 949 | }; |
| 933 | 950 | MODULE_DEVICE_TABLE(acpi, bcm_acpi_match); |
| 934 | 951 | #endif |
| 935 | 952 | |
| 936 | −/* Platform suspend and resume callbacks */ | |
| 953 | +/* suspend and resume callbacks */ | |
| 937 | 954 | static const struct dev_pm_ops bcm_pm_ops = { |
| 938 | 955 | SET_SYSTEM_SLEEP_PM_OPS(bcm_suspend, bcm_resume) |
| 939 | 956 | SET_RUNTIME_PM_OPS(bcm_suspend_device, bcm_resume_device, NULL) |
| @@ -951,29 +968,41 @@ static struct platform_driver bcm_driver = { · 11 unmodified lines | ||
| 951 | 968 | |
| 952 | 969 | static int bcm_serdev_probe(struct serdev_device *serdev) |
| 953 | 970 | { |
| 954 | − struct bcm_serdev *bcmdev; | |
| 955 | − u32 speed; | |
| 971 | + struct bcm_device *bcmdev; | |
| 956 | 972 | int err; |
| 957 | 973 | |
| 958 | 974 | bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL); |
| 959 | 975 | if (!bcmdev) |
| 960 | 976 | return -ENOMEM; |
| 961 | 977 | |
| 962 | − bcmdev->hu.serdev = serdev; | |
| 978 | + bcmdev->dev = &serdev->dev; | |
| 979 | +#ifdef CONFIG_PM | |
| 980 | + bcmdev->hu = &bcmdev->serdev_hu; | |
| 981 | +#endif | |
| 982 | + bcmdev->serdev_hu.serdev = serdev; | |
| 963 | 983 | serdev_device_set_drvdata(serdev, bcmdev); |
| 964 | 984 | |
| 965 | − err = device_property_read_u32(&serdev->dev, "max-speed", &speed); | |
| 966 | − if (!err) | |
| 967 | − bcmdev->hu.oper_speed = speed; | |
| 985 | + if (has_acpi_companion(&serdev->dev)) | |
| 986 | + err = bcm_acpi_probe(bcmdev); | |
| 987 | + else | |
| 988 | + err = bcm_of_probe(bcmdev); | |
| 989 | + if (err) | |
| 990 | + return err; | |
| 991 | + | |
| 992 | + err = bcm_get_resources(bcmdev); | |
| 993 | + if (err) | |
| 994 | + return err; | |
| 995 | + | |
| 996 | + bcm_gpio_set_power(bcmdev, false); | |
| 968 | 997 | |
| 969 | − return hci_uart_register_device(&bcmdev->hu, &bcm_proto); | |
| 998 | + return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); | |
| 970 | 999 | } |
| 971 | 1000 | |
| 972 | 1001 | static void bcm_serdev_remove(struct serdev_device *serdev) |
| 973 | 1002 | { |
| 974 | − struct bcm_serdev *bcmdev = serdev_device_get_drvdata(serdev); | |
| 1003 | + struct bcm_device *bcmdev = serdev_device_get_drvdata(serdev); | |
| 975 | 1004 | |
| 976 | − hci_uart_unregister_device(&bcmdev->hu); | |
| 1005 | + hci_uart_unregister_device(&bcmdev->serdev_hu); | |
| 977 | 1006 | } |
| 978 | 1007 | |
| 979 | 1008 | #ifdef CONFIG_OF |
| @@ -990,6 +1019,8 @@ static struct serdev_device_driver bcm_serdev_driver = { · 10 unmodified lines | ||
| 990 | 1019 | .driver = { |
| 991 | 1020 | .name = "hci_uart_bcm", |
| 992 | 1021 | .of_match_table = of_match_ptr(bcm_bluetooth_of_match), |
| 1022 | + .acpi_match_table = ACPI_PTR(bcm_acpi_match), | |
| 1023 | + .pm = &bcm_pm_ops, | |
| 993 | 1024 | }, |
| 994 | 1025 | }; |
| 995 | 1026 | |
| @@ -65,6 +65,7 @@ struct bcsp_struct { · 64 unmodified lines | ||
| 65 | 65 | u8 rxseq_txack; /* rxseq == txack. */ |
| 66 | 66 | u8 rxack; /* Last packet sent by us that the peer ack'ed */ |
| 67 | 67 | struct timer_list tbcsp; |
| 68 | + struct hci_uart *hu; | |
| 68 | 69 | |
| 69 | 70 | enum { |
| 70 | 71 | BCSP_W4_PKT_DELIMITER, |
| @@ -697,10 +698,10 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) · 626 unmodified lines | ||
| 697 | 698 | } |
| 698 | 699 | |
| 699 | 700 | /* Arrange to retransmit all messages in the relq. */ |
| 700 | −static void bcsp_timed_event(unsigned long arg) | |
| 701 | +static void bcsp_timed_event(struct timer_list *t) | |
| 701 | 702 | { |
| 702 | − struct hci_uart *hu = (struct hci_uart *)arg; | |
| 703 | − struct bcsp_struct *bcsp = hu->priv; | |
| 703 | + struct bcsp_struct *bcsp = from_timer(bcsp, t, tbcsp); | |
| 704 | + struct hci_uart *hu = bcsp->hu; | |
| 704 | 705 | struct sk_buff *skb; |
| 705 | 706 | unsigned long flags; |
| 706 | 707 | |
| @@ -729,11 +730,12 @@ static int bcsp_open(struct hci_uart *hu) · 22 unmodified lines | ||
| 729 | 730 | return -ENOMEM; |
| 730 | 731 | |
| 731 | 732 | hu->priv = bcsp; |
| 733 | + bcsp->hu = hu; | |
| 732 | 734 | skb_queue_head_init(&bcsp->unack); |
| 733 | 735 | skb_queue_head_init(&bcsp->rel); |
| 734 | 736 | skb_queue_head_init(&bcsp->unrel); |
| 735 | 737 | |
| 736 | − setup_timer(&bcsp->tbcsp, bcsp_timed_event, (u_long)hu); | |
| 738 | + timer_setup(&bcsp->tbcsp, bcsp_timed_event, 0); | |
| 737 | 739 | |
| 738 | 740 | bcsp->rx_state = BCSP_W4_PKT_DELIMITER; |
| 739 | 741 | |
| @@ -132,7 +132,7 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count) · 131 unmodified lines | ||
| 132 | 132 | h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts)); |
| 133 | 133 | if (IS_ERR(h4->rx_skb)) { |
| 134 | 134 | int err = PTR_ERR(h4->rx_skb); |
| 135 | − BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | |
| 135 | + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); | |
| 136 | 136 | h4->rx_skb = NULL; |
| 137 | 137 | return err; |
| 138 | 138 | } |
| @@ -78,6 +78,7 @@ struct h5 { · 77 unmodified lines | ||
| 78 | 78 | int (*rx_func)(struct hci_uart *hu, u8 c); |
| 79 | 79 | |
| 80 | 80 | struct timer_list timer; /* Retransmission timer */ |
| 81 | + struct hci_uart *hu; /* Parent HCI UART */ | |
| 81 | 82 | |
| 82 | 83 | u8 tx_seq; /* Next seq number to send */ |
| 83 | 84 | u8 tx_ack; /* Next ack number to send */ |
| @@ -120,12 +121,12 @@ static u8 h5_cfg_field(struct h5 *h5) · 36 unmodified lines | ||
| 120 | 121 | return h5->tx_win & 0x07; |
| 121 | 122 | } |
| 122 | 123 | |
| 123 | −static void h5_timed_event(unsigned long arg) | |
| 124 | +static void h5_timed_event(struct timer_list *t) | |
| 124 | 125 | { |
| 125 | 126 | const unsigned char sync_req[] = { 0x01, 0x7e }; |
| 126 | 127 | unsigned char conf_req[3] = { 0x03, 0xfc }; |
| 127 | − struct hci_uart *hu = (struct hci_uart *)arg; | |
| 128 | − struct h5 *h5 = hu->priv; | |
| 128 | + struct h5 *h5 = from_timer(h5, t, timer); | |
| 129 | + struct hci_uart *hu = h5->hu; | |
| 129 | 130 | struct sk_buff *skb; |
| 130 | 131 | unsigned long flags; |
| 131 | 132 | |
| @@ -197,6 +198,7 @@ static int h5_open(struct hci_uart *hu) · 65 unmodified lines | ||
| 197 | 198 | return -ENOMEM; |
| 198 | 199 | |
| 199 | 200 | hu->priv = h5; |
| 201 | + h5->hu = hu; | |
| 200 | 202 | |
| 201 | 203 | skb_queue_head_init(&h5->unack); |
| 202 | 204 | skb_queue_head_init(&h5->rel); |
| @@ -204,7 +206,7 @@ static int h5_open(struct hci_uart *hu) · 1 unmodified line | ||
| 204 | 206 | |
| 205 | 207 | h5_reset_rx(h5); |
| 206 | 208 | |
| 207 | − setup_timer(&h5->timer, h5_timed_event, (unsigned long)hu); | |
| 209 | + timer_setup(&h5->timer, h5_timed_event, 0); | |
| 208 | 210 | |
| 209 | 211 | h5->tx_win = H5_TX_WIN_MAX; |
| 210 | 212 | |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <linux/ioctl.h> |
| 42 | 42 | #include <linux/skbuff.h> |
| 43 | 43 | #include <linux/firmware.h> |
| 44 | +#include <linux/serdev.h> | |
| 44 | 45 | |
| 45 | 46 | #include <net/bluetooth/bluetooth.h> |
| 46 | 47 | #include <net/bluetooth/hci_core.h> |
| @@ -114,12 +115,12 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) · 67 unmodified lines | ||
| 114 | 115 | struct sk_buff *skb = hu->tx_skb; |
| 115 | 116 | |
| 116 | 117 | if (!skb) { |
| 117 | − read_lock(&hu->proto_lock); | |
| 118 | + percpu_down_read(&hu->proto_lock); | |
| 118 | 119 | |
| 119 | 120 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
| 120 | 121 | skb = hu->proto->dequeue(hu); |
| 121 | 122 | |
| 122 | − read_unlock(&hu->proto_lock); | |
| 123 | + percpu_up_read(&hu->proto_lock); | |
| 123 | 124 | } else { |
| 124 | 125 | hu->tx_skb = NULL; |
| 125 | 126 | } |
| @@ -129,7 +130,14 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu) · 3 unmodified lines | ||
| 129 | 130 | |
| 130 | 131 | int hci_uart_tx_wakeup(struct hci_uart *hu) |
| 131 | 132 | { |
| 132 | − read_lock(&hu->proto_lock); | |
| 133 | + /* This may be called in an IRQ context, so we can't sleep. Therefore | |
| 134 | + * we try to acquire the lock only, and if that fails we assume the | |
| 135 | + * tty is being closed because that is the only time the write lock is | |
| 136 | + * acquired. If, however, at some point in the future the write lock | |
| 137 | + * is also acquired in other situations, then this must be revisited. | |
| 138 | + */ | |
| 139 | + if (!percpu_down_read_trylock(&hu->proto_lock)) | |
| 140 | + return 0; | |
| 133 | 141 | |
| 134 | 142 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
| 135 | 143 | goto no_schedule; |
| @@ -144,7 +152,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) · 8 unmodified lines | ||
| 144 | 152 | schedule_work(&hu->write_work); |
| 145 | 153 | |
| 146 | 154 | no_schedule: |
| 147 | − read_unlock(&hu->proto_lock); | |
| 155 | + percpu_up_read(&hu->proto_lock); | |
| 148 | 156 | |
| 149 | 157 | return 0; |
| 150 | 158 | } |
| @@ -246,12 +254,12 @@ static int hci_uart_flush(struct hci_dev *hdev) · 95 unmodified lines | ||
| 246 | 254 | tty_ldisc_flush(tty); |
| 247 | 255 | tty_driver_flush_buffer(tty); |
| 248 | 256 | |
| 249 | − read_lock(&hu->proto_lock); | |
| 257 | + percpu_down_read(&hu->proto_lock); | |
| 250 | 258 | |
| 251 | 259 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) |
| 252 | 260 | hu->proto->flush(hu); |
| 253 | 261 | |
| 254 | − read_unlock(&hu->proto_lock); | |
| 262 | + percpu_up_read(&hu->proto_lock); | |
| 255 | 263 | |
| 256 | 264 | return 0; |
| 257 | 265 | } |
| @@ -274,15 +282,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) · 16 unmodified lines | ||
| 274 | 282 | BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb), |
| 275 | 283 | skb->len); |
| 276 | 284 | |
| 277 | − read_lock(&hu->proto_lock); | |
| 285 | + percpu_down_read(&hu->proto_lock); | |
| 278 | 286 | |
| 279 | 287 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { |
| 280 | − read_unlock(&hu->proto_lock); | |
| 288 | + percpu_up_read(&hu->proto_lock); | |
| 281 | 289 | return -EUNATCH; |
| 282 | 290 | } |
| 283 | 291 | |
| 284 | 292 | hu->proto->enqueue(hu, skb); |
| 285 | − read_unlock(&hu->proto_lock); | |
| 293 | + percpu_up_read(&hu->proto_lock); | |
| 286 | 294 | |
| 287 | 295 | hci_uart_tx_wakeup(hu); |
| 288 | 296 | |
| @@ -298,6 +306,12 @@ void hci_uart_set_flow_control(struct hci_uart *hu, bool enable) · 9 unmodified lines | ||
| 298 | 306 | unsigned int set = 0; |
| 299 | 307 | unsigned int clear = 0; |
| 300 | 308 | |
| 309 | + if (hu->serdev) { | |
| 310 | + serdev_device_set_flow_control(hu->serdev, !enable); | |
| 311 | + serdev_device_set_rts(hu->serdev, !enable); | |
| 312 | + return; | |
| 313 | + } | |
| 314 | + | |
| 301 | 315 | if (enable) { |
| 302 | 316 | /* Disable hardware flow control */ |
| 303 | 317 | ktermios = tty->termios; |
| @@ -479,7 +493,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) · 175 unmodified lines | ||
| 479 | 493 | INIT_WORK(&hu->init_ready, hci_uart_init_work); |
| 480 | 494 | INIT_WORK(&hu->write_work, hci_uart_write_work); |
| 481 | 495 | |
| 482 | − rwlock_init(&hu->proto_lock); | |
| 496 | + percpu_init_rwsem(&hu->proto_lock); | |
| 483 | 497 | |
| 484 | 498 | /* Flush any pending characters in the driver */ |
| 485 | 499 | tty_driver_flush_buffer(tty); |
| @@ -496,7 +510,6 @@ static void hci_uart_tty_close(struct tty_struct *tty) · 10 unmodified lines | ||
| 496 | 510 | { |
| 497 | 511 | struct hci_uart *hu = tty->disc_data; |
| 498 | 512 | struct hci_dev *hdev; |
| 499 | − unsigned long flags; | |
| 500 | 513 | |
| 501 | 514 | BT_DBG("tty %p", tty); |
| 502 | 515 | |
| @@ -510,12 +523,12 @@ static void hci_uart_tty_close(struct tty_struct *tty) · 7 unmodified lines | ||
| 510 | 523 | if (hdev) |
| 511 | 524 | hci_uart_close(hdev); |
| 512 | 525 | |
| 513 | − cancel_work_sync(&hu->write_work); | |
| 514 | − | |
| 515 | 526 | if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) { |
| 516 | − write_lock_irqsave(&hu->proto_lock, flags); | |
| 527 | + percpu_down_write(&hu->proto_lock); | |
| 517 | 528 | clear_bit(HCI_UART_PROTO_READY, &hu->flags); |
| 518 | − write_unlock_irqrestore(&hu->proto_lock, flags); | |
| 529 | + percpu_up_write(&hu->proto_lock); | |
| 530 | + | |
| 531 | + cancel_work_sync(&hu->write_work); | |
| 519 | 532 | |
| 520 | 533 | if (hdev) { |
| 521 | 534 | if (test_bit(HCI_UART_REGISTERED, &hu->flags)) |
| @@ -575,10 +588,10 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, · 53 unmodified lines | ||
| 575 | 588 | if (!hu || tty != hu->tty) |
| 576 | 589 | return; |
| 577 | 590 | |
| 578 | − read_lock(&hu->proto_lock); | |
| 591 | + percpu_down_read(&hu->proto_lock); | |
| 579 | 592 | |
| 580 | 593 | if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { |
| 581 | − read_unlock(&hu->proto_lock); | |
| 594 | + percpu_up_read(&hu->proto_lock); | |
| 582 | 595 | return; |
| 583 | 596 | } |
| 584 | 597 | |
| @@ -586,7 +599,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, · 1 unmodified line | ||
| 586 | 599 | * tty caller |
| 587 | 600 | */ |
| 588 | 601 | hu->proto->recv(hu, data, count); |
| 589 | − read_unlock(&hu->proto_lock); | |
| 602 | + percpu_up_read(&hu->proto_lock); | |
| 590 | 603 | |
| 591 | 604 | if (hu->hdev) |
| 592 | 605 | hu->hdev->stat.byte_rx += count; |
| @@ -242,7 +242,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) · 241 unmodified lines | ||
| 242 | 242 | * perfectly safe to always send one. |
| 243 | 243 | */ |
| 244 | 244 | BT_DBG("dual wake-up-indication"); |
| 245 | − /* deliberate fall-through - do not add break */ | |
| 245 | + /* fall through */ | |
| 246 | 246 | case HCILL_ASLEEP: |
| 247 | 247 | /* acknowledge device wake up */ |
| 248 | 248 | if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) { |
| @@ -307,10 +307,10 @@ static void qca_wq_serial_tx_clock_vote_off(struct work_struct *work) · 306 unmodified lines | ||
| 307 | 307 | serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu); |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | −static void hci_ibs_tx_idle_timeout(unsigned long arg) | |
| 310 | +static void hci_ibs_tx_idle_timeout(struct timer_list *t) | |
| 311 | 311 | { |
| 312 | − struct hci_uart *hu = (struct hci_uart *)arg; | |
| 313 | − struct qca_data *qca = hu->priv; | |
| 312 | + struct qca_data *qca = from_timer(qca, t, tx_idle_timer); | |
| 313 | + struct hci_uart *hu = qca->hu; | |
| 314 | 314 | unsigned long flags; |
| 315 | 315 | |
| 316 | 316 | BT_DBG("hu %p idle timeout in %d state", hu, qca->tx_ibs_state); |
| @@ -342,10 +342,10 @@ static void hci_ibs_tx_idle_timeout(unsigned long arg) · 25 unmodified lines | ||
| 342 | 342 | spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); |
| 343 | 343 | } |
| 344 | 344 | |
| 345 | −static void hci_ibs_wake_retrans_timeout(unsigned long arg) | |
| 345 | +static void hci_ibs_wake_retrans_timeout(struct timer_list *t) | |
| 346 | 346 | { |
| 347 | − struct hci_uart *hu = (struct hci_uart *)arg; | |
| 348 | − struct qca_data *qca = hu->priv; | |
| 347 | + struct qca_data *qca = from_timer(qca, t, wake_retrans_timer); | |
| 348 | + struct hci_uart *hu = qca->hu; | |
| 349 | 349 | unsigned long flags, retrans_delay; |
| 350 | 350 | bool retransmit = false; |
| 351 | 351 | |
| @@ -438,11 +438,10 @@ static int qca_open(struct hci_uart *hu) · 86 unmodified lines | ||
| 438 | 438 | |
| 439 | 439 | hu->priv = qca; |
| 440 | 440 | |
| 441 | − setup_timer(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, | |
| 442 | − (u_long)hu); | |
| 441 | + timer_setup(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, 0); | |
| 443 | 442 | qca->wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS; |
| 444 | 443 | |
| 445 | − setup_timer(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, (u_long)hu); | |
| 444 | + timer_setup(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, 0); | |
| 446 | 445 | qca->tx_idle_delay = IBS_TX_IDLE_TIMEOUT_MS; |
| 447 | 446 | |
| 448 | 447 | BT_DBG("HCI_UART_QCA open, tx_idle_delay=%u, wake_retrans=%u", |
| @@ -801,7 +800,7 @@ static int qca_recv(struct hci_uart *hu, const void *data, int count) · 352 unmodified lines | ||
| 801 | 800 | qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts)); |
| 802 | 801 | if (IS_ERR(qca->rx_skb)) { |
| 803 | 802 | int err = PTR_ERR(qca->rx_skb); |
| 804 | − BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); | |
| 803 | + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); | |
| 805 | 804 | qca->rx_skb = NULL; |
| 806 | 805 | return err; |
| 807 | 806 | } |
| @@ -864,7 +863,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) · 56 unmodified lines | ||
| 864 | 863 | |
| 865 | 864 | skb = bt_skb_alloc(sizeof(cmd), GFP_ATOMIC); |
| 866 | 865 | if (!skb) { |
| 867 | − BT_ERR("Failed to allocate memory for baudrate packet"); | |
| 866 | + bt_dev_err(hdev, "Failed to allocate baudrate packet"); | |
| 868 | 867 | return -ENOMEM; |
| 869 | 868 | } |
| 870 | 869 | |
| @@ -893,7 +892,7 @@ static int qca_setup(struct hci_uart *hu) · 22 unmodified lines | ||
| 893 | 892 | unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; |
| 894 | 893 | int ret; |
| 895 | 894 | |
| 896 | − BT_INFO("%s: ROME setup", hdev->name); | |
| 895 | + bt_dev_info(hdev, "ROME setup"); | |
| 897 | 896 | |
| 898 | 897 | /* Patch downloading has to be done without IBS mode */ |
| 899 | 898 | clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); |
| @@ -918,11 +917,11 @@ static int qca_setup(struct hci_uart *hu) · 18 unmodified lines | ||
| 918 | 917 | if (speed) { |
| 919 | 918 | qca_baudrate = qca_get_baudrate_value(speed); |
| 920 | 919 | |
| 921 | − BT_INFO("%s: Set UART speed to %d", hdev->name, speed); | |
| 920 | + bt_dev_info(hdev, "Set UART speed to %d", speed); | |
| 922 | 921 | ret = qca_set_baudrate(hdev, qca_baudrate); |
| 923 | 922 | if (ret) { |
| 924 | − BT_ERR("%s: Failed to change the baud rate (%d)", | |
| 925 | − hdev->name, ret); | |
| 923 | + bt_dev_err(hdev, "Failed to change the baud rate (%d)", | |
| 924 | + ret); | |
| 926 | 925 | return ret; |
| 927 | 926 | } |
| 928 | 927 | hci_uart_set_baudrate(hu, speed); |
| @@ -185,7 +185,7 @@ static int hci_uart_setup(struct hci_dev *hdev) · 184 unmodified lines | ||
| 185 | 185 | if (hu->proto->set_baudrate && speed) { |
| 186 | 186 | err = hu->proto->set_baudrate(hu, speed); |
| 187 | 187 | if (err) |
| 188 | − BT_ERR("%s: failed to set baudrate", hdev->name); | |
| 188 | + bt_dev_err(hdev, "Failed to set baudrate"); | |
| 189 | 189 | else |
| 190 | 190 | serdev_device_set_baudrate(hu->serdev, speed); |
| 191 | 191 | } |
| @@ -199,14 +199,13 @@ static int hci_uart_setup(struct hci_dev *hdev) · 7 unmodified lines | ||
| 199 | 199 | skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, |
| 200 | 200 | HCI_INIT_TIMEOUT); |
| 201 | 201 | if (IS_ERR(skb)) { |
| 202 | − BT_ERR("%s: Reading local version information failed (%ld)", | |
| 203 | − hdev->name, PTR_ERR(skb)); | |
| 202 | + bt_dev_err(hdev, "Reading local version info failed (%ld)", | |
| 203 | + PTR_ERR(skb)); | |
| 204 | 204 | return 0; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | if (skb->len != sizeof(*ver)) { |
| 208 | − BT_ERR("%s: Event length mismatch for version information", | |
| 209 | − hdev->name); | |
| 208 | + bt_dev_err(hdev, "Event length mismatch for version info"); | |
| 210 | 209 | } |
| 211 | 210 | |
| 212 | 211 | kfree_skb(skb); |
| @@ -87,7 +87,7 @@ struct hci_uart { · 86 unmodified lines | ||
| 87 | 87 | struct work_struct write_work; |
| 88 | 88 | |
| 89 | 89 | const struct hci_uart_proto *proto; |
| 90 | − rwlock_t proto_lock; /* Stop work for proto close */ | |
| 90 | + struct percpu_rw_semaphore proto_lock; /* Stop work for proto close */ | |
| 91 | 91 | void *priv; |
| 92 | 92 | |
| 93 | 93 | struct sk_buff *tx_skb; |
| @@ -45,7 +45,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, · 44 unmodified lines | ||
| 45 | 45 | return NULL; |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | − atomic_set(&cbq->refcnt, 1); | |
| 48 | + refcount_set(&cbq->refcnt, 1); | |
| 49 | 49 | |
| 50 | 50 | atomic_inc(&dev->refcnt); |
| 51 | 51 | cbq->pdev = dev; |
| @@ -58,7 +58,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, · 6 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | void cn_queue_release_callback(struct cn_callback_entry *cbq) |
| 60 | 60 | { |
| 61 | − if (!atomic_dec_and_test(&cbq->refcnt)) | |
| 61 | + if (!refcount_dec_and_test(&cbq->refcnt)) | |
| 62 | 62 | return; |
| 63 | 63 | |
| 64 | 64 | atomic_dec(&cbq->pdev->refcnt); |
| @@ -157,7 +157,7 @@ static int cn_call_callback(struct sk_buff *skb) · 156 unmodified lines | ||
| 157 | 157 | spin_lock_bh(&dev->cbdev->queue_lock); |
| 158 | 158 | list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) { |
| 159 | 159 | if (cn_cb_equal(&i->id.id, &msg->id)) { |
| 160 | − atomic_inc(&i->refcnt); | |
| 160 | + refcount_inc(&i->refcnt); | |
| 161 | 161 | cbq = i; |
| 162 | 162 | break; |
| 163 | 163 | } |
| @@ -2,6 +2,7 @@ config INFINIBAND_QEDR · 1 unmodified line | ||
| 2 | 2 | tristate "QLogic RoCE driver" |
| 3 | 3 | depends on 64BIT && QEDE |
| 4 | 4 | select QED_LL2 |
| 5 | + select QED_OOO | |
| 5 | 6 | select QED_RDMA |
| 6 | 7 | ---help--- |
| 7 | 8 | This driver provides low-level InfiniBand over Ethernet |
| @@ -893,13 +893,17 @@ dev_stop: · 892 unmodified lines | ||
| 893 | 893 | void ipoib_pkey_dev_check_presence(struct net_device *dev) |
| 894 | 894 | { |
| 895 | 895 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
| 896 | + struct rdma_netdev *rn = netdev_priv(dev); | |
| 896 | 897 | |
| 897 | 898 | if (!(priv->pkey & 0x7fff) || |
| 898 | 899 | ib_find_pkey(priv->ca, priv->port, priv->pkey, |
| 899 | − &priv->pkey_index)) | |
| 900 | + &priv->pkey_index)) { | |
| 900 | 901 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
| 901 | − else | |
| 902 | + } else { | |
| 903 | + if (rn->set_id) | |
| 904 | + rn->set_id(dev, priv->pkey_index); | |
| 902 | 905 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
| 906 | + } | |
| 903 | 907 | } |
| 904 | 908 | |
| 905 | 909 | void ipoib_ib_dev_up(struct net_device *dev) |
| @@ -1203,10 +1207,15 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, · 297 unmodified lines | ||
| 1203 | 1207 | ipoib_ib_dev_down(dev); |
| 1204 | 1208 | |
| 1205 | 1209 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1210 | + rtnl_lock(); | |
| 1206 | 1211 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1207 | 1212 | ipoib_ib_dev_stop(dev); |
| 1208 | − if (ipoib_ib_dev_open(dev) != 0) | |
| 1213 | + | |
| 1214 | + result = ipoib_ib_dev_open(dev); | |
| 1215 | + rtnl_unlock(); | |
| 1216 | + if (result) | |
| 1209 | 1217 | return; |
| 1218 | + | |
| 1210 | 1219 | if (netif_queue_stopped(dev)) |
| 1211 | 1220 | netif_start_queue(dev); |
| 1212 | 1221 | } |
| @@ -89,6 +89,7 @@ static int start_cbsend(struct cardstate *); · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | struct bas_cardstate { |
| 91 | 91 | struct usb_device *udev; /* USB device pointer */ |
| 92 | + struct cardstate *cs; | |
| 92 | 93 | struct usb_interface *interface; /* interface for this device */ |
| 93 | 94 | unsigned char minor; /* starting minor number */ |
| 94 | 95 | |
| @@ -433,10 +434,10 @@ static void check_pending(struct bas_cardstate *ucs) · 338 unmodified lines | ||
| 433 | 434 | * argument: |
| 434 | 435 | * controller state structure |
| 435 | 436 | */ |
| 436 | −static void cmd_in_timeout(unsigned long data) | |
| 437 | +static void cmd_in_timeout(struct timer_list *t) | |
| 437 | 438 | { |
| 438 | − struct cardstate *cs = (struct cardstate *) data; | |
| 439 | − struct bas_cardstate *ucs = cs->hw.bas; | |
| 439 | + struct bas_cardstate *ucs = from_timer(ucs, t, timer_cmd_in); | |
| 440 | + struct cardstate *cs = ucs->cs; | |
| 440 | 441 | int rc; |
| 441 | 442 | |
| 442 | 443 | if (!ucs->rcvbuf_size) { |
| @@ -639,10 +640,10 @@ static void int_in_work(struct work_struct *work) · 196 unmodified lines | ||
| 639 | 640 | * argument: |
| 640 | 641 | * controller state structure |
| 641 | 642 | */ |
| 642 | −static void int_in_resubmit(unsigned long data) | |
| 643 | +static void int_in_resubmit(struct timer_list *t) | |
| 643 | 644 | { |
| 644 | − struct cardstate *cs = (struct cardstate *) data; | |
| 645 | − struct bas_cardstate *ucs = cs->hw.bas; | |
| 645 | + struct bas_cardstate *ucs = from_timer(ucs, t, timer_int_in); | |
| 646 | + struct cardstate *cs = ucs->cs; | |
| 646 | 647 | int rc; |
| 647 | 648 | |
| 648 | 649 | if (ucs->retry_int_in++ >= BAS_RETRY) { |
| @@ -1441,10 +1442,10 @@ error: · 792 unmodified lines | ||
| 1441 | 1442 | * argument: |
| 1442 | 1443 | * controller state structure |
| 1443 | 1444 | */ |
| 1444 | −static void req_timeout(unsigned long data) | |
| 1445 | +static void req_timeout(struct timer_list *t) | |
| 1445 | 1446 | { |
| 1446 | − struct cardstate *cs = (struct cardstate *) data; | |
| 1447 | − struct bas_cardstate *ucs = cs->hw.bas; | |
| 1447 | + struct bas_cardstate *ucs = from_timer(ucs, t, timer_ctrl); | |
| 1448 | + struct cardstate *cs = ucs->cs; | |
| 1448 | 1449 | int pending; |
| 1449 | 1450 | unsigned long flags; |
| 1450 | 1451 | |
| @@ -1837,10 +1838,10 @@ static void write_command_callback(struct urb *urb) · 386 unmodified lines | ||
| 1837 | 1838 | * argument: |
| 1838 | 1839 | * controller state structure |
| 1839 | 1840 | */ |
| 1840 | −static void atrdy_timeout(unsigned long data) | |
| 1841 | +static void atrdy_timeout(struct timer_list *t) | |
| 1841 | 1842 | { |
| 1842 | − struct cardstate *cs = (struct cardstate *) data; | |
| 1843 | − struct bas_cardstate *ucs = cs->hw.bas; | |
| 1843 | + struct bas_cardstate *ucs = from_timer(ucs, t, timer_atrdy); | |
| 1844 | + struct cardstate *cs = ucs->cs; | |
| 1844 | 1845 | |
| 1845 | 1846 | dev_warn(cs->dev, "timeout waiting for HD_READY_SEND_ATDATA\n"); |
| 1846 | 1847 | |
| @@ -2200,7 +2201,7 @@ static int gigaset_initcshw(struct cardstate *cs) · 353 unmodified lines | ||
| 2200 | 2201 | { |
| 2201 | 2202 | struct bas_cardstate *ucs; |
| 2202 | 2203 | |
| 2203 | − cs->hw.bas = ucs = kmalloc(sizeof *ucs, GFP_KERNEL); | |
| 2204 | + cs->hw.bas = ucs = kzalloc(sizeof(*ucs), GFP_KERNEL); | |
| 2204 | 2205 | if (!ucs) { |
| 2205 | 2206 | pr_err("out of memory\n"); |
| 2206 | 2207 | return -ENOMEM; |
| @@ -2212,19 +2213,12 @@ static int gigaset_initcshw(struct cardstate *cs) · 5 unmodified lines | ||
| 2212 | 2213 | return -ENOMEM; |
| 2213 | 2214 | } |
| 2214 | 2215 | |
| 2215 | − ucs->urb_cmd_in = NULL; | |
| 2216 | − ucs->urb_cmd_out = NULL; | |
| 2217 | − ucs->rcvbuf = NULL; | |
| 2218 | − ucs->rcvbuf_size = 0; | |
| 2219 | − | |
| 2220 | 2216 | spin_lock_init(&ucs->lock); |
| 2221 | − ucs->pending = 0; | |
| 2222 | − | |
| 2223 | − ucs->basstate = 0; | |
| 2224 | − setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); | |
| 2225 | − setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); | |
| 2226 | − setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); | |
| 2227 | − setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs); | |
| 2217 | + ucs->cs = cs; | |
| 2218 | + timer_setup(&ucs->timer_ctrl, req_timeout, 0); | |
| 2219 | + timer_setup(&ucs->timer_atrdy, atrdy_timeout, 0); | |
| 2220 | + timer_setup(&ucs->timer_cmd_in, cmd_in_timeout, 0); | |
| 2221 | + timer_setup(&ucs->timer_int_in, int_in_resubmit, 0); | |
| 2228 | 2222 | init_waitqueue_head(&ucs->waitqueue); |
| 2229 | 2223 | INIT_WORK(&ucs->int_in_wq, int_in_work); |
| 2230 | 2224 | |
| @@ -153,9 +153,9 @@ static int test_timeout(struct at_state_t *at_state) · 152 unmodified lines | ||
| 153 | 153 | return 1; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static void timer_tick(unsigned long data) | |
| 156 | +static void timer_tick(struct timer_list *t) | |
| 157 | 157 | { |
| 158 | − struct cardstate *cs = (struct cardstate *) data; | |
| 158 | + struct cardstate *cs = from_timer(cs, t, timer); | |
| 159 | 159 | unsigned long flags; |
| 160 | 160 | unsigned channel; |
| 161 | 161 | struct at_state_t *at_state; |
| @@ -687,7 +687,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, · 525 unmodified lines | ||
| 687 | 687 | cs->ignoreframes = ignoreframes; |
| 688 | 688 | INIT_LIST_HEAD(&cs->temp_at_states); |
| 689 | 689 | cs->running = 0; |
| 690 | − init_timer(&cs->timer); /* clear next & prev */ | |
| 690 | + timer_setup(&cs->timer, timer_tick, 0); | |
| 691 | 691 | spin_lock_init(&cs->ev_lock); |
| 692 | 692 | cs->ev_tail = 0; |
| 693 | 693 | cs->ev_head = 0; |
| @@ -768,7 +768,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, · 74 unmodified lines | ||
| 768 | 768 | spin_lock_irqsave(&cs->lock, flags); |
| 769 | 769 | cs->running = 1; |
| 770 | 770 | spin_unlock_irqrestore(&cs->lock, flags); |
| 771 | − setup_timer(&cs->timer, timer_tick, (unsigned long) cs); | |
| 772 | 771 | cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK); |
| 773 | 772 | add_timer(&cs->timer); |
| 774 | 773 | |
| @@ -4501,6 +4501,7 @@ static void control_rc(PLCI *plci, byte req, byte rc, byte ch, byte global_req, · 4500 unmodified lines | ||
| 4501 | 4501 | plci->channels++; |
| 4502 | 4502 | a->ncci_state[ncci] = OUTG_CON_PENDING; |
| 4503 | 4503 | } |
| 4504 | + /* fall through */ | |
| 4504 | 4505 | |
| 4505 | 4506 | default: |
| 4506 | 4507 | if (plci->internal_command_queue[0]) |
| @@ -7020,6 +7021,7 @@ static void nl_ind(PLCI *plci) · 2513 unmodified lines | ||
| 7020 | 7021 | plci->NL.RNum = 1; |
| 7021 | 7022 | return; |
| 7022 | 7023 | } |
| 7024 | + /* fall through */ | |
| 7023 | 7025 | case N_BDATA: |
| 7024 | 7026 | case N_DATA: |
| 7025 | 7027 | if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */ |
| @@ -9626,9 +9628,9 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 2600 unmodified lines | ||
| 9626 | 9628 | { |
| 9627 | 9629 | |
| 9628 | 9630 | case DTMF_LISTEN_TONE_START: |
| 9629 | − mask <<= 1; | |
| 9631 | + mask <<= 1; /* fall through */ | |
| 9630 | 9632 | case DTMF_LISTEN_MF_START: |
| 9631 | − mask <<= 1; | |
| 9633 | + mask <<= 1; /* fall through */ | |
| 9632 | 9634 | |
| 9633 | 9635 | case DTMF_LISTEN_START: |
| 9634 | 9636 | switch (internal_command) |
| @@ -9636,6 +9638,7 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 1 unmodified line | ||
| 9636 | 9638 | default: |
| 9637 | 9639 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | |
| 9638 | 9640 | B1_FACILITY_DTMFR), DTMF_COMMAND_1); |
| 9641 | + /* fall through */ | |
| 9639 | 9642 | case DTMF_COMMAND_1: |
| 9640 | 9643 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 9641 | 9644 | { |
| @@ -9646,6 +9649,7 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 9646 | 9649 | } |
| 9647 | 9650 | if (plci->internal_command) |
| 9648 | 9651 | return; |
| 9652 | + /* fall through */ | |
| 9649 | 9653 | case DTMF_COMMAND_2: |
| 9650 | 9654 | if (plci_nl_busy(plci)) |
| 9651 | 9655 | { |
| @@ -9673,9 +9677,9 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 21 unmodified lines | ||
| 9673 | 9677 | |
| 9674 | 9678 | |
| 9675 | 9679 | case DTMF_LISTEN_TONE_STOP: |
| 9676 | − mask <<= 1; | |
| 9680 | + mask <<= 1; /* fall through */ | |
| 9677 | 9681 | case DTMF_LISTEN_MF_STOP: |
| 9678 | − mask <<= 1; | |
| 9682 | + mask <<= 1; /* fall through */ | |
| 9679 | 9683 | |
| 9680 | 9684 | case DTMF_LISTEN_STOP: |
| 9681 | 9685 | switch (internal_command) |
| @@ -9710,6 +9714,7 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 28 unmodified lines | ||
| 9710 | 9714 | */ |
| 9711 | 9715 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & |
| 9712 | 9716 | ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3); |
| 9717 | + /* fall through */ | |
| 9713 | 9718 | case DTMF_COMMAND_3: |
| 9714 | 9719 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 9715 | 9720 | { |
| @@ -9726,9 +9731,9 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 10 unmodified lines | ||
| 9726 | 9731 | |
| 9727 | 9732 | |
| 9728 | 9733 | case DTMF_SEND_TONE: |
| 9729 | − mask <<= 1; | |
| 9734 | + mask <<= 1; /* fall through */ | |
| 9730 | 9735 | case DTMF_SEND_MF: |
| 9731 | − mask <<= 1; | |
| 9736 | + mask <<= 1; /* fall through */ | |
| 9732 | 9737 | |
| 9733 | 9738 | case DTMF_DIGITS_SEND: |
| 9734 | 9739 | switch (internal_command) |
| @@ -9737,6 +9742,7 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 2 unmodified lines | ||
| 9737 | 9742 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | |
| 9738 | 9743 | ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)), |
| 9739 | 9744 | DTMF_COMMAND_1); |
| 9745 | + /* fall through */ | |
| 9740 | 9746 | case DTMF_COMMAND_1: |
| 9741 | 9747 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 9742 | 9748 | { |
| @@ -9747,6 +9753,7 @@ static void dtmf_command(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 9747 | 9753 | } |
| 9748 | 9754 | if (plci->internal_command) |
| 9749 | 9755 | return; |
| 9756 | + /* fall through */ | |
| 9750 | 9757 | case DTMF_COMMAND_2: |
| 9751 | 9758 | if (plci_nl_busy(plci)) |
| 9752 | 9759 | { |
| @@ -9863,7 +9870,7 @@ static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci · 110 unmodified lines | ||
| 9863 | 9870 | |
| 9864 | 9871 | case DTMF_LISTEN_TONE_START: |
| 9865 | 9872 | case DTMF_LISTEN_TONE_STOP: |
| 9866 | − mask <<= 1; | |
| 9873 | + mask <<= 1; /* fall through */ | |
| 9867 | 9874 | case DTMF_LISTEN_MF_START: |
| 9868 | 9875 | case DTMF_LISTEN_MF_STOP: |
| 9869 | 9876 | mask <<= 1; |
| @@ -9875,6 +9882,7 @@ static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci · 5 unmodified lines | ||
| 9875 | 9882 | PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); |
| 9876 | 9883 | break; |
| 9877 | 9884 | } |
| 9885 | + /* fall through */ | |
| 9878 | 9886 | |
| 9879 | 9887 | case DTMF_LISTEN_START: |
| 9880 | 9888 | case DTMF_LISTEN_STOP: |
| @@ -9904,7 +9912,7 @@ static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci · 23 unmodified lines | ||
| 9904 | 9912 | |
| 9905 | 9913 | |
| 9906 | 9914 | case DTMF_SEND_TONE: |
| 9907 | − mask <<= 1; | |
| 9915 | + mask <<= 1; /* fall through */ | |
| 9908 | 9916 | case DTMF_SEND_MF: |
| 9909 | 9917 | mask <<= 1; |
| 9910 | 9918 | if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1]) |
| @@ -9915,6 +9923,7 @@ static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci · 4 unmodified lines | ||
| 9915 | 9923 | PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); |
| 9916 | 9924 | break; |
| 9917 | 9925 | } |
| 9926 | + /* fall through */ | |
| 9918 | 9927 | |
| 9919 | 9928 | case DTMF_DIGITS_SEND: |
| 9920 | 9929 | if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) |
| @@ -11315,6 +11324,7 @@ static word mixer_restore_config(dword Id, PLCI *plci, byte Rc) · 1394 unmodified lines | ||
| 11315 | 11324 | } |
| 11316 | 11325 | plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; |
| 11317 | 11326 | Rc = OK; |
| 11327 | + /* fall through */ | |
| 11318 | 11328 | case ADJUST_B_RESTORE_MIXER_2: |
| 11319 | 11329 | case ADJUST_B_RESTORE_MIXER_3: |
| 11320 | 11330 | case ADJUST_B_RESTORE_MIXER_4: |
| @@ -11344,10 +11354,12 @@ static word mixer_restore_config(dword Id, PLCI *plci, byte Rc) · 23 unmodified lines | ||
| 11344 | 11354 | plci->internal_command = plci->adjust_b_command; |
| 11345 | 11355 | break; |
| 11346 | 11356 | } |
| 11357 | + /* fall through */ | |
| 11347 | 11358 | case ADJUST_B_RESTORE_MIXER_5: |
| 11348 | 11359 | xconnect_write_coefs(plci, plci->adjust_b_command); |
| 11349 | 11360 | plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6; |
| 11350 | 11361 | Rc = OK; |
| 11362 | + /* fall through */ | |
| 11351 | 11363 | case ADJUST_B_RESTORE_MIXER_6: |
| 11352 | 11364 | if (!xconnect_write_coefs_process(Id, plci, Rc)) |
| 11353 | 11365 | { |
| @@ -11392,6 +11404,7 @@ static void mixer_command(dword Id, PLCI *plci, byte Rc) · 38 unmodified lines | ||
| 11392 | 11404 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | |
| 11393 | 11405 | B1_FACILITY_MIXER), MIXER_COMMAND_1); |
| 11394 | 11406 | } |
| 11407 | + /* fall through */ | |
| 11395 | 11408 | case MIXER_COMMAND_1: |
| 11396 | 11409 | if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) |
| 11397 | 11410 | { |
| @@ -11419,6 +11432,7 @@ static void mixer_command(dword Id, PLCI *plci, byte Rc) · 21 unmodified lines | ||
| 11419 | 11432 | mixer_indication_coefs_set(Id, plci); |
| 11420 | 11433 | } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); |
| 11421 | 11434 | } |
| 11435 | + /* fall through */ | |
| 11422 | 11436 | case MIXER_COMMAND_2: |
| 11423 | 11437 | if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) |
| 11424 | 11438 | || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER) |
| @@ -11450,6 +11464,7 @@ static void mixer_command(dword Id, PLCI *plci, byte Rc) · 25 unmodified lines | ||
| 11450 | 11464 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & |
| 11451 | 11465 | ~B1_FACILITY_MIXER), MIXER_COMMAND_3); |
| 11452 | 11466 | } |
| 11467 | + /* fall through */ | |
| 11453 | 11468 | case MIXER_COMMAND_3: |
| 11454 | 11469 | if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) |
| 11455 | 11470 | { |
| @@ -12602,6 +12617,7 @@ static void ec_command(dword Id, PLCI *plci, byte Rc) · 1146 unmodified lines | ||
| 12602 | 12617 | default: |
| 12603 | 12618 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | |
| 12604 | 12619 | B1_FACILITY_EC), EC_COMMAND_1); |
| 12620 | + /* fall through */ | |
| 12605 | 12621 | case EC_COMMAND_1: |
| 12606 | 12622 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 12607 | 12623 | { |
| @@ -12612,6 +12628,7 @@ static void ec_command(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 12612 | 12628 | } |
| 12613 | 12629 | if (plci->internal_command) |
| 12614 | 12630 | return; |
| 12631 | + /* fall through */ | |
| 12615 | 12632 | case EC_COMMAND_2: |
| 12616 | 12633 | if (plci->sig_req) |
| 12617 | 12634 | { |
| @@ -12650,6 +12667,7 @@ static void ec_command(dword Id, PLCI *plci, byte Rc) · 32 unmodified lines | ||
| 12650 | 12667 | return; |
| 12651 | 12668 | } |
| 12652 | 12669 | Rc = OK; |
| 12670 | + /* fall through */ | |
| 12653 | 12671 | case EC_COMMAND_2: |
| 12654 | 12672 | if ((Rc != OK) && (Rc != OK_FC)) |
| 12655 | 12673 | { |
| @@ -12660,6 +12678,7 @@ static void ec_command(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 12660 | 12678 | } |
| 12661 | 12679 | adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & |
| 12662 | 12680 | ~B1_FACILITY_EC), EC_COMMAND_3); |
| 12681 | + /* fall through */ | |
| 12663 | 12682 | case EC_COMMAND_3: |
| 12664 | 12683 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 12665 | 12684 | { |
| @@ -13485,6 +13504,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 819 unmodified lines | ||
| 13485 | 13504 | } |
| 13486 | 13505 | plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1; |
| 13487 | 13506 | Rc = OK; |
| 13507 | + /* fall through */ | |
| 13488 | 13508 | case ADJUST_B_SAVE_MIXER_1: |
| 13489 | 13509 | if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) |
| 13490 | 13510 | { |
| @@ -13496,6 +13516,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 5 unmodified lines | ||
| 13496 | 13516 | } |
| 13497 | 13517 | plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1; |
| 13498 | 13518 | Rc = OK; |
| 13519 | + /* fall through */ | |
| 13499 | 13520 | case ADJUST_B_SAVE_DTMF_1: |
| 13500 | 13521 | if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) |
| 13501 | 13522 | { |
| @@ -13506,6 +13527,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 13506 | 13527 | |
| 13507 | 13528 | } |
| 13508 | 13529 | plci->adjust_b_state = ADJUST_B_REMOVE_L23_1; |
| 13530 | + /* fall through */ | |
| 13509 | 13531 | case ADJUST_B_REMOVE_L23_1: |
| 13510 | 13532 | if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) |
| 13511 | 13533 | && plci->NL.Id && !plci->nl_remove_id) |
| @@ -13530,6 +13552,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 18 unmodified lines | ||
| 13530 | 13552 | } |
| 13531 | 13553 | plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; |
| 13532 | 13554 | Rc = OK; |
| 13555 | + /* fall through */ | |
| 13533 | 13556 | case ADJUST_B_REMOVE_L23_2: |
| 13534 | 13557 | if ((Rc != OK) && (Rc != OK_FC)) |
| 13535 | 13558 | { |
| @@ -13548,6 +13571,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 12 unmodified lines | ||
| 13548 | 13571 | } |
| 13549 | 13572 | plci->adjust_b_state = ADJUST_B_SAVE_EC_1; |
| 13550 | 13573 | Rc = OK; |
| 13574 | + /* fall through */ | |
| 13551 | 13575 | case ADJUST_B_SAVE_EC_1: |
| 13552 | 13576 | if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) |
| 13553 | 13577 | { |
| @@ -13559,6 +13583,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 5 unmodified lines | ||
| 13559 | 13583 | } |
| 13560 | 13584 | plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1; |
| 13561 | 13585 | Rc = OK; |
| 13586 | + /* fall through */ | |
| 13562 | 13587 | case ADJUST_B_SAVE_DTMF_PARAMETER_1: |
| 13563 | 13588 | if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) |
| 13564 | 13589 | { |
| @@ -13570,6 +13595,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 5 unmodified lines | ||
| 13570 | 13595 | } |
| 13571 | 13596 | plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1; |
| 13572 | 13597 | Rc = OK; |
| 13598 | + /* fall through */ | |
| 13573 | 13599 | case ADJUST_B_SAVE_VOICE_1: |
| 13574 | 13600 | if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) |
| 13575 | 13601 | { |
| @@ -13578,6 +13604,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 2 unmodified lines | ||
| 13578 | 13604 | break; |
| 13579 | 13605 | } |
| 13580 | 13606 | plci->adjust_b_state = ADJUST_B_SWITCH_L1_1; |
| 13607 | + /* fall through */ | |
| 13581 | 13608 | case ADJUST_B_SWITCH_L1_1: |
| 13582 | 13609 | if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) |
| 13583 | 13610 | { |
| @@ -13608,6 +13635,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 24 unmodified lines | ||
| 13608 | 13635 | } |
| 13609 | 13636 | plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; |
| 13610 | 13637 | Rc = OK; |
| 13638 | + /* fall through */ | |
| 13611 | 13639 | case ADJUST_B_SWITCH_L1_2: |
| 13612 | 13640 | if ((Rc != OK) && (Rc != OK_FC)) |
| 13613 | 13641 | { |
| @@ -13619,6 +13647,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 5 unmodified lines | ||
| 13619 | 13647 | } |
| 13620 | 13648 | plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; |
| 13621 | 13649 | Rc = OK; |
| 13650 | + /* fall through */ | |
| 13622 | 13651 | case ADJUST_B_RESTORE_VOICE_1: |
| 13623 | 13652 | case ADJUST_B_RESTORE_VOICE_2: |
| 13624 | 13653 | if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) |
| @@ -13629,6 +13658,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 13629 | 13658 | } |
| 13630 | 13659 | plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; |
| 13631 | 13660 | Rc = OK; |
| 13661 | + /* fall through */ | |
| 13632 | 13662 | case ADJUST_B_RESTORE_DTMF_PARAMETER_1: |
| 13633 | 13663 | case ADJUST_B_RESTORE_DTMF_PARAMETER_2: |
| 13634 | 13664 | if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) |
| @@ -13641,6 +13671,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 6 unmodified lines | ||
| 13641 | 13671 | } |
| 13642 | 13672 | plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; |
| 13643 | 13673 | Rc = OK; |
| 13674 | + /* fall through */ | |
| 13644 | 13675 | case ADJUST_B_RESTORE_EC_1: |
| 13645 | 13676 | case ADJUST_B_RESTORE_EC_2: |
| 13646 | 13677 | if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) |
| @@ -13652,6 +13683,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 5 unmodified lines | ||
| 13652 | 13683 | |
| 13653 | 13684 | } |
| 13654 | 13685 | plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1; |
| 13686 | + /* fall through */ | |
| 13655 | 13687 | case ADJUST_B_ASSIGN_L23_1: |
| 13656 | 13688 | if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) |
| 13657 | 13689 | { |
| @@ -13681,6 +13713,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 23 unmodified lines | ||
| 13681 | 13713 | } |
| 13682 | 13714 | plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; |
| 13683 | 13715 | Rc = ASSIGN_OK; |
| 13716 | + /* fall through */ | |
| 13684 | 13717 | case ADJUST_B_ASSIGN_L23_2: |
| 13685 | 13718 | if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK)) |
| 13686 | 13719 | { |
| @@ -13703,6 +13736,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 16 unmodified lines | ||
| 13703 | 13736 | break; |
| 13704 | 13737 | } |
| 13705 | 13738 | plci->adjust_b_state = ADJUST_B_CONNECT_1; |
| 13739 | + /* fall through */ | |
| 13706 | 13740 | case ADJUST_B_CONNECT_1: |
| 13707 | 13741 | if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) |
| 13708 | 13742 | { |
| @@ -13716,6 +13750,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 7 unmodified lines | ||
| 13716 | 13750 | } |
| 13717 | 13751 | plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; |
| 13718 | 13752 | Rc = OK; |
| 13753 | + /* fall through */ | |
| 13719 | 13754 | case ADJUST_B_CONNECT_2: |
| 13720 | 13755 | case ADJUST_B_CONNECT_3: |
| 13721 | 13756 | case ADJUST_B_CONNECT_4: |
| @@ -13751,6 +13786,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 29 unmodified lines | ||
| 13751 | 13786 | break; |
| 13752 | 13787 | } |
| 13753 | 13788 | Rc = OK; |
| 13789 | + /* fall through */ | |
| 13754 | 13790 | case ADJUST_B_RESTORE_DTMF_1: |
| 13755 | 13791 | case ADJUST_B_RESTORE_DTMF_2: |
| 13756 | 13792 | if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) |
| @@ -13763,6 +13799,7 @@ static word adjust_b_process(dword Id, PLCI *plci, byte Rc) · 6 unmodified lines | ||
| 13763 | 13799 | } |
| 13764 | 13800 | plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; |
| 13765 | 13801 | Rc = OK; |
| 13802 | + /* fall through */ | |
| 13766 | 13803 | case ADJUST_B_RESTORE_MIXER_1: |
| 13767 | 13804 | case ADJUST_B_RESTORE_MIXER_2: |
| 13768 | 13805 | case ADJUST_B_RESTORE_MIXER_3: |
| @@ -13827,6 +13864,7 @@ static void adjust_b_restore(dword Id, PLCI *plci, byte Rc) · 58 unmodified lines | ||
| 13827 | 13864 | break; |
| 13828 | 13865 | } |
| 13829 | 13866 | Rc = OK; |
| 13867 | + /* fall through */ | |
| 13830 | 13868 | case ADJUST_B_RESTORE_1: |
| 13831 | 13869 | if ((Rc != OK) && (Rc != OK_FC)) |
| 13832 | 13870 | { |
| @@ -13841,6 +13879,7 @@ static void adjust_b_restore(dword Id, PLCI *plci, byte Rc) · 8 unmodified lines | ||
| 13841 | 13879 | plci->adjust_b_state = ADJUST_B_START; |
| 13842 | 13880 | dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...", |
| 13843 | 13881 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 13882 | + /* fall through */ | |
| 13844 | 13883 | case ADJUST_B_RESTORE_2: |
| 13845 | 13884 | if (adjust_b_process(Id, plci, Rc) != GOOD) |
| 13846 | 13885 | { |
| @@ -13877,6 +13916,7 @@ static void reset_b3_command(dword Id, PLCI *plci, byte Rc) · 30 unmodified lines | ||
| 13877 | 13916 | plci->adjust_b_state = ADJUST_B_START; |
| 13878 | 13917 | dbug(1, dprintf("[%06lx] %s,%d: Reset B3...", |
| 13879 | 13918 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 13919 | + /* fall through */ | |
| 13880 | 13920 | case RESET_B3_COMMAND_1: |
| 13881 | 13921 | Info = adjust_b_process(Id, plci, Rc); |
| 13882 | 13922 | if (Info != GOOD) |
| @@ -13930,6 +13970,7 @@ static void select_b_command(dword Id, PLCI *plci, byte Rc) · 47 unmodified lines | ||
| 13930 | 13970 | plci->adjust_b_state = ADJUST_B_START; |
| 13931 | 13971 | dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...", |
| 13932 | 13972 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 13973 | + /* fall through */ | |
| 13933 | 13974 | case SELECT_B_COMMAND_1: |
| 13934 | 13975 | Info = adjust_b_process(Id, plci, Rc); |
| 13935 | 13976 | if (Info != GOOD) |
| @@ -13965,7 +14006,7 @@ static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc) · 29 unmodified lines | ||
| 13965 | 14006 | switch (internal_command) |
| 13966 | 14007 | { |
| 13967 | 14008 | default: |
| 13968 | − plci->command = 0; | |
| 14009 | + plci->command = 0; /* fall through */ | |
| 13969 | 14010 | case FAX_CONNECT_ACK_COMMAND_1: |
| 13970 | 14011 | if (plci_nl_busy(plci)) |
| 13971 | 14012 | { |
| @@ -14013,6 +14054,7 @@ static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc) · 41 unmodified lines | ||
| 14013 | 14054 | { |
| 14014 | 14055 | default: |
| 14015 | 14056 | plci->command = 0; |
| 14057 | + /* fall through */ | |
| 14016 | 14058 | case FAX_EDATA_ACK_COMMAND_1: |
| 14017 | 14059 | if (plci_nl_busy(plci)) |
| 14018 | 14060 | { |
| @@ -14052,7 +14094,7 @@ static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc) · 33 unmodified lines | ||
| 14052 | 14094 | switch (internal_command) |
| 14053 | 14095 | { |
| 14054 | 14096 | default: |
| 14055 | − plci->command = 0; | |
| 14097 | + plci->command = 0; /* fall through */ | |
| 14056 | 14098 | case FAX_CONNECT_INFO_COMMAND_1: |
| 14057 | 14099 | if (plci_nl_busy(plci)) |
| 14058 | 14100 | { |
| @@ -14112,6 +14154,7 @@ static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc) · 53 unmodified lines | ||
| 14112 | 14154 | plci->adjust_b_state = ADJUST_B_START; |
| 14113 | 14155 | dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...", |
| 14114 | 14156 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 14157 | + /* fall through */ | |
| 14115 | 14158 | case FAX_ADJUST_B23_COMMAND_1: |
| 14116 | 14159 | Info = adjust_b_process(Id, plci, Rc); |
| 14117 | 14160 | if (Info != GOOD) |
| @@ -14122,6 +14165,7 @@ static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc) · 4 unmodified lines | ||
| 14122 | 14165 | } |
| 14123 | 14166 | if (plci->internal_command) |
| 14124 | 14167 | return; |
| 14168 | + /* fall through */ | |
| 14125 | 14169 | case FAX_ADJUST_B23_COMMAND_2: |
| 14126 | 14170 | if (plci_nl_busy(plci)) |
| 14127 | 14171 | { |
| @@ -14194,7 +14238,7 @@ static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc) · 66 unmodified lines | ||
| 14194 | 14238 | switch (internal_command) |
| 14195 | 14239 | { |
| 14196 | 14240 | default: |
| 14197 | − plci->command = 0; | |
| 14241 | + plci->command = 0; /* fall through */ | |
| 14198 | 14242 | case RTP_CONNECT_B3_REQ_COMMAND_1: |
| 14199 | 14243 | if (plci_nl_busy(plci)) |
| 14200 | 14244 | { |
| @@ -14245,7 +14289,7 @@ static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc) · 44 unmodified lines | ||
| 14245 | 14289 | switch (internal_command) |
| 14246 | 14290 | { |
| 14247 | 14291 | default: |
| 14248 | − plci->command = 0; | |
| 14292 | + plci->command = 0; /* fall through */ | |
| 14249 | 14293 | case RTP_CONNECT_B3_RES_COMMAND_1: |
| 14250 | 14294 | if (plci_nl_busy(plci)) |
| 14251 | 14295 | { |
| @@ -14310,6 +14354,7 @@ static void hold_save_command(dword Id, PLCI *plci, byte Rc) · 58 unmodified lines | ||
| 14310 | 14354 | plci->adjust_b_state = ADJUST_B_START; |
| 14311 | 14355 | dbug(1, dprintf("[%06lx] %s,%d: HOLD save...", |
| 14312 | 14356 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 14357 | + /* fall through */ | |
| 14313 | 14358 | case HOLD_SAVE_COMMAND_1: |
| 14314 | 14359 | Info = adjust_b_process(Id, plci, Rc); |
| 14315 | 14360 | if (Info != GOOD) |
| @@ -14349,6 +14394,7 @@ static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc) · 33 unmodified lines | ||
| 14349 | 14394 | plci->adjust_b_state = ADJUST_B_START; |
| 14350 | 14395 | dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...", |
| 14351 | 14396 | UnMapId(Id), (char *)(FILE_), __LINE__)); |
| 14397 | + /* fall through */ | |
| 14352 | 14398 | case RETRIEVE_RESTORE_COMMAND_1: |
| 14353 | 14399 | Info = adjust_b_process(Id, plci, Rc); |
| 14354 | 14400 | if (Info != GOOD) |
| @@ -2265,7 +2265,7 @@ static struct pci_driver hfc_driver = { · 2264 unmodified lines | ||
| 2265 | 2265 | }; |
| 2266 | 2266 | |
| 2267 | 2267 | static int |
| 2268 | −_hfcpci_softirq(struct device *dev, void *arg) | |
| 2268 | +_hfcpci_softirq(struct device *dev, void *unused) | |
| 2269 | 2269 | { |
| 2270 | 2270 | struct hfc_pci *hc = dev_get_drvdata(dev); |
| 2271 | 2271 | struct bchannel *bch; |
| @@ -2290,9 +2290,9 @@ _hfcpci_softirq(struct device *dev, void *arg) · 18 unmodified lines | ||
| 2290 | 2290 | } |
| 2291 | 2291 | |
| 2292 | 2292 | static void |
| 2293 | −hfcpci_softirq(void *arg) | |
| 2293 | +hfcpci_softirq(struct timer_list *unused) | |
| 2294 | 2294 | { |
| 2295 | − WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg, | |
| 2295 | + WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, NULL, | |
| 2296 | 2296 | _hfcpci_softirq) != 0); |
| 2297 | 2297 | |
| 2298 | 2298 | /* if next event would be in the past ... */ |
| @@ -2327,9 +2327,7 @@ HFC_init(void) · 28 unmodified lines | ||
| 2327 | 2327 | if (poll != HFCPCI_BTRANS_THRESHOLD) { |
| 2328 | 2328 | printk(KERN_INFO "%s: Using alternative poll value of %d\n", |
| 2329 | 2329 | __func__, poll); |
| 2330 | − hfc_tl.function = (void *)hfcpci_softirq; | |
| 2331 | − hfc_tl.data = 0; | |
| 2332 | − init_timer(&hfc_tl); | |
| 2330 | + timer_setup(&hfc_tl, hfcpci_softirq, 0); | |
| 2333 | 2331 | hfc_tl.expires = jiffies + tics; |
| 2334 | 2332 | hfc_jiffies = hfc_tl.expires; |
| 2335 | 2333 | add_timer(&hfc_tl); |
| @@ -172,7 +172,6 @@ isac_fill_fifo(struct isac_hw *isac) · 171 unmodified lines | ||
| 172 | 172 | pr_debug("%s: %s dbusytimer running\n", isac->name, __func__); |
| 173 | 173 | del_timer(&isac->dch.timer); |
| 174 | 174 | } |
| 175 | − init_timer(&isac->dch.timer); | |
| 176 | 175 | isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); |
| 177 | 176 | add_timer(&isac->dch.timer); |
| 178 | 177 | if (isac->dch.debug & DEBUG_HW_DFIFO) { |
| @@ -727,8 +726,9 @@ isac_release(struct isac_hw *isac) · 548 unmodified lines | ||
| 727 | 726 | } |
| 728 | 727 | |
| 729 | 728 | static void |
| 730 | −dbusy_timer_handler(struct isac_hw *isac) | |
| 729 | +dbusy_timer_handler(struct timer_list *t) | |
| 731 | 730 | { |
| 731 | + struct isac_hw *isac = from_timer(isac, t, dch.timer); | |
| 732 | 732 | int rbch, star; |
| 733 | 733 | u_long flags; |
| 734 | 734 | |
| @@ -796,8 +796,7 @@ isac_init(struct isac_hw *isac) · 61 unmodified lines | ||
| 796 | 796 | } |
| 797 | 797 | isac->mon_tx = NULL; |
| 798 | 798 | isac->mon_rx = NULL; |
| 799 | − setup_timer(&isac->dch.timer, (void *)dbusy_timer_handler, | |
| 800 | − (long)isac); | |
| 799 | + timer_setup(&isac->dch.timer, dbusy_timer_handler, 0); | |
| 801 | 800 | isac->mocr = 0xaa; |
| 802 | 801 | if (isac->type & IPAC_TYPE_ISACX) { |
| 803 | 802 | /* Disable all IRQ */ |
| @@ -311,7 +311,6 @@ W6692_fill_Dfifo(struct w6692_hw *card) · 310 unmodified lines | ||
| 311 | 311 | pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name); |
| 312 | 312 | del_timer(&dch->timer); |
| 313 | 313 | } |
| 314 | − init_timer(&dch->timer); | |
| 315 | 314 | dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); |
| 316 | 315 | add_timer(&dch->timer); |
| 317 | 316 | if (debug & DEBUG_HW_DFIFO) { |
| @@ -819,8 +818,9 @@ w6692_irq(int intno, void *dev_id) · 501 unmodified lines | ||
| 819 | 818 | } |
| 820 | 819 | |
| 821 | 820 | static void |
| 822 | −dbusy_timer_handler(struct dchannel *dch) | |
| 821 | +dbusy_timer_handler(struct timer_list *t) | |
| 823 | 822 | { |
| 823 | + struct dchannel *dch = from_timer(dch, t, timer); | |
| 824 | 824 | struct w6692_hw *card = dch->hw; |
| 825 | 825 | int rbch, star; |
| 826 | 826 | u_long flags; |
| @@ -852,8 +852,7 @@ static void initW6692(struct w6692_hw *card) · 25 unmodified lines | ||
| 852 | 852 | { |
| 853 | 853 | u8 val; |
| 854 | 854 | |
| 855 | − setup_timer(&card->dch.timer, (void *)dbusy_timer_handler, | |
| 856 | − (u_long)&card->dch); | |
| 855 | + timer_setup(&card->dch.timer, dbusy_timer_handler, 0); | |
| 857 | 856 | w6692_mode(&card->bc[0], ISDN_P_NONE); |
| 858 | 857 | w6692_mode(&card->bc[1], ISDN_P_NONE); |
| 859 | 858 | WriteW6692(card, W_D_CTL, 0x00); |
| @@ -398,7 +398,6 @@ Amd7930_fill_Dfifo(struct IsdnCardState *cs) · 397 unmodified lines | ||
| 398 | 398 | debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running"); |
| 399 | 399 | del_timer(&cs->dbusytimer); |
| 400 | 400 | } |
| 401 | − init_timer(&cs->dbusytimer); | |
| 402 | 401 | cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); |
| 403 | 402 | add_timer(&cs->dbusytimer); |
| 404 | 403 | |
| @@ -686,8 +685,9 @@ DC_Close_Amd7930(struct IsdnCardState *cs) { · 281 unmodified lines | ||
| 686 | 685 | |
| 687 | 686 | |
| 688 | 687 | static void |
| 689 | −dbusy_timer_handler(struct IsdnCardState *cs) | |
| 688 | +dbusy_timer_handler(struct timer_list *t) | |
| 690 | 689 | { |
| 690 | + struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); | |
| 691 | 691 | u_long flags; |
| 692 | 692 | struct PStack *stptr; |
| 693 | 693 | WORD dtcr, der; |
| @@ -790,5 +790,5 @@ void Amd7930_init(struct IsdnCardState *cs) · 96 unmodified lines | ||
| 790 | 790 | void setup_Amd7930(struct IsdnCardState *cs) |
| 791 | 791 | { |
| 792 | 792 | INIT_WORK(&cs->tqueue, Amd7930_bh); |
| 793 | − setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, (long)cs); | |
| 793 | + timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); | |
| 794 | 794 | } |
| @@ -23,7 +23,6 @@ add_arcofi_timer(struct IsdnCardState *cs) { · 22 unmodified lines | ||
| 23 | 23 | if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { |
| 24 | 24 | del_timer(&cs->dc.isac.arcofitimer); |
| 25 | 25 | } |
| 26 | − init_timer(&cs->dc.isac.arcofitimer); | |
| 27 | 26 | cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ) / 1000); |
| 28 | 27 | add_timer(&cs->dc.isac.arcofitimer); |
| 29 | 28 | } |
| @@ -112,7 +111,8 @@ arcofi_fsm(struct IsdnCardState *cs, int event, void *data) { · 82 unmodified lines | ||
| 112 | 111 | } |
| 113 | 112 | |
| 114 | 113 | static void |
| 115 | −arcofi_timer(struct IsdnCardState *cs) { | |
| 114 | +arcofi_timer(struct timer_list *t) { | |
| 115 | + struct IsdnCardState *cs = from_timer(cs, t, dc.isac.arcofitimer); | |
| 116 | 116 | arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL); |
| 117 | 117 | } |
| 118 | 118 | |
| @@ -125,7 +125,7 @@ clear_arcofi(struct IsdnCardState *cs) { · 6 unmodified lines | ||
| 125 | 125 | |
| 126 | 126 | void |
| 127 | 127 | init_arcofi(struct IsdnCardState *cs) { |
| 128 | − setup_timer(&cs->dc.isac.arcofitimer, (void *)arcofi_timer, (long)cs); | |
| 128 | + timer_setup(&cs->dc.isac.arcofitimer, arcofi_timer, 0); | |
| 129 | 129 | init_waitqueue_head(&cs->dc.isac.arcofi_wait); |
| 130 | 130 | test_and_set_bit(HW_ARCOFI, &cs->HW_Flags); |
| 131 | 131 | } |
| @@ -798,8 +798,9 @@ reset_diva(struct IsdnCardState *cs) · 797 unmodified lines | ||
| 798 | 798 | #define DIVA_ASSIGN 1 |
| 799 | 799 | |
| 800 | 800 | static void |
| 801 | −diva_led_handler(struct IsdnCardState *cs) | |
| 801 | +diva_led_handler(struct timer_list *t) | |
| 802 | 802 | { |
| 803 | + struct IsdnCardState *cs = from_timer(cs, t, hw.diva.tl); | |
| 803 | 804 | int blink = 0; |
| 804 | 805 | |
| 805 | 806 | if ((cs->subtyp == DIVA_IPAC_ISA) || |
| @@ -828,7 +829,6 @@ diva_led_handler(struct IsdnCardState *cs) · 22 unmodified lines | ||
| 828 | 829 | |
| 829 | 830 | byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); |
| 830 | 831 | if (blink) { |
| 831 | − init_timer(&cs->hw.diva.tl); | |
| 832 | 832 | cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); |
| 833 | 833 | add_timer(&cs->hw.diva.tl); |
| 834 | 834 | } |
| @@ -900,7 +900,7 @@ Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) · 65 unmodified lines | ||
| 900 | 900 | (cs->subtyp != DIVA_IPAC_PCI) && |
| 901 | 901 | (cs->subtyp != DIVA_IPACX_PCI)) { |
| 902 | 902 | spin_lock_irqsave(&cs->lock, flags); |
| 903 | − diva_led_handler(cs); | |
| 903 | + diva_led_handler(&cs->hw.diva.tl); | |
| 904 | 904 | spin_unlock_irqrestore(&cs->lock, flags); |
| 905 | 905 | } |
| 906 | 906 | return (0); |
| @@ -978,8 +978,7 @@ static int setup_diva_common(struct IsdnCardState *cs) · 71 unmodified lines | ||
| 978 | 978 | printk(KERN_INFO "Diva: IPACX Design Id: %x\n", |
| 979 | 979 | MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F); |
| 980 | 980 | } else { /* DIVA 2.0 */ |
| 981 | − setup_timer(&cs->hw.diva.tl, (void *)diva_led_handler, | |
| 982 | − (long)cs); | |
| 981 | + timer_setup(&cs->hw.diva.tl, diva_led_handler, 0); | |
| 983 | 982 | cs->readisac = &ReadISAC; |
| 984 | 983 | cs->writeisac = &WriteISAC; |
| 985 | 984 | cs->readisacfifo = &ReadISACfifo; |
| @@ -606,8 +606,9 @@ check_arcofi(struct IsdnCardState *cs) · 605 unmodified lines | ||
| 606 | 606 | #endif /* ARCOFI_USE */ |
| 607 | 607 | |
| 608 | 608 | static void |
| 609 | −elsa_led_handler(struct IsdnCardState *cs) | |
| 609 | +elsa_led_handler(struct timer_list *t) | |
| 610 | 610 | { |
| 611 | + struct IsdnCardState *cs = from_timer(cs, t, hw.elsa.tl); | |
| 611 | 612 | int blink = 0; |
| 612 | 613 | |
| 613 | 614 | if (cs->subtyp == ELSA_PCMCIA || cs->subtyp == ELSA_PCMCIA_IPAC) |
| @@ -640,7 +641,6 @@ elsa_led_handler(struct IsdnCardState *cs) · 26 unmodified lines | ||
| 640 | 641 | } else |
| 641 | 642 | byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); |
| 642 | 643 | if (blink) { |
| 643 | − init_timer(&cs->hw.elsa.tl); | |
| 644 | 644 | cs->hw.elsa.tl.expires = jiffies + ((blink * HZ) / 1000); |
| 645 | 645 | add_timer(&cs->hw.elsa.tl); |
| 646 | 646 | } |
| @@ -715,7 +715,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) · 68 unmodified lines | ||
| 715 | 715 | init_modem(cs); |
| 716 | 716 | } |
| 717 | 717 | #endif |
| 718 | − elsa_led_handler(cs); | |
| 718 | + elsa_led_handler(&cs->hw.elsa.tl); | |
| 719 | 719 | return (ret); |
| 720 | 720 | case (MDL_REMOVE | REQUEST): |
| 721 | 721 | cs->hw.elsa.status &= 0; |
| @@ -767,7 +767,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) · 45 unmodified lines | ||
| 767 | 767 | else |
| 768 | 768 | cs->hw.elsa.status &= ~ELSA_BAD_PWR; |
| 769 | 769 | } |
| 770 | − elsa_led_handler(cs); | |
| 770 | + elsa_led_handler(&cs->hw.elsa.tl); | |
| 771 | 771 | return (ret); |
| 772 | 772 | } |
| 773 | 773 | |
| @@ -1147,7 +1147,7 @@ static int setup_elsa_common(struct IsdnCard *card) · 373 unmodified lines | ||
| 1147 | 1147 | init_arcofi(cs); |
| 1148 | 1148 | #endif |
| 1149 | 1149 | setup_isac(cs); |
| 1150 | − setup_timer(&cs->hw.elsa.tl, (void *)elsa_led_handler, (long)cs); | |
| 1150 | + timer_setup(&cs->hw.elsa.tl, elsa_led_handler, 0); | |
| 1151 | 1151 | /* Teste Timer */ |
| 1152 | 1152 | if (cs->hw.elsa.timer) { |
| 1153 | 1153 | byteout(cs->hw.elsa.trig, 0xff); |
| @@ -85,8 +85,9 @@ FsmChangeState(struct FsmInst *fi, int newstate) · 84 unmodified lines | ||
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | static void |
| 88 | −FsmExpireTimer(struct FsmTimer *ft) | |
| 88 | +FsmExpireTimer(struct timer_list *t) | |
| 89 | 89 | { |
| 90 | + struct FsmTimer *ft = from_timer(ft, t, tl); | |
| 90 | 91 | #if FSM_TIMER_DEBUG |
| 91 | 92 | if (ft->fi->debug) |
| 92 | 93 | ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft); |
| @@ -102,7 +103,7 @@ FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft) · 9 unmodified lines | ||
| 102 | 103 | if (ft->fi->debug) |
| 103 | 104 | ft->fi->printdebug(ft->fi, "FsmInitTimer %lx", (long) ft); |
| 104 | 105 | #endif |
| 105 | − setup_timer(&ft->tl, (void *)FsmExpireTimer, (long)ft); | |
| 106 | + timer_setup(&ft->tl, FsmExpireTimer, 0); | |
| 106 | 107 | } |
| 107 | 108 | |
| 108 | 109 | void |
| @@ -131,7 +132,6 @@ FsmAddTimer(struct FsmTimer *ft, · 22 unmodified lines | ||
| 131 | 132 | ft->fi->printdebug(ft->fi, "FsmAddTimer already active!"); |
| 132 | 133 | return -1; |
| 133 | 134 | } |
| 134 | − init_timer(&ft->tl); | |
| 135 | 135 | ft->event = event; |
| 136 | 136 | ft->arg = arg; |
| 137 | 137 | ft->tl.expires = jiffies + (millisec * HZ) / 1000; |
| @@ -152,7 +152,6 @@ FsmRestartTimer(struct FsmTimer *ft, · 14 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | if (timer_pending(&ft->tl)) |
| 154 | 154 | del_timer(&ft->tl); |
| 155 | − init_timer(&ft->tl); | |
| 156 | 155 | ft->event = event; |
| 157 | 156 | ft->arg = arg; |
| 158 | 157 | ft->tl.expires = jiffies + (millisec * HZ) / 1000; |
| @@ -591,8 +591,9 @@ bch_l2l1(struct hisax_if *ifc, int pr, void *arg) · 590 unmodified lines | ||
| 591 | 591 | /* layer 1 timer function */ |
| 592 | 592 | /**************************/ |
| 593 | 593 | static void |
| 594 | −hfc_l1_timer(struct hfc4s8s_l1 *l1) | |
| 594 | +hfc_l1_timer(struct timer_list *t) | |
| 595 | 595 | { |
| 596 | + struct hfc4s8s_l1 *l1 = from_timer(l1, t, l1_timer); | |
| 596 | 597 | u_long flags; |
| 597 | 598 | |
| 598 | 599 | if (!l1->enabled) |
| @@ -1396,8 +1397,7 @@ setup_instance(hfc4s8s_hw *hw) · 797 unmodified lines | ||
| 1396 | 1397 | l1p = hw->l1 + i; |
| 1397 | 1398 | spin_lock_init(&l1p->lock); |
| 1398 | 1399 | l1p->hw = hw; |
| 1399 | − setup_timer(&l1p->l1_timer, (void *)hfc_l1_timer, | |
| 1400 | − (long)(l1p)); | |
| 1400 | + timer_setup(&l1p->l1_timer, hfc_l1_timer, 0); | |
| 1401 | 1401 | l1p->st_num = i; |
| 1402 | 1402 | skb_queue_head_init(&l1p->d_tx_queue); |
| 1403 | 1403 | l1p->d_if.ifc.priv = hw->l1 + i; |
| @@ -1014,7 +1014,7 @@ setstack_hfcd(struct PStack *st, struct IsdnCardState *cs) · 1013 unmodified lines | ||
| 1014 | 1014 | } |
| 1015 | 1015 | |
| 1016 | 1016 | static void |
| 1017 | −hfc_dbusy_timer(struct IsdnCardState *cs) | |
| 1017 | +hfc_dbusy_timer(struct timer_list *t) | |
| 1018 | 1018 | { |
| 1019 | 1019 | } |
| 1020 | 1020 | |
| @@ -1073,6 +1073,6 @@ set_cs_func(struct IsdnCardState *cs) · 52 unmodified lines | ||
| 1073 | 1073 | cs->writeisacfifo = &dummyf; |
| 1074 | 1074 | cs->BC_Read_Reg = &ReadReg; |
| 1075 | 1075 | cs->BC_Write_Reg = &WriteReg; |
| 1076 | − setup_timer(&cs->dbusytimer, (void *)hfc_dbusy_timer, (long)cs); | |
| 1076 | + timer_setup(&cs->dbusytimer, hfc_dbusy_timer, 0); | |
| 1077 | 1077 | INIT_WORK(&cs->tqueue, hfcd_bh); |
| 1078 | 1078 | } |
| @@ -165,8 +165,9 @@ reset_hfcpci(struct IsdnCardState *cs) · 164 unmodified lines | ||
| 165 | 165 | /* Timer function called when kernel timer expires */ |
| 166 | 166 | /***************************************************/ |
| 167 | 167 | static void |
| 168 | −hfcpci_Timer(struct IsdnCardState *cs) | |
| 168 | +hfcpci_Timer(struct timer_list *t) | |
| 169 | 169 | { |
| 170 | + struct IsdnCardState *cs = from_timer(cs, t, hw.hfcpci.timer); | |
| 170 | 171 | cs->hw.hfcpci.timer.expires = jiffies + 75; |
| 171 | 172 | /* WD RESET */ |
| 172 | 173 | /* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcpci.ctmt | 0x80); |
| @@ -1095,7 +1096,7 @@ hfcpci_interrupt(int intno, void *dev_id) · 922 unmodified lines | ||
| 1095 | 1096 | /* timer callback for D-chan busy resolution. Currently no function */ |
| 1096 | 1097 | /********************************************************************/ |
| 1097 | 1098 | static void |
| 1098 | −hfcpci_dbusy_timer(struct IsdnCardState *cs) | |
| 1099 | +hfcpci_dbusy_timer(struct timer_list *t) | |
| 1099 | 1100 | { |
| 1100 | 1101 | } |
| 1101 | 1102 | |
| @@ -1582,7 +1583,7 @@ inithfcpci(struct IsdnCardState *cs) · 480 unmodified lines | ||
| 1582 | 1583 | cs->bcs[1].BC_SetStack = setstack_2b; |
| 1583 | 1584 | cs->bcs[0].BC_Close = close_hfcpci; |
| 1584 | 1585 | cs->bcs[1].BC_Close = close_hfcpci; |
| 1585 | − setup_timer(&cs->dbusytimer, (void *)hfcpci_dbusy_timer, (long)cs); | |
| 1586 | + timer_setup(&cs->dbusytimer, hfcpci_dbusy_timer, 0); | |
| 1586 | 1587 | mode_hfcpci(cs->bcs, 0, 0); |
| 1587 | 1588 | mode_hfcpci(cs->bcs + 1, 0, 1); |
| 1588 | 1589 | } |
| @@ -1744,7 +1745,7 @@ setup_hfcpci(struct IsdnCard *card) · 155 unmodified lines | ||
| 1744 | 1745 | cs->BC_Write_Reg = NULL; |
| 1745 | 1746 | cs->irq_func = &hfcpci_interrupt; |
| 1746 | 1747 | cs->irq_flags |= IRQF_SHARED; |
| 1747 | − setup_timer(&cs->hw.hfcpci.timer, (void *)hfcpci_Timer, (long)cs); | |
| 1748 | + timer_setup(&cs->hw.hfcpci.timer, hfcpci_Timer, 0); | |
| 1748 | 1749 | cs->cardmsg = &hfcpci_card_msg; |
| 1749 | 1750 | cs->auxcmd = &hfcpci_auxcmd; |
| 1750 | 1751 | |
| @@ -418,8 +418,9 @@ reset_hfcsx(struct IsdnCardState *cs) · 417 unmodified lines | ||
| 418 | 418 | /* Timer function called when kernel timer expires */ |
| 419 | 419 | /***************************************************/ |
| 420 | 420 | static void |
| 421 | −hfcsx_Timer(struct IsdnCardState *cs) | |
| 421 | +hfcsx_Timer(struct timer_list *t) | |
| 422 | 422 | { |
| 423 | + struct IsdnCardState *cs = from_timer(cs, t, hw.hfcsx.timer); | |
| 423 | 424 | cs->hw.hfcsx.timer.expires = jiffies + 75; |
| 424 | 425 | /* WD RESET */ |
| 425 | 426 | /* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcsx.ctmt | 0x80); |
| @@ -860,7 +861,7 @@ hfcsx_interrupt(int intno, void *dev_id) · 434 unmodified lines | ||
| 860 | 861 | /* timer callback for D-chan busy resolution. Currently no function */ |
| 861 | 862 | /********************************************************************/ |
| 862 | 863 | static void |
| 863 | −hfcsx_dbusy_timer(struct IsdnCardState *cs) | |
| 864 | +hfcsx_dbusy_timer(struct timer_list *t) | |
| 864 | 865 | { |
| 865 | 866 | } |
| 866 | 867 | |
| @@ -1495,7 +1496,7 @@ int setup_hfcsx(struct IsdnCard *card) · 628 unmodified lines | ||
| 1495 | 1496 | } else |
| 1496 | 1497 | return (0); /* no valid card type */ |
| 1497 | 1498 | |
| 1498 | − setup_timer(&cs->dbusytimer, (void *)hfcsx_dbusy_timer, (long)cs); | |
| 1499 | + timer_setup(&cs->dbusytimer, hfcsx_dbusy_timer, 0); | |
| 1499 | 1500 | INIT_WORK(&cs->tqueue, hfcsx_bh); |
| 1500 | 1501 | cs->readisac = NULL; |
| 1501 | 1502 | cs->writeisac = NULL; |
| @@ -1507,7 +1508,7 @@ int setup_hfcsx(struct IsdnCard *card) · 5 unmodified lines | ||
| 1507 | 1508 | |
| 1508 | 1509 | cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ |
| 1509 | 1510 | cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */ |
| 1510 | − setup_timer(&cs->hw.hfcsx.timer, (void *)hfcsx_Timer, (long)cs); | |
| 1511 | + timer_setup(&cs->hw.hfcsx.timer, hfcsx_Timer, 0); | |
| 1511 | 1512 | |
| 1512 | 1513 | reset_hfcsx(cs); |
| 1513 | 1514 | cs->cardmsg = &hfcsx_card_msg; |
| @@ -343,8 +343,9 @@ handle_led(hfcusb_data *hfc, int event) · 342 unmodified lines | ||
| 343 | 343 | |
| 344 | 344 | /* ISDN l1 timer T3 expires */ |
| 345 | 345 | static void |
| 346 | −l1_timer_expire_t3(hfcusb_data *hfc) | |
| 346 | +l1_timer_expire_t3(struct timer_list *t) | |
| 347 | 347 | { |
| 348 | + hfcusb_data *hfc = from_timer(hfc, t, t3_timer); | |
| 348 | 349 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, |
| 349 | 350 | NULL); |
| 350 | 351 | |
| @@ -360,8 +361,9 @@ l1_timer_expire_t3(hfcusb_data *hfc) · 9 unmodified lines | ||
| 360 | 361 | |
| 361 | 362 | /* ISDN l1 timer T4 expires */ |
| 362 | 363 | static void |
| 363 | −l1_timer_expire_t4(hfcusb_data *hfc) | |
| 364 | +l1_timer_expire_t4(struct timer_list *t) | |
| 364 | 365 | { |
| 366 | + hfcusb_data *hfc = from_timer(hfc, t, t4_timer); | |
| 365 | 367 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, |
| 366 | 368 | NULL); |
| 367 | 369 | |
| @@ -1165,10 +1167,10 @@ hfc_usb_init(hfcusb_data *hfc) · 797 unmodified lines | ||
| 1165 | 1167 | hfc->old_led_state = 0; |
| 1166 | 1168 | |
| 1167 | 1169 | /* init the t3 timer */ |
| 1168 | − setup_timer(&hfc->t3_timer, (void *)l1_timer_expire_t3, (long)hfc); | |
| 1170 | + timer_setup(&hfc->t3_timer, l1_timer_expire_t3, 0); | |
| 1169 | 1171 | |
| 1170 | 1172 | /* init the t4 timer */ |
| 1171 | − setup_timer(&hfc->t4_timer, (void *)l1_timer_expire_t4, (long)hfc); | |
| 1173 | + timer_setup(&hfc->t4_timer, l1_timer_expire_t4, 0); | |
| 1172 | 1174 | |
| 1173 | 1175 | /* init the background machinery for control requests */ |
| 1174 | 1176 | hfc->ctrl_read.bRequestType = 0xc0; |
| @@ -41,8 +41,9 @@ hfcs_interrupt(int intno, void *dev_id) · 40 unmodified lines | ||
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | static void |
| 44 | −hfcs_Timer(struct IsdnCardState *cs) | |
| 44 | +hfcs_Timer(struct timer_list *t) | |
| 45 | 45 | { |
| 46 | + struct IsdnCardState *cs = from_timer(cs, t, hw.hfcD.timer); | |
| 46 | 47 | cs->hw.hfcD.timer.expires = jiffies + 75; |
| 47 | 48 | /* WD RESET */ |
| 48 | 49 | /* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt | 0x80); |
| @@ -253,7 +254,7 @@ int setup_hfcs(struct IsdnCard *card) · 204 unmodified lines | ||
| 253 | 254 | outb(0x57, cs->hw.hfcD.addr | 1); |
| 254 | 255 | } |
| 255 | 256 | set_cs_func(cs); |
| 256 | − setup_timer(&cs->hw.hfcD.timer, (void *)hfcs_Timer, (long)cs); | |
| 257 | + timer_setup(&cs->hw.hfcD.timer, hfcs_Timer, 0); | |
| 257 | 258 | cs->cardmsg = &hfcs_card_msg; |
| 258 | 259 | cs->irq_func = &hfcs_interrupt; |
| 259 | 260 | return (1); |
| @@ -168,7 +168,6 @@ icc_fill_fifo(struct IsdnCardState *cs) · 167 unmodified lines | ||
| 168 | 168 | debugl1(cs, "icc_fill_fifo dbusytimer running"); |
| 169 | 169 | del_timer(&cs->dbusytimer); |
| 170 | 170 | } |
| 171 | − init_timer(&cs->dbusytimer); | |
| 172 | 171 | cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); |
| 173 | 172 | add_timer(&cs->dbusytimer); |
| 174 | 173 | if (cs->debug & L1_DEB_ISAC_FIFO) { |
| @@ -580,8 +579,9 @@ DC_Close_icc(struct IsdnCardState *cs) { · 405 unmodified lines | ||
| 580 | 579 | } |
| 581 | 580 | |
| 582 | 581 | static void |
| 583 | −dbusy_timer_handler(struct IsdnCardState *cs) | |
| 582 | +dbusy_timer_handler(struct timer_list *t) | |
| 584 | 583 | { |
| 584 | + struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); | |
| 585 | 585 | struct PStack *stptr; |
| 586 | 586 | int rbch, star; |
| 587 | 587 | |
| @@ -676,5 +676,5 @@ clear_pending_icc_ints(struct IsdnCardState *cs) · 88 unmodified lines | ||
| 676 | 676 | void setup_icc(struct IsdnCardState *cs) |
| 677 | 677 | { |
| 678 | 678 | INIT_WORK(&cs->tqueue, icc_bh); |
| 679 | − setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, (long)cs); | |
| 679 | + timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); | |
| 680 | 680 | } |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | static void ph_command(struct IsdnCardState *cs, unsigned int command); |
| 36 | 36 | static inline void cic_int(struct IsdnCardState *cs); |
| 37 | 37 | static void dch_l2l1(struct PStack *st, int pr, void *arg); |
| 38 | −static void dbusy_timer_handler(struct IsdnCardState *cs); | |
| 38 | +static void dbusy_timer_handler(struct timer_list *t); | |
| 39 | 39 | static void dch_empty_fifo(struct IsdnCardState *cs, int count); |
| 40 | 40 | static void dch_fill_fifo(struct IsdnCardState *cs); |
| 41 | 41 | static inline void dch_int(struct IsdnCardState *cs); |
| @@ -198,8 +198,9 @@ dch_l2l1(struct PStack *st, int pr, void *arg) · 156 unmodified lines | ||
| 198 | 198 | //---------------------------------------------------------- |
| 199 | 199 | //---------------------------------------------------------- |
| 200 | 200 | static void |
| 201 | −dbusy_timer_handler(struct IsdnCardState *cs) | |
| 201 | +dbusy_timer_handler(struct timer_list *t) | |
| 202 | 202 | { |
| 203 | + struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); | |
| 203 | 204 | struct PStack *st; |
| 204 | 205 | int rbchd, stard; |
| 205 | 206 | |
| @@ -298,7 +299,6 @@ dch_fill_fifo(struct IsdnCardState *cs) · 92 unmodified lines | ||
| 298 | 299 | debugl1(cs, "dch_fill_fifo dbusytimer running"); |
| 299 | 300 | del_timer(&cs->dbusytimer); |
| 300 | 301 | } |
| 301 | − init_timer(&cs->dbusytimer); | |
| 302 | 302 | cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); |
| 303 | 303 | add_timer(&cs->dbusytimer); |
| 304 | 304 | |
| @@ -424,7 +424,7 @@ dch_init(struct IsdnCardState *cs) · 119 unmodified lines | ||
| 424 | 424 | |
| 425 | 425 | cs->setstack_d = dch_setstack; |
| 426 | 426 | |
| 427 | − setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, (long)cs); | |
| 427 | + timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); | |
| 428 | 428 | |
| 429 | 429 | cs->writeisac(cs, IPACX_TR_CONF0, 0x00); // clear LDD |
| 430 | 430 | cs->writeisac(cs, IPACX_TR_CONF2, 0x00); // enable transmitter |
| @@ -171,7 +171,6 @@ isac_fill_fifo(struct IsdnCardState *cs) · 170 unmodified lines | ||
| 171 | 171 | debugl1(cs, "isac_fill_fifo dbusytimer running"); |
| 172 | 172 | del_timer(&cs->dbusytimer); |
| 173 | 173 | } |
| 174 | − init_timer(&cs->dbusytimer); | |
| 175 | 174 | cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); |
| 176 | 175 | add_timer(&cs->dbusytimer); |
| 177 | 176 | if (cs->debug & L1_DEB_ISAC_FIFO) { |
| @@ -584,8 +583,9 @@ DC_Close_isac(struct IsdnCardState *cs) · 406 unmodified lines | ||
| 584 | 583 | } |
| 585 | 584 | |
| 586 | 585 | static void |
| 587 | −dbusy_timer_handler(struct IsdnCardState *cs) | |
| 586 | +dbusy_timer_handler(struct timer_list *t) | |
| 588 | 587 | { |
| 588 | + struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); | |
| 589 | 589 | struct PStack *stptr; |
| 590 | 590 | int rbch, star; |
| 591 | 591 | |
| @@ -677,5 +677,5 @@ void clear_pending_isac_ints(struct IsdnCardState *cs) · 85 unmodified lines | ||
| 677 | 677 | void setup_isac(struct IsdnCardState *cs) |
| 678 | 678 | { |
| 679 | 679 | INIT_WORK(&cs->tqueue, isac_bh); |
| 680 | − setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, (long)cs); | |
| 680 | + timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); | |
| 681 | 681 | } |
| @@ -1267,7 +1267,8 @@ isar_int_main(struct IsdnCardState *cs) · 1266 unmodified lines | ||
| 1267 | 1267 | } |
| 1268 | 1268 | |
| 1269 | 1269 | static void |
| 1270 | −ftimer_handler(struct BCState *bcs) { | |
| 1270 | +ftimer_handler(struct timer_list *t) { | |
| 1271 | + struct BCState *bcs = from_timer(bcs, t, hw.isar.ftimer); | |
| 1271 | 1272 | if (bcs->cs->debug) |
| 1272 | 1273 | debugl1(bcs->cs, "ftimer flags %04lx", |
| 1273 | 1274 | bcs->Flag); |
| @@ -1902,8 +1903,6 @@ void initisar(struct IsdnCardState *cs) · 628 unmodified lines | ||
| 1902 | 1903 | cs->bcs[1].BC_SetStack = setstack_isar; |
| 1903 | 1904 | cs->bcs[0].BC_Close = close_isarstate; |
| 1904 | 1905 | cs->bcs[1].BC_Close = close_isarstate; |
| 1905 | − setup_timer(&cs->bcs[0].hw.isar.ftimer, (void *)ftimer_handler, | |
| 1906 | − (long)&cs->bcs[0]); | |
| 1907 | − setup_timer(&cs->bcs[1].hw.isar.ftimer, (void *)ftimer_handler, | |
| 1908 | − (long)&cs->bcs[1]); | |
| 1906 | + timer_setup(&cs->bcs[0].hw.isar.ftimer, ftimer_handler, 0); | |
| 1907 | + timer_setup(&cs->bcs[1].hw.isar.ftimer, ftimer_handler, 0); | |
| 1909 | 1908 | } |
| @@ -160,8 +160,9 @@ newl3state(struct l3_process *pc, int state) · 159 unmodified lines | ||
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | static void |
| 163 | −L3ExpireTimer(struct L3Timer *t) | |
| 163 | +L3ExpireTimer(struct timer_list *timer) | |
| 164 | 164 | { |
| 165 | + struct L3Timer *t = from_timer(t, timer, tl); | |
| 165 | 166 | t->pc->st->lli.l4l3(t->pc->st, t->event, t->pc); |
| 166 | 167 | } |
| 167 | 168 | |
| @@ -169,7 +170,7 @@ void · 1 unmodified line | ||
| 169 | 170 | L3InitTimer(struct l3_process *pc, struct L3Timer *t) |
| 170 | 171 | { |
| 171 | 172 | t->pc = pc; |
| 172 | − setup_timer(&t->tl, (void *)L3ExpireTimer, (long)t); | |
| 173 | + timer_setup(&t->tl, L3ExpireTimer, 0); | |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | 176 | void |
| @@ -186,7 +187,6 @@ L3AddTimer(struct L3Timer *t, · 10 unmodified lines | ||
| 186 | 187 | printk(KERN_WARNING "L3AddTimer: timer already active!\n"); |
| 187 | 188 | return -1; |
| 188 | 189 | } |
| 189 | − init_timer(&t->tl); | |
| 190 | 190 | t->event = event; |
| 191 | 191 | t->tl.expires = jiffies + (millisec * HZ) / 1000; |
| 192 | 192 | add_timer(&t->tl); |
| @@ -159,8 +159,9 @@ Start_ISAC: · 158 unmodified lines | ||
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | static void |
| 162 | −SaphirWatchDog(struct IsdnCardState *cs) | |
| 162 | +SaphirWatchDog(struct timer_list *t) | |
| 163 | 163 | { |
| 164 | + struct IsdnCardState *cs = from_timer(cs, t, hw.saphir.timer); | |
| 164 | 165 | u_long flags; |
| 165 | 166 | |
| 166 | 167 | spin_lock_irqsave(&cs->lock, flags); |
| @@ -268,9 +269,7 @@ int setup_saphir(struct IsdnCard *card) · 101 unmodified lines | ||
| 268 | 269 | cs->irq, cs->hw.saphir.cfg_reg); |
| 269 | 270 | |
| 270 | 271 | setup_isac(cs); |
| 271 | − cs->hw.saphir.timer.function = (void *) SaphirWatchDog; | |
| 272 | − cs->hw.saphir.timer.data = (long) cs; | |
| 273 | − init_timer(&cs->hw.saphir.timer); | |
| 272 | + timer_setup(&cs->hw.saphir.timer, SaphirWatchDog, 0); | |
| 274 | 273 | cs->hw.saphir.timer.expires = jiffies + 4 * HZ; |
| 275 | 274 | add_timer(&cs->hw.saphir.timer); |
| 276 | 275 | if (saphir_reset(cs)) { |
| @@ -179,8 +179,9 @@ Start_ISAC: · 178 unmodified lines | ||
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | static void |
| 182 | −TeleInt_Timer(struct IsdnCardState *cs) | |
| 182 | +TeleInt_Timer(struct timer_list *t) | |
| 183 | 183 | { |
| 184 | + struct IsdnCardState *cs = from_timer(cs, t, hw.hfc.timer); | |
| 184 | 185 | int stat = 0; |
| 185 | 186 | u_long flags; |
| 186 | 187 | |
| @@ -278,7 +279,7 @@ int setup_TeleInt(struct IsdnCard *card) · 91 unmodified lines | ||
| 278 | 279 | cs->bcs[0].hw.hfc.send = NULL; |
| 279 | 280 | cs->bcs[1].hw.hfc.send = NULL; |
| 280 | 281 | cs->hw.hfc.fifosize = 7 * 1024 + 512; |
| 281 | − setup_timer(&cs->hw.hfc.timer, (void *)TeleInt_Timer, (long)cs); | |
| 282 | + timer_setup(&cs->hw.hfc.timer, TeleInt_Timer, 0); | |
| 282 | 283 | if (!request_region(cs->hw.hfc.addr, 2, "TeleInt isdn")) { |
| 283 | 284 | printk(KERN_WARNING |
| 284 | 285 | "HiSax: TeleInt config port %x-%x already in use\n", |
| @@ -188,7 +188,6 @@ W6692_fill_fifo(struct IsdnCardState *cs) · 187 unmodified lines | ||
| 188 | 188 | debugl1(cs, "W6692_fill_fifo dbusytimer running"); |
| 189 | 189 | del_timer(&cs->dbusytimer); |
| 190 | 190 | } |
| 191 | − init_timer(&cs->dbusytimer); | |
| 192 | 191 | cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); |
| 193 | 192 | add_timer(&cs->dbusytimer); |
| 194 | 193 | if (cs->debug & L1_DEB_ISAC_FIFO) { |
| @@ -684,8 +683,9 @@ DC_Close_W6692(struct IsdnCardState *cs) · 489 unmodified lines | ||
| 684 | 683 | } |
| 685 | 684 | |
| 686 | 685 | static void |
| 687 | −dbusy_timer_handler(struct IsdnCardState *cs) | |
| 686 | +dbusy_timer_handler(struct timer_list *t) | |
| 688 | 687 | { |
| 688 | + struct IsdnCardState *cs = from_timer(cs, t, dbusytimer); | |
| 689 | 689 | struct PStack *stptr; |
| 690 | 690 | int rbch, star; |
| 691 | 691 | u_long flags; |
| @@ -904,8 +904,7 @@ static void initW6692(struct IsdnCardState *cs, int part) · 212 unmodified lines | ||
| 904 | 904 | if (part & 1) { |
| 905 | 905 | cs->setstack_d = setstack_W6692; |
| 906 | 906 | cs->DC_Close = DC_Close_W6692; |
| 907 | − setup_timer(&cs->dbusytimer, (void *)dbusy_timer_handler, | |
| 908 | − (long)cs); | |
| 907 | + timer_setup(&cs->dbusytimer, dbusy_timer_handler, 0); | |
| 909 | 908 | resetW6692(cs); |
| 910 | 909 | ph_command(cs, W_L1CMD_RST); |
| 911 | 910 | cs->dc.w6692.ph_state = W_L1CMD_RST; |
| @@ -90,9 +90,9 @@ isdnloop_bchan_send(isdnloop_card *card, int ch) · 89 unmodified lines | ||
| 90 | 90 | * data = pointer to card struct, set by kernel timer.data |
| 91 | 91 | */ |
| 92 | 92 | static void |
| 93 | −isdnloop_pollbchan(unsigned long data) | |
| 93 | +isdnloop_pollbchan(struct timer_list *t) | |
| 94 | 94 | { |
| 95 | − isdnloop_card *card = (isdnloop_card *) data; | |
| 95 | + isdnloop_card *card = from_timer(card, t, rb_timer); | |
| 96 | 96 | unsigned long flags; |
| 97 | 97 | |
| 98 | 98 | if (card->flags & ISDNLOOP_FLAGS_B1ACTIVE) |
| @@ -305,9 +305,9 @@ isdnloop_putmsg(isdnloop_card *card, unsigned char c) · 206 unmodified lines | ||
| 305 | 305 | * data = pointer to card struct |
| 306 | 306 | */ |
| 307 | 307 | static void |
| 308 | −isdnloop_polldchan(unsigned long data) | |
| 308 | +isdnloop_polldchan(struct timer_list *t) | |
| 309 | 309 | { |
| 310 | − isdnloop_card *card = (isdnloop_card *) data; | |
| 310 | + isdnloop_card *card = from_timer(card, t, st_timer); | |
| 311 | 311 | struct sk_buff *skb; |
| 312 | 312 | int avail; |
| 313 | 313 | int left; |
| @@ -373,8 +373,6 @@ isdnloop_polldchan(unsigned long data) · 59 unmodified lines | ||
| 373 | 373 | card->flags |= ISDNLOOP_FLAGS_RBTIMER; |
| 374 | 374 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
| 375 | 375 | del_timer(&card->rb_timer); |
| 376 | − card->rb_timer.function = isdnloop_pollbchan; | |
| 377 | − card->rb_timer.data = (unsigned long) card; | |
| 378 | 376 | card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; |
| 379 | 377 | add_timer(&card->rb_timer); |
| 380 | 378 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
| @@ -588,9 +586,10 @@ isdnloop_atimeout(isdnloop_card *card, int ch) · 207 unmodified lines | ||
| 588 | 586 | * Wrapper for isdnloop_atimeout(). |
| 589 | 587 | */ |
| 590 | 588 | static void |
| 591 | −isdnloop_atimeout0(unsigned long data) | |
| 589 | +isdnloop_atimeout0(struct timer_list *t) | |
| 592 | 590 | { |
| 593 | − isdnloop_card *card = (isdnloop_card *) data; | |
| 591 | + isdnloop_card *card = from_timer(card, t, c_timer[0]); | |
| 592 | + | |
| 594 | 593 | isdnloop_atimeout(card, 0); |
| 595 | 594 | } |
| 596 | 595 | |
| @@ -598,9 +597,10 @@ isdnloop_atimeout0(unsigned long data) · 1 unmodified line | ||
| 598 | 597 | * Wrapper for isdnloop_atimeout(). |
| 599 | 598 | */ |
| 600 | 599 | static void |
| 601 | −isdnloop_atimeout1(unsigned long data) | |
| 600 | +isdnloop_atimeout1(struct timer_list *t) | |
| 602 | 601 | { |
| 603 | − isdnloop_card *card = (isdnloop_card *) data; | |
| 602 | + isdnloop_card *card = from_timer(card, t, c_timer[1]); | |
| 603 | + | |
| 604 | 604 | isdnloop_atimeout(card, 1); |
| 605 | 605 | } |
| 606 | 606 | |
| @@ -617,13 +617,9 @@ isdnloop_start_ctimer(isdnloop_card *card, int ch) · 10 unmodified lines | ||
| 617 | 617 | unsigned long flags; |
| 618 | 618 | |
| 619 | 619 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
| 620 | − init_timer(&card->c_timer[ch]); | |
| 620 | + timer_setup(&card->c_timer[ch], ch ? isdnloop_atimeout1 | |
| 621 | + : isdnloop_atimeout0, 0); | |
| 621 | 622 | card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; |
| 622 | − if (ch) | |
| 623 | − card->c_timer[ch].function = isdnloop_atimeout1; | |
| 624 | − else | |
| 625 | − card->c_timer[ch].function = isdnloop_atimeout0; | |
| 626 | − card->c_timer[ch].data = (unsigned long) card; | |
| 627 | 623 | add_timer(&card->c_timer[ch]); |
| 628 | 624 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
| 629 | 625 | } |
| @@ -1113,10 +1109,9 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) · 483 unmodified lines | ||
| 1113 | 1109 | sdef.ptype); |
| 1114 | 1110 | return -EINVAL; |
| 1115 | 1111 | } |
| 1116 | − init_timer(&card->st_timer); | |
| 1112 | + timer_setup(&card->rb_timer, isdnloop_pollbchan, 0); | |
| 1113 | + timer_setup(&card->st_timer, isdnloop_polldchan, 0); | |
| 1117 | 1114 | card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD; |
| 1118 | − card->st_timer.function = isdnloop_polldchan; | |
| 1119 | − card->st_timer.data = (unsigned long) card; | |
| 1120 | 1115 | add_timer(&card->st_timer); |
| 1121 | 1116 | card->flags |= ISDNLOOP_FLAGS_RUNNING; |
| 1122 | 1117 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
| @@ -259,7 +259,7 @@ extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, · 258 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | extern int dsp_tone(struct dsp *dsp, int tone); |
| 261 | 261 | extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len); |
| 262 | −extern void dsp_tone_timeout(void *arg); | |
| 262 | +extern void dsp_tone_timeout(struct timer_list *t); | |
| 263 | 263 | |
| 264 | 264 | extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len); |
| 265 | 265 | extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len); |
| @@ -1092,7 +1092,7 @@ dspcreate(struct channel_req *crq) · 1091 unmodified lines | ||
| 1092 | 1092 | ndsp->pcm_bank_tx = -1; |
| 1093 | 1093 | ndsp->hfc_conf = -1; /* current conference number */ |
| 1094 | 1094 | /* set tone timer */ |
| 1095 | − setup_timer(&ndsp->tone.tl, (void *)dsp_tone_timeout, (long)ndsp); | |
| 1095 | + timer_setup(&ndsp->tone.tl, dsp_tone_timeout, 0); | |
| 1096 | 1096 | |
| 1097 | 1097 | if (dtmfthreshold < 20 || dtmfthreshold > 500) |
| 1098 | 1098 | dtmfthreshold = 200; |
| @@ -1202,9 +1202,7 @@ static int __init dsp_init(void) · 103 unmodified lines | ||
| 1202 | 1202 | } |
| 1203 | 1203 | |
| 1204 | 1204 | /* set sample timer */ |
| 1205 | − dsp_spl_tl.function = (void *)dsp_cmx_send; | |
| 1206 | − dsp_spl_tl.data = 0; | |
| 1207 | − init_timer(&dsp_spl_tl); | |
| 1205 | + timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0); | |
| 1208 | 1206 | dsp_spl_tl.expires = jiffies + dsp_tics; |
| 1209 | 1207 | dsp_spl_jiffies = dsp_spl_tl.expires; |
| 1210 | 1208 | add_timer(&dsp_spl_tl); |
| @@ -457,9 +457,9 @@ dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len) · 456 unmodified lines | ||
| 457 | 457 | * timer expires * |
| 458 | 458 | *****************/ |
| 459 | 459 | void |
| 460 | −dsp_tone_timeout(void *arg) | |
| 460 | +dsp_tone_timeout(struct timer_list *t) | |
| 461 | 461 | { |
| 462 | − struct dsp *dsp = arg; | |
| 462 | + struct dsp *dsp = from_timer(dsp, t, tone.tl); | |
| 463 | 463 | struct dsp_tone *tone = &dsp->tone; |
| 464 | 464 | struct pattern *pat = (struct pattern *)tone->pattern; |
| 465 | 465 | int index = tone->index; |
| @@ -478,7 +478,6 @@ dsp_tone_timeout(void *arg) · 12 unmodified lines | ||
| 478 | 478 | else |
| 479 | 479 | dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index])); |
| 480 | 480 | /* set timer */ |
| 481 | − init_timer(&tone->tl); | |
| 482 | 481 | tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000; |
| 483 | 482 | add_timer(&tone->tl); |
| 484 | 483 | } |
| @@ -541,7 +540,6 @@ dsp_tone(struct dsp *dsp, int tone) · 56 unmodified lines | ||
| 541 | 540 | /* set timer */ |
| 542 | 541 | if (timer_pending(&tonet->tl)) |
| 543 | 542 | del_timer(&tonet->tl); |
| 544 | − init_timer(&tonet->tl); | |
| 545 | 543 | tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000; |
| 546 | 544 | add_timer(&tonet->tl); |
| 547 | 545 | } else { |
| @@ -100,8 +100,9 @@ mISDN_FsmChangeState(struct FsmInst *fi, int newstate) · 99 unmodified lines | ||
| 100 | 100 | EXPORT_SYMBOL(mISDN_FsmChangeState); |
| 101 | 101 | |
| 102 | 102 | static void |
| 103 | −FsmExpireTimer(struct FsmTimer *ft) | |
| 103 | +FsmExpireTimer(struct timer_list *t) | |
| 104 | 104 | { |
| 105 | + struct FsmTimer *ft = from_timer(ft, t, tl); | |
| 105 | 106 | #if FSM_TIMER_DEBUG |
| 106 | 107 | if (ft->fi->debug) |
| 107 | 108 | ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft); |
| @@ -117,7 +118,7 @@ mISDN_FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft) · 9 unmodified lines | ||
| 117 | 118 | if (ft->fi->debug) |
| 118 | 119 | ft->fi->printdebug(ft->fi, "mISDN_FsmInitTimer %lx", (long) ft); |
| 119 | 120 | #endif |
| 120 | − setup_timer(&ft->tl, (void *)FsmExpireTimer, (long)ft); | |
| 121 | + timer_setup(&ft->tl, FsmExpireTimer, 0); | |
| 121 | 122 | } |
| 122 | 123 | EXPORT_SYMBOL(mISDN_FsmInitTimer); |
| 123 | 124 | |
| @@ -153,7 +154,6 @@ mISDN_FsmAddTimer(struct FsmTimer *ft, · 29 unmodified lines | ||
| 153 | 154 | } |
| 154 | 155 | return -1; |
| 155 | 156 | } |
| 156 | − init_timer(&ft->tl); | |
| 157 | 157 | ft->event = event; |
| 158 | 158 | ft->arg = arg; |
| 159 | 159 | ft->tl.expires = jiffies + (millisec * HZ) / 1000; |
| @@ -175,7 +175,6 @@ mISDN_FsmRestartTimer(struct FsmTimer *ft, · 15 unmodified lines | ||
| 175 | 175 | |
| 176 | 176 | if (timer_pending(&ft->tl)) |
| 177 | 177 | del_timer(&ft->tl); |
| 178 | − init_timer(&ft->tl); | |
| 179 | 178 | ft->event = event; |
| 180 | 179 | ft->arg = arg; |
| 181 | 180 | ft->tl.expires = jiffies + (millisec * HZ) / 1000; |
| @@ -440,14 +440,8 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase, · 439 unmodified lines | ||
| 440 | 440 | |
| 441 | 441 | #ifdef REORDER_DEBUG |
| 442 | 442 | if (hc->chan[channel].disorder_flag) { |
| 443 | − struct sk_buff *skb; | |
| 444 | − int cnt; | |
| 445 | − skb = hc->chan[channel].disorder_skb; | |
| 446 | − hc->chan[channel].disorder_skb = nskb; | |
| 447 | − nskb = skb; | |
| 448 | − cnt = hc->chan[channel].disorder_cnt; | |
| 449 | − hc->chan[channel].disorder_cnt = rx_counter; | |
| 450 | − rx_counter = cnt; | |
| 443 | + swap(hc->chan[channel].disorder_skb, nskb); | |
| 444 | + swap(hc->chan[channel].disorder_cnt, rx_counter); | |
| 451 | 445 | } |
| 452 | 446 | hc->chan[channel].disorder_flag ^= 1; |
| 453 | 447 | if (nskb) |
| @@ -842,17 +836,18 @@ l1oip_send_bh(struct work_struct *work) · 388 unmodified lines | ||
| 842 | 836 | * timer stuff |
| 843 | 837 | */ |
| 844 | 838 | static void |
| 845 | −l1oip_keepalive(void *data) | |
| 839 | +l1oip_keepalive(struct timer_list *t) | |
| 846 | 840 | { |
| 847 | − struct l1oip *hc = (struct l1oip *)data; | |
| 841 | + struct l1oip *hc = from_timer(hc, t, keep_tl); | |
| 848 | 842 | |
| 849 | 843 | schedule_work(&hc->workq); |
| 850 | 844 | } |
| 851 | 845 | |
| 852 | 846 | static void |
| 853 | −l1oip_timeout(void *data) | |
| 847 | +l1oip_timeout(struct timer_list *t) | |
| 854 | 848 | { |
| 855 | − struct l1oip *hc = (struct l1oip *)data; | |
| 849 | + struct l1oip *hc = from_timer(hc, t, | |
| 850 | + timeout_tl); | |
| 856 | 851 | struct dchannel *dch = hc->chan[hc->d_idx].dch; |
| 857 | 852 | |
| 858 | 853 | if (debug & DEBUG_L1OIP_MSG) |
| @@ -1437,13 +1432,11 @@ init_card(struct l1oip *hc, int pri, int bundle) · 578 unmodified lines | ||
| 1437 | 1432 | if (ret) |
| 1438 | 1433 | return ret; |
| 1439 | 1434 | |
| 1440 | − hc->keep_tl.function = (void *)l1oip_keepalive; | |
| 1441 | − hc->keep_tl.data = (ulong)hc; | |
| 1442 | − init_timer(&hc->keep_tl); | |
| 1435 | + timer_setup(&hc->keep_tl, l1oip_keepalive, 0); | |
| 1443 | 1436 | hc->keep_tl.expires = jiffies + 2 * HZ; /* two seconds first time */ |
| 1444 | 1437 | add_timer(&hc->keep_tl); |
| 1445 | 1438 | |
| 1446 | − setup_timer(&hc->timeout_tl, (void *)l1oip_timeout, (ulong)hc); | |
| 1439 | + timer_setup(&hc->timeout_tl, l1oip_timeout, 0); | |
| 1447 | 1440 | hc->timeout_on = 0; /* state that we have timer off */ |
| 1448 | 1441 | |
| 1449 | 1442 | return 0; |
| @@ -162,9 +162,9 @@ mISDN_poll(struct file *filep, poll_table *wait) · 161 unmodified lines | ||
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | static void |
| 165 | −dev_expire_timer(unsigned long data) | |
| 165 | +dev_expire_timer(struct timer_list *t) | |
| 166 | 166 | { |
| 167 | − struct mISDNtimer *timer = (void *)data; | |
| 167 | + struct mISDNtimer *timer = from_timer(timer, t, tl); | |
| 168 | 168 | u_long flags; |
| 169 | 169 | |
| 170 | 170 | spin_lock_irqsave(&timer->dev->lock, flags); |
| @@ -189,7 +189,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) · 18 unmodified lines | ||
| 189 | 189 | if (!timer) |
| 190 | 190 | return -ENOMEM; |
| 191 | 191 | timer->dev = dev; |
| 192 | − setup_timer(&timer->tl, dev_expire_timer, (long)timer); | |
| 192 | + timer_setup(&timer->tl, dev_expire_timer, 0); | |
| 193 | 193 | spin_lock_irq(&dev->lock); |
| 194 | 194 | id = timer->id = dev->next_id++; |
| 195 | 195 | if (dev->next_id < 0) |
| @@ -483,6 +483,18 @@ config FUJITSU_ES · 482 unmodified lines | ||
| 483 | 483 | This driver provides support for Extended Socket network device |
| 484 | 484 | on Extended Partitioning of FUJITSU PRIMEQUEST 2000 E2 series. |
| 485 | 485 | |
| 486 | +config THUNDERBOLT_NET | |
| 487 | + tristate "Networking over Thunderbolt cable" | |
| 488 | + depends on THUNDERBOLT && INET | |
| 489 | + help | |
| 490 | + Select this if you want to create network between two | |
| 491 | + computers over a Thunderbolt cable. The driver supports Apple | |
| 492 | + ThunderboltIP protocol and allows communication with any host | |
| 493 | + supporting the same protocol including Windows and macOS. | |
| 494 | + | |
| 495 | + To compile this driver a module, choose M here. The module will be | |
| 496 | + called thunderbolt-net. | |
| 497 | + | |
| 486 | 498 | source "drivers/net/hyperv/Kconfig" |
| 487 | 499 | |
| 488 | 500 | endif # NETDEVICES |
| @@ -75,3 +75,6 @@ obj-$(CONFIG_HYPERV_NET) += hyperv/ · 74 unmodified lines | ||
| 75 | 75 | obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o |
| 76 | 76 | |
| 77 | 77 | obj-$(CONFIG_FUJITSU_ES) += fjes/ |
| 78 | + | |
| 79 | +thunderbolt-net-y += thunderbolt.o | |
| 80 | +obj-$(CONFIG_THUNDERBOLT_NET) += thunderbolt-net.o | |
| @@ -155,6 +155,7 @@ static int cops_irqlist[] = { · 154 unmodified lines | ||
| 155 | 155 | }; |
| 156 | 156 | |
| 157 | 157 | static struct timer_list cops_timer; |
| 158 | +static struct net_device *cops_timer_dev; | |
| 158 | 159 | |
| 159 | 160 | /* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ |
| 160 | 161 | #ifndef COPS_DEBUG |
| @@ -187,7 +188,7 @@ static void cops_load (struct net_device *dev); · 26 unmodified lines | ||
| 187 | 188 | static int cops_nodeid (struct net_device *dev, int nodeid); |
| 188 | 189 | |
| 189 | 190 | static irqreturn_t cops_interrupt (int irq, void *dev_id); |
| 190 | −static void cops_poll (unsigned long ltdev); | |
| 191 | +static void cops_poll(struct timer_list *t); | |
| 191 | 192 | static void cops_timeout(struct net_device *dev); |
| 192 | 193 | static void cops_rx (struct net_device *dev); |
| 193 | 194 | static netdev_tx_t cops_send_packet (struct sk_buff *skb, |
| @@ -424,9 +425,8 @@ static int cops_open(struct net_device *dev) · 230 unmodified lines | ||
| 424 | 425 | */ |
| 425 | 426 | if(lp->board==TANGENT) /* Poll 20 times per second */ |
| 426 | 427 | { |
| 427 | − init_timer(&cops_timer); | |
| 428 | − cops_timer.function = cops_poll; | |
| 429 | − cops_timer.data = (unsigned long)dev; | |
| 428 | + cops_timer_dev = dev; | |
| 429 | + timer_setup(&cops_timer, cops_poll, 0); | |
| 430 | 430 | cops_timer.expires = jiffies + HZ/20; |
| 431 | 431 | add_timer(&cops_timer); |
| 432 | 432 | } |
| @@ -673,12 +673,11 @@ static int cops_nodeid (struct net_device *dev, int nodeid) · 240 unmodified lines | ||
| 673 | 673 | * Poll the Tangent type cards to see if we have work. |
| 674 | 674 | */ |
| 675 | 675 | |
| 676 | −static void cops_poll(unsigned long ltdev) | |
| 676 | +static void cops_poll(struct timer_list *unused) | |
| 677 | 677 | { |
| 678 | 678 | int ioaddr, status; |
| 679 | 679 | int boguscount = 0; |
| 680 | − | |
| 681 | − struct net_device *dev = (struct net_device *)ltdev; | |
| 680 | + struct net_device *dev = cops_timer_dev; | |
| 682 | 681 | |
| 683 | 682 | del_timer(&cops_timer); |
| 684 | 683 | |
| @@ -694,6 +694,7 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen, · 693 unmodified lines | ||
| 694 | 694 | /* end of idle handlers -- what should be seen is do_read, do_write */ |
| 695 | 695 | |
| 696 | 696 | static struct timer_list ltpc_timer; |
| 697 | +static struct net_device *ltpc_timer_dev; | |
| 697 | 698 | |
| 698 | 699 | static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev); |
| 699 | 700 | |
| @@ -867,10 +868,8 @@ static void set_multicast_list(struct net_device *dev) · 167 unmodified lines | ||
| 867 | 868 | |
| 868 | 869 | static int ltpc_poll_counter; |
| 869 | 870 | |
| 870 | −static void ltpc_poll(unsigned long l) | |
| 871 | +static void ltpc_poll(struct timer_list *unused) | |
| 871 | 872 | { |
| 872 | − struct net_device *dev = (struct net_device *) l; | |
| 873 | − | |
| 874 | 873 | del_timer(<pc_timer); |
| 875 | 874 | |
| 876 | 875 | if(debug & DEBUG_VERBOSE) { |
| @@ -880,14 +879,10 @@ static void ltpc_poll(unsigned long l) · 3 unmodified lines | ||
| 880 | 879 | } |
| 881 | 880 | ltpc_poll_counter--; |
| 882 | 881 | } |
| 883 | − | |
| 884 | − if (!dev) | |
| 885 | − return; /* we've been downed */ | |
| 886 | 882 | |
| 887 | 883 | /* poll 20 times per second */ |
| 888 | − idle(dev); | |
| 884 | + idle(ltpc_timer_dev); | |
| 889 | 885 | ltpc_timer.expires = jiffies + HZ/20; |
| 890 | − | |
| 891 | 886 | add_timer(<pc_timer); |
| 892 | 887 | } |
| 893 | 888 | |
| @@ -1165,9 +1160,8 @@ struct net_device * __init ltpc_probe(void) · 271 unmodified lines | ||
| 1165 | 1160 | dev->irq = 0; |
| 1166 | 1161 | /* polled mode -- 20 times per second */ |
| 1167 | 1162 | /* this is really, really slow... should it poll more often? */ |
| 1168 | − init_timer(<pc_timer); | |
| 1169 | − ltpc_timer.function=ltpc_poll; | |
| 1170 | − ltpc_timer.data = (unsigned long) dev; | |
| 1163 | + ltpc_timer_dev = dev; | |
| 1164 | + timer_setup(<pc_timer, ltpc_poll, 0); | |
| 1171 | 1165 | |
| 1172 | 1166 | ltpc_timer.expires = jiffies + HZ/20; |
| 1173 | 1167 | add_timer(<pc_timer); |
| @@ -1254,8 +1248,6 @@ static void __exit ltpc_cleanup(void) · 80 unmodified lines | ||
| 1254 | 1248 | if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); |
| 1255 | 1249 | unregister_netdev(dev_ltpc); |
| 1256 | 1250 | |
| 1257 | − ltpc_timer.data = 0; /* signal the poll routine that we're done */ | |
| 1258 | − | |
| 1259 | 1251 | del_timer_sync(<pc_timer); |
| 1260 | 1252 | |
| 1261 | 1253 | if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); |
| @@ -382,9 +382,10 @@ static void arcdev_setup(struct net_device *dev) · 381 unmodified lines | ||
| 382 | 382 | dev->flags = IFF_BROADCAST; |
| 383 | 383 | } |
| 384 | 384 | |
| 385 | −static void arcnet_timer(unsigned long data) | |
| 385 | +static void arcnet_timer(struct timer_list *t) | |
| 386 | 386 | { |
| 387 | − struct net_device *dev = (struct net_device *)data; | |
| 387 | + struct arcnet_local *lp = from_timer(lp, t, timer); | |
| 388 | + struct net_device *dev = lp->dev; | |
| 388 | 389 | |
| 389 | 390 | if (!netif_carrier_ok(dev)) { |
| 390 | 391 | netif_carrier_on(dev); |
| @@ -450,9 +451,7 @@ struct net_device *alloc_arcdev(const char *name) · 59 unmodified lines | ||
| 450 | 451 | |
| 451 | 452 | lp->dev = dev; |
| 452 | 453 | spin_lock_init(&lp->lock); |
| 453 | − init_timer(&lp->timer); | |
| 454 | − lp->timer.data = (unsigned long) dev; | |
| 455 | − lp->timer.function = arcnet_timer; | |
| 454 | + timer_setup(&lp->timer, arcnet_timer, 0); | |
| 456 | 455 | } |
| 457 | 456 | |
| 458 | 457 | return dev; |
| @@ -1217,25 +1217,21 @@ static enum netdev_lag_tx_type bond_lag_tx_type(struct bonding *bond) · 1216 unmodified lines | ||
| 1217 | 1217 | } |
| 1218 | 1218 | } |
| 1219 | 1219 | |
| 1220 | −static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave) | |
| 1220 | +static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave, | |
| 1221 | + struct netlink_ext_ack *extack) | |
| 1221 | 1222 | { |
| 1222 | 1223 | struct netdev_lag_upper_info lag_upper_info; |
| 1223 | − int err; | |
| 1224 | 1224 | |
| 1225 | 1225 | lag_upper_info.tx_type = bond_lag_tx_type(bond); |
| 1226 | − err = netdev_master_upper_dev_link(slave->dev, bond->dev, slave, | |
| 1227 | − &lag_upper_info); | |
| 1228 | − if (err) | |
| 1229 | − return err; | |
| 1230 | − rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL); | |
| 1231 | − return 0; | |
| 1226 | + | |
| 1227 | + return netdev_master_upper_dev_link(slave->dev, bond->dev, slave, | |
| 1228 | + &lag_upper_info, extack); | |
| 1232 | 1229 | } |
| 1233 | 1230 | |
| 1234 | 1231 | static void bond_upper_dev_unlink(struct bonding *bond, struct slave *slave) |
| 1235 | 1232 | { |
| 1236 | 1233 | netdev_upper_dev_unlink(slave->dev, bond->dev); |
| 1237 | 1234 | slave->dev->flags &= ~IFF_SLAVE; |
| 1238 | − rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL); | |
| 1239 | 1235 | } |
| 1240 | 1236 | |
| 1241 | 1237 | static struct slave *bond_alloc_slave(struct bonding *bond) |
| @@ -1328,7 +1324,8 @@ void bond_lower_state_changed(struct slave *slave) · 86 unmodified lines | ||
| 1328 | 1324 | } |
| 1329 | 1325 | |
| 1330 | 1326 | /* enslave device <slave> to bond device <master> */ |
| 1331 | −int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |
| 1327 | +int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, | |
| 1328 | + struct netlink_ext_ack *extack) | |
| 1332 | 1329 | { |
| 1333 | 1330 | struct bonding *bond = netdev_priv(bond_dev); |
| 1334 | 1331 | const struct net_device_ops *slave_ops = slave_dev->netdev_ops; |
| @@ -1346,12 +1343,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 11 unmodified lines | ||
| 1346 | 1343 | |
| 1347 | 1344 | /* already in-use? */ |
| 1348 | 1345 | if (netdev_is_rx_handler_busy(slave_dev)) { |
| 1346 | + NL_SET_ERR_MSG(extack, "Device is in use and cannot be enslaved"); | |
| 1349 | 1347 | netdev_err(bond_dev, |
| 1350 | 1348 | "Error: Device is in use and cannot be enslaved\n"); |
| 1351 | 1349 | return -EBUSY; |
| 1352 | 1350 | } |
| 1353 | 1351 | |
| 1354 | 1352 | if (bond_dev == slave_dev) { |
| 1353 | + NL_SET_ERR_MSG(extack, "Cannot enslave bond to itself."); | |
| 1355 | 1354 | netdev_err(bond_dev, "cannot enslave bond to itself.\n"); |
| 1356 | 1355 | return -EPERM; |
| 1357 | 1356 | } |
| @@ -1362,6 +1361,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 4 unmodified lines | ||
| 1362 | 1361 | netdev_dbg(bond_dev, "%s is NETIF_F_VLAN_CHALLENGED\n", |
| 1363 | 1362 | slave_dev->name); |
| 1364 | 1363 | if (vlan_uses_dev(bond_dev)) { |
| 1364 | + NL_SET_ERR_MSG(extack, "Can not enslave VLAN challenged device to VLAN enabled bond"); | |
| 1365 | 1365 | netdev_err(bond_dev, "Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", |
| 1366 | 1366 | slave_dev->name, bond_dev->name); |
| 1367 | 1367 | return -EPERM; |
| @@ -1381,6 +1381,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 13 unmodified lines | ||
| 1381 | 1381 | * enslaving it; the old ifenslave will not. |
| 1382 | 1382 | */ |
| 1383 | 1383 | if (slave_dev->flags & IFF_UP) { |
| 1384 | + NL_SET_ERR_MSG(extack, "Device can not be enslaved while up"); | |
| 1384 | 1385 | netdev_err(bond_dev, "%s is up - this may be due to an out of date ifenslave\n", |
| 1385 | 1386 | slave_dev->name); |
| 1386 | 1387 | return -EPERM; |
| @@ -1421,6 +1422,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 34 unmodified lines | ||
| 1421 | 1422 | bond_dev); |
| 1422 | 1423 | } |
| 1423 | 1424 | } else if (bond_dev->type != slave_dev->type) { |
| 1425 | + NL_SET_ERR_MSG(extack, "Device type is different from other slaves"); | |
| 1424 | 1426 | netdev_err(bond_dev, "%s ether type (%d) is different from other slaves (%d), can not enslave it\n", |
| 1425 | 1427 | slave_dev->name, slave_dev->type, bond_dev->type); |
| 1426 | 1428 | return -EINVAL; |
| @@ -1428,6 +1430,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 1 unmodified line | ||
| 1428 | 1430 | |
| 1429 | 1431 | if (slave_dev->type == ARPHRD_INFINIBAND && |
| 1430 | 1432 | BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { |
| 1433 | + NL_SET_ERR_MSG(extack, "Only active-backup mode is supported for infiniband slaves"); | |
| 1431 | 1434 | netdev_warn(bond_dev, "Type (%d) supports only active-backup mode\n", |
| 1432 | 1435 | slave_dev->type); |
| 1433 | 1436 | res = -EOPNOTSUPP; |
| @@ -1443,6 +1446,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 9 unmodified lines | ||
| 1443 | 1446 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; |
| 1444 | 1447 | netdev_warn(bond_dev, "Setting fail_over_mac to active for active-backup mode\n"); |
| 1445 | 1448 | } else { |
| 1449 | + NL_SET_ERR_MSG(extack, "Slave device does not support setting the MAC address, but fail_over_mac is not set to active"); | |
| 1446 | 1450 | netdev_err(bond_dev, "The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active\n"); |
| 1447 | 1451 | res = -EOPNOTSUPP; |
| 1448 | 1452 | goto err_undo_flags; |
| @@ -1709,7 +1713,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) · 260 unmodified lines | ||
| 1709 | 1713 | goto err_detach; |
| 1710 | 1714 | } |
| 1711 | 1715 | |
| 1712 | − res = bond_master_upper_dev_link(bond, new_slave); | |
| 1716 | + res = bond_master_upper_dev_link(bond, new_slave, extack); | |
| 1713 | 1717 | if (res) { |
| 1714 | 1718 | netdev_dbg(bond_dev, "Error %d calling bond_master_upper_dev_link\n", res); |
| 1715 | 1719 | goto err_unregister; |
| @@ -2492,7 +2496,8 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, · 776 unmodified lines | ||
| 2492 | 2496 | struct slave *curr_active_slave, *curr_arp_slave; |
| 2493 | 2497 | unsigned char *arp_ptr; |
| 2494 | 2498 | __be32 sip, tip; |
| 2495 | − int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP); | |
| 2499 | + int is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP); | |
| 2500 | + unsigned int alen; | |
| 2496 | 2501 | |
| 2497 | 2502 | if (!slave_do_arp_validate(bond, slave)) { |
| 2498 | 2503 | if ((slave_do_arp_validate_only(bond) && is_arp) || |
| @@ -3073,7 +3078,16 @@ static int bond_slave_netdev_event(unsigned long event, · 574 unmodified lines | ||
| 3073 | 3078 | break; |
| 3074 | 3079 | case NETDEV_UP: |
| 3075 | 3080 | case NETDEV_CHANGE: |
| 3076 | − bond_update_speed_duplex(slave); | |
| 3081 | + /* For 802.3ad mode only: | |
| 3082 | + * Getting invalid Speed/Duplex values here will put slave | |
| 3083 | + * in weird state. So mark it as link-down for the time | |
| 3084 | + * being and let link-monitoring (miimon) set it right when | |
| 3085 | + * correct speeds/duplex are available. | |
| 3086 | + */ | |
| 3087 | + if (bond_update_speed_duplex(slave) && | |
| 3088 | + BOND_MODE(bond) == BOND_MODE_8023AD) | |
| 3089 | + slave->link = BOND_LINK_DOWN; | |
| 3090 | + | |
| 3077 | 3091 | if (BOND_MODE(bond) == BOND_MODE_8023AD) |
| 3078 | 3092 | bond_3ad_adapter_speed_duplex_changed(slave); |
| 3079 | 3093 | /* Fallthrough */ |
| @@ -3483,7 +3497,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd · 403 unmodified lines | ||
| 3483 | 3497 | switch (cmd) { |
| 3484 | 3498 | case BOND_ENSLAVE_OLD: |
| 3485 | 3499 | case SIOCBONDENSLAVE: |
| 3486 | − res = bond_enslave(bond_dev, slave_dev); | |
| 3500 | + res = bond_enslave(bond_dev, slave_dev, NULL); | |
| 3487 | 3501 | break; |
| 3488 | 3502 | case BOND_RELEASE_OLD: |
| 3489 | 3503 | case SIOCBONDRELEASE: |
| @@ -1383,7 +1383,7 @@ static int bond_option_slaves_set(struct bonding *bond, · 1382 unmodified lines | ||
| 1383 | 1383 | switch (command[0]) { |
| 1384 | 1384 | case '+': |
| 1385 | 1385 | netdev_dbg(bond->dev, "Adding slave %s\n", dev->name); |
| 1386 | − ret = bond_enslave(bond->dev, dev); | |
| 1386 | + ret = bond_enslave(bond->dev, dev, NULL); | |
| 1387 | 1387 | break; |
| 1388 | 1388 | |
| 1389 | 1389 | case '-': |
| @@ -1211,17 +1211,14 @@ static int cfhsi_open(struct net_device *ndev) · 1210 unmodified lines | ||
| 1211 | 1211 | init_waitqueue_head(&cfhsi->flush_fifo_wait); |
| 1212 | 1212 | |
| 1213 | 1213 | /* Setup the inactivity timer. */ |
| 1214 | − init_timer(&cfhsi->inactivity_timer); | |
| 1215 | − cfhsi->inactivity_timer.data = (unsigned long)cfhsi; | |
| 1216 | − cfhsi->inactivity_timer.function = cfhsi_inactivity_tout; | |
| 1214 | + setup_timer(&cfhsi->inactivity_timer, cfhsi_inactivity_tout, | |
| 1215 | + (unsigned long)cfhsi); | |
| 1217 | 1216 | /* Setup the slowpath RX timer. */ |
| 1218 | − init_timer(&cfhsi->rx_slowpath_timer); | |
| 1219 | − cfhsi->rx_slowpath_timer.data = (unsigned long)cfhsi; | |
| 1220 | − cfhsi->rx_slowpath_timer.function = cfhsi_rx_slowpath; | |
| 1217 | + setup_timer(&cfhsi->rx_slowpath_timer, cfhsi_rx_slowpath, | |
| 1218 | + (unsigned long)cfhsi); | |
| 1221 | 1219 | /* Setup the aggregation timer. */ |
| 1222 | − init_timer(&cfhsi->aggregation_timer); | |
| 1223 | − cfhsi->aggregation_timer.data = (unsigned long)cfhsi; | |
| 1224 | − cfhsi->aggregation_timer.function = cfhsi_aggregation_tout; | |
| 1220 | + setup_timer(&cfhsi->aggregation_timer, cfhsi_aggregation_tout, | |
| 1221 | + (unsigned long)cfhsi); | |
| 1225 | 1222 | |
| 1226 | 1223 | /* Activate HSI interface. */ |
| 1227 | 1224 | res = cfhsi->ops->cfhsi_up(cfhsi->ops); |
| @@ -807,10 +807,10 @@ static irqreturn_t grcan_interrupt(int irq, void *dev_id) · 806 unmodified lines | ||
| 807 | 807 | * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug |
| 808 | 808 | * for single shot) |
| 809 | 809 | */ |
| 810 | −static void grcan_running_reset(unsigned long data) | |
| 810 | +static void grcan_running_reset(struct timer_list *t) | |
| 811 | 811 | { |
| 812 | − struct net_device *dev = (struct net_device *)data; | |
| 813 | − struct grcan_priv *priv = netdev_priv(dev); | |
| 812 | + struct grcan_priv *priv = from_timer(priv, t, rr_timer); | |
| 813 | + struct net_device *dev = priv->dev; | |
| 814 | 814 | struct grcan_registers __iomem *regs = priv->regs; |
| 815 | 815 | unsigned long flags; |
| 816 | 816 | |
| @@ -898,10 +898,10 @@ static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate) · 81 unmodified lines | ||
| 898 | 898 | } |
| 899 | 899 | |
| 900 | 900 | /* Disable channels and schedule a running reset */ |
| 901 | −static void grcan_initiate_running_reset(unsigned long data) | |
| 901 | +static void grcan_initiate_running_reset(struct timer_list *t) | |
| 902 | 902 | { |
| 903 | − struct net_device *dev = (struct net_device *)data; | |
| 904 | − struct grcan_priv *priv = netdev_priv(dev); | |
| 903 | + struct grcan_priv *priv = from_timer(priv, t, hang_timer); | |
| 904 | + struct net_device *dev = priv->dev; | |
| 905 | 905 | struct grcan_registers __iomem *regs = priv->regs; |
| 906 | 906 | unsigned long flags; |
| 907 | 907 | |
| @@ -1626,13 +1626,8 @@ static int grcan_setup_netdev(struct platform_device *ofdev, · 718 unmodified lines | ||
| 1626 | 1626 | spin_lock_init(&priv->lock); |
| 1627 | 1627 | |
| 1628 | 1628 | if (priv->need_txbug_workaround) { |
| 1629 | − init_timer(&priv->rr_timer); | |
| 1630 | − priv->rr_timer.function = grcan_running_reset; | |
| 1631 | − priv->rr_timer.data = (unsigned long)dev; | |
| 1632 | − | |
| 1633 | − init_timer(&priv->hang_timer); | |
| 1634 | − priv->hang_timer.function = grcan_initiate_running_reset; | |
| 1635 | − priv->hang_timer.data = (unsigned long)dev; | |
| 1629 | + timer_setup(&priv->rr_timer, grcan_running_reset, 0); | |
| 1630 | + timer_setup(&priv->hang_timer, grcan_initiate_running_reset, 0); | |
| 1636 | 1631 | } |
| 1637 | 1632 | |
| 1638 | 1633 | netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT); |
| @@ -381,9 +381,9 @@ static inline void pcan_set_can_power(struct pcan_pccard *card, int onoff) · 380 unmodified lines | ||
| 381 | 381 | /* |
| 382 | 382 | * set leds state according to channel activity |
| 383 | 383 | */ |
| 384 | −static void pcan_led_timer(unsigned long arg) | |
| 384 | +static void pcan_led_timer(struct timer_list *t) | |
| 385 | 385 | { |
| 386 | − struct pcan_pccard *card = (struct pcan_pccard *)arg; | |
| 386 | + struct pcan_pccard *card = from_timer(card, t, led_timer); | |
| 387 | 387 | struct net_device *netdev; |
| 388 | 388 | int i, up_count = 0; |
| 389 | 389 | u8 ccr; |
| @@ -692,9 +692,7 @@ static int pcan_probe(struct pcmcia_device *pdev) · 302 unmodified lines | ||
| 692 | 692 | } |
| 693 | 693 | |
| 694 | 694 | /* init the timer which controls the leds */ |
| 695 | − init_timer(&card->led_timer); | |
| 696 | − card->led_timer.function = pcan_led_timer; | |
| 697 | − card->led_timer.data = (unsigned long)card; | |
| 695 | + timer_setup(&card->led_timer, pcan_led_timer, 0); | |
| 698 | 696 | |
| 699 | 697 | /* request the given irq */ |
| 700 | 698 | err = request_irq(pdev->irq, &pcan_isr, IRQF_SHARED, PCC_NAME, card); |
| @@ -259,10 +259,13 @@ static int pcan_usb_write_mode(struct peak_usb_device *dev, u8 onoff) · 258 unmodified lines | ||
| 259 | 259 | /* |
| 260 | 260 | * handle end of waiting for the device to reset |
| 261 | 261 | */ |
| 262 | −static void pcan_usb_restart(unsigned long arg) | |
| 262 | +static void pcan_usb_restart(struct timer_list *t) | |
| 263 | 263 | { |
| 264 | + struct pcan_usb *pdev = from_timer(pdev, t, restart_timer); | |
| 265 | + struct peak_usb_device *dev = &pdev->dev; | |
| 266 | + | |
| 264 | 267 | /* notify candev and netdev */ |
| 265 | − peak_usb_restart_complete((struct peak_usb_device *)arg); | |
| 268 | + peak_usb_restart_complete(dev); | |
| 266 | 269 | } |
| 267 | 270 | |
| 268 | 271 | /* |
| @@ -798,9 +801,7 @@ static int pcan_usb_init(struct peak_usb_device *dev) · 529 unmodified lines | ||
| 798 | 801 | int err; |
| 799 | 802 | |
| 800 | 803 | /* initialize a timer needed to wait for hardware restart */ |
| 801 | − init_timer(&pdev->restart_timer); | |
| 802 | − pdev->restart_timer.function = pcan_usb_restart; | |
| 803 | − pdev->restart_timer.data = (unsigned long)dev; | |
| 804 | + timer_setup(&pdev->restart_timer, pcan_usb_restart, 0); | |
| 804 | 805 | |
| 805 | 806 | /* |
| 806 | 807 | * explicit use of dev_xxx() instead of netdev_xxx() here: |
| @@ -1,6 +1,8 @@ | ||
| 1 | 1 | menuconfig B53 |
| 2 | 2 | tristate "Broadcom BCM53xx managed switch support" |
| 3 | 3 | depends on NET_DSA |
| 4 | + select NET_DSA_TAG_BRCM | |
| 5 | + select NET_DSA_TAG_BRCM_PREPEND | |
| 4 | 6 | help |
| 5 | 7 | This driver adds support for Broadcom managed switch chips. It supports |
| 6 | 8 | BCM5325E, BCM5365, BCM539x, BCM53115 and BCM53125 as well as BCM63XX |
| @@ -325,7 +325,6 @@ static void b53_get_vlan_entry(struct b53_device *dev, u16 vid, · 324 unmodified lines | ||
| 325 | 325 | |
| 326 | 326 | static void b53_set_forwarding(struct b53_device *dev, int enable) |
| 327 | 327 | { |
| 328 | − struct dsa_switch *ds = dev->ds; | |
| 329 | 328 | u8 mgmt; |
| 330 | 329 | |
| 331 | 330 | b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); |
| @@ -337,14 +336,11 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) · 5 unmodified lines | ||
| 337 | 336 | |
| 338 | 337 | b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); |
| 339 | 338 | |
| 340 | − /* Include IMP port in dumb forwarding mode when no tagging protocol is | |
| 341 | − * set | |
| 339 | + /* Include IMP port in dumb forwarding mode | |
| 342 | 340 | */ |
| 343 | − if (ds->ops->get_tag_protocol(ds) == DSA_TAG_PROTO_NONE) { | |
| 344 | − b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); | |
| 345 | − mgmt |= B53_MII_DUMB_FWDG_EN; | |
| 346 | − b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); | |
| 347 | − } | |
| 341 | + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); | |
| 342 | + mgmt |= B53_MII_DUMB_FWDG_EN; | |
| 343 | + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); | |
| 348 | 344 | } |
| 349 | 345 | |
| 350 | 346 | static void b53_enable_vlan(struct b53_device *dev, bool enable) |
| @@ -484,7 +480,7 @@ static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) · 133 unmodified lines | ||
| 484 | 480 | return b53_flush_arl(dev, FAST_AGE_VLAN); |
| 485 | 481 | } |
| 486 | 482 | |
| 487 | −static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) | |
| 483 | +void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) | |
| 488 | 484 | { |
| 489 | 485 | struct b53_device *dev = ds->priv; |
| 490 | 486 | unsigned int i; |
| @@ -500,12 +496,12 @@ static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) · 9 unmodified lines | ||
| 500 | 496 | b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), pvlan); |
| 501 | 497 | } |
| 502 | 498 | } |
| 499 | +EXPORT_SYMBOL(b53_imp_vlan_setup); | |
| 503 | 500 | |
| 504 | −static int b53_enable_port(struct dsa_switch *ds, int port, | |
| 505 | − struct phy_device *phy) | |
| 501 | +int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) | |
| 506 | 502 | { |
| 507 | 503 | struct b53_device *dev = ds->priv; |
| 508 | − unsigned int cpu_port = dev->cpu_port; | |
| 504 | + unsigned int cpu_port = ds->ports[port].cpu_dp->index; | |
| 509 | 505 | u16 pvlan; |
| 510 | 506 | |
| 511 | 507 | /* Clear the Rx and Tx disable bits and set to no spanning tree */ |
| @@ -523,11 +519,15 @@ static int b53_enable_port(struct dsa_switch *ds, int port, · 11 unmodified lines | ||
| 523 | 519 | |
| 524 | 520 | b53_imp_vlan_setup(ds, cpu_port); |
| 525 | 521 | |
| 522 | + /* If EEE was enabled, restore it */ | |
| 523 | + if (dev->ports[port].eee.eee_enabled) | |
| 524 | + b53_eee_enable_set(ds, port, true); | |
| 525 | + | |
| 526 | 526 | return 0; |
| 527 | 527 | } |
| 528 | +EXPORT_SYMBOL(b53_enable_port); | |
| 528 | 529 | |
| 529 | −static void b53_disable_port(struct dsa_switch *ds, int port, | |
| 530 | − struct phy_device *phy) | |
| 530 | +void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy) | |
| 531 | 531 | { |
| 532 | 532 | struct b53_device *dev = ds->priv; |
| 533 | 533 | u8 reg; |
| @@ -537,20 +537,80 @@ static void b53_disable_port(struct dsa_switch *ds, int port, · 3 unmodified lines | ||
| 537 | 537 | reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; |
| 538 | 538 | b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); |
| 539 | 539 | } |
| 540 | +EXPORT_SYMBOL(b53_disable_port); | |
| 540 | 541 | |
| 541 | −static void b53_enable_cpu_port(struct b53_device *dev) | |
| 542 | +void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) | |
| 543 | +{ | |
| 544 | + bool tag_en = !(ds->ops->get_tag_protocol(ds, port) == | |
| 545 | + DSA_TAG_PROTO_NONE); | |
| 546 | + struct b53_device *dev = ds->priv; | |
| 547 | + u8 hdr_ctl, val; | |
| 548 | + u16 reg; | |
| 549 | + | |
| 550 | + /* Resolve which bit controls the Broadcom tag */ | |
| 551 | + switch (port) { | |
| 552 | + case 8: | |
| 553 | + val = BRCM_HDR_P8_EN; | |
| 554 | + break; | |
| 555 | + case 7: | |
| 556 | + val = BRCM_HDR_P7_EN; | |
| 557 | + break; | |
| 558 | + case 5: | |
| 559 | + val = BRCM_HDR_P5_EN; | |
| 560 | + break; | |
| 561 | + default: | |
| 562 | + val = 0; | |
| 563 | + break; | |
| 564 | + } | |
| 565 | + | |
| 566 | + /* Enable Broadcom tags for IMP port */ | |
| 567 | + b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl); | |
| 568 | + if (tag_en) | |
| 569 | + hdr_ctl |= val; | |
| 570 | + else | |
| 571 | + hdr_ctl &= ~val; | |
| 572 | + b53_write8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, hdr_ctl); | |
| 573 | + | |
| 574 | + /* Registers below are only accessible on newer devices */ | |
| 575 | + if (!is58xx(dev)) | |
| 576 | + return; | |
| 577 | + | |
| 578 | + /* Enable reception Broadcom tag for CPU TX (switch RX) to | |
| 579 | + * allow us to tag outgoing frames | |
| 580 | + */ | |
| 581 | + b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, ®); | |
| 582 | + if (tag_en) | |
| 583 | + reg &= ~BIT(port); | |
| 584 | + else | |
| 585 | + reg |= BIT(port); | |
| 586 | + b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, reg); | |
| 587 | + | |
| 588 | + /* Enable transmission of Broadcom tags from the switch (CPU RX) to | |
| 589 | + * allow delivering frames to the per-port net_devices | |
| 590 | + */ | |
| 591 | + b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, ®); | |
| 592 | + if (tag_en) | |
| 593 | + reg &= ~BIT(port); | |
| 594 | + else | |
| 595 | + reg |= BIT(port); | |
| 596 | + b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, reg); | |
| 597 | +} | |
| 598 | +EXPORT_SYMBOL(b53_brcm_hdr_setup); | |
| 599 | + | |
| 600 | +static void b53_enable_cpu_port(struct b53_device *dev, int port) | |
| 542 | 601 | { |
| 543 | − unsigned int cpu_port = dev->cpu_port; | |
| 544 | 602 | u8 port_ctrl; |
| 545 | 603 | |
| 546 | 604 | /* BCM5325 CPU port is at 8 */ |
| 547 | − if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25) | |
| 548 | − cpu_port = B53_CPU_PORT; | |
| 605 | + if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25) | |
| 606 | + port = B53_CPU_PORT; | |
| 549 | 607 | |
| 550 | 608 | port_ctrl = PORT_CTRL_RX_BCST_EN | |
| 551 | 609 | PORT_CTRL_RX_MCST_EN | |
| 552 | 610 | PORT_CTRL_RX_UCST_EN; |
| 553 | − b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl); | |
| 611 | + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl); | |
| 612 | + | |
| 613 | + b53_brcm_hdr_setup(dev->ds, port); | |
| 554 | 614 | } |
| 555 | 615 | |
| 556 | 616 | static void b53_enable_mib(struct b53_device *dev) |
| @@ -562,8 +622,9 @@ static void b53_enable_mib(struct b53_device *dev) · 5 unmodified lines | ||
| 562 | 622 | b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); |
| 563 | 623 | } |
| 564 | 624 | |
| 565 | −static int b53_configure_vlan(struct b53_device *dev) | |
| 625 | +int b53_configure_vlan(struct dsa_switch *ds) | |
| 566 | 626 | { |
| 627 | + struct b53_device *dev = ds->priv; | |
| 567 | 628 | struct b53_vlan vl = { 0 }; |
| 568 | 629 | int i; |
| 569 | 630 | |
| @@ -586,6 +647,7 @@ static int b53_configure_vlan(struct b53_device *dev) · 16 unmodified lines | ||
| 586 | 647 | |
| 587 | 648 | return 0; |
| 588 | 649 | } |
| 650 | +EXPORT_SYMBOL(b53_configure_vlan); | |
| 589 | 651 | |
| 590 | 652 | static void b53_switch_reset_gpio(struct b53_device *dev) |
| 591 | 653 | { |
| @@ -700,7 +762,7 @@ static int b53_apply_config(struct b53_device *priv) · 108 unmodified lines | ||
| 700 | 762 | /* disable switching */ |
| 701 | 763 | b53_set_forwarding(priv, 0); |
| 702 | 764 | |
| 703 | − b53_configure_vlan(priv); | |
| 765 | + b53_configure_vlan(priv->ds); | |
| 704 | 766 | |
| 705 | 767 | /* enable switching */ |
| 706 | 768 | b53_set_forwarding(priv, 1); |
| @@ -816,12 +878,13 @@ static int b53_setup(struct dsa_switch *ds) · 109 unmodified lines | ||
| 816 | 878 | if (ret) |
| 817 | 879 | dev_err(ds->dev, "failed to apply configuration\n"); |
| 818 | 880 | |
| 881 | + /* Configure IMP/CPU port, disable unused ports. Enabled | |
| 882 | + * ports will be configured with .port_enable | |
| 883 | + */ | |
| 819 | 884 | for (port = 0; port < dev->num_ports; port++) { |
| 820 | − if (BIT(port) & ds->enabled_port_mask) | |
| 821 | − b53_enable_port(ds, port, NULL); | |
| 822 | − else if (dsa_is_cpu_port(ds, port)) | |
| 823 | − b53_enable_cpu_port(dev); | |
| 824 | − else | |
| 885 | + if (dsa_is_cpu_port(ds, port)) | |
| 886 | + b53_enable_cpu_port(dev, port); | |
| 887 | + else if (dsa_is_unused_port(ds, port)) | |
| 825 | 888 | b53_disable_port(ds, port, NULL); |
| 826 | 889 | } |
| 827 | 890 | |
| @@ -832,6 +895,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, · 4 unmodified lines | ||
| 832 | 895 | struct phy_device *phydev) |
| 833 | 896 | { |
| 834 | 897 | struct b53_device *dev = ds->priv; |
| 898 | + struct ethtool_eee *p = &dev->ports[port].eee; | |
| 835 | 899 | u8 rgmii_ctrl = 0, reg = 0, off; |
| 836 | 900 | |
| 837 | 901 | if (!phy_is_pseudo_fixed_link(phydev)) |
| @@ -953,6 +1017,9 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, · 115 unmodified lines | ||
| 953 | 1017 | b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); |
| 954 | 1018 | } |
| 955 | 1019 | } |
| 1020 | + | |
| 1021 | + /* Re-negotiate EEE if it was enabled already */ | |
| 1022 | + p->eee_enabled = b53_eee_init(ds, port, phydev); | |
| 956 | 1023 | } |
| 957 | 1024 | |
| 958 | 1025 | int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering) |
| @@ -986,7 +1053,6 @@ void b53_vlan_add(struct dsa_switch *ds, int port, · 27 unmodified lines | ||
| 986 | 1053 | struct b53_device *dev = ds->priv; |
| 987 | 1054 | bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
| 988 | 1055 | bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; |
| 989 | − unsigned int cpu_port = dev->cpu_port; | |
| 990 | 1056 | struct b53_vlan *vl; |
| 991 | 1057 | u16 vid; |
| 992 | 1058 | |
| @@ -995,12 +1061,11 @@ void b53_vlan_add(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 995 | 1061 | |
| 996 | 1062 | b53_get_vlan_entry(dev, vid, vl); |
| 997 | 1063 | |
| 998 | − vl->members |= BIT(port) | BIT(cpu_port); | |
| 1064 | + vl->members |= BIT(port); | |
| 999 | 1065 | if (untagged) |
| 1000 | 1066 | vl->untag |= BIT(port); |
| 1001 | 1067 | else |
| 1002 | 1068 | vl->untag &= ~BIT(port); |
| 1003 | − vl->untag &= ~BIT(cpu_port); | |
| 1004 | 1069 | |
| 1005 | 1070 | b53_set_vlan_entry(dev, vid, vl); |
| 1006 | 1071 | b53_fast_age_vlan(dev, vid); |
| @@ -1280,7 +1345,7 @@ EXPORT_SYMBOL(b53_fdb_dump); · 273 unmodified lines | ||
| 1280 | 1345 | int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) |
| 1281 | 1346 | { |
| 1282 | 1347 | struct b53_device *dev = ds->priv; |
| 1283 | − s8 cpu_port = ds->dst->cpu_dp->index; | |
| 1348 | + s8 cpu_port = ds->ports[port].cpu_dp->index; | |
| 1284 | 1349 | u16 pvlan, reg; |
| 1285 | 1350 | unsigned int i; |
| 1286 | 1351 | |
| @@ -1298,7 +1363,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) · 11 unmodified lines | ||
| 1298 | 1363 | b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); |
| 1299 | 1364 | |
| 1300 | 1365 | b53_for_each_port(dev, i) { |
| 1301 | − if (ds->ports[i].bridge_dev != br) | |
| 1366 | + if (dsa_to_port(ds, i)->bridge_dev != br) | |
| 1302 | 1367 | continue; |
| 1303 | 1368 | |
| 1304 | 1369 | /* Add this local port to the remote port VLAN control |
| @@ -1326,7 +1391,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) · 21 unmodified lines | ||
| 1326 | 1391 | { |
| 1327 | 1392 | struct b53_device *dev = ds->priv; |
| 1328 | 1393 | struct b53_vlan *vl = &dev->vlans[0]; |
| 1329 | − s8 cpu_port = ds->dst->cpu_dp->index; | |
| 1394 | + s8 cpu_port = ds->ports[port].cpu_dp->index; | |
| 1330 | 1395 | unsigned int i; |
| 1331 | 1396 | u16 pvlan, reg, pvid; |
| 1332 | 1397 | |
| @@ -1334,7 +1399,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) · 1 unmodified line | ||
| 1334 | 1399 | |
| 1335 | 1400 | b53_for_each_port(dev, i) { |
| 1336 | 1401 | /* Don't touch the remaining ports */ |
| 1337 | − if (ds->ports[i].bridge_dev != br) | |
| 1402 | + if (dsa_to_port(ds, i)->bridge_dev != br) | |
| 1338 | 1403 | continue; |
| 1339 | 1404 | |
| 1340 | 1405 | b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); |
| @@ -1364,8 +1429,8 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) · 23 unmodified lines | ||
| 1364 | 1429 | b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); |
| 1365 | 1430 | } else { |
| 1366 | 1431 | b53_get_vlan_entry(dev, pvid, vl); |
| 1367 | − vl->members |= BIT(port) | BIT(dev->cpu_port); | |
| 1368 | − vl->untag |= BIT(port) | BIT(dev->cpu_port); | |
| 1432 | + vl->members |= BIT(port) | BIT(cpu_port); | |
| 1433 | + vl->untag |= BIT(port) | BIT(cpu_port); | |
| 1369 | 1434 | b53_set_vlan_entry(dev, pvid, vl); |
| 1370 | 1435 | } |
| 1371 | 1436 | } |
| @@ -1414,9 +1479,40 @@ void b53_br_fast_age(struct dsa_switch *ds, int port) · 42 unmodified lines | ||
| 1414 | 1479 | } |
| 1415 | 1480 | EXPORT_SYMBOL(b53_br_fast_age); |
| 1416 | 1481 | |
| 1417 | −static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds) | |
| 1482 | +static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port) | |
| 1483 | +{ | |
| 1484 | + /* Broadcom switches will accept enabling Broadcom tags on the | |
| 1485 | + * following ports: 5, 7 and 8, any other port is not supported | |
| 1486 | + */ | |
| 1487 | + switch (port) { | |
| 1488 | + case B53_CPU_PORT_25: | |
| 1489 | + case 7: | |
| 1490 | + case B53_CPU_PORT: | |
| 1491 | + return true; | |
| 1492 | + } | |
| 1493 | + | |
| 1494 | + dev_warn(ds->dev, "Port %d is not Broadcom tag capable\n", port); | |
| 1495 | + return false; | |
| 1496 | +} | |
| 1497 | + | |
| 1498 | +static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, | |
| 1499 | + int port) | |
| 1418 | 1500 | { |
| 1419 | − return DSA_TAG_PROTO_NONE; | |
| 1501 | + struct b53_device *dev = ds->priv; | |
| 1502 | + | |
| 1503 | + /* Older models support a different tag format that we do not | |
| 1504 | + * support in net/dsa/tag_brcm.c yet. | |
| 1505 | + */ | |
| 1506 | + if (is5325(dev) || is5365(dev) || !b53_can_enable_brcm_tags(ds, port)) | |
| 1507 | + return DSA_TAG_PROTO_NONE; | |
| 1508 | + | |
| 1509 | + /* Broadcom BCM58xx chips have a flow accelerator on Port 8 | |
| 1510 | + * which requires us to use the prepended Broadcom tag type | |
| 1511 | + */ | |
| 1512 | + if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) | |
| 1513 | + return DSA_TAG_PROTO_BRCM_PREPEND; | |
| 1514 | + | |
| 1515 | + return DSA_TAG_PROTO_BRCM; | |
| 1420 | 1516 | } |
| 1421 | 1517 | |
| 1422 | 1518 | int b53_mirror_add(struct dsa_switch *ds, int port, |
| @@ -1484,6 +1580,69 @@ void b53_mirror_del(struct dsa_switch *ds, int port, · 61 unmodified lines | ||
| 1484 | 1580 | } |
| 1485 | 1581 | EXPORT_SYMBOL(b53_mirror_del); |
| 1486 | 1582 | |
| 1583 | +void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable) | |
| 1584 | +{ | |
| 1585 | + struct b53_device *dev = ds->priv; | |
| 1586 | + u16 reg; | |
| 1587 | + | |
| 1588 | + b53_read16(dev, B53_EEE_PAGE, B53_EEE_EN_CTRL, ®); | |
| 1589 | + if (enable) | |
| 1590 | + reg |= BIT(port); | |
| 1591 | + else | |
| 1592 | + reg &= ~BIT(port); | |
| 1593 | + b53_write16(dev, B53_EEE_PAGE, B53_EEE_EN_CTRL, reg); | |
| 1594 | +} | |
| 1595 | +EXPORT_SYMBOL(b53_eee_enable_set); | |
| 1596 | + | |
| 1597 | + | |
| 1598 | +/* Returns 0 if EEE was not enabled, or 1 otherwise | |
| 1599 | + */ | |
| 1600 | +int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy) | |
| 1601 | +{ | |
| 1602 | + int ret; | |
| 1603 | + | |
| 1604 | + ret = phy_init_eee(phy, 0); | |
| 1605 | + if (ret) | |
| 1606 | + return 0; | |
| 1607 | + | |
| 1608 | + b53_eee_enable_set(ds, port, true); | |
| 1609 | + | |
| 1610 | + return 1; | |
| 1611 | +} | |
| 1612 | +EXPORT_SYMBOL(b53_eee_init); | |
| 1613 | + | |
| 1614 | +int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) | |
| 1615 | +{ | |
| 1616 | + struct b53_device *dev = ds->priv; | |
| 1617 | + struct ethtool_eee *p = &dev->ports[port].eee; | |
| 1618 | + u16 reg; | |
| 1619 | + | |
| 1620 | + if (is5325(dev) || is5365(dev)) | |
| 1621 | + return -EOPNOTSUPP; | |
| 1622 | + | |
| 1623 | + b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, ®); | |
| 1624 | + e->eee_enabled = p->eee_enabled; | |
| 1625 | + e->eee_active = !!(reg & BIT(port)); | |
| 1626 | + | |
| 1627 | + return 0; | |
| 1628 | +} | |
| 1629 | +EXPORT_SYMBOL(b53_get_mac_eee); | |
| 1630 | + | |
| 1631 | +int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) | |
| 1632 | +{ | |
| 1633 | + struct b53_device *dev = ds->priv; | |
| 1634 | + struct ethtool_eee *p = &dev->ports[port].eee; | |
| 1635 | + | |
| 1636 | + if (is5325(dev) || is5365(dev)) | |
| 1637 | + return -EOPNOTSUPP; | |
| 1638 | + | |
| 1639 | + p->eee_enabled = e->eee_enabled; | |
| 1640 | + b53_eee_enable_set(ds, port, e->eee_enabled); | |
| 1641 | + | |
| 1642 | + return 0; | |
| 1643 | +} | |
| 1644 | +EXPORT_SYMBOL(b53_set_mac_eee); | |
| 1645 | + | |
| 1487 | 1646 | static const struct dsa_switch_ops b53_switch_ops = { |
| 1488 | 1647 | .get_tag_protocol = b53_get_tag_protocol, |
| 1489 | 1648 | .setup = b53_setup, |
| @@ -1495,6 +1654,8 @@ static const struct dsa_switch_ops b53_switch_ops = { · 5 unmodified lines | ||
| 1495 | 1654 | .adjust_link = b53_adjust_link, |
| 1496 | 1655 | .port_enable = b53_enable_port, |
| 1497 | 1656 | .port_disable = b53_disable_port, |
| 1657 | + .get_mac_eee = b53_get_mac_eee, | |
| 1658 | + .set_mac_eee = b53_set_mac_eee, | |
| 1498 | 1659 | .port_bridge_join = b53_br_join, |
| 1499 | 1660 | .port_bridge_leave = b53_br_leave, |
| 1500 | 1661 | .port_stp_state_set = b53_br_set_stp_state, |
| @@ -70,6 +70,7 @@ enum { · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | struct b53_port { |
| 72 | 72 | u16 vlan_ctl_mask; |
| 73 | + struct ethtool_eee eee; | |
| 73 | 74 | }; |
| 74 | 75 | |
| 75 | 76 | struct b53_vlan { |
| @@ -186,11 +187,6 @@ static inline int is58xx(struct b53_device *dev) · 110 unmodified lines | ||
| 186 | 187 | #define B53_CPU_PORT_25 5 |
| 187 | 188 | #define B53_CPU_PORT 8 |
| 188 | 189 | |
| 189 | −static inline int is_cpu_port(struct b53_device *dev, int port) | |
| 190 | −{ | |
| 191 | − return dev->cpu_port; | |
| 192 | −} | |
| 193 | − | |
| 194 | 190 | struct b53_device *b53_switch_alloc(struct device *base, |
| 195 | 191 | const struct b53_io_ops *ops, |
| 196 | 192 | void *priv); |
| @@ -204,119 +200,30 @@ static inline void b53_switch_remove(struct b53_device *dev) · 7 unmodified lines | ||
| 204 | 200 | dsa_unregister_switch(dev->ds); |
| 205 | 201 | } |
| 206 | 202 | |
| 207 | −static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) | |
| 208 | −{ | |
| 209 | − int ret; | |
| 210 | − | |
| 211 | − mutex_lock(&dev->reg_mutex); | |
| 212 | − ret = dev->ops->read8(dev, page, reg, val); | |
| 213 | − mutex_unlock(&dev->reg_mutex); | |
| 214 | − | |
| 215 | − return ret; | |
| 203 | +#define b53_build_op(type_op_size, val_type) \ | |
| 204 | +static inline int b53_##type_op_size(struct b53_device *dev, u8 page, \ | |
| 205 | + u8 reg, val_type val) \ | |
| 206 | +{ \ | |
| 207 | + int ret; \ | |
| 208 | + \ | |
| 209 | + mutex_lock(&dev->reg_mutex); \ | |
| 210 | + ret = dev->ops->type_op_size(dev, page, reg, val); \ | |
| 211 | + mutex_unlock(&dev->reg_mutex); \ | |
| 212 | + \ | |
| 213 | + return ret; \ | |
| 216 | 214 | } |
| 217 | 215 | |
| 218 | −static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) | |
| 219 | −{ | |
| 220 | − int ret; | |
| 221 | − | |
| 222 | − mutex_lock(&dev->reg_mutex); | |
| 223 | − ret = dev->ops->read16(dev, page, reg, val); | |
| 224 | − mutex_unlock(&dev->reg_mutex); | |
| 225 | − | |
| 226 | − return ret; | |
| 227 | −} | |
| 228 | − | |
| 229 | −static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) | |
| 230 | −{ | |
| 231 | − int ret; | |
| 232 | − | |
| 233 | − mutex_lock(&dev->reg_mutex); | |
| 234 | − ret = dev->ops->read32(dev, page, reg, val); | |
| 235 | − mutex_unlock(&dev->reg_mutex); | |
| 236 | − | |
| 237 | − return ret; | |
| 238 | −} | |
| 239 | − | |
| 240 | −static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) | |
| 241 | −{ | |
| 242 | − int ret; | |
| 243 | − | |
| 244 | − mutex_lock(&dev->reg_mutex); | |
| 245 | − ret = dev->ops->read48(dev, page, reg, val); | |
| 246 | − mutex_unlock(&dev->reg_mutex); | |
| 247 | − | |
| 248 | − return ret; | |
| 249 | −} | |
| 250 | − | |
| 251 | −static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) | |
| 252 | −{ | |
| 253 | − int ret; | |
| 254 | − | |
| 255 | − mutex_lock(&dev->reg_mutex); | |
| 256 | − ret = dev->ops->read64(dev, page, reg, val); | |
| 257 | − mutex_unlock(&dev->reg_mutex); | |
| 258 | − | |
| 259 | − return ret; | |
| 260 | −} | |
| 216 | +b53_build_op(read8, u8 *); | |
| 217 | +b53_build_op(read16, u16 *); | |
| 218 | +b53_build_op(read32, u32 *); | |
| 219 | +b53_build_op(read48, u64 *); | |
| 220 | +b53_build_op(read64, u64 *); | |
| 261 | 221 | |
| 262 | −static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) | |
| 263 | −{ | |
| 264 | − int ret; | |
| 265 | − | |
| 266 | − mutex_lock(&dev->reg_mutex); | |
| 267 | − ret = dev->ops->write8(dev, page, reg, value); | |
| 268 | − mutex_unlock(&dev->reg_mutex); | |
| 269 | − | |
| 270 | − return ret; | |
| 271 | −} | |
| 272 | − | |
| 273 | −static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg, | |
| 274 | − u16 value) | |
| 275 | −{ | |
| 276 | − int ret; | |
| 277 | − | |
| 278 | − mutex_lock(&dev->reg_mutex); | |
| 279 | − ret = dev->ops->write16(dev, page, reg, value); | |
| 280 | − mutex_unlock(&dev->reg_mutex); | |
| 281 | − | |
| 282 | − return ret; | |
| 283 | −} | |
| 284 | − | |
| 285 | −static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg, | |
| 286 | − u32 value) | |
| 287 | −{ | |
| 288 | − int ret; | |
| 289 | − | |
| 290 | − mutex_lock(&dev->reg_mutex); | |
| 291 | − ret = dev->ops->write32(dev, page, reg, value); | |
| 292 | − mutex_unlock(&dev->reg_mutex); | |
| 293 | − | |
| 294 | − return ret; | |
| 295 | −} | |
| 296 | − | |
| 297 | −static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg, | |
| 298 | − u64 value) | |
| 299 | −{ | |
| 300 | − int ret; | |
| 301 | − | |
| 302 | − mutex_lock(&dev->reg_mutex); | |
| 303 | − ret = dev->ops->write48(dev, page, reg, value); | |
| 304 | − mutex_unlock(&dev->reg_mutex); | |
| 305 | − | |
| 306 | − return ret; | |
| 307 | −} | |
| 308 | − | |
| 309 | −static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg, | |
| 310 | − u64 value) | |
| 311 | −{ | |
| 312 | − int ret; | |
| 313 | − | |
| 314 | − mutex_lock(&dev->reg_mutex); | |
| 315 | − ret = dev->ops->write64(dev, page, reg, value); | |
| 316 | − mutex_unlock(&dev->reg_mutex); | |
| 317 | − | |
| 318 | − return ret; | |
| 319 | −} | |
| 222 | +b53_build_op(write8, u8); | |
| 223 | +b53_build_op(write16, u16); | |
| 224 | +b53_build_op(write32, u32); | |
| 225 | +b53_build_op(write48, u64); | |
| 226 | +b53_build_op(write64, u64); | |
| 320 | 227 | |
| 321 | 228 | struct b53_arl_entry { |
| 322 | 229 | u8 port; |
| @@ -377,6 +284,8 @@ static inline int b53_switch_get_reset_gpio(struct b53_device *dev) · 54 unmodified lines | ||
| 377 | 284 | #endif |
| 378 | 285 | |
| 379 | 286 | /* Exported functions towards other drivers */ |
| 287 | +void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port); | |
| 288 | +int b53_configure_vlan(struct dsa_switch *ds); | |
| 380 | 289 | void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data); |
| 381 | 290 | void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); |
| 382 | 291 | int b53_get_sset_count(struct dsa_switch *ds); |
| @@ -403,5 +312,12 @@ int b53_mirror_add(struct dsa_switch *ds, int port, · 20 unmodified lines | ||
| 403 | 312 | struct dsa_mall_mirror_tc_entry *mirror, bool ingress); |
| 404 | 313 | void b53_mirror_del(struct dsa_switch *ds, int port, |
| 405 | 314 | struct dsa_mall_mirror_tc_entry *mirror); |
| 315 | +int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); | |
| 316 | +void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy); | |
| 317 | +void b53_brcm_hdr_setup(struct dsa_switch *ds, int port); | |
| 318 | +void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable); | |
| 319 | +int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy); | |
| 320 | +int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); | |
| 321 | +int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); | |
| 406 | 322 | |
| 407 | 323 | #endif |
| @@ -50,6 +50,9 @@ · 49 unmodified lines | ||
| 50 | 50 | /* Jumbo Frame Registers */ |
| 51 | 51 | #define B53_JUMBO_PAGE 0x40 |
| 52 | 52 | |
| 53 | +/* EEE Control Registers Page */ | |
| 54 | +#define B53_EEE_PAGE 0x92 | |
| 55 | + | |
| 53 | 56 | /* CFP Configuration Registers Page */ |
| 54 | 57 | #define B53_CFP_PAGE 0xa1 |
| 55 | 58 | |
| @@ -210,6 +213,7 @@ · 154 unmodified lines | ||
| 210 | 213 | #define B53_BRCM_HDR 0x03 |
| 211 | 214 | #define BRCM_HDR_P8_EN BIT(0) /* Enable tagging on port 8 */ |
| 212 | 215 | #define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */ |
| 216 | +#define BRCM_HDR_P7_EN BIT(2) /* Enable tagging on port 7 */ | |
| 213 | 217 | |
| 214 | 218 | /* Mirror capture control register (16 bit) */ |
| 215 | 219 | #define B53_MIR_CAP_CTL 0x10 |
| @@ -249,6 +253,12 @@ · 33 unmodified lines | ||
| 249 | 253 | /* Revision ID register (8 bit) */ |
| 250 | 254 | #define B53_REV_ID 0x40 |
| 251 | 255 | |
| 256 | +/* Broadcom header RX control (16 bit) */ | |
| 257 | +#define B53_BRCM_HDR_RX_DIS 0x60 | |
| 258 | + | |
| 259 | +/* Broadcom header TX control (16 bit) */ | |
| 260 | +#define B53_BRCM_HDR_TX_DIS 0x62 | |
| 261 | + | |
| 252 | 262 | /************************************************************************* |
| 253 | 263 | * ARL Access Page Registers |
| 254 | 264 | *************************************************************************/ |
| @@ -464,6 +474,44 @@ · 209 unmodified lines | ||
| 464 | 474 | #define JMS_MIN_SIZE 1518 |
| 465 | 475 | #define JMS_MAX_SIZE 9724 |
| 466 | 476 | |
| 477 | +/************************************************************************* | |
| 478 | + * EEE Configuration Page Registers | |
| 479 | + *************************************************************************/ | |
| 480 | + | |
| 481 | +/* EEE Enable control register (16 bit) */ | |
| 482 | +#define B53_EEE_EN_CTRL 0x00 | |
| 483 | + | |
| 484 | +/* EEE LPI assert status register (16 bit) */ | |
| 485 | +#define B53_EEE_LPI_ASSERT_STS 0x02 | |
| 486 | + | |
| 487 | +/* EEE LPI indicate status register (16 bit) */ | |
| 488 | +#define B53_EEE_LPI_INDICATE 0x4 | |
| 489 | + | |
| 490 | +/* EEE Receiving idle symbols status register (16 bit) */ | |
| 491 | +#define B53_EEE_RX_IDLE_SYM_STS 0x6 | |
| 492 | + | |
| 493 | +/* EEE Pipeline timer register (32 bit) */ | |
| 494 | +#define B53_EEE_PIP_TIMER 0xC | |
| 495 | + | |
| 496 | +/* EEE Sleep timer Gig register (32 bit) */ | |
| 497 | +#define B53_EEE_SLEEP_TIMER_GIG(i) (0x10 + 4 * (i)) | |
| 498 | + | |
| 499 | +/* EEE Sleep timer FE register (32 bit) */ | |
| 500 | +#define B53_EEE_SLEEP_TIMER_FE(i) (0x34 + 4 * (i)) | |
| 501 | + | |
| 502 | +/* EEE Minimum LP timer Gig register (32 bit) */ | |
| 503 | +#define B53_EEE_MIN_LP_TIMER_GIG(i) (0x58 + 4 * (i)) | |
| 504 | + | |
| 505 | +/* EEE Minimum LP timer FE register (32 bit) */ | |
| 506 | +#define B53_EEE_MIN_LP_TIMER_FE(i) (0x7c + 4 * (i)) | |
| 507 | + | |
| 508 | +/* EEE Wake timer Gig register (16 bit) */ | |
| 509 | +#define B53_EEE_WAKE_TIMER_GIG(i) (0xa0 + 2 * (i)) | |
| 510 | + | |
| 511 | +/* EEE Wake timer FE register (16 bit) */ | |
| 512 | +#define B53_EEE_WAKE_TIMER_FE(i) (0xb2 + 2 * (i)) | |
| 513 | + | |
| 514 | + | |
| 467 | 515 | /************************************************************************* |
| 468 | 516 | * CFP Configuration Page Registers |
| 469 | 517 | *************************************************************************/ |
| @@ -35,71 +35,12 @@ · 34 unmodified lines | ||
| 35 | 35 | #include "b53/b53_priv.h" |
| 36 | 36 | #include "b53/b53_regs.h" |
| 37 | 37 | |
| 38 | −static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds) | |
| 38 | +static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds, | |
| 39 | + int port) | |
| 39 | 40 | { |
| 40 | 41 | return DSA_TAG_PROTO_BRCM; |
| 41 | 42 | } |
| 42 | 43 | |
| 43 | −static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) | |
| 44 | −{ | |
| 45 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 46 | − unsigned int i; | |
| 47 | − u32 reg; | |
| 48 | − | |
| 49 | − /* Enable the IMP Port to be in the same VLAN as the other ports | |
| 50 | − * on a per-port basis such that we only have Port i and IMP in | |
| 51 | − * the same VLAN. | |
| 52 | − */ | |
| 53 | − for (i = 0; i < priv->hw_params.num_ports; i++) { | |
| 54 | − if (!((1 << i) & ds->enabled_port_mask)) | |
| 55 | − continue; | |
| 56 | − | |
| 57 | − reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i)); | |
| 58 | − reg |= (1 << cpu_port); | |
| 59 | − core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(i)); | |
| 60 | − } | |
| 61 | −} | |
| 62 | − | |
| 63 | −static void bcm_sf2_brcm_hdr_setup(struct bcm_sf2_priv *priv, int port) | |
| 64 | −{ | |
| 65 | − u32 reg, val; | |
| 66 | − | |
| 67 | − /* Resolve which bit controls the Broadcom tag */ | |
| 68 | − switch (port) { | |
| 69 | − case 8: | |
| 70 | − val = BRCM_HDR_EN_P8; | |
| 71 | − break; | |
| 72 | − case 7: | |
| 73 | − val = BRCM_HDR_EN_P7; | |
| 74 | − break; | |
| 75 | − case 5: | |
| 76 | − val = BRCM_HDR_EN_P5; | |
| 77 | − break; | |
| 78 | − default: | |
| 79 | − val = 0; | |
| 80 | − break; | |
| 81 | − } | |
| 82 | − | |
| 83 | − /* Enable Broadcom tags for IMP port */ | |
| 84 | − reg = core_readl(priv, CORE_BRCM_HDR_CTRL); | |
| 85 | − reg |= val; | |
| 86 | − core_writel(priv, reg, CORE_BRCM_HDR_CTRL); | |
| 87 | − | |
| 88 | − /* Enable reception Broadcom tag for CPU TX (switch RX) to | |
| 89 | − * allow us to tag outgoing frames | |
| 90 | − */ | |
| 91 | − reg = core_readl(priv, CORE_BRCM_HDR_RX_DIS); | |
| 92 | − reg &= ~(1 << port); | |
| 93 | − core_writel(priv, reg, CORE_BRCM_HDR_RX_DIS); | |
| 94 | − | |
| 95 | − /* Enable transmission of Broadcom tags from the switch (CPU RX) to | |
| 96 | − * allow delivering frames to the per-port net_devices | |
| 97 | − */ | |
| 98 | − reg = core_readl(priv, CORE_BRCM_HDR_TX_DIS); | |
| 99 | − reg &= ~(1 << port); | |
| 100 | − core_writel(priv, reg, CORE_BRCM_HDR_TX_DIS); | |
| 101 | −} | |
| 102 | − | |
| 103 | 44 | static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) |
| 104 | 45 | { |
| 105 | 46 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| @@ -138,7 +79,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) · 32 unmodified lines | ||
| 138 | 79 | reg |= i << (PRT_TO_QID_SHIFT * i); |
| 139 | 80 | core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port)); |
| 140 | 81 | |
| 141 | − bcm_sf2_brcm_hdr_setup(priv, port); | |
| 82 | + b53_brcm_hdr_setup(ds, port); | |
| 142 | 83 | |
| 143 | 84 | /* Force link status for IMP port */ |
| 144 | 85 | reg = core_readl(priv, offset); |
| @@ -146,19 +87,6 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) · 1 unmodified line | ||
| 146 | 87 | core_writel(priv, reg, offset); |
| 147 | 88 | } |
| 148 | 89 | |
| 149 | −static void bcm_sf2_eee_enable_set(struct dsa_switch *ds, int port, bool enable) | |
| 150 | −{ | |
| 151 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 152 | − u32 reg; | |
| 153 | − | |
| 154 | − reg = core_readl(priv, CORE_EEE_EN_CTRL); | |
| 155 | − if (enable) | |
| 156 | − reg |= 1 << port; | |
| 157 | − else | |
| 158 | − reg &= ~(1 << port); | |
| 159 | − core_writel(priv, reg, CORE_EEE_EN_CTRL); | |
| 160 | −} | |
| 161 | − | |
| 162 | 90 | static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) |
| 163 | 91 | { |
| 164 | 92 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| @@ -236,7 +164,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, · 71 unmodified lines | ||
| 236 | 164 | struct phy_device *phy) |
| 237 | 165 | { |
| 238 | 166 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| 239 | − s8 cpu_port = ds->dst->cpu_dp->index; | |
| 240 | 167 | unsigned int i; |
| 241 | 168 | u32 reg; |
| 242 | 169 | |
| @@ -247,7 +174,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, · 4 unmodified lines | ||
| 247 | 174 | |
| 248 | 175 | /* Enable Broadcom tags for that port if requested */ |
| 249 | 176 | if (priv->brcm_tag_mask & BIT(port)) |
| 250 | − bcm_sf2_brcm_hdr_setup(priv, port); | |
| 177 | + b53_brcm_hdr_setup(ds, port); | |
| 251 | 178 | |
| 252 | 179 | /* Configure Traffic Class to QoS mapping, allow each priority to map |
| 253 | 180 | * to a different queue number |
| @@ -257,9 +184,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, · 3 unmodified lines | ||
| 257 | 184 | reg |= i << (PRT_TO_QID_SHIFT * i); |
| 258 | 185 | core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port)); |
| 259 | 186 | |
| 260 | − /* Clear the Rx and Tx disable bits and set to no spanning tree */ | |
| 261 | − core_writel(priv, 0, CORE_G_PCTL_PORT(port)); | |
| 262 | − | |
| 263 | 187 | /* Re-enable the GPHY and re-apply workarounds */ |
| 264 | 188 | if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) { |
| 265 | 189 | bcm_sf2_gphy_enable_set(ds, true); |
| @@ -282,23 +206,20 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, · 16 unmodified lines | ||
| 282 | 206 | if (port == priv->moca_port) |
| 283 | 207 | bcm_sf2_port_intr_enable(priv, port); |
| 284 | 208 | |
| 285 | − /* Set this port, and only this one to be in the default VLAN, | |
| 286 | − * if member of a bridge, restore its membership prior to | |
| 287 | − * bringing down this port. | |
| 288 | − */ | |
| 289 | − reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(port)); | |
| 290 | − reg &= ~PORT_VLAN_CTRL_MASK; | |
| 291 | − reg |= (1 << port); | |
| 292 | − reg |= priv->dev->ports[port].vlan_ctl_mask; | |
| 293 | − core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port)); | |
| 294 | − | |
| 295 | − bcm_sf2_imp_vlan_setup(ds, cpu_port); | |
| 296 | − | |
| 297 | − /* If EEE was enabled, restore it */ | |
| 298 | − if (priv->port_sts[port].eee.eee_enabled) | |
| 299 | − bcm_sf2_eee_enable_set(ds, port, true); | |
| 209 | + /* Set per-queue pause threshold to 32 */ | |
| 210 | + core_writel(priv, 32, CORE_TXQ_THD_PAUSE_QN_PORT(port)); | |
| 211 | + | |
| 212 | + /* Set ACB threshold to 24 */ | |
| 213 | + for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++) { | |
| 214 | + reg = acb_readl(priv, ACB_QUEUE_CFG(port * | |
| 215 | + SF2_NUM_EGRESS_QUEUES + i)); | |
| 216 | + reg &= ~XOFF_THRESHOLD_MASK; | |
| 217 | + reg |= 24; | |
| 218 | + acb_writel(priv, reg, ACB_QUEUE_CFG(port * | |
| 219 | + SF2_NUM_EGRESS_QUEUES + i)); | |
| 220 | + } | |
| 300 | 221 | |
| 301 | − return 0; | |
| 222 | + return b53_enable_port(ds, port, phy); | |
| 302 | 223 | } |
| 303 | 224 | |
| 304 | 225 | static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, |
| @@ -321,9 +242,7 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, · 16 unmodified lines | ||
| 321 | 242 | else |
| 322 | 243 | off = CORE_G_PCTL_PORT(port); |
| 323 | 244 | |
| 324 | − reg = core_readl(priv, off); | |
| 325 | − reg |= RX_DIS | TX_DIS; | |
| 326 | − core_writel(priv, reg, off); | |
| 245 | + b53_disable_port(ds, port, phy); | |
| 327 | 246 | |
| 328 | 247 | /* Power down the port memory */ |
| 329 | 248 | reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); |
| @@ -331,47 +250,6 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, · 1 unmodified line | ||
| 331 | 250 | core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); |
| 332 | 251 | } |
| 333 | 252 | |
| 334 | −/* Returns 0 if EEE was not enabled, or 1 otherwise | |
| 335 | − */ | |
| 336 | −static int bcm_sf2_eee_init(struct dsa_switch *ds, int port, | |
| 337 | − struct phy_device *phy) | |
| 338 | −{ | |
| 339 | − int ret; | |
| 340 | − | |
| 341 | − ret = phy_init_eee(phy, 0); | |
| 342 | − if (ret) | |
| 343 | − return 0; | |
| 344 | − | |
| 345 | − bcm_sf2_eee_enable_set(ds, port, true); | |
| 346 | − | |
| 347 | − return 1; | |
| 348 | −} | |
| 349 | − | |
| 350 | −static int bcm_sf2_sw_get_mac_eee(struct dsa_switch *ds, int port, | |
| 351 | − struct ethtool_eee *e) | |
| 352 | −{ | |
| 353 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 354 | − struct ethtool_eee *p = &priv->port_sts[port].eee; | |
| 355 | − u32 reg; | |
| 356 | − | |
| 357 | − reg = core_readl(priv, CORE_EEE_LPI_INDICATE); | |
| 358 | − e->eee_enabled = p->eee_enabled; | |
| 359 | − e->eee_active = !!(reg & (1 << port)); | |
| 360 | − | |
| 361 | − return 0; | |
| 362 | −} | |
| 363 | − | |
| 364 | −static int bcm_sf2_sw_set_mac_eee(struct dsa_switch *ds, int port, | |
| 365 | − struct ethtool_eee *e) | |
| 366 | −{ | |
| 367 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 368 | − struct ethtool_eee *p = &priv->port_sts[port].eee; | |
| 369 | − | |
| 370 | − p->eee_enabled = e->eee_enabled; | |
| 371 | − bcm_sf2_eee_enable_set(ds, port, e->eee_enabled); | |
| 372 | − | |
| 373 | − return 0; | |
| 374 | −} | |
| 375 | 253 | |
| 376 | 254 | static int bcm_sf2_sw_indir_rw(struct bcm_sf2_priv *priv, int op, int addr, |
| 377 | 255 | int regnum, u16 val) |
| @@ -606,7 +484,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, · 228 unmodified lines | ||
| 606 | 484 | struct phy_device *phydev) |
| 607 | 485 | { |
| 608 | 486 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| 609 | − struct ethtool_eee *p = &priv->port_sts[port].eee; | |
| 487 | + struct ethtool_eee *p = &priv->dev->ports[port].eee; | |
| 610 | 488 | u32 id_mode_dis = 0, port_mode; |
| 611 | 489 | const char *str = NULL; |
| 612 | 490 | u32 reg, offset; |
| @@ -688,7 +566,7 @@ force_link: · 75 unmodified lines | ||
| 688 | 566 | core_writel(priv, reg, offset); |
| 689 | 567 | |
| 690 | 568 | if (!phydev->is_pseudo_fixed_link) |
| 691 | − p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); | |
| 569 | + p->eee_enabled = b53_eee_init(ds, port, phydev); | |
| 692 | 570 | } |
| 693 | 571 | |
| 694 | 572 | static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, |
| @@ -724,7 +602,7 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, · 29 unmodified lines | ||
| 724 | 602 | * state machine and make it go in PHY_FORCING state instead. |
| 725 | 603 | */ |
| 726 | 604 | if (!status->link) |
| 727 | − netif_carrier_off(ds->ports[port].netdev); | |
| 605 | + netif_carrier_off(ds->ports[port].slave); | |
| 728 | 606 | status->duplex = 1; |
| 729 | 607 | } else { |
| 730 | 608 | status->link = 1; |
| @@ -749,6 +627,20 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, · 18 unmodified lines | ||
| 749 | 627 | status->pause = 1; |
| 750 | 628 | } |
| 751 | 629 | |
| 630 | +static void bcm_sf2_enable_acb(struct dsa_switch *ds) | |
| 631 | +{ | |
| 632 | + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 633 | + u32 reg; | |
| 634 | + | |
| 635 | + /* Enable ACB globally */ | |
| 636 | + reg = acb_readl(priv, ACB_CONTROL); | |
| 637 | + reg |= (ACB_FLUSH_MASK << ACB_FLUSH_SHIFT); | |
| 638 | + acb_writel(priv, reg, ACB_CONTROL); | |
| 639 | + reg &= ~(ACB_FLUSH_MASK << ACB_FLUSH_SHIFT); | |
| 640 | + reg |= ACB_EN | ACB_ALGORITHM; | |
| 641 | + acb_writel(priv, reg, ACB_CONTROL); | |
| 642 | +} | |
| 643 | + | |
| 752 | 644 | static int bcm_sf2_sw_suspend(struct dsa_switch *ds) |
| 753 | 645 | { |
| 754 | 646 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| @@ -761,8 +653,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds) · 6 unmodified lines | ||
| 761 | 653 | * bcm_sf2_sw_setup |
| 762 | 654 | */ |
| 763 | 655 | for (port = 0; port < DSA_MAX_PORTS; port++) { |
| 764 | − if ((1 << port) & ds->enabled_port_mask || | |
| 765 | − dsa_is_cpu_port(ds, port)) | |
| 656 | + if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port)) | |
| 766 | 657 | bcm_sf2_port_disable(ds, port, NULL); |
| 767 | 658 | } |
| 768 | 659 | |
| @@ -785,19 +676,21 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds) · 16 unmodified lines | ||
| 785 | 676 | bcm_sf2_gphy_enable_set(ds, true); |
| 786 | 677 | |
| 787 | 678 | for (port = 0; port < DSA_MAX_PORTS; port++) { |
| 788 | − if ((1 << port) & ds->enabled_port_mask) | |
| 679 | + if (dsa_is_user_port(ds, port)) | |
| 789 | 680 | bcm_sf2_port_setup(ds, port, NULL); |
| 790 | 681 | else if (dsa_is_cpu_port(ds, port)) |
| 791 | 682 | bcm_sf2_imp_setup(ds, port); |
| 792 | 683 | } |
| 793 | 684 | |
| 685 | + bcm_sf2_enable_acb(ds); | |
| 686 | + | |
| 794 | 687 | return 0; |
| 795 | 688 | } |
| 796 | 689 | |
| 797 | 690 | static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, |
| 798 | 691 | struct ethtool_wolinfo *wol) |
| 799 | 692 | { |
| 800 | − struct net_device *p = ds->dst->cpu_dp->netdev; | |
| 693 | + struct net_device *p = ds->ports[port].cpu_dp->master; | |
| 801 | 694 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| 802 | 695 | struct ethtool_wolinfo pwol; |
| 803 | 696 | |
| @@ -820,9 +713,9 @@ static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, · 16 unmodified lines | ||
| 820 | 713 | static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, |
| 821 | 714 | struct ethtool_wolinfo *wol) |
| 822 | 715 | { |
| 823 | − struct net_device *p = ds->dst->cpu_dp->netdev; | |
| 716 | + struct net_device *p = ds->ports[port].cpu_dp->master; | |
| 824 | 717 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| 825 | − s8 cpu_port = ds->dst->cpu_dp->index; | |
| 718 | + s8 cpu_port = ds->ports[port].cpu_dp->index; | |
| 826 | 719 | struct ethtool_wolinfo pwol; |
| 827 | 720 | |
| 828 | 721 | p->ethtool_ops->get_wol(p, &pwol); |
| @@ -846,45 +739,6 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, · 17 unmodified lines | ||
| 846 | 739 | return p->ethtool_ops->set_wol(p, wol); |
| 847 | 740 | } |
| 848 | 741 | |
| 849 | −static int bcm_sf2_vlan_op_wait(struct bcm_sf2_priv *priv) | |
| 850 | −{ | |
| 851 | − unsigned int timeout = 10; | |
| 852 | − u32 reg; | |
| 853 | − | |
| 854 | − do { | |
| 855 | − reg = core_readl(priv, CORE_ARLA_VTBL_RWCTRL); | |
| 856 | − if (!(reg & ARLA_VTBL_STDN)) | |
| 857 | − return 0; | |
| 858 | − | |
| 859 | − usleep_range(1000, 2000); | |
| 860 | − } while (timeout--); | |
| 861 | − | |
| 862 | − return -ETIMEDOUT; | |
| 863 | −} | |
| 864 | − | |
| 865 | −static int bcm_sf2_vlan_op(struct bcm_sf2_priv *priv, u8 op) | |
| 866 | −{ | |
| 867 | − core_writel(priv, ARLA_VTBL_STDN | op, CORE_ARLA_VTBL_RWCTRL); | |
| 868 | − | |
| 869 | − return bcm_sf2_vlan_op_wait(priv); | |
| 870 | −} | |
| 871 | − | |
| 872 | −static void bcm_sf2_sw_configure_vlan(struct dsa_switch *ds) | |
| 873 | −{ | |
| 874 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 875 | − unsigned int port; | |
| 876 | − | |
| 877 | − /* Clear all VLANs */ | |
| 878 | − bcm_sf2_vlan_op(priv, ARLA_VTBL_CMD_CLEAR); | |
| 879 | − | |
| 880 | − for (port = 0; port < priv->hw_params.num_ports; port++) { | |
| 881 | − if (!((1 << port) & ds->enabled_port_mask)) | |
| 882 | − continue; | |
| 883 | − | |
| 884 | − core_writel(priv, 1, CORE_DEFAULT_1Q_TAG_P(port)); | |
| 885 | − } | |
| 886 | −} | |
| 887 | − | |
| 888 | 742 | static int bcm_sf2_sw_setup(struct dsa_switch *ds) |
| 889 | 743 | { |
| 890 | 744 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| @@ -893,7 +747,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) · 2 unmodified lines | ||
| 893 | 747 | /* Enable all valid ports and disable those unused */ |
| 894 | 748 | for (port = 0; port < priv->hw_params.num_ports; port++) { |
| 895 | 749 | /* IMP port receives special treatment */ |
| 896 | − if ((1 << port) & ds->enabled_port_mask) | |
| 750 | + if (dsa_is_user_port(ds, port)) | |
| 897 | 751 | bcm_sf2_port_setup(ds, port, NULL); |
| 898 | 752 | else if (dsa_is_cpu_port(ds, port)) |
| 899 | 753 | bcm_sf2_imp_setup(ds, port); |
| @@ -901,7 +755,8 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) · 1 unmodified line | ||
| 901 | 755 | bcm_sf2_port_disable(ds, port, NULL); |
| 902 | 756 | } |
| 903 | 757 | |
| 904 | − bcm_sf2_sw_configure_vlan(ds); | |
| 758 | + b53_configure_vlan(ds); | |
| 759 | + bcm_sf2_enable_acb(ds); | |
| 905 | 760 | |
| 906 | 761 | return 0; |
| 907 | 762 | } |
| @@ -1020,8 +875,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = { · 112 unmodified lines | ||
| 1020 | 875 | .set_wol = bcm_sf2_sw_set_wol, |
| 1021 | 876 | .port_enable = bcm_sf2_port_setup, |
| 1022 | 877 | .port_disable = bcm_sf2_port_disable, |
| 1023 | − .get_mac_eee = bcm_sf2_sw_get_mac_eee, | |
| 1024 | − .set_mac_eee = bcm_sf2_sw_set_mac_eee, | |
| 878 | + .get_mac_eee = b53_get_mac_eee, | |
| 879 | + .set_mac_eee = b53_set_mac_eee, | |
| 1025 | 880 | .port_bridge_join = b53_br_join, |
| 1026 | 881 | .port_bridge_leave = b53_br_leave, |
| 1027 | 882 | .port_stp_state_set = b53_br_set_stp_state, |
| @@ -1173,6 +1028,7 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) · 145 unmodified lines | ||
| 1173 | 1028 | * permanently used |
| 1174 | 1029 | */ |
| 1175 | 1030 | set_bit(0, priv->cfp.used); |
| 1031 | + set_bit(0, priv->cfp.unique); | |
| 1176 | 1032 | |
| 1177 | 1033 | bcm_sf2_identify_ports(priv, dn->child); |
| 1178 | 1034 | |
| @@ -48,14 +48,13 @@ struct bcm_sf2_hw_params { · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | struct bcm_sf2_port_status { |
| 50 | 50 | unsigned int link; |
| 51 | − | |
| 52 | − struct ethtool_eee eee; | |
| 53 | 51 | }; |
| 54 | 52 | |
| 55 | 53 | struct bcm_sf2_cfp_priv { |
| 56 | 54 | /* Mutex protecting concurrent accesses to the CFP registers */ |
| 57 | 55 | struct mutex lock; |
| 58 | 56 | DECLARE_BITMAP(used, CFP_NUM_RULES); |
| 57 | + DECLARE_BITMAP(unique, CFP_NUM_RULES); | |
| 59 | 58 | unsigned int rules_cnt; |
| 60 | 59 | }; |
| 61 | 60 | |
| @@ -20,37 +20,102 @@ · 19 unmodified lines | ||
| 20 | 20 | #include "bcm_sf2.h" |
| 21 | 21 | #include "bcm_sf2_regs.h" |
| 22 | 22 | |
| 23 | −struct cfp_udf_layout { | |
| 24 | − u8 slices[UDF_NUM_SLICES]; | |
| 23 | +struct cfp_udf_slice_layout { | |
| 24 | + u8 slices[UDFS_PER_SLICE]; | |
| 25 | 25 | u32 mask_value; |
| 26 | + u32 base_offset; | |
| 27 | +}; | |
| 26 | 28 | |
| 29 | +struct cfp_udf_layout { | |
| 30 | + struct cfp_udf_slice_layout udfs[UDF_NUM_SLICES]; | |
| 27 | 31 | }; |
| 28 | 32 | |
| 33 | +static const u8 zero_slice[UDFS_PER_SLICE] = { }; | |
| 34 | + | |
| 29 | 35 | /* UDF slices layout for a TCPv4/UDPv4 specification */ |
| 30 | 36 | static const struct cfp_udf_layout udf_tcpip4_layout = { |
| 31 | − .slices = { | |
| 32 | − /* End of L2, byte offset 12, src IP[0:15] */ | |
| 33 | − CFG_UDF_EOL2 | 6, | |
| 34 | − /* End of L2, byte offset 14, src IP[16:31] */ | |
| 35 | − CFG_UDF_EOL2 | 7, | |
| 36 | − /* End of L2, byte offset 16, dst IP[0:15] */ | |
| 37 | − CFG_UDF_EOL2 | 8, | |
| 38 | − /* End of L2, byte offset 18, dst IP[16:31] */ | |
| 39 | − CFG_UDF_EOL2 | 9, | |
| 40 | − /* End of L3, byte offset 0, src port */ | |
| 41 | − CFG_UDF_EOL3 | 0, | |
| 42 | − /* End of L3, byte offset 2, dst port */ | |
| 43 | − CFG_UDF_EOL3 | 1, | |
| 44 | − 0, 0, 0 | |
| 37 | + .udfs = { | |
| 38 | + [1] = { | |
| 39 | + .slices = { | |
| 40 | + /* End of L2, byte offset 12, src IP[0:15] */ | |
| 41 | + CFG_UDF_EOL2 | 6, | |
| 42 | + /* End of L2, byte offset 14, src IP[16:31] */ | |
| 43 | + CFG_UDF_EOL2 | 7, | |
| 44 | + /* End of L2, byte offset 16, dst IP[0:15] */ | |
| 45 | + CFG_UDF_EOL2 | 8, | |
| 46 | + /* End of L2, byte offset 18, dst IP[16:31] */ | |
| 47 | + CFG_UDF_EOL2 | 9, | |
| 48 | + /* End of L3, byte offset 0, src port */ | |
| 49 | + CFG_UDF_EOL3 | 0, | |
| 50 | + /* End of L3, byte offset 2, dst port */ | |
| 51 | + CFG_UDF_EOL3 | 1, | |
| 52 | + 0, 0, 0 | |
| 53 | + }, | |
| 54 | + .mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG, | |
| 55 | + .base_offset = CORE_UDF_0_A_0_8_PORT_0 + UDF_SLICE_OFFSET, | |
| 56 | + }, | |
| 57 | + }, | |
| 58 | +}; | |
| 59 | + | |
| 60 | +/* UDF slices layout for a TCPv6/UDPv6 specification */ | |
| 61 | +static const struct cfp_udf_layout udf_tcpip6_layout = { | |
| 62 | + .udfs = { | |
| 63 | + [0] = { | |
| 64 | + .slices = { | |
| 65 | + /* End of L2, byte offset 8, src IP[0:15] */ | |
| 66 | + CFG_UDF_EOL2 | 4, | |
| 67 | + /* End of L2, byte offset 10, src IP[16:31] */ | |
| 68 | + CFG_UDF_EOL2 | 5, | |
| 69 | + /* End of L2, byte offset 12, src IP[32:47] */ | |
| 70 | + CFG_UDF_EOL2 | 6, | |
| 71 | + /* End of L2, byte offset 14, src IP[48:63] */ | |
| 72 | + CFG_UDF_EOL2 | 7, | |
| 73 | + /* End of L2, byte offset 16, src IP[64:79] */ | |
| 74 | + CFG_UDF_EOL2 | 8, | |
| 75 | + /* End of L2, byte offset 18, src IP[80:95] */ | |
| 76 | + CFG_UDF_EOL2 | 9, | |
| 77 | + /* End of L2, byte offset 20, src IP[96:111] */ | |
| 78 | + CFG_UDF_EOL2 | 10, | |
| 79 | + /* End of L2, byte offset 22, src IP[112:127] */ | |
| 80 | + CFG_UDF_EOL2 | 11, | |
| 81 | + /* End of L3, byte offset 0, src port */ | |
| 82 | + CFG_UDF_EOL3 | 0, | |
| 83 | + }, | |
| 84 | + .mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG, | |
| 85 | + .base_offset = CORE_UDF_0_B_0_8_PORT_0, | |
| 86 | + }, | |
| 87 | + [3] = { | |
| 88 | + .slices = { | |
| 89 | + /* End of L2, byte offset 24, dst IP[0:15] */ | |
| 90 | + CFG_UDF_EOL2 | 12, | |
| 91 | + /* End of L2, byte offset 26, dst IP[16:31] */ | |
| 92 | + CFG_UDF_EOL2 | 13, | |
| 93 | + /* End of L2, byte offset 28, dst IP[32:47] */ | |
| 94 | + CFG_UDF_EOL2 | 14, | |
| 95 | + /* End of L2, byte offset 30, dst IP[48:63] */ | |
| 96 | + CFG_UDF_EOL2 | 15, | |
| 97 | + /* End of L2, byte offset 32, dst IP[64:79] */ | |
| 98 | + CFG_UDF_EOL2 | 16, | |
| 99 | + /* End of L2, byte offset 34, dst IP[80:95] */ | |
| 100 | + CFG_UDF_EOL2 | 17, | |
| 101 | + /* End of L2, byte offset 36, dst IP[96:111] */ | |
| 102 | + CFG_UDF_EOL2 | 18, | |
| 103 | + /* End of L2, byte offset 38, dst IP[112:127] */ | |
| 104 | + CFG_UDF_EOL2 | 19, | |
| 105 | + /* End of L3, byte offset 2, dst port */ | |
| 106 | + CFG_UDF_EOL3 | 1, | |
| 107 | + }, | |
| 108 | + .mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG, | |
| 109 | + .base_offset = CORE_UDF_0_D_0_11_PORT_0, | |
| 110 | + }, | |
| 45 | 111 | }, |
| 46 | − .mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG, | |
| 47 | 112 | }; |
| 48 | 113 | |
| 49 | 114 | static inline unsigned int bcm_sf2_get_num_udf_slices(const u8 *layout) |
| 50 | 115 | { |
| 51 | 116 | unsigned int i, count = 0; |
| 52 | 117 | |
| 53 | − for (i = 0; i < UDF_NUM_SLICES; i++) { | |
| 118 | + for (i = 0; i < UDFS_PER_SLICE; i++) { | |
| 54 | 119 | if (layout[i] != 0) |
| 55 | 120 | count++; |
| 56 | 121 | } |
| @@ -58,15 +123,42 @@ static inline unsigned int bcm_sf2_get_num_udf_slices(const u8 *layout) · 1 unmodified line | ||
| 58 | 123 | return count; |
| 59 | 124 | } |
| 60 | 125 | |
| 126 | +static inline u32 udf_upper_bits(unsigned int num_udf) | |
| 127 | +{ | |
| 128 | + return GENMASK(num_udf - 1, 0) >> (UDFS_PER_SLICE - 1); | |
| 129 | +} | |
| 130 | + | |
| 131 | +static inline u32 udf_lower_bits(unsigned int num_udf) | |
| 132 | +{ | |
| 133 | + return (u8)GENMASK(num_udf - 1, 0); | |
| 134 | +} | |
| 135 | + | |
| 136 | +static unsigned int bcm_sf2_get_slice_number(const struct cfp_udf_layout *l, | |
| 137 | + unsigned int start) | |
| 138 | +{ | |
| 139 | + const struct cfp_udf_slice_layout *slice_layout; | |
| 140 | + unsigned int slice_idx; | |
| 141 | + | |
| 142 | + for (slice_idx = start; slice_idx < UDF_NUM_SLICES; slice_idx++) { | |
| 143 | + slice_layout = &l->udfs[slice_idx]; | |
| 144 | + if (memcmp(slice_layout->slices, zero_slice, | |
| 145 | + sizeof(zero_slice))) | |
| 146 | + break; | |
| 147 | + } | |
| 148 | + | |
| 149 | + return slice_idx; | |
| 150 | +} | |
| 151 | + | |
| 61 | 152 | static void bcm_sf2_cfp_udf_set(struct bcm_sf2_priv *priv, |
| 62 | − unsigned int slice_num, | |
| 63 | − const u8 *layout) | |
| 153 | + const struct cfp_udf_layout *layout, | |
| 154 | + unsigned int slice_num) | |
| 64 | 155 | { |
| 65 | − u32 offset = CORE_UDF_0_A_0_8_PORT_0 + slice_num * UDF_SLICE_OFFSET; | |
| 156 | + u32 offset = layout->udfs[slice_num].base_offset; | |
| 66 | 157 | unsigned int i; |
| 67 | 158 | |
| 68 | − for (i = 0; i < UDF_NUM_SLICES; i++) | |
| 69 | − core_writel(priv, layout[i], offset + i * 4); | |
| 159 | + for (i = 0; i < UDFS_PER_SLICE; i++) | |
| 160 | + core_writel(priv, layout->udfs[slice_num].slices[i], | |
| 161 | + offset + i * 4); | |
| 70 | 162 | } |
| 71 | 163 | |
| 72 | 164 | static int bcm_sf2_cfp_op(struct bcm_sf2_priv *priv, unsigned int op) |
| @@ -112,104 +204,80 @@ static inline unsigned int bcm_sf2_cfp_rule_size(struct bcm_sf2_priv *priv) · 39 unmodified lines | ||
| 112 | 204 | return priv->num_cfp_rules - 1; |
| 113 | 205 | } |
| 114 | 206 | |
| 115 | −static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, | |
| 116 | − struct ethtool_rx_flow_spec *fs) | |
| 207 | +static int bcm_sf2_cfp_act_pol_set(struct bcm_sf2_priv *priv, | |
| 208 | + unsigned int rule_index, | |
| 209 | + unsigned int port_num, | |
| 210 | + unsigned int queue_num, | |
| 211 | + bool fwd_map_change) | |
| 117 | 212 | { |
| 118 | − struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 119 | − struct ethtool_tcpip4_spec *v4_spec; | |
| 120 | − const struct cfp_udf_layout *layout; | |
| 121 | − unsigned int slice_num, rule_index; | |
| 122 | − unsigned int queue_num, port_num; | |
| 123 | − u8 ip_proto, ip_frag; | |
| 124 | − u8 num_udf; | |
| 125 | − u32 reg; | |
| 126 | 213 | int ret; |
| 214 | + u32 reg; | |
| 127 | 215 | |
| 128 | − /* Check for unsupported extensions */ | |
| 129 | − if ((fs->flow_type & FLOW_EXT) && | |
| 130 | − (fs->m_ext.vlan_etype || fs->m_ext.data[1])) | |
| 131 | − return -EINVAL; | |
| 132 | − | |
| 133 | − if (fs->location != RX_CLS_LOC_ANY && | |
| 134 | − test_bit(fs->location, priv->cfp.used)) | |
| 135 | − return -EBUSY; | |
| 136 | − | |
| 137 | − if (fs->location != RX_CLS_LOC_ANY && | |
| 138 | − fs->location > bcm_sf2_cfp_rule_size(priv)) | |
| 139 | − return -EINVAL; | |
| 216 | + /* Replace ARL derived destination with DST_MAP derived, define | |
| 217 | + * which port and queue this should be forwarded to. | |
| 218 | + */ | |
| 219 | + if (fwd_map_change) | |
| 220 | + reg = CHANGE_FWRD_MAP_IB_REP_ARL | | |
| 221 | + BIT(port_num + DST_MAP_IB_SHIFT) | | |
| 222 | + CHANGE_TC | queue_num << NEW_TC_SHIFT; | |
| 223 | + else | |
| 224 | + reg = 0; | |
| 140 | 225 | |
| 141 | − ip_frag = be32_to_cpu(fs->m_ext.data[0]); | |
| 226 | + core_writel(priv, reg, CORE_ACT_POL_DATA0); | |
| 142 | 227 | |
| 143 | − /* We do not support discarding packets, check that the | |
| 144 | − * destination port is enabled and that we are within the | |
| 145 | − * number of ports supported by the switch | |
| 146 | − */ | |
| 147 | − port_num = fs->ring_cookie / 8; | |
| 228 | + /* Set classification ID that needs to be put in Broadcom tag */ | |
| 229 | + core_writel(priv, rule_index << CHAIN_ID_SHIFT, CORE_ACT_POL_DATA1); | |
| 148 | 230 | |
| 149 | − if (fs->ring_cookie == RX_CLS_FLOW_DISC || | |
| 150 | − !(BIT(port_num) & ds->enabled_port_mask) || | |
| 151 | − port_num >= priv->hw_params.num_ports) | |
| 152 | − return -EINVAL; | |
| 231 | + core_writel(priv, 0, CORE_ACT_POL_DATA2); | |
| 153 | 232 | |
| 154 | − switch (fs->flow_type & ~FLOW_EXT) { | |
| 155 | − case TCP_V4_FLOW: | |
| 156 | − ip_proto = IPPROTO_TCP; | |
| 157 | − v4_spec = &fs->h_u.tcp_ip4_spec; | |
| 158 | − break; | |
| 159 | − case UDP_V4_FLOW: | |
| 160 | − ip_proto = IPPROTO_UDP; | |
| 161 | − v4_spec = &fs->h_u.udp_ip4_spec; | |
| 162 | − break; | |
| 163 | − default: | |
| 164 | − return -EINVAL; | |
| 233 | + /* Configure policer RAM now */ | |
| 234 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | ACT_POL_RAM); | |
| 235 | + if (ret) { | |
| 236 | + pr_err("Policer entry at %d failed\n", rule_index); | |
| 237 | + return ret; | |
| 165 | 238 | } |
| 166 | 239 | |
| 167 | − /* We only use one UDF slice for now */ | |
| 168 | − slice_num = 1; | |
| 169 | − layout = &udf_tcpip4_layout; | |
| 170 | − num_udf = bcm_sf2_get_num_udf_slices(layout->slices); | |
| 171 | − | |
| 172 | − /* Apply the UDF layout for this filter */ | |
| 173 | − bcm_sf2_cfp_udf_set(priv, slice_num, layout->slices); | |
| 240 | + /* Disable the policer */ | |
| 241 | + core_writel(priv, POLICER_MODE_DISABLE, CORE_RATE_METER0); | |
| 174 | 242 | |
| 175 | − /* Apply to all packets received through this port */ | |
| 176 | − core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7)); | |
| 243 | + /* Now the rate meter */ | |
| 244 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | RATE_METER_RAM); | |
| 245 | + if (ret) { | |
| 246 | + pr_err("Meter entry at %d failed\n", rule_index); | |
| 247 | + return ret; | |
| 248 | + } | |
| 177 | 249 | |
| 178 | − /* S-Tag status [31:30] | |
| 179 | − * C-Tag status [29:28] | |
| 180 | − * L2 framing [27:26] | |
| 181 | − * L3 framing [25:24] | |
| 182 | − * IP ToS [23:16] | |
| 183 | − * IP proto [15:08] | |
| 184 | − * IP Fragm [7] | |
| 185 | − * Non 1st frag [6] | |
| 186 | − * IP Authen [5] | |
| 187 | − * TTL range [4:3] | |
| 188 | − * PPPoE session [2] | |
| 189 | − * Reserved [1] | |
| 190 | − * UDF_Valid[8] [0] | |
| 191 | − */ | |
| 192 | − core_writel(priv, v4_spec->tos << 16 | ip_proto << 8 | ip_frag << 7, | |
| 193 | − CORE_CFP_DATA_PORT(6)); | |
| 250 | + return 0; | |
| 251 | +} | |
| 194 | 252 | |
| 195 | − /* UDF_Valid[7:0] [31:24] | |
| 196 | − * S-Tag [23:8] | |
| 197 | − * C-Tag [7:0] | |
| 198 | − */ | |
| 199 | − core_writel(priv, GENMASK(num_udf - 1, 0) << 24, CORE_CFP_DATA_PORT(5)); | |
| 253 | +static void bcm_sf2_cfp_slice_ipv4(struct bcm_sf2_priv *priv, | |
| 254 | + struct ethtool_tcpip4_spec *v4_spec, | |
| 255 | + unsigned int slice_num, | |
| 256 | + bool mask) | |
| 257 | +{ | |
| 258 | + u32 reg, offset; | |
| 200 | 259 | |
| 201 | 260 | /* C-Tag [31:24] |
| 202 | 261 | * UDF_n_A8 [23:8] |
| 203 | 262 | * UDF_n_A7 [7:0] |
| 204 | 263 | */ |
| 205 | − core_writel(priv, 0, CORE_CFP_DATA_PORT(4)); | |
| 264 | + reg = 0; | |
| 265 | + if (mask) | |
| 266 | + offset = CORE_CFP_MASK_PORT(4); | |
| 267 | + else | |
| 268 | + offset = CORE_CFP_DATA_PORT(4); | |
| 269 | + core_writel(priv, reg, offset); | |
| 206 | 270 | |
| 207 | 271 | /* UDF_n_A7 [31:24] |
| 208 | 272 | * UDF_n_A6 [23:8] |
| 209 | 273 | * UDF_n_A5 [7:0] |
| 210 | 274 | */ |
| 211 | − core_writel(priv, be16_to_cpu(v4_spec->pdst) >> 8, | |
| 212 | − CORE_CFP_DATA_PORT(3)); | |
| 275 | + reg = be16_to_cpu(v4_spec->pdst) >> 8; | |
| 276 | + if (mask) | |
| 277 | + offset = CORE_CFP_MASK_PORT(3); | |
| 278 | + else | |
| 279 | + offset = CORE_CFP_DATA_PORT(3); | |
| 280 | + core_writel(priv, reg, offset); | |
| 213 | 281 | |
| 214 | 282 | /* UDF_n_A5 [31:24] |
| 215 | 283 | * UDF_n_A4 [23:8] |
| @@ -218,7 +286,11 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 218 | 286 | reg = (be16_to_cpu(v4_spec->pdst) & 0xff) << 24 | |
| 219 | 287 | (u32)be16_to_cpu(v4_spec->psrc) << 8 | |
| 220 | 288 | (be32_to_cpu(v4_spec->ip4dst) & 0x0000ff00) >> 8; |
| 221 | − core_writel(priv, reg, CORE_CFP_DATA_PORT(2)); | |
| 289 | + if (mask) | |
| 290 | + offset = CORE_CFP_MASK_PORT(2); | |
| 291 | + else | |
| 292 | + offset = CORE_CFP_DATA_PORT(2); | |
| 293 | + core_writel(priv, reg, offset); | |
| 222 | 294 | |
| 223 | 295 | /* UDF_n_A3 [31:24] |
| 224 | 296 | * UDF_n_A2 [23:8] |
| @@ -227,7 +299,11 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 227 | 299 | reg = (u32)(be32_to_cpu(v4_spec->ip4dst) & 0xff) << 24 | |
| 228 | 300 | (u32)(be32_to_cpu(v4_spec->ip4dst) >> 16) << 8 | |
| 229 | 301 | (be32_to_cpu(v4_spec->ip4src) & 0x0000ff00) >> 8; |
| 230 | − core_writel(priv, reg, CORE_CFP_DATA_PORT(1)); | |
| 302 | + if (mask) | |
| 303 | + offset = CORE_CFP_MASK_PORT(1); | |
| 304 | + else | |
| 305 | + offset = CORE_CFP_DATA_PORT(1); | |
| 306 | + core_writel(priv, reg, offset); | |
| 231 | 307 | |
| 232 | 308 | /* UDF_n_A1 [31:24] |
| 233 | 309 | * UDF_n_A0 [23:8] |
| @@ -238,25 +314,42 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, · 4 unmodified lines | ||
| 238 | 314 | reg = (u32)(be32_to_cpu(v4_spec->ip4src) & 0xff) << 24 | |
| 239 | 315 | (u32)(be32_to_cpu(v4_spec->ip4src) >> 16) << 8 | |
| 240 | 316 | SLICE_NUM(slice_num) | SLICE_VALID; |
| 241 | − core_writel(priv, reg, CORE_CFP_DATA_PORT(0)); | |
| 242 | − | |
| 243 | − /* Source port map match */ | |
| 244 | − core_writel(priv, 0xff, CORE_CFP_MASK_PORT(7)); | |
| 245 | − | |
| 246 | − /* Mask with the specific layout for IPv4 packets */ | |
| 247 | − core_writel(priv, layout->mask_value, CORE_CFP_MASK_PORT(6)); | |
| 317 | + if (mask) | |
| 318 | + offset = CORE_CFP_MASK_PORT(0); | |
| 319 | + else | |
| 320 | + offset = CORE_CFP_DATA_PORT(0); | |
| 321 | + core_writel(priv, reg, offset); | |
| 322 | +} | |
| 248 | 323 | |
| 249 | − /* Mask all but valid UDFs */ | |
| 250 | − core_writel(priv, GENMASK(num_udf - 1, 0) << 24, CORE_CFP_MASK_PORT(5)); | |
| 324 | +static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port, | |
| 325 | + unsigned int port_num, | |
| 326 | + unsigned int queue_num, | |
| 327 | + struct ethtool_rx_flow_spec *fs) | |
| 328 | +{ | |
| 329 | + struct ethtool_tcpip4_spec *v4_spec, *v4_m_spec; | |
| 330 | + const struct cfp_udf_layout *layout; | |
| 331 | + unsigned int slice_num, rule_index; | |
| 332 | + u8 ip_proto, ip_frag; | |
| 333 | + u8 num_udf; | |
| 334 | + u32 reg; | |
| 335 | + int ret; | |
| 251 | 336 | |
| 252 | − /* Mask all */ | |
| 253 | − core_writel(priv, 0, CORE_CFP_MASK_PORT(4)); | |
| 337 | + switch (fs->flow_type & ~FLOW_EXT) { | |
| 338 | + case TCP_V4_FLOW: | |
| 339 | + ip_proto = IPPROTO_TCP; | |
| 340 | + v4_spec = &fs->h_u.tcp_ip4_spec; | |
| 341 | + v4_m_spec = &fs->m_u.tcp_ip4_spec; | |
| 342 | + break; | |
| 343 | + case UDP_V4_FLOW: | |
| 344 | + ip_proto = IPPROTO_UDP; | |
| 345 | + v4_spec = &fs->h_u.udp_ip4_spec; | |
| 346 | + v4_m_spec = &fs->m_u.udp_ip4_spec; | |
| 347 | + break; | |
| 348 | + default: | |
| 349 | + return -EINVAL; | |
| 350 | + } | |
| 254 | 351 | |
| 255 | − /* All other UDFs should be matched with the filter */ | |
| 256 | − core_writel(priv, 0xff, CORE_CFP_MASK_PORT(3)); | |
| 257 | − core_writel(priv, 0xffffffff, CORE_CFP_MASK_PORT(2)); | |
| 258 | − core_writel(priv, 0xffffffff, CORE_CFP_MASK_PORT(1)); | |
| 259 | − core_writel(priv, 0xffffff0f, CORE_CFP_MASK_PORT(0)); | |
| 352 | + ip_frag = be32_to_cpu(fs->m_ext.data[0]); | |
| 260 | 353 | |
| 261 | 354 | /* Locate the first rule available */ |
| 262 | 355 | if (fs->location == RX_CLS_LOC_ANY) |
| @@ -265,52 +358,73 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 265 | 358 | else |
| 266 | 359 | rule_index = fs->location; |
| 267 | 360 | |
| 268 | − /* Insert into TCAM now */ | |
| 269 | − bcm_sf2_cfp_rule_addr_set(priv, rule_index); | |
| 361 | + layout = &udf_tcpip4_layout; | |
| 362 | + /* We only use one UDF slice for now */ | |
| 363 | + slice_num = bcm_sf2_get_slice_number(layout, 0); | |
| 364 | + if (slice_num == UDF_NUM_SLICES) | |
| 365 | + return -EINVAL; | |
| 270 | 366 | |
| 271 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 272 | − if (ret) { | |
| 273 | − pr_err("TCAM entry at addr %d failed\n", rule_index); | |
| 274 | − return ret; | |
| 275 | − } | |
| 367 | + num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); | |
| 276 | 368 | |
| 277 | − /* Replace ARL derived destination with DST_MAP derived, define | |
| 278 | − * which port and queue this should be forwarded to. | |
| 279 | − * | |
| 280 | − * We have a small oddity where Port 6 just does not have a | |
| 281 | − * valid bit here (so we subtract by one). | |
| 369 | + /* Apply the UDF layout for this filter */ | |
| 370 | + bcm_sf2_cfp_udf_set(priv, layout, slice_num); | |
| 371 | + | |
| 372 | + /* Apply to all packets received through this port */ | |
| 373 | + core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7)); | |
| 374 | + | |
| 375 | + /* Source port map match */ | |
| 376 | + core_writel(priv, 0xff, CORE_CFP_MASK_PORT(7)); | |
| 377 | + | |
| 378 | + /* S-Tag status [31:30] | |
| 379 | + * C-Tag status [29:28] | |
| 380 | + * L2 framing [27:26] | |
| 381 | + * L3 framing [25:24] | |
| 382 | + * IP ToS [23:16] | |
| 383 | + * IP proto [15:08] | |
| 384 | + * IP Fragm [7] | |
| 385 | + * Non 1st frag [6] | |
| 386 | + * IP Authen [5] | |
| 387 | + * TTL range [4:3] | |
| 388 | + * PPPoE session [2] | |
| 389 | + * Reserved [1] | |
| 390 | + * UDF_Valid[8] [0] | |
| 282 | 391 | */ |
| 283 | − queue_num = fs->ring_cookie % 8; | |
| 284 | − if (port_num >= 7) | |
| 285 | − port_num -= 1; | |
| 392 | + core_writel(priv, v4_spec->tos << IPTOS_SHIFT | | |
| 393 | + ip_proto << IPPROTO_SHIFT | ip_frag << IP_FRAG_SHIFT | | |
| 394 | + udf_upper_bits(num_udf), | |
| 395 | + CORE_CFP_DATA_PORT(6)); | |
| 286 | 396 | |
| 287 | − reg = CHANGE_FWRD_MAP_IB_REP_ARL | BIT(port_num + DST_MAP_IB_SHIFT) | | |
| 288 | − CHANGE_TC | queue_num << NEW_TC_SHIFT; | |
| 397 | + /* Mask with the specific layout for IPv4 packets */ | |
| 398 | + core_writel(priv, layout->udfs[slice_num].mask_value | | |
| 399 | + udf_upper_bits(num_udf), CORE_CFP_MASK_PORT(6)); | |
| 289 | 400 | |
| 290 | − core_writel(priv, reg, CORE_ACT_POL_DATA0); | |
| 401 | + /* UDF_Valid[7:0] [31:24] | |
| 402 | + * S-Tag [23:8] | |
| 403 | + * C-Tag [7:0] | |
| 404 | + */ | |
| 405 | + core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5)); | |
| 291 | 406 | |
| 292 | − /* Set classification ID that needs to be put in Broadcom tag */ | |
| 293 | − core_writel(priv, rule_index << CHAIN_ID_SHIFT, | |
| 294 | − CORE_ACT_POL_DATA1); | |
| 407 | + /* Mask all but valid UDFs */ | |
| 408 | + core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5)); | |
| 295 | 409 | |
| 296 | − core_writel(priv, 0, CORE_ACT_POL_DATA2); | |
| 410 | + /* Program the match and the mask */ | |
| 411 | + bcm_sf2_cfp_slice_ipv4(priv, v4_spec, slice_num, false); | |
| 412 | + bcm_sf2_cfp_slice_ipv4(priv, v4_m_spec, SLICE_NUM_MASK, true); | |
| 297 | 413 | |
| 298 | − /* Configure policer RAM now */ | |
| 299 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | ACT_POL_RAM); | |
| 414 | + /* Insert into TCAM now */ | |
| 415 | + bcm_sf2_cfp_rule_addr_set(priv, rule_index); | |
| 416 | + | |
| 417 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 300 | 418 | if (ret) { |
| 301 | − pr_err("Policer entry at %d failed\n", rule_index); | |
| 419 | + pr_err("TCAM entry at addr %d failed\n", rule_index); | |
| 302 | 420 | return ret; |
| 303 | 421 | } |
| 304 | 422 | |
| 305 | − /* Disable the policer */ | |
| 306 | − core_writel(priv, POLICER_MODE_DISABLE, CORE_RATE_METER0); | |
| 307 | − | |
| 308 | − /* Now the rate meter */ | |
| 309 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | RATE_METER_RAM); | |
| 310 | − if (ret) { | |
| 311 | − pr_err("Meter entry at %d failed\n", rule_index); | |
| 423 | + /* Insert into Action and policer RAMs now */ | |
| 424 | + ret = bcm_sf2_cfp_act_pol_set(priv, rule_index, port_num, | |
| 425 | + queue_num, true); | |
| 426 | + if (ret) | |
| 312 | 427 | return ret; |
| 313 | − } | |
| 314 | 428 | |
| 315 | 429 | /* Turn on CFP for this rule now */ |
| 316 | 430 | reg = core_readl(priv, CORE_CFP_CTL_REG); |
| @@ -319,143 +433,480 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 319 | 433 | |
| 320 | 434 | /* Flag the rule as being used and return it */ |
| 321 | 435 | set_bit(rule_index, priv->cfp.used); |
| 436 | + set_bit(rule_index, priv->cfp.unique); | |
| 322 | 437 | fs->location = rule_index; |
| 323 | 438 | |
| 324 | 439 | return 0; |
| 325 | 440 | } |
| 326 | 441 | |
| 327 | −static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, | |
| 328 | − u32 loc) | |
| 442 | +static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv, | |
| 443 | + const __be32 *ip6_addr, const __be16 port, | |
| 444 | + unsigned int slice_num, | |
| 445 | + bool mask) | |
| 329 | 446 | { |
| 330 | − int ret; | |
| 331 | − u32 reg; | |
| 332 | − | |
| 333 | − /* Refuse deletion of unused rules, and the default reserved rule */ | |
| 334 | − if (!test_bit(loc, priv->cfp.used) || loc == 0) | |
| 335 | − return -EINVAL; | |
| 336 | − | |
| 337 | − /* Indicate which rule we want to read */ | |
| 338 | − bcm_sf2_cfp_rule_addr_set(priv, loc); | |
| 447 | + u32 reg, tmp, val, offset; | |
| 339 | 448 | |
| 340 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL); | |
| 341 | − if (ret) | |
| 342 | − return ret; | |
| 449 | + /* C-Tag [31:24] | |
| 450 | + * UDF_n_B8 [23:8] (port) | |
| 451 | + * UDF_n_B7 (upper) [7:0] (addr[15:8]) | |
| 452 | + */ | |
| 453 | + reg = be32_to_cpu(ip6_addr[3]); | |
| 454 | + val = (u32)be16_to_cpu(port) << 8 | ((reg >> 8) & 0xff); | |
| 455 | + if (mask) | |
| 456 | + offset = CORE_CFP_MASK_PORT(4); | |
| 457 | + else | |
| 458 | + offset = CORE_CFP_DATA_PORT(4); | |
| 459 | + core_writel(priv, val, offset); | |
| 343 | 460 | |
| 344 | − /* Clear its valid bits */ | |
| 345 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(0)); | |
| 346 | − reg &= ~SLICE_VALID; | |
| 347 | − core_writel(priv, reg, CORE_CFP_DATA_PORT(0)); | |
| 461 | + /* UDF_n_B7 (lower) [31:24] (addr[7:0]) | |
| 462 | + * UDF_n_B6 [23:8] (addr[31:16]) | |
| 463 | + * UDF_n_B5 (upper) [7:0] (addr[47:40]) | |
| 464 | + */ | |
| 465 | + tmp = be32_to_cpu(ip6_addr[2]); | |
| 466 | + val = (u32)(reg & 0xff) << 24 | (u32)(reg >> 16) << 8 | | |
| 467 | + ((tmp >> 8) & 0xff); | |
| 468 | + if (mask) | |
| 469 | + offset = CORE_CFP_MASK_PORT(3); | |
| 470 | + else | |
| 471 | + offset = CORE_CFP_DATA_PORT(3); | |
| 472 | + core_writel(priv, val, offset); | |
| 348 | 473 | |
| 349 | − /* Write back this entry into the TCAM now */ | |
| 350 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 351 | − if (ret) | |
| 352 | − return ret; | |
| 474 | + /* UDF_n_B5 (lower) [31:24] (addr[39:32]) | |
| 475 | + * UDF_n_B4 [23:8] (addr[63:48]) | |
| 476 | + * UDF_n_B3 (upper) [7:0] (addr[79:72]) | |
| 477 | + */ | |
| 478 | + reg = be32_to_cpu(ip6_addr[1]); | |
| 479 | + val = (u32)(tmp & 0xff) << 24 | (u32)(tmp >> 16) << 8 | | |
| 480 | + ((reg >> 8) & 0xff); | |
| 481 | + if (mask) | |
| 482 | + offset = CORE_CFP_MASK_PORT(2); | |
| 483 | + else | |
| 484 | + offset = CORE_CFP_DATA_PORT(2); | |
| 485 | + core_writel(priv, val, offset); | |
| 353 | 486 | |
| 354 | − clear_bit(loc, priv->cfp.used); | |
| 487 | + /* UDF_n_B3 (lower) [31:24] (addr[71:64]) | |
| 488 | + * UDF_n_B2 [23:8] (addr[95:80]) | |
| 489 | + * UDF_n_B1 (upper) [7:0] (addr[111:104]) | |
| 490 | + */ | |
| 491 | + tmp = be32_to_cpu(ip6_addr[0]); | |
| 492 | + val = (u32)(reg & 0xff) << 24 | (u32)(reg >> 16) << 8 | | |
| 493 | + ((tmp >> 8) & 0xff); | |
| 494 | + if (mask) | |
| 495 | + offset = CORE_CFP_MASK_PORT(1); | |
| 496 | + else | |
| 497 | + offset = CORE_CFP_DATA_PORT(1); | |
| 498 | + core_writel(priv, val, offset); | |
| 355 | 499 | |
| 356 | − return 0; | |
| 500 | + /* UDF_n_B1 (lower) [31:24] (addr[103:96]) | |
| 501 | + * UDF_n_B0 [23:8] (addr[127:112]) | |
| 502 | + * Reserved [7:4] | |
| 503 | + * Slice ID [3:2] | |
| 504 | + * Slice valid [1:0] | |
| 505 | + */ | |
| 506 | + reg = (u32)(tmp & 0xff) << 24 | (u32)(tmp >> 16) << 8 | | |
| 507 | + SLICE_NUM(slice_num) | SLICE_VALID; | |
| 508 | + if (mask) | |
| 509 | + offset = CORE_CFP_MASK_PORT(0); | |
| 510 | + else | |
| 511 | + offset = CORE_CFP_DATA_PORT(0); | |
| 512 | + core_writel(priv, reg, offset); | |
| 357 | 513 | } |
| 358 | 514 | |
| 359 | −static void bcm_sf2_invert_masks(struct ethtool_rx_flow_spec *flow) | |
| 515 | +static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port, | |
| 516 | + unsigned int port_num, | |
| 517 | + unsigned int queue_num, | |
| 518 | + struct ethtool_rx_flow_spec *fs) | |
| 360 | 519 | { |
| 361 | − unsigned int i; | |
| 362 | − | |
| 363 | − for (i = 0; i < sizeof(flow->m_u); i++) | |
| 364 | − flow->m_u.hdata[i] ^= 0xff; | |
| 520 | + struct ethtool_tcpip6_spec *v6_spec, *v6_m_spec; | |
| 521 | + unsigned int slice_num, rule_index[2]; | |
| 522 | + const struct cfp_udf_layout *layout; | |
| 523 | + u8 ip_proto, ip_frag; | |
| 524 | + int ret = 0; | |
| 525 | + u8 num_udf; | |
| 526 | + u32 reg; | |
| 365 | 527 | |
| 366 | − flow->m_ext.vlan_etype ^= cpu_to_be16(~0); | |
| 367 | − flow->m_ext.vlan_tci ^= cpu_to_be16(~0); | |
| 368 | − flow->m_ext.data[0] ^= cpu_to_be32(~0); | |
| 369 | − flow->m_ext.data[1] ^= cpu_to_be32(~0); | |
| 370 | −} | |
| 528 | + switch (fs->flow_type & ~FLOW_EXT) { | |
| 529 | + case TCP_V6_FLOW: | |
| 530 | + ip_proto = IPPROTO_TCP; | |
| 531 | + v6_spec = &fs->h_u.tcp_ip6_spec; | |
| 532 | + v6_m_spec = &fs->m_u.tcp_ip6_spec; | |
| 533 | + break; | |
| 534 | + case UDP_V6_FLOW: | |
| 535 | + ip_proto = IPPROTO_UDP; | |
| 536 | + v6_spec = &fs->h_u.udp_ip6_spec; | |
| 537 | + v6_m_spec = &fs->m_u.udp_ip6_spec; | |
| 538 | + break; | |
| 539 | + default: | |
| 540 | + return -EINVAL; | |
| 541 | + } | |
| 371 | 542 | |
| 372 | −static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port, | |
| 373 | − struct ethtool_rxnfc *nfc, bool search) | |
| 374 | −{ | |
| 375 | − struct ethtool_tcpip4_spec *v4_spec; | |
| 376 | − unsigned int queue_num; | |
| 377 | − u16 src_dst_port; | |
| 378 | − u32 reg, ipv4; | |
| 379 | − int ret; | |
| 543 | + ip_frag = be32_to_cpu(fs->m_ext.data[0]); | |
| 380 | 544 | |
| 381 | − if (!search) { | |
| 382 | − bcm_sf2_cfp_rule_addr_set(priv, nfc->fs.location); | |
| 545 | + layout = &udf_tcpip6_layout; | |
| 546 | + slice_num = bcm_sf2_get_slice_number(layout, 0); | |
| 547 | + if (slice_num == UDF_NUM_SLICES) | |
| 548 | + return -EINVAL; | |
| 383 | 549 | |
| 384 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | ACT_POL_RAM); | |
| 385 | − if (ret) | |
| 386 | − return ret; | |
| 550 | + num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); | |
| 551 | + | |
| 552 | + /* Negotiate two indexes, one for the second half which we are chained | |
| 553 | + * from, which is what we will return to user-space, and a second one | |
| 554 | + * which is used to store its first half. That first half does not | |
| 555 | + * allow any choice of placement, so it just needs to find the next | |
| 556 | + * available bit. We return the second half as fs->location because | |
| 557 | + * that helps with the rule lookup later on since the second half is | |
| 558 | + * chained from its first half, we can easily identify IPv6 CFP rules | |
| 559 | + * by looking whether they carry a CHAIN_ID. | |
| 560 | + * | |
| 561 | + * We also want the second half to have a lower rule_index than its | |
| 562 | + * first half because the HW search is by incrementing addresses. | |
| 563 | + */ | |
| 564 | + if (fs->location == RX_CLS_LOC_ANY) | |
| 565 | + rule_index[0] = find_first_zero_bit(priv->cfp.used, | |
| 566 | + bcm_sf2_cfp_rule_size(priv)); | |
| 567 | + else | |
| 568 | + rule_index[0] = fs->location; | |
| 387 | 569 | |
| 388 | − reg = core_readl(priv, CORE_ACT_POL_DATA0); | |
| 570 | + /* Flag it as used (cleared on error path) such that we can immediately | |
| 571 | + * obtain a second one to chain from. | |
| 572 | + */ | |
| 573 | + set_bit(rule_index[0], priv->cfp.used); | |
| 389 | 574 | |
| 390 | − ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL); | |
| 391 | − if (ret) | |
| 392 | − return ret; | |
| 393 | − } else { | |
| 394 | − reg = core_readl(priv, CORE_ACT_POL_DATA0); | |
| 575 | + rule_index[1] = find_first_zero_bit(priv->cfp.used, | |
| 576 | + bcm_sf2_cfp_rule_size(priv)); | |
| 577 | + if (rule_index[1] > bcm_sf2_cfp_rule_size(priv)) { | |
| 578 | + ret = -ENOSPC; | |
| 579 | + goto out_err; | |
| 395 | 580 | } |
| 396 | 581 | |
| 397 | − /* Extract the destination port */ | |
| 398 | − nfc->fs.ring_cookie = fls((reg >> DST_MAP_IB_SHIFT) & | |
| 399 | − DST_MAP_IB_MASK) - 1; | |
| 582 | + /* Apply the UDF layout for this filter */ | |
| 583 | + bcm_sf2_cfp_udf_set(priv, layout, slice_num); | |
| 400 | 584 | |
| 401 | − /* There is no Port 6, so we compensate for that here */ | |
| 402 | − if (nfc->fs.ring_cookie >= 6) | |
| 403 | − nfc->fs.ring_cookie++; | |
| 404 | − nfc->fs.ring_cookie *= 8; | |
| 585 | + /* Apply to all packets received through this port */ | |
| 586 | + core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7)); | |
| 405 | 587 | |
| 406 | − /* Extract the destination queue */ | |
| 407 | − queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK; | |
| 408 | − nfc->fs.ring_cookie += queue_num; | |
| 588 | + /* Source port map match */ | |
| 589 | + core_writel(priv, 0xff, CORE_CFP_MASK_PORT(7)); | |
| 409 | 590 | |
| 410 | − /* Extract the IP protocol */ | |
| 411 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(6)); | |
| 412 | − switch ((reg & IPPROTO_MASK) >> IPPROTO_SHIFT) { | |
| 413 | − case IPPROTO_TCP: | |
| 414 | − nfc->fs.flow_type = TCP_V4_FLOW; | |
| 415 | − v4_spec = &nfc->fs.h_u.tcp_ip4_spec; | |
| 591 | + /* S-Tag status [31:30] | |
| 592 | + * C-Tag status [29:28] | |
| 593 | + * L2 framing [27:26] | |
| 594 | + * L3 framing [25:24] | |
| 595 | + * IP ToS [23:16] | |
| 596 | + * IP proto [15:08] | |
| 597 | + * IP Fragm [7] | |
| 598 | + * Non 1st frag [6] | |
| 599 | + * IP Authen [5] | |
| 600 | + * TTL range [4:3] | |
| 601 | + * PPPoE session [2] | |
| 602 | + * Reserved [1] | |
| 603 | + * UDF_Valid[8] [0] | |
| 604 | + */ | |
| 605 | + reg = 1 << L3_FRAMING_SHIFT | ip_proto << IPPROTO_SHIFT | | |
| 606 | + ip_frag << IP_FRAG_SHIFT | udf_upper_bits(num_udf); | |
| 607 | + core_writel(priv, reg, CORE_CFP_DATA_PORT(6)); | |
| 608 | + | |
| 609 | + /* Mask with the specific layout for IPv6 packets including | |
| 610 | + * UDF_Valid[8] | |
| 611 | + */ | |
| 612 | + reg = layout->udfs[slice_num].mask_value | udf_upper_bits(num_udf); | |
| 613 | + core_writel(priv, reg, CORE_CFP_MASK_PORT(6)); | |
| 614 | + | |
| 615 | + /* UDF_Valid[7:0] [31:24] | |
| 616 | + * S-Tag [23:8] | |
| 617 | + * C-Tag [7:0] | |
| 618 | + */ | |
| 619 | + core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_DATA_PORT(5)); | |
| 620 | + | |
| 621 | + /* Mask all but valid UDFs */ | |
| 622 | + core_writel(priv, udf_lower_bits(num_udf) << 24, CORE_CFP_MASK_PORT(5)); | |
| 623 | + | |
| 624 | + /* Slice the IPv6 source address and port */ | |
| 625 | + bcm_sf2_cfp_slice_ipv6(priv, v6_spec->ip6src, v6_spec->psrc, | |
| 626 | + slice_num, false); | |
| 627 | + bcm_sf2_cfp_slice_ipv6(priv, v6_m_spec->ip6src, v6_m_spec->psrc, | |
| 628 | + slice_num, true); | |
| 629 | + | |
| 630 | + /* Insert into TCAM now because we need to insert a second rule */ | |
| 631 | + bcm_sf2_cfp_rule_addr_set(priv, rule_index[0]); | |
| 632 | + | |
| 633 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 634 | + if (ret) { | |
| 635 | + pr_err("TCAM entry at addr %d failed\n", rule_index[0]); | |
| 636 | + goto out_err; | |
| 637 | + } | |
| 638 | + | |
| 639 | + /* Insert into Action and policer RAMs now */ | |
| 640 | + ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port_num, | |
| 641 | + queue_num, false); | |
| 642 | + if (ret) | |
| 643 | + goto out_err; | |
| 644 | + | |
| 645 | + /* Now deal with the second slice to chain this rule */ | |
| 646 | + slice_num = bcm_sf2_get_slice_number(layout, slice_num + 1); | |
| 647 | + if (slice_num == UDF_NUM_SLICES) { | |
| 648 | + ret = -EINVAL; | |
| 649 | + goto out_err; | |
| 650 | + } | |
| 651 | + | |
| 652 | + num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); | |
| 653 | + | |
| 654 | + /* Apply the UDF layout for this filter */ | |
| 655 | + bcm_sf2_cfp_udf_set(priv, layout, slice_num); | |
| 656 | + | |
| 657 | + /* Chained rule, source port match is coming from the rule we are | |
| 658 | + * chained from. | |
| 659 | + */ | |
| 660 | + core_writel(priv, 0, CORE_CFP_DATA_PORT(7)); | |
| 661 | + core_writel(priv, 0, CORE_CFP_MASK_PORT(7)); | |
| 662 | + | |
| 663 | + /* | |
| 664 | + * CHAIN ID [31:24] chain to previous slice | |
| 665 | + * Reserved [23:20] | |
| 666 | + * UDF_Valid[11:8] [19:16] | |
| 667 | + * UDF_Valid[7:0] [15:8] | |
| 668 | + * UDF_n_D11 [7:0] | |
| 669 | + */ | |
| 670 | + reg = rule_index[0] << 24 | udf_upper_bits(num_udf) << 16 | | |
| 671 | + udf_lower_bits(num_udf) << 8; | |
| 672 | + core_writel(priv, reg, CORE_CFP_DATA_PORT(6)); | |
| 673 | + | |
| 674 | + /* Mask all except chain ID, UDF Valid[8] and UDF Valid[7:0] */ | |
| 675 | + reg = XCESS_ADDR_MASK << 24 | udf_upper_bits(num_udf) << 16 | | |
| 676 | + udf_lower_bits(num_udf) << 8; | |
| 677 | + core_writel(priv, reg, CORE_CFP_MASK_PORT(6)); | |
| 678 | + | |
| 679 | + /* Don't care */ | |
| 680 | + core_writel(priv, 0, CORE_CFP_DATA_PORT(5)); | |
| 681 | + | |
| 682 | + /* Mask all */ | |
| 683 | + core_writel(priv, 0, CORE_CFP_MASK_PORT(5)); | |
| 684 | + | |
| 685 | + bcm_sf2_cfp_slice_ipv6(priv, v6_spec->ip6dst, v6_spec->pdst, slice_num, | |
| 686 | + false); | |
| 687 | + bcm_sf2_cfp_slice_ipv6(priv, v6_m_spec->ip6dst, v6_m_spec->pdst, | |
| 688 | + SLICE_NUM_MASK, true); | |
| 689 | + | |
| 690 | + /* Insert into TCAM now */ | |
| 691 | + bcm_sf2_cfp_rule_addr_set(priv, rule_index[1]); | |
| 692 | + | |
| 693 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 694 | + if (ret) { | |
| 695 | + pr_err("TCAM entry at addr %d failed\n", rule_index[1]); | |
| 696 | + goto out_err; | |
| 697 | + } | |
| 698 | + | |
| 699 | + /* Insert into Action and policer RAMs now, set chain ID to | |
| 700 | + * the one we are chained to | |
| 701 | + */ | |
| 702 | + ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port_num, | |
| 703 | + queue_num, true); | |
| 704 | + if (ret) | |
| 705 | + goto out_err; | |
| 706 | + | |
| 707 | + /* Turn on CFP for this rule now */ | |
| 708 | + reg = core_readl(priv, CORE_CFP_CTL_REG); | |
| 709 | + reg |= BIT(port); | |
| 710 | + core_writel(priv, reg, CORE_CFP_CTL_REG); | |
| 711 | + | |
| 712 | + /* Flag the second half rule as being used now, return it as the | |
| 713 | + * location, and flag it as unique while dumping rules | |
| 714 | + */ | |
| 715 | + set_bit(rule_index[1], priv->cfp.used); | |
| 716 | + set_bit(rule_index[1], priv->cfp.unique); | |
| 717 | + fs->location = rule_index[1]; | |
| 718 | + | |
| 719 | + return ret; | |
| 720 | + | |
| 721 | +out_err: | |
| 722 | + clear_bit(rule_index[0], priv->cfp.used); | |
| 723 | + return ret; | |
| 724 | +} | |
| 725 | + | |
| 726 | +static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, | |
| 727 | + struct ethtool_rx_flow_spec *fs) | |
| 728 | +{ | |
| 729 | + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | |
| 730 | + unsigned int queue_num, port_num; | |
| 731 | + int ret = -EINVAL; | |
| 732 | + | |
| 733 | + /* Check for unsupported extensions */ | |
| 734 | + if ((fs->flow_type & FLOW_EXT) && (fs->m_ext.vlan_etype || | |
| 735 | + fs->m_ext.data[1])) | |
| 736 | + return -EINVAL; | |
| 737 | + | |
| 738 | + if (fs->location != RX_CLS_LOC_ANY && | |
| 739 | + test_bit(fs->location, priv->cfp.used)) | |
| 740 | + return -EBUSY; | |
| 741 | + | |
| 742 | + if (fs->location != RX_CLS_LOC_ANY && | |
| 743 | + fs->location > bcm_sf2_cfp_rule_size(priv)) | |
| 744 | + return -EINVAL; | |
| 745 | + | |
| 746 | + /* We do not support discarding packets, check that the | |
| 747 | + * destination port is enabled and that we are within the | |
| 748 | + * number of ports supported by the switch | |
| 749 | + */ | |
| 750 | + port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES; | |
| 751 | + | |
| 752 | + if (fs->ring_cookie == RX_CLS_FLOW_DISC || | |
| 753 | + !dsa_is_user_port(ds, port_num) || | |
| 754 | + port_num >= priv->hw_params.num_ports) | |
| 755 | + return -EINVAL; | |
| 756 | + /* | |
| 757 | + * We have a small oddity where Port 6 just does not have a | |
| 758 | + * valid bit here (so we substract by one). | |
| 759 | + */ | |
| 760 | + queue_num = fs->ring_cookie % SF2_NUM_EGRESS_QUEUES; | |
| 761 | + if (port_num >= 7) | |
| 762 | + port_num -= 1; | |
| 763 | + | |
| 764 | + switch (fs->flow_type & ~FLOW_EXT) { | |
| 765 | + case TCP_V4_FLOW: | |
| 766 | + case UDP_V4_FLOW: | |
| 767 | + ret = bcm_sf2_cfp_ipv4_rule_set(priv, port, port_num, | |
| 768 | + queue_num, fs); | |
| 416 | 769 | break; |
| 417 | − case IPPROTO_UDP: | |
| 418 | − nfc->fs.flow_type = UDP_V4_FLOW; | |
| 419 | − v4_spec = &nfc->fs.h_u.udp_ip4_spec; | |
| 770 | + case TCP_V6_FLOW: | |
| 771 | + case UDP_V6_FLOW: | |
| 772 | + ret = bcm_sf2_cfp_ipv6_rule_set(priv, port, port_num, | |
| 773 | + queue_num, fs); | |
| 420 | 774 | break; |
| 421 | 775 | default: |
| 422 | − /* Clear to exit the search process */ | |
| 423 | − if (search) | |
| 424 | − core_readl(priv, CORE_CFP_DATA_PORT(7)); | |
| 425 | − return -EINVAL; | |
| 776 | + break; | |
| 426 | 777 | } |
| 427 | 778 | |
| 428 | − v4_spec->tos = (reg >> 16) & IPPROTO_MASK; | |
| 429 | − nfc->fs.m_ext.data[0] = cpu_to_be32((reg >> 7) & 1); | |
| 779 | + return ret; | |
| 780 | +} | |
| 781 | + | |
| 782 | +static int bcm_sf2_cfp_rule_del_one(struct bcm_sf2_priv *priv, int port, | |
| 783 | + u32 loc, u32 *next_loc) | |
| 784 | +{ | |
| 785 | + int ret; | |
| 786 | + u32 reg; | |
| 430 | 787 | |
| 431 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(3)); | |
| 788 | + /* Refuse deletion of unused rules, and the default reserved rule */ | |
| 789 | + if (!test_bit(loc, priv->cfp.used) || loc == 0) | |
| 790 | + return -EINVAL; | |
| 791 | + | |
| 792 | + /* Indicate which rule we want to read */ | |
| 793 | + bcm_sf2_cfp_rule_addr_set(priv, loc); | |
| 794 | + | |
| 795 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL); | |
| 796 | + if (ret) | |
| 797 | + return ret; | |
| 798 | + | |
| 799 | + /* Check if this is possibly an IPv6 rule that would | |
| 800 | + * indicate we need to delete its companion rule | |
| 801 | + * as well | |
| 802 | + */ | |
| 803 | + reg = core_readl(priv, CORE_CFP_DATA_PORT(6)); | |
| 804 | + if (next_loc) | |
| 805 | + *next_loc = (reg >> 24) & CHAIN_ID_MASK; | |
| 806 | + | |
| 807 | + /* Clear its valid bits */ | |
| 808 | + reg = core_readl(priv, CORE_CFP_DATA_PORT(0)); | |
| 809 | + reg &= ~SLICE_VALID; | |
| 810 | + core_writel(priv, reg, CORE_CFP_DATA_PORT(0)); | |
| 811 | + | |
| 812 | + /* Write back this entry into the TCAM now */ | |
| 813 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); | |
| 814 | + if (ret) | |
| 815 | + return ret; | |
| 816 | + | |
| 817 | + clear_bit(loc, priv->cfp.used); | |
| 818 | + clear_bit(loc, priv->cfp.unique); | |
| 819 | + | |
| 820 | + return 0; | |
| 821 | +} | |
| 822 | + | |
| 823 | +static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, | |
| 824 | + u32 loc) | |
| 825 | +{ | |
| 826 | + u32 next_loc = 0; | |
| 827 | + int ret; | |
| 828 | + | |
| 829 | + ret = bcm_sf2_cfp_rule_del_one(priv, port, loc, &next_loc); | |
| 830 | + if (ret) | |
| 831 | + return ret; | |
| 832 | + | |
| 833 | + /* If this was an IPv6 rule, delete is companion rule too */ | |
| 834 | + if (next_loc) | |
| 835 | + ret = bcm_sf2_cfp_rule_del_one(priv, port, next_loc, NULL); | |
| 836 | + | |
| 837 | + return ret; | |
| 838 | +} | |
| 839 | + | |
| 840 | +static void bcm_sf2_invert_masks(struct ethtool_rx_flow_spec *flow) | |
| 841 | +{ | |
| 842 | + unsigned int i; | |
| 843 | + | |
| 844 | + for (i = 0; i < sizeof(flow->m_u); i++) | |
| 845 | + flow->m_u.hdata[i] ^= 0xff; | |
| 846 | + | |
| 847 | + flow->m_ext.vlan_etype ^= cpu_to_be16(~0); | |
| 848 | + flow->m_ext.vlan_tci ^= cpu_to_be16(~0); | |
| 849 | + flow->m_ext.data[0] ^= cpu_to_be32(~0); | |
| 850 | + flow->m_ext.data[1] ^= cpu_to_be32(~0); | |
| 851 | +} | |
| 852 | + | |
| 853 | +static int bcm_sf2_cfp_unslice_ipv4(struct bcm_sf2_priv *priv, | |
| 854 | + struct ethtool_tcpip4_spec *v4_spec, | |
| 855 | + bool mask) | |
| 856 | +{ | |
| 857 | + u32 reg, offset, ipv4; | |
| 858 | + u16 src_dst_port; | |
| 859 | + | |
| 860 | + if (mask) | |
| 861 | + offset = CORE_CFP_MASK_PORT(3); | |
| 862 | + else | |
| 863 | + offset = CORE_CFP_DATA_PORT(3); | |
| 864 | + | |
| 865 | + reg = core_readl(priv, offset); | |
| 432 | 866 | /* src port [15:8] */ |
| 433 | 867 | src_dst_port = reg << 8; |
| 434 | 868 | |
| 435 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(2)); | |
| 869 | + if (mask) | |
| 870 | + offset = CORE_CFP_MASK_PORT(2); | |
| 871 | + else | |
| 872 | + offset = CORE_CFP_DATA_PORT(2); | |
| 873 | + | |
| 874 | + reg = core_readl(priv, offset); | |
| 436 | 875 | /* src port [7:0] */ |
| 437 | 876 | src_dst_port |= (reg >> 24); |
| 438 | 877 | |
| 439 | 878 | v4_spec->pdst = cpu_to_be16(src_dst_port); |
| 440 | − nfc->fs.m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0); | |
| 441 | 879 | v4_spec->psrc = cpu_to_be16((u16)(reg >> 8)); |
| 442 | − nfc->fs.m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0); | |
| 443 | 880 | |
| 444 | 881 | /* IPv4 dst [15:8] */ |
| 445 | 882 | ipv4 = (reg & 0xff) << 8; |
| 446 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(1)); | |
| 883 | + | |
| 884 | + if (mask) | |
| 885 | + offset = CORE_CFP_MASK_PORT(1); | |
| 886 | + else | |
| 887 | + offset = CORE_CFP_DATA_PORT(1); | |
| 888 | + | |
| 889 | + reg = core_readl(priv, offset); | |
| 447 | 890 | /* IPv4 dst [31:16] */ |
| 448 | 891 | ipv4 |= ((reg >> 8) & 0xffff) << 16; |
| 449 | 892 | /* IPv4 dst [7:0] */ |
| 450 | 893 | ipv4 |= (reg >> 24) & 0xff; |
| 451 | 894 | v4_spec->ip4dst = cpu_to_be32(ipv4); |
| 452 | − nfc->fs.m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0); | |
| 453 | 895 | |
| 454 | 896 | /* IPv4 src [15:8] */ |
| 455 | 897 | ipv4 = (reg & 0xff) << 8; |
| 456 | − reg = core_readl(priv, CORE_CFP_DATA_PORT(0)); | |
| 457 | 898 | |
| 458 | − if (!(reg & SLICE_VALID)) | |
| 899 | + if (mask) | |
| 900 | + offset = CORE_CFP_MASK_PORT(0); | |
| 901 | + else | |
| 902 | + offset = CORE_CFP_DATA_PORT(0); | |
| 903 | + reg = core_readl(priv, offset); | |
| 904 | + | |
| 905 | + /* Once the TCAM is programmed, the mask reflects the slice number | |
| 906 | + * being matched, don't bother checking it when reading back the | |
| 907 | + * mask spec | |
| 908 | + */ | |
| 909 | + if (!mask && !(reg & SLICE_VALID)) | |
| 459 | 910 | return -EINVAL; |
| 460 | 911 | |
| 461 | 912 | /* IPv4 src [7:0] */ |
| @@ -463,7 +914,233 @@ static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port, · 1 unmodified line | ||
| 463 | 914 | /* IPv4 src [31:16] */ |
| 464 | 915 | ipv4 |= ((reg >> 8) & 0xffff) << 16; |
| 465 | 916 | v4_spec->ip4src = cpu_to_be32(ipv4); |
| 466 | − nfc->fs.m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0); | |
| 917 | + | |
| 918 | + return 0; | |
| 919 | +} | |
| 920 | + | |
| 921 | +static int bcm_sf2_cfp_ipv4_rule_get(struct bcm_sf2_priv *priv, int port, | |
| 922 | + struct ethtool_rx_flow_spec *fs) | |
| 923 | +{ | |
| 924 | + struct ethtool_tcpip4_spec *v4_spec = NULL, *v4_m_spec = NULL; | |
| 925 | + u32 reg; | |
| 926 | + int ret; | |
| 927 | + | |
| 928 | + reg = core_readl(priv, CORE_CFP_DATA_PORT(6)); | |
| 929 | + | |
| 930 | + switch ((reg & IPPROTO_MASK) >> IPPROTO_SHIFT) { | |
| 931 | + case IPPROTO_TCP: | |
| 932 | + fs->flow_type = TCP_V4_FLOW; | |
| 933 | + v4_spec = &fs->h_u.tcp_ip4_spec; | |
| 934 | + v4_m_spec = &fs->m_u.tcp_ip4_spec; | |
| 935 | + break; | |
| 936 | + case IPPROTO_UDP: | |
| 937 | + fs->flow_type = UDP_V4_FLOW; | |
| 938 | + v4_spec = &fs->h_u.udp_ip4_spec; | |
| 939 | + v4_m_spec = &fs->m_u.udp_ip4_spec; | |
| 940 | + break; | |
| 941 | + default: | |
| 942 | + return -EINVAL; | |
| 943 | + } | |
| 944 | + | |
| 945 | + fs->m_ext.data[0] = cpu_to_be32((reg >> IP_FRAG_SHIFT) & 1); | |
| 946 | + v4_spec->tos = (reg >> IPTOS_SHIFT) & IPTOS_MASK; | |
| 947 | + | |
| 948 | + ret = bcm_sf2_cfp_unslice_ipv4(priv, v4_spec, false); | |
| 949 | + if (ret) | |
| 950 | + return ret; | |
| 951 | + | |
| 952 | + return bcm_sf2_cfp_unslice_ipv4(priv, v4_m_spec, true); | |
| 953 | +} | |
| 954 | + | |
| 955 | +static int bcm_sf2_cfp_unslice_ipv6(struct bcm_sf2_priv *priv, | |
| 956 | + __be32 *ip6_addr, __be16 *port, | |
| 957 | + bool mask) | |
| 958 | +{ | |
| 959 | + u32 reg, tmp, offset; | |
| 960 | + | |
| 961 | + /* C-Tag [31:24] | |
| 962 | + * UDF_n_B8 [23:8] (port) | |
| 963 | + * UDF_n_B7 (upper) [7:0] (addr[15:8]) | |
| 964 | + */ | |
| 965 | + if (mask) | |
| 966 | + offset = CORE_CFP_MASK_PORT(4); | |
| 967 | + else | |
| 968 | + offset = CORE_CFP_DATA_PORT(4); | |
| 969 | + reg = core_readl(priv, offset); | |
| 970 | + *port = cpu_to_be32(reg) >> 8; | |
| 971 | + tmp = (u32)(reg & 0xff) << 8; | |
| 972 | + | |
| 973 | + /* UDF_n_B7 (lower) [31:24] (addr[7:0]) | |
| 974 | + * UDF_n_B6 [23:8] (addr[31:16]) | |
| 975 | + * UDF_n_B5 (upper) [7:0] (addr[47:40]) | |
| 976 | + */ | |
| 977 | + if (mask) | |
| 978 | + offset = CORE_CFP_MASK_PORT(3); | |
| 979 | + else | |
| 980 | + offset = CORE_CFP_DATA_PORT(3); | |
| 981 | + reg = core_readl(priv, offset); | |
| 982 | + tmp |= (reg >> 24) & 0xff; | |
| 983 | + tmp |= (u32)((reg >> 8) << 16); | |
| 984 | + ip6_addr[3] = cpu_to_be32(tmp); | |
| 985 | + tmp = (u32)(reg & 0xff) << 8; | |
| 986 | + | |
| 987 | + /* UDF_n_B5 (lower) [31:24] (addr[39:32]) | |
| 988 | + * UDF_n_B4 [23:8] (addr[63:48]) | |
| 989 | + * UDF_n_B3 (upper) [7:0] (addr[79:72]) | |
| 990 | + */ | |
| 991 | + if (mask) | |
| 992 | + offset = CORE_CFP_MASK_PORT(2); | |
| 993 | + else | |
| 994 | + offset = CORE_CFP_DATA_PORT(2); | |
| 995 | + reg = core_readl(priv, offset); | |
| 996 | + tmp |= (reg >> 24) & 0xff; | |
| 997 | + tmp |= (u32)((reg >> 8) << 16); | |
| 998 | + ip6_addr[2] = cpu_to_be32(tmp); | |
| 999 | + tmp = (u32)(reg & 0xff) << 8; | |
| 1000 | + | |
| 1001 | + /* UDF_n_B3 (lower) [31:24] (addr[71:64]) | |
| 1002 | + * UDF_n_B2 [23:8] (addr[95:80]) | |
| 1003 | + * UDF_n_B1 (upper) [7:0] (addr[111:104]) | |
| 1004 | + */ | |
| 1005 | + if (mask) | |
| 1006 | + offset = CORE_CFP_MASK_PORT(1); | |
| 1007 | + else | |
| 1008 | + offset = CORE_CFP_DATA_PORT(1); | |
| 1009 | + reg = core_readl(priv, offset); | |
| 1010 | + tmp |= (reg >> 24) & 0xff; | |
| 1011 | + tmp |= (u32)((reg >> 8) << 16); | |
| 1012 | + ip6_addr[1] = cpu_to_be32(tmp); | |
| 1013 | + tmp = (u32)(reg & 0xff) << 8; | |
| 1014 | + | |
| 1015 | + /* UDF_n_B1 (lower) [31:24] (addr[103:96]) | |
| 1016 | + * UDF_n_B0 [23:8] (addr[127:112]) | |
| 1017 | + * Reserved [7:4] | |
| 1018 | + * Slice ID [3:2] | |
| 1019 | + * Slice valid [1:0] | |
| 1020 | + */ | |
| 1021 | + if (mask) | |
| 1022 | + offset = CORE_CFP_MASK_PORT(0); | |
| 1023 | + else | |
| 1024 | + offset = CORE_CFP_DATA_PORT(0); | |
| 1025 | + reg = core_readl(priv, offset); | |
| 1026 | + tmp |= (reg >> 24) & 0xff; | |
| 1027 | + tmp |= (u32)((reg >> 8) << 16); | |
| 1028 | + ip6_addr[0] = cpu_to_be32(tmp); | |
| 1029 | + | |
| 1030 | + if (!mask && !(reg & SLICE_VALID)) | |
| 1031 | + return -EINVAL; | |
| 1032 | + | |
| 1033 | + return 0; | |
| 1034 | +} | |
| 1035 | + | |
| 1036 | +static int bcm_sf2_cfp_ipv6_rule_get(struct bcm_sf2_priv *priv, int port, | |
| 1037 | + struct ethtool_rx_flow_spec *fs, | |
| 1038 | + u32 next_loc) | |
| 1039 | +{ | |
| 1040 | + struct ethtool_tcpip6_spec *v6_spec = NULL, *v6_m_spec = NULL; | |
| 1041 | + u32 reg; | |
| 1042 | + int ret; | |
| 1043 | + | |
| 1044 | + /* UDPv6 and TCPv6 both use ethtool_tcpip6_spec so we are fine | |
| 1045 | + * assuming tcp_ip6_spec here being an union. | |
| 1046 | + */ | |
| 1047 | + v6_spec = &fs->h_u.tcp_ip6_spec; | |
| 1048 | + v6_m_spec = &fs->m_u.tcp_ip6_spec; | |
| 1049 | + | |
| 1050 | + /* Read the second half first */ | |
| 1051 | + ret = bcm_sf2_cfp_unslice_ipv6(priv, v6_spec->ip6dst, &v6_spec->pdst, | |
| 1052 | + false); | |
| 1053 | + if (ret) | |
| 1054 | + return ret; | |
| 1055 | + | |
| 1056 | + ret = bcm_sf2_cfp_unslice_ipv6(priv, v6_m_spec->ip6dst, | |
| 1057 | + &v6_m_spec->pdst, true); | |
| 1058 | + if (ret) | |
| 1059 | + return ret; | |
| 1060 | + | |
| 1061 | + /* Read last to avoid next entry clobbering the results during search | |
| 1062 | + * operations. We would not have the port enabled for this rule, so | |
| 1063 | + * don't bother checking it. | |
| 1064 | + */ | |
| 1065 | + (void)core_readl(priv, CORE_CFP_DATA_PORT(7)); | |
| 1066 | + | |
| 1067 | + /* The slice number is valid, so read the rule we are chained from now | |
| 1068 | + * which is our first half. | |
| 1069 | + */ | |
| 1070 | + bcm_sf2_cfp_rule_addr_set(priv, next_loc); | |
| 1071 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL); | |
| 1072 | + if (ret) | |
| 1073 | + return ret; | |
| 1074 | + | |
| 1075 | + reg = core_readl(priv, CORE_CFP_DATA_PORT(6)); | |
| 1076 | + | |
| 1077 | + switch ((reg & IPPROTO_MASK) >> IPPROTO_SHIFT) { | |
| 1078 | + case IPPROTO_TCP: | |
| 1079 | + fs->flow_type = TCP_V6_FLOW; | |
| 1080 | + break; | |
| 1081 | + case IPPROTO_UDP: | |
| 1082 | + fs->flow_type = UDP_V6_FLOW; | |
| 1083 | + break; | |
| 1084 | + default: | |
| 1085 | + return -EINVAL; | |
| 1086 | + } | |
| 1087 | + | |
| 1088 | + ret = bcm_sf2_cfp_unslice_ipv6(priv, v6_spec->ip6src, &v6_spec->psrc, | |
| 1089 | + false); | |
| 1090 | + if (ret) | |
| 1091 | + return ret; | |
| 1092 | + | |
| 1093 | + return bcm_sf2_cfp_unslice_ipv6(priv, v6_m_spec->ip6src, | |
| 1094 | + &v6_m_spec->psrc, true); | |
| 1095 | +} | |
| 1096 | + | |
| 1097 | +static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port, | |
| 1098 | + struct ethtool_rxnfc *nfc) | |
| 1099 | +{ | |
| 1100 | + u32 reg, ipv4_or_chain_id; | |
| 1101 | + unsigned int queue_num; | |
| 1102 | + int ret; | |
| 1103 | + | |
| 1104 | + bcm_sf2_cfp_rule_addr_set(priv, nfc->fs.location); | |
| 1105 | + | |
| 1106 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | ACT_POL_RAM); | |
| 1107 | + if (ret) | |
| 1108 | + return ret; | |
| 1109 | + | |
| 1110 | + reg = core_readl(priv, CORE_ACT_POL_DATA0); | |
| 1111 | + | |
| 1112 | + ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL); | |
| 1113 | + if (ret) | |
| 1114 | + return ret; | |
| 1115 | + | |
| 1116 | + /* Extract the destination port */ | |
| 1117 | + nfc->fs.ring_cookie = fls((reg >> DST_MAP_IB_SHIFT) & | |
| 1118 | + DST_MAP_IB_MASK) - 1; | |
| 1119 | + | |
| 1120 | + /* There is no Port 6, so we compensate for that here */ | |
| 1121 | + if (nfc->fs.ring_cookie >= 6) | |
| 1122 | + nfc->fs.ring_cookie++; | |
| 1123 | + nfc->fs.ring_cookie *= SF2_NUM_EGRESS_QUEUES; | |
| 1124 | + | |
| 1125 | + /* Extract the destination queue */ | |
| 1126 | + queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK; | |
| 1127 | + nfc->fs.ring_cookie += queue_num; | |
| 1128 | + | |
| 1129 | + /* Extract the L3_FRAMING or CHAIN_ID */ | |
| 1130 | + reg = core_readl(priv, CORE_CFP_DATA_PORT(6)); | |
| 1131 | + | |
| 1132 | + /* With IPv6 rules this would contain a non-zero chain ID since | |
| 1133 | + * we reserve entry 0 and it cannot be used. So if we read 0 here | |
| 1134 | + * this means an IPv4 rule. | |
| 1135 | + */ | |
| 1136 | + ipv4_or_chain_id = (reg >> L3_FRAMING_SHIFT) & 0xff; | |
| 1137 | + if (ipv4_or_chain_id == 0) | |
| 1138 | + ret = bcm_sf2_cfp_ipv4_rule_get(priv, port, &nfc->fs); | |
| 1139 | + else | |
| 1140 | + ret = bcm_sf2_cfp_ipv6_rule_get(priv, port, &nfc->fs, | |
| 1141 | + ipv4_or_chain_id); | |
| 1142 | + if (ret) | |
| 1143 | + return ret; | |
| 467 | 1144 | |
| 468 | 1145 | /* Read last to avoid next entry clobbering the results during search |
| 469 | 1146 | * operations |
| @@ -486,44 +1163,11 @@ static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv, · 16 unmodified lines | ||
| 486 | 1163 | u32 *rule_locs) |
| 487 | 1164 | { |
| 488 | 1165 | unsigned int index = 1, rules_cnt = 0; |
| 489 | − int ret; | |
| 490 | − u32 reg; | |
| 491 | − | |
| 492 | − /* Do not poll on OP_STR_DONE to be self-clearing for search | |
| 493 | − * operations, we cannot use bcm_sf2_cfp_op here because it completes | |
| 494 | − * on clearing OP_STR_DONE which won't clear until the entire search | |
| 495 | − * operation is over. | |
| 496 | − */ | |
| 497 | − reg = core_readl(priv, CORE_CFP_ACC); | |
| 498 | − reg &= ~(XCESS_ADDR_MASK << XCESS_ADDR_SHIFT); | |
| 499 | − reg |= index << XCESS_ADDR_SHIFT; | |
| 500 | − reg &= ~(OP_SEL_MASK | RAM_SEL_MASK); | |
| 501 | − reg |= OP_SEL_SEARCH | TCAM_SEL | OP_STR_DONE; | |
| 502 | − core_writel(priv, reg, CORE_CFP_ACC); | |
| 503 | 1166 | |
| 504 | − do { | |
| 505 | − /* Wait for results to be ready */ | |
| 506 | − reg = core_readl(priv, CORE_CFP_ACC); | |
| 507 | − | |
| 508 | − /* Extract the address we are searching */ | |
| 509 | − index = reg >> XCESS_ADDR_SHIFT; | |
| 510 | − index &= XCESS_ADDR_MASK; | |
| 511 | − | |
| 512 | − /* We have a valid search result, so flag it accordingly */ | |
| 513 | − if (reg & SEARCH_STS) { | |
| 514 | − ret = bcm_sf2_cfp_rule_get(priv, port, nfc, true); | |
| 515 | − if (ret) | |
| 516 | − continue; | |
| 517 | − | |
| 518 | − rule_locs[rules_cnt] = index; | |
| 519 | − rules_cnt++; | |
| 520 | − } | |
| 521 | − | |
| 522 | − /* Search is over break out */ | |
| 523 | − if (!(reg & OP_STR_DONE)) | |
| 524 | − break; | |
| 525 | − | |
| 526 | − } while (index < priv->num_cfp_rules); | |
| 1167 | + for_each_set_bit_from(index, priv->cfp.unique, priv->num_cfp_rules) { | |
| 1168 | + rule_locs[rules_cnt] = index; | |
| 1169 | + rules_cnt++; | |
| 1170 | + } | |
| 527 | 1171 | |
| 528 | 1172 | /* Put the TCAM size here */ |
| 529 | 1173 | nfc->data = bcm_sf2_cfp_rule_size(priv); |
| @@ -543,13 +1187,13 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port, · 13 unmodified lines | ||
| 543 | 1187 | switch (nfc->cmd) { |
| 544 | 1188 | case ETHTOOL_GRXCLSRLCNT: |
| 545 | 1189 | /* Subtract the default, unusable rule */ |
| 546 | − nfc->rule_cnt = bitmap_weight(priv->cfp.used, | |
| 1190 | + nfc->rule_cnt = bitmap_weight(priv->cfp.unique, | |
| 547 | 1191 | priv->num_cfp_rules) - 1; |
| 548 | 1192 | /* We support specifying rule locations */ |
| 549 | 1193 | nfc->data |= RX_CLS_LOC_SPECIAL; |
| 550 | 1194 | break; |
| 551 | 1195 | case ETHTOOL_GRXCLSRULE: |
| 552 | − ret = bcm_sf2_cfp_rule_get(priv, port, nfc, false); | |
| 1196 | + ret = bcm_sf2_cfp_rule_get(priv, port, nfc); | |
| 553 | 1197 | break; |
| 554 | 1198 | case ETHTOOL_GRXCLSRLALL: |
| 555 | 1199 | ret = bcm_sf2_cfp_rule_get_all(priv, port, nfc, rule_locs); |
| @@ -115,6 +115,24 @@ enum bcm_sf2_reg_offs { · 114 unmodified lines | ||
| 115 | 115 | #define P7_IRQ_OFF 0 |
| 116 | 116 | #define P_IRQ_OFF(x) ((6 - (x)) * P_NUM_IRQ) |
| 117 | 117 | |
| 118 | +/* Register set relative to 'ACB' */ | |
| 119 | +#define ACB_CONTROL 0x00 | |
| 120 | +#define ACB_EN (1 << 0) | |
| 121 | +#define ACB_ALGORITHM (1 << 1) | |
| 122 | +#define ACB_FLUSH_SHIFT 2 | |
| 123 | +#define ACB_FLUSH_MASK 0x3 | |
| 124 | + | |
| 125 | +#define ACB_QUEUE_0_CFG 0x08 | |
| 126 | +#define XOFF_THRESHOLD_MASK 0x7ff | |
| 127 | +#define XON_EN (1 << 11) | |
| 128 | +#define TOTAL_XOFF_THRESHOLD_SHIFT 12 | |
| 129 | +#define TOTAL_XOFF_THRESHOLD_MASK 0x7ff | |
| 130 | +#define TOTAL_XOFF_EN (1 << 23) | |
| 131 | +#define TOTAL_XON_EN (1 << 24) | |
| 132 | +#define PKTLEN_SHIFT 25 | |
| 133 | +#define PKTLEN_MASK 0x3f | |
| 134 | +#define ACB_QUEUE_CFG(x) (ACB_QUEUE_0_CFG + ((x) * 0x4)) | |
| 135 | + | |
| 118 | 136 | /* Register set relative to 'CORE' */ |
| 119 | 137 | #define CORE_G_PCTL_PORT0 0x00000 |
| 120 | 138 | #define CORE_G_PCTL_PORT(x) (CORE_G_PCTL_PORT0 + (x * 0x4)) |
| @@ -205,16 +223,8 @@ enum bcm_sf2_reg_offs { · 84 unmodified lines | ||
| 205 | 223 | |
| 206 | 224 | #define CORE_IMP0_PRT_ID 0x0804 |
| 207 | 225 | |
| 208 | −#define CORE_BRCM_HDR_CTRL 0x0080c | |
| 209 | −#define BRCM_HDR_EN_P8 (1 << 0) | |
| 210 | −#define BRCM_HDR_EN_P5 (1 << 1) | |
| 211 | −#define BRCM_HDR_EN_P7 (1 << 2) | |
| 212 | − | |
| 213 | 226 | #define CORE_RST_MIB_CNT_EN 0x0950 |
| 214 | 227 | |
| 215 | −#define CORE_BRCM_HDR_RX_DIS 0x0980 | |
| 216 | −#define CORE_BRCM_HDR_TX_DIS 0x0988 | |
| 217 | − | |
| 218 | 228 | #define CORE_ARLA_VTBL_RWCTRL 0x1600 |
| 219 | 229 | #define ARLA_VTBL_CMD_WRITE 0 |
| 220 | 230 | #define ARLA_VTBL_CMD_READ 1 |
| @@ -245,6 +255,11 @@ enum bcm_sf2_reg_offs { · 24 unmodified lines | ||
| 245 | 255 | #define CORE_PORT_VLAN_CTL_PORT(x) (0xc400 + ((x) * 0x8)) |
| 246 | 256 | #define PORT_VLAN_CTRL_MASK 0x1ff |
| 247 | 257 | |
| 258 | +#define CORE_TXQ_THD_PAUSE_QN_PORT_0 0x2c80 | |
| 259 | +#define TXQ_PAUSE_THD_MASK 0x7ff | |
| 260 | +#define CORE_TXQ_THD_PAUSE_QN_PORT(x) (CORE_TXQ_THD_PAUSE_QN_PORT_0 + \ | |
| 261 | + (x) * 0x8) | |
| 262 | + | |
| 248 | 263 | #define CORE_DEFAULT_1Q_TAG_P(x) (0xd040 + ((x) * 8)) |
| 249 | 264 | #define CFI_SHIFT 12 |
| 250 | 265 | #define PRI_SHIFT 13 |
| @@ -252,9 +267,6 @@ enum bcm_sf2_reg_offs { · 1 unmodified line | ||
| 252 | 267 | |
| 253 | 268 | #define CORE_JOIN_ALL_VLAN_EN 0xd140 |
| 254 | 269 | |
| 255 | −#define CORE_EEE_EN_CTRL 0x24800 | |
| 256 | −#define CORE_EEE_LPI_INDICATE 0x24810 | |
| 257 | − | |
| 258 | 270 | #define CORE_CFP_ACC 0x28000 |
| 259 | 271 | #define OP_STR_DONE (1 << 0) |
| 260 | 272 | #define OP_SEL_SHIFT 1 |
| @@ -290,14 +302,18 @@ enum bcm_sf2_reg_offs { · 29 unmodified lines | ||
| 290 | 302 | /* UDF_DATA7 */ |
| 291 | 303 | #define L3_FRAMING_SHIFT 24 |
| 292 | 304 | #define L3_FRAMING_MASK (0x3 << L3_FRAMING_SHIFT) |
| 305 | +#define IPTOS_SHIFT 16 | |
| 306 | +#define IPTOS_MASK 0xff | |
| 293 | 307 | #define IPPROTO_SHIFT 8 |
| 294 | 308 | #define IPPROTO_MASK (0xff << IPPROTO_SHIFT) |
| 295 | −#define IP_FRAG (1 << 7) | |
| 309 | +#define IP_FRAG_SHIFT 7 | |
| 310 | +#define IP_FRAG (1 << IP_FRAG_SHIFT) | |
| 296 | 311 | |
| 297 | 312 | /* UDF_DATA0 */ |
| 298 | 313 | #define SLICE_VALID 3 |
| 299 | 314 | #define SLICE_NUM_SHIFT 2 |
| 300 | 315 | #define SLICE_NUM(x) ((x) << SLICE_NUM_SHIFT) |
| 316 | +#define SLICE_NUM_MASK 0x3 | |
| 301 | 317 | |
| 302 | 318 | #define CORE_CFP_MASK_PORT_0 0x280c0 |
| 303 | 319 | |
| @@ -393,8 +409,15 @@ enum bcm_sf2_reg_offs { · 89 unmodified lines | ||
| 393 | 409 | #define CFG_UDF_EOL2 (2 << CFG_UDF_OFFSET_BASE_SHIFT) |
| 394 | 410 | #define CFG_UDF_EOL3 (3 << CFG_UDF_OFFSET_BASE_SHIFT) |
| 395 | 411 | |
| 412 | +/* IPv6 slices */ | |
| 413 | +#define CORE_UDF_0_B_0_8_PORT_0 0x28500 | |
| 414 | + | |
| 415 | +/* IPv6 chained slices */ | |
| 416 | +#define CORE_UDF_0_D_0_11_PORT_0 0x28680 | |
| 417 | + | |
| 396 | 418 | /* Number of slices for IPv4, IPv6 and non-IP */ |
| 397 | −#define UDF_NUM_SLICES 9 | |
| 419 | +#define UDF_NUM_SLICES 4 | |
| 420 | +#define UDFS_PER_SLICE 9 | |
| 398 | 421 | |
| 399 | 422 | /* Spacing between different slices */ |
| 400 | 423 | #define UDF_SLICE_OFFSET 0x40 |
| @@ -64,7 +64,8 @@ struct dsa_loop_priv { · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | static struct phy_device *phydevs[PHY_MAX_ADDR]; |
| 66 | 66 | |
| 67 | −static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds) | |
| 67 | +static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds, | |
| 68 | + int port) | |
| 68 | 69 | { |
| 69 | 70 | dev_dbg(ds->dev, "%s\n", __func__); |
| 70 | 71 | |
| @@ -110,13 +111,6 @@ static void dsa_loop_get_ethtool_stats(struct dsa_switch *ds, int port, · 39 unmodified lines | ||
| 110 | 111 | data[i] = ps->ports[port].mib[i].val; |
| 111 | 112 | } |
| 112 | 113 | |
| 113 | −static int dsa_loop_set_addr(struct dsa_switch *ds, u8 *addr) | |
| 114 | −{ | |
| 115 | − dev_dbg(ds->dev, "%s\n", __func__); | |
| 116 | − | |
| 117 | − return 0; | |
| 118 | −} | |
| 119 | − | |
| 120 | 114 | static int dsa_loop_phy_read(struct dsa_switch *ds, int port, int regnum) |
| 121 | 115 | { |
| 122 | 116 | struct dsa_loop_priv *ps = ds->priv; |
| @@ -263,7 +257,6 @@ static const struct dsa_switch_ops dsa_loop_driver = { · 140 unmodified lines | ||
| 263 | 257 | .get_strings = dsa_loop_get_strings, |
| 264 | 258 | .get_ethtool_stats = dsa_loop_get_ethtool_stats, |
| 265 | 259 | .get_sset_count = dsa_loop_get_sset_count, |
| 266 | − .set_addr = dsa_loop_set_addr, | |
| 267 | 260 | .phy_read = dsa_loop_phy_read, |
| 268 | 261 | .phy_write = dsa_loop_phy_write, |
| 269 | 262 | .port_bridge_join = dsa_loop_port_bridge_join, |
| @@ -17,6 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/regmap.h> |
| 18 | 18 | #include <linux/mutex.h> |
| 19 | 19 | #include <linux/mii.h> |
| 20 | +#include <linux/phy.h> | |
| 21 | +#include <linux/if_bridge.h> | |
| 22 | +#include <linux/etherdevice.h> | |
| 20 | 23 | |
| 21 | 24 | #include "lan9303.h" |
| 22 | 25 | |
| @@ -57,6 +60,7 @@ · 34 unmodified lines | ||
| 57 | 60 | #define LAN9303_SWITCH_CSR_CMD_LANES (BIT(19) | BIT(18) | BIT(17) | BIT(16)) |
| 58 | 61 | #define LAN9303_VIRT_PHY_BASE 0x70 |
| 59 | 62 | #define LAN9303_VIRT_SPECIAL_CTRL 0x77 |
| 63 | +#define LAN9303_VIRT_SPECIAL_TURBO BIT(10) /*Turbo MII Enable*/ | |
| 60 | 64 | |
| 61 | 65 | /*13.4 Switch Fabric Control and Status Registers |
| 62 | 66 | * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA. |
| @@ -121,6 +125,21 @@ · 58 unmodified lines | ||
| 121 | 125 | #define LAN9303_MAC_RX_CFG_2 0x0c01 |
| 122 | 126 | #define LAN9303_MAC_TX_CFG_2 0x0c40 |
| 123 | 127 | #define LAN9303_SWE_ALR_CMD 0x1800 |
| 128 | +# define LAN9303_ALR_CMD_MAKE_ENTRY BIT(2) | |
| 129 | +# define LAN9303_ALR_CMD_GET_FIRST BIT(1) | |
| 130 | +# define LAN9303_ALR_CMD_GET_NEXT BIT(0) | |
| 131 | +#define LAN9303_SWE_ALR_WR_DAT_0 0x1801 | |
| 132 | +#define LAN9303_SWE_ALR_WR_DAT_1 0x1802 | |
| 133 | +# define LAN9303_ALR_DAT1_VALID BIT(26) | |
| 134 | +# define LAN9303_ALR_DAT1_END_OF_TABL BIT(25) | |
| 135 | +# define LAN9303_ALR_DAT1_AGE_OVERRID BIT(25) | |
| 136 | +# define LAN9303_ALR_DAT1_STATIC BIT(24) | |
| 137 | +# define LAN9303_ALR_DAT1_PORT_BITOFFS 16 | |
| 138 | +# define LAN9303_ALR_DAT1_PORT_MASK (7 << LAN9303_ALR_DAT1_PORT_BITOFFS) | |
| 139 | +#define LAN9303_SWE_ALR_RD_DAT_0 0x1805 | |
| 140 | +#define LAN9303_SWE_ALR_RD_DAT_1 0x1806 | |
| 141 | +#define LAN9303_SWE_ALR_CMD_STS 0x1808 | |
| 142 | +# define ALR_STS_MAKE_PEND BIT(0) | |
| 124 | 143 | #define LAN9303_SWE_VLAN_CMD 0x180b |
| 125 | 144 | # define LAN9303_SWE_VLAN_CMD_RNW BIT(5) |
| 126 | 145 | # define LAN9303_SWE_VLAN_CMD_PVIDNVLAN BIT(4) |
| @@ -134,6 +153,8 @@ · 7 unmodified lines | ||
| 134 | 153 | # define LAN9303_SWE_VLAN_UNTAG_PORT0 BIT(12) |
| 135 | 154 | #define LAN9303_SWE_VLAN_CMD_STS 0x1810 |
| 136 | 155 | #define LAN9303_SWE_GLB_INGRESS_CFG 0x1840 |
| 156 | +# define LAN9303_SWE_GLB_INGR_IGMP_TRAP BIT(7) | |
| 157 | +# define LAN9303_SWE_GLB_INGR_IGMP_PORT(p) BIT(10 + p) | |
| 137 | 158 | #define LAN9303_SWE_PORT_STATE 0x1843 |
| 138 | 159 | # define LAN9303_SWE_PORT_STATE_FORWARDING_PORT2 (0) |
| 139 | 160 | # define LAN9303_SWE_PORT_STATE_LEARNING_PORT2 BIT(5) |
| @@ -144,6 +165,7 @@ · 4 unmodified lines | ||
| 144 | 165 | # define LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 (0) |
| 145 | 166 | # define LAN9303_SWE_PORT_STATE_LEARNING_PORT0 BIT(1) |
| 146 | 167 | # define LAN9303_SWE_PORT_STATE_BLOCKING_PORT0 BIT(0) |
| 168 | +# define LAN9303_SWE_PORT_STATE_DISABLED_PORT0 (3) | |
| 147 | 169 | #define LAN9303_SWE_PORT_MIRROR 0x1846 |
| 148 | 170 | # define LAN9303_SWE_PORT_MIRROR_SNIFF_ALL BIT(8) |
| 149 | 171 | # define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT2 BIT(7) |
| @@ -154,7 +176,9 @@ · 4 unmodified lines | ||
| 154 | 176 | # define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT0 BIT(2) |
| 155 | 177 | # define LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING BIT(1) |
| 156 | 178 | # define LAN9303_SWE_PORT_MIRROR_ENABLE_TX_MIRRORING BIT(0) |
| 179 | +# define LAN9303_SWE_PORT_MIRROR_DISABLED 0 | |
| 157 | 180 | #define LAN9303_SWE_INGRESS_PORT_TYPE 0x1847 |
| 181 | +#define LAN9303_SWE_INGRESS_PORT_TYPE_VLAN 3 | |
| 158 | 182 | #define LAN9303_BM_CFG 0x1c00 |
| 159 | 183 | #define LAN9303_BM_EGRSS_PORT_TYPE 0x1c0c |
| 160 | 184 | # define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT2 (BIT(17) | BIT(16)) |
| @@ -262,7 +286,7 @@ static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip) · 101 unmodified lines | ||
| 262 | 286 | } |
| 263 | 287 | if (!(reg & LAN9303_PMI_ACCESS_MII_BUSY)) |
| 264 | 288 | return 0; |
| 265 | − msleep(1); | |
| 289 | + usleep_range(1000, 2000); | |
| 266 | 290 | } |
| 267 | 291 | |
| 268 | 292 | return -EIO; |
| @@ -354,7 +378,7 @@ static int lan9303_switch_wait_for_completion(struct lan9303 *chip) · 85 unmodified lines | ||
| 354 | 378 | } |
| 355 | 379 | if (!(reg & LAN9303_SWITCH_CSR_CMD_BUSY)) |
| 356 | 380 | return 0; |
| 357 | − msleep(1); | |
| 381 | + usleep_range(1000, 2000); | |
| 358 | 382 | } |
| 359 | 383 | |
| 360 | 384 | return -EIO; |
| @@ -428,6 +452,21 @@ on_error: · 67 unmodified lines | ||
| 428 | 452 | return ret; |
| 429 | 453 | } |
| 430 | 454 | |
| 455 | +static int lan9303_write_switch_reg_mask(struct lan9303 *chip, u16 regnum, | |
| 456 | + u32 val, u32 mask) | |
| 457 | +{ | |
| 458 | + int ret; | |
| 459 | + u32 reg; | |
| 460 | + | |
| 461 | + ret = lan9303_read_switch_reg(chip, regnum, ®); | |
| 462 | + if (ret) | |
| 463 | + return ret; | |
| 464 | + | |
| 465 | + reg = (reg & ~mask) | val; | |
| 466 | + | |
| 467 | + return lan9303_write_switch_reg(chip, regnum, reg); | |
| 468 | +} | |
| 469 | + | |
| 431 | 470 | static int lan9303_write_switch_port(struct lan9303 *chip, int port, |
| 432 | 471 | u16 regnum, u32 val) |
| 433 | 472 | { |
| @@ -472,6 +511,220 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip) · 38 unmodified lines | ||
| 472 | 511 | return 0; |
| 473 | 512 | } |
| 474 | 513 | |
| 514 | +/* Map ALR-port bits to port bitmap, and back */ | |
| 515 | +static const int alrport_2_portmap[] = {1, 2, 4, 0, 3, 5, 6, 7 }; | |
| 516 | +static const int portmap_2_alrport[] = {3, 0, 1, 4, 2, 5, 6, 7 }; | |
| 517 | + | |
| 518 | +/* Return pointer to first free ALR cache entry, return NULL if none */ | |
| 519 | +static struct lan9303_alr_cache_entry * | |
| 520 | +lan9303_alr_cache_find_free(struct lan9303 *chip) | |
| 521 | +{ | |
| 522 | + int i; | |
| 523 | + struct lan9303_alr_cache_entry *entr = chip->alr_cache; | |
| 524 | + | |
| 525 | + for (i = 0; i < LAN9303_NUM_ALR_RECORDS; i++, entr++) | |
| 526 | + if (entr->port_map == 0) | |
| 527 | + return entr; | |
| 528 | + | |
| 529 | + return NULL; | |
| 530 | +} | |
| 531 | + | |
| 532 | +/* Return pointer to ALR cache entry matching MAC address */ | |
| 533 | +static struct lan9303_alr_cache_entry * | |
| 534 | +lan9303_alr_cache_find_mac(struct lan9303 *chip, const u8 *mac_addr) | |
| 535 | +{ | |
| 536 | + int i; | |
| 537 | + struct lan9303_alr_cache_entry *entr = chip->alr_cache; | |
| 538 | + | |
| 539 | + BUILD_BUG_ON_MSG(sizeof(struct lan9303_alr_cache_entry) & 1, | |
| 540 | + "ether_addr_equal require u16 alignment"); | |
| 541 | + | |
| 542 | + for (i = 0; i < LAN9303_NUM_ALR_RECORDS; i++, entr++) | |
| 543 | + if (ether_addr_equal(entr->mac_addr, mac_addr)) | |
| 544 | + return entr; | |
| 545 | + | |
| 546 | + return NULL; | |
| 547 | +} | |
| 548 | + | |
| 549 | +/* Wait a while until mask & reg == value. Otherwise return timeout. */ | |
| 550 | +static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno, | |
| 551 | + int mask, char value) | |
| 552 | +{ | |
| 553 | + int i; | |
| 554 | + | |
| 555 | + for (i = 0; i < 0x1000; i++) { | |
| 556 | + u32 reg; | |
| 557 | + | |
| 558 | + lan9303_read_switch_reg(chip, regno, ®); | |
| 559 | + if ((reg & mask) == value) | |
| 560 | + return 0; | |
| 561 | + usleep_range(1000, 2000); | |
| 562 | + } | |
| 563 | + return -ETIMEDOUT; | |
| 564 | +} | |
| 565 | + | |
| 566 | +static int lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1) | |
| 567 | +{ | |
| 568 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_WR_DAT_0, dat0); | |
| 569 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_WR_DAT_1, dat1); | |
| 570 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, | |
| 571 | + LAN9303_ALR_CMD_MAKE_ENTRY); | |
| 572 | + lan9303_csr_reg_wait(chip, LAN9303_SWE_ALR_CMD_STS, ALR_STS_MAKE_PEND, | |
| 573 | + 0); | |
| 574 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); | |
| 575 | + | |
| 576 | + return 0; | |
| 577 | +} | |
| 578 | + | |
| 579 | +typedef void alr_loop_cb_t(struct lan9303 *chip, u32 dat0, u32 dat1, | |
| 580 | + int portmap, void *ctx); | |
| 581 | + | |
| 582 | +static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) | |
| 583 | +{ | |
| 584 | + int i; | |
| 585 | + | |
| 586 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, | |
| 587 | + LAN9303_ALR_CMD_GET_FIRST); | |
| 588 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); | |
| 589 | + | |
| 590 | + for (i = 1; i < LAN9303_NUM_ALR_RECORDS; i++) { | |
| 591 | + u32 dat0, dat1; | |
| 592 | + int alrport, portmap; | |
| 593 | + | |
| 594 | + lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_0, &dat0); | |
| 595 | + lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_1, &dat1); | |
| 596 | + if (dat1 & LAN9303_ALR_DAT1_END_OF_TABL) | |
| 597 | + break; | |
| 598 | + | |
| 599 | + alrport = (dat1 & LAN9303_ALR_DAT1_PORT_MASK) >> | |
| 600 | + LAN9303_ALR_DAT1_PORT_BITOFFS; | |
| 601 | + portmap = alrport_2_portmap[alrport]; | |
| 602 | + | |
| 603 | + cb(chip, dat0, dat1, portmap, ctx); | |
| 604 | + | |
| 605 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, | |
| 606 | + LAN9303_ALR_CMD_GET_NEXT); | |
| 607 | + lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); | |
| 608 | + } | |
| 609 | +} | |
| 610 | + | |
| 611 | +static void alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6]) | |
| 612 | +{ | |
| 613 | + mac[0] = (dat0 >> 0) & 0xff; | |
| 614 | + mac[1] = (dat0 >> 8) & 0xff; | |
| 615 | + mac[2] = (dat0 >> 16) & 0xff; | |
| 616 | + mac[3] = (dat0 >> 24) & 0xff; | |
| 617 | + mac[4] = (dat1 >> 0) & 0xff; | |
| 618 | + mac[5] = (dat1 >> 8) & 0xff; | |
| 619 | +} | |
| 620 | + | |
| 621 | +struct del_port_learned_ctx { | |
| 622 | + int port; | |
| 623 | +}; | |
| 624 | + | |
| 625 | +/* Clear learned (non-static) entry on given port */ | |
| 626 | +static void alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0, | |
| 627 | + u32 dat1, int portmap, void *ctx) | |
| 628 | +{ | |
| 629 | + struct del_port_learned_ctx *del_ctx = ctx; | |
| 630 | + int port = del_ctx->port; | |
| 631 | + | |
| 632 | + if (((BIT(port) & portmap) == 0) || (dat1 & LAN9303_ALR_DAT1_STATIC)) | |
| 633 | + return; | |
| 634 | + | |
| 635 | + /* learned entries has only one port, we can just delete */ | |
| 636 | + dat1 &= ~LAN9303_ALR_DAT1_VALID; /* delete entry */ | |
| 637 | + lan9303_alr_make_entry_raw(chip, dat0, dat1); | |
| 638 | +} | |
| 639 | + | |
| 640 | +struct port_fdb_dump_ctx { | |
| 641 | + int port; | |
| 642 | + void *data; | |
| 643 | + dsa_fdb_dump_cb_t *cb; | |
| 644 | +}; | |
| 645 | + | |
| 646 | +static void alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0, | |
| 647 | + u32 dat1, int portmap, void *ctx) | |
| 648 | +{ | |
| 649 | + struct port_fdb_dump_ctx *dump_ctx = ctx; | |
| 650 | + u8 mac[ETH_ALEN]; | |
| 651 | + bool is_static; | |
| 652 | + | |
| 653 | + if ((BIT(dump_ctx->port) & portmap) == 0) | |
| 654 | + return; | |
| 655 | + | |
| 656 | + alr_reg_to_mac(dat0, dat1, mac); | |
| 657 | + is_static = !!(dat1 & LAN9303_ALR_DAT1_STATIC); | |
| 658 | + dump_ctx->cb(mac, 0, is_static, dump_ctx->data); | |
| 659 | +} | |
| 660 | + | |
| 661 | +/* Set a static ALR entry. Delete entry if port_map is zero */ | |
| 662 | +static void lan9303_alr_set_entry(struct lan9303 *chip, const u8 *mac, | |
| 663 | + u8 port_map, bool stp_override) | |
| 664 | +{ | |
| 665 | + u32 dat0, dat1, alr_port; | |
| 666 | + | |
| 667 | + dev_dbg(chip->dev, "%s(%pM, %d)\n", __func__, mac, port_map); | |
| 668 | + dat1 = LAN9303_ALR_DAT1_STATIC; | |
| 669 | + if (port_map) | |
| 670 | + dat1 |= LAN9303_ALR_DAT1_VALID; | |
| 671 | + /* otherwise no ports: delete entry */ | |
| 672 | + if (stp_override) | |
| 673 | + dat1 |= LAN9303_ALR_DAT1_AGE_OVERRID; | |
| 674 | + | |
| 675 | + alr_port = portmap_2_alrport[port_map & 7]; | |
| 676 | + dat1 &= ~LAN9303_ALR_DAT1_PORT_MASK; | |
| 677 | + dat1 |= alr_port << LAN9303_ALR_DAT1_PORT_BITOFFS; | |
| 678 | + | |
| 679 | + dat0 = 0; | |
| 680 | + dat0 |= (mac[0] << 0); | |
| 681 | + dat0 |= (mac[1] << 8); | |
| 682 | + dat0 |= (mac[2] << 16); | |
| 683 | + dat0 |= (mac[3] << 24); | |
| 684 | + | |
| 685 | + dat1 |= (mac[4] << 0); | |
| 686 | + dat1 |= (mac[5] << 8); | |
| 687 | + | |
| 688 | + lan9303_alr_make_entry_raw(chip, dat0, dat1); | |
| 689 | +} | |
| 690 | + | |
| 691 | +/* Add port to static ALR entry, create new static entry if needed */ | |
| 692 | +static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac, int port, | |
| 693 | + bool stp_override) | |
| 694 | +{ | |
| 695 | + struct lan9303_alr_cache_entry *entr; | |
| 696 | + | |
| 697 | + entr = lan9303_alr_cache_find_mac(chip, mac); | |
| 698 | + if (!entr) { /*New entry */ | |
| 699 | + entr = lan9303_alr_cache_find_free(chip); | |
| 700 | + if (!entr) | |
| 701 | + return -ENOSPC; | |
| 702 | + ether_addr_copy(entr->mac_addr, mac); | |
| 703 | + } | |
| 704 | + entr->port_map |= BIT(port); | |
| 705 | + entr->stp_override = stp_override; | |
| 706 | + lan9303_alr_set_entry(chip, mac, entr->port_map, stp_override); | |
| 707 | + | |
| 708 | + return 0; | |
| 709 | +} | |
| 710 | + | |
| 711 | +/* Delete static port from ALR entry, delete entry if last port */ | |
| 712 | +static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac, int port) | |
| 713 | +{ | |
| 714 | + struct lan9303_alr_cache_entry *entr; | |
| 715 | + | |
| 716 | + entr = lan9303_alr_cache_find_mac(chip, mac); | |
| 717 | + if (!entr) | |
| 718 | + return 0; /* no static entry found */ | |
| 719 | + | |
| 720 | + entr->port_map &= ~BIT(port); | |
| 721 | + if (entr->port_map == 0) /* zero means its free again */ | |
| 722 | + eth_zero_addr(entr->mac_addr); | |
| 723 | + lan9303_alr_set_entry(chip, mac, entr->port_map, entr->stp_override); | |
| 724 | + | |
| 725 | + return 0; | |
| 726 | +} | |
| 727 | + | |
| 475 | 728 | static int lan9303_disable_processing_port(struct lan9303 *chip, |
| 476 | 729 | unsigned int port) |
| 477 | 730 | { |
| @@ -508,16 +761,36 @@ static int lan9303_enable_processing_port(struct lan9303 *chip, · 30 unmodified lines | ||
| 508 | 761 | LAN9303_MAC_TX_CFG_X_TX_ENABLE); |
| 509 | 762 | } |
| 510 | 763 | |
| 764 | +/* forward special tagged packets from port 0 to port 1 *or* port 2 */ | |
| 765 | +static int lan9303_setup_tagging(struct lan9303 *chip) | |
| 766 | +{ | |
| 767 | + int ret; | |
| 768 | + u32 val; | |
| 769 | + /* enable defining the destination port via special VLAN tagging | |
| 770 | + * for port 0 | |
| 771 | + */ | |
| 772 | + ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE, | |
| 773 | + LAN9303_SWE_INGRESS_PORT_TYPE_VLAN); | |
| 774 | + if (ret) | |
| 775 | + return ret; | |
| 776 | + | |
| 777 | + /* tag incoming packets at port 1 and 2 on their way to port 0 to be | |
| 778 | + * able to discover their source port | |
| 779 | + */ | |
| 780 | + val = LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0; | |
| 781 | + return lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE, val); | |
| 782 | +} | |
| 783 | + | |
| 511 | 784 | /* We want a special working switch: |
| 512 | 785 | * - do not forward packets between port 1 and 2 |
| 513 | 786 | * - forward everything from port 1 to port 0 |
| 514 | 787 | * - forward everything from port 2 to port 0 |
| 515 | − * - forward special tagged packets from port 0 to port 1 *or* port 2 | |
| 516 | 788 | */ |
| 517 | 789 | static int lan9303_separate_ports(struct lan9303 *chip) |
| 518 | 790 | { |
| 519 | 791 | int ret; |
| 520 | 792 | |
| 793 | + lan9303_alr_del_port(chip, eth_stp_addr, 0); | |
| 521 | 794 | ret = lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR, |
| 522 | 795 | LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0 | |
| 523 | 796 | LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1 | |
| @@ -527,22 +800,6 @@ static int lan9303_separate_ports(struct lan9303 *chip) · 3 unmodified lines | ||
| 527 | 800 | if (ret) |
| 528 | 801 | return ret; |
| 529 | 802 | |
| 530 | − /* enable defining the destination port via special VLAN tagging | |
| 531 | − * for port 0 | |
| 532 | − */ | |
| 533 | − ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE, | |
| 534 | − 0x03); | |
| 535 | − if (ret) | |
| 536 | − return ret; | |
| 537 | − | |
| 538 | − /* tag incoming packets at port 1 and 2 on their way to port 0 to be | |
| 539 | − * able to discover their source port | |
| 540 | − */ | |
| 541 | − ret = lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE, | |
| 542 | − LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0); | |
| 543 | − if (ret) | |
| 544 | − return ret; | |
| 545 | − | |
| 546 | 803 | /* prevent port 1 and 2 from forwarding packets by their own */ |
| 547 | 804 | return lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE, |
| 548 | 805 | LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 | |
| @@ -550,6 +807,17 @@ static int lan9303_separate_ports(struct lan9303 *chip) · 1 unmodified line | ||
| 550 | 807 | LAN9303_SWE_PORT_STATE_BLOCKING_PORT2); |
| 551 | 808 | } |
| 552 | 809 | |
| 810 | +static void lan9303_bridge_ports(struct lan9303 *chip) | |
| 811 | +{ | |
| 812 | + /* ports bridged: remove mirroring */ | |
| 813 | + lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR, | |
| 814 | + LAN9303_SWE_PORT_MIRROR_DISABLED); | |
| 815 | + | |
| 816 | + lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE, | |
| 817 | + chip->swe_port_state); | |
| 818 | + lan9303_alr_add_port(chip, eth_stp_addr, 0, true); | |
| 819 | +} | |
| 820 | + | |
| 553 | 821 | static int lan9303_handle_reset(struct lan9303 *chip) |
| 554 | 822 | { |
| 555 | 823 | if (!chip->reset_gpio) |
| @@ -569,7 +837,7 @@ static int lan9303_disable_processing(struct lan9303 *chip) · 13 unmodified lines | ||
| 569 | 837 | { |
| 570 | 838 | int p; |
| 571 | 839 | |
| 572 | − for (p = 0; p < LAN9303_NUM_PORTS; p++) { | |
| 840 | + for (p = 1; p < LAN9303_NUM_PORTS; p++) { | |
| 573 | 841 | int ret = lan9303_disable_processing_port(chip, p); |
| 574 | 842 | |
| 575 | 843 | if (ret) |
| @@ -626,7 +894,8 @@ static int lan9303_check_device(struct lan9303 *chip) · 50 unmodified lines | ||
| 626 | 894 | |
| 627 | 895 | /* ---------------------------- DSA -----------------------------------*/ |
| 628 | 896 | |
| 629 | −static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds) | |
| 897 | +static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds, | |
| 898 | + int port) | |
| 630 | 899 | { |
| 631 | 900 | return DSA_TAG_PROTO_LAN9303; |
| 632 | 901 | } |
| @@ -642,6 +911,10 @@ static int lan9303_setup(struct dsa_switch *ds) · 9 unmodified lines | ||
| 642 | 911 | return -EINVAL; |
| 643 | 912 | } |
| 644 | 913 | |
| 914 | + ret = lan9303_setup_tagging(chip); | |
| 915 | + if (ret) | |
| 916 | + dev_err(chip->dev, "failed to setup port tagging %d\n", ret); | |
| 917 | + | |
| 645 | 918 | ret = lan9303_separate_ports(chip); |
| 646 | 919 | if (ret) |
| 647 | 920 | dev_err(chip->dev, "failed to separate ports %d\n", ret); |
| @@ -650,6 +923,15 @@ static int lan9303_setup(struct dsa_switch *ds) · 2 unmodified lines | ||
| 650 | 923 | if (ret) |
| 651 | 924 | dev_err(chip->dev, "failed to re-enable switching %d\n", ret); |
| 652 | 925 | |
| 926 | + /* Trap IGMP to port 0 */ | |
| 927 | + ret = lan9303_write_switch_reg_mask(chip, LAN9303_SWE_GLB_INGRESS_CFG, | |
| 928 | + LAN9303_SWE_GLB_INGR_IGMP_TRAP | | |
| 929 | + LAN9303_SWE_GLB_INGR_IGMP_PORT(0), | |
| 930 | + LAN9303_SWE_GLB_INGR_IGMP_PORT(1) | | |
| 931 | + LAN9303_SWE_GLB_INGR_IGMP_PORT(2)); | |
| 932 | + if (ret) | |
| 933 | + dev_err(chip->dev, "failed to setup IGMP trap %d\n", ret); | |
| 934 | + | |
| 653 | 935 | return 0; |
| 654 | 936 | } |
| 655 | 937 | |
| @@ -760,22 +1042,49 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum, · 104 unmodified lines | ||
| 760 | 1042 | return chip->ops->phy_write(chip, phy, regnum, val); |
| 761 | 1043 | } |
| 762 | 1044 | |
| 763 | −static int lan9303_port_enable(struct dsa_switch *ds, int port, | |
| 764 | − struct phy_device *phy) | |
| 1045 | +static void lan9303_adjust_link(struct dsa_switch *ds, int port, | |
| 1046 | + struct phy_device *phydev) | |
| 765 | 1047 | { |
| 766 | 1048 | struct lan9303 *chip = ds->priv; |
| 1049 | + int ctl, res; | |
| 767 | 1050 | |
| 768 | − /* enable internal packet processing */ | |
| 769 | − switch (port) { | |
| 770 | − case 1: | |
| 771 | − case 2: | |
| 772 | − return lan9303_enable_processing_port(chip, port); | |
| 773 | − default: | |
| 774 | − dev_dbg(chip->dev, | |
| 775 | − "Error: request to power up invalid port %d\n", port); | |
| 1051 | + if (!phy_is_pseudo_fixed_link(phydev)) | |
| 1052 | + return; | |
| 1053 | + | |
| 1054 | + ctl = lan9303_phy_read(ds, port, MII_BMCR); | |
| 1055 | + | |
| 1056 | + ctl &= ~BMCR_ANENABLE; | |
| 1057 | + | |
| 1058 | + if (phydev->speed == SPEED_100) | |
| 1059 | + ctl |= BMCR_SPEED100; | |
| 1060 | + else if (phydev->speed == SPEED_10) | |
| 1061 | + ctl &= ~BMCR_SPEED100; | |
| 1062 | + else | |
| 1063 | + dev_err(ds->dev, "unsupported speed: %d\n", phydev->speed); | |
| 1064 | + | |
| 1065 | + if (phydev->duplex == DUPLEX_FULL) | |
| 1066 | + ctl |= BMCR_FULLDPLX; | |
| 1067 | + else | |
| 1068 | + ctl &= ~BMCR_FULLDPLX; | |
| 1069 | + | |
| 1070 | + res = lan9303_phy_write(ds, port, MII_BMCR, ctl); | |
| 1071 | + | |
| 1072 | + if (port == chip->phy_addr_sel_strap) { | |
| 1073 | + /* Virtual Phy: Remove Turbo 200Mbit mode */ | |
| 1074 | + lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl); | |
| 1075 | + | |
| 1076 | + ctl &= ~LAN9303_VIRT_SPECIAL_TURBO; | |
| 1077 | + res = regmap_write(chip->regmap, | |
| 1078 | + LAN9303_VIRT_SPECIAL_CTRL, ctl); | |
| 776 | 1079 | } |
| 1080 | +} | |
| 777 | 1081 | |
| 778 | − return -ENODEV; | |
| 1082 | +static int lan9303_port_enable(struct dsa_switch *ds, int port, | |
| 1083 | + struct phy_device *phy) | |
| 1084 | +{ | |
| 1085 | + struct lan9303 *chip = ds->priv; | |
| 1086 | + | |
| 1087 | + return lan9303_enable_processing_port(chip, port); | |
| 779 | 1088 | } |
| 780 | 1089 | |
| 781 | 1090 | static void lan9303_port_disable(struct dsa_switch *ds, int port, |
| @@ -783,18 +1092,171 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port, · 1 unmodified line | ||
| 783 | 1092 | { |
| 784 | 1093 | struct lan9303 *chip = ds->priv; |
| 785 | 1094 | |
| 786 | − /* disable internal packet processing */ | |
| 787 | − switch (port) { | |
| 788 | − case 1: | |
| 789 | − case 2: | |
| 790 | − lan9303_disable_processing_port(chip, port); | |
| 791 | − lan9303_phy_write(ds, chip->phy_addr_sel_strap + port, | |
| 792 | − MII_BMCR, BMCR_PDOWN); | |
| 1095 | + lan9303_disable_processing_port(chip, port); | |
| 1096 | + lan9303_phy_write(ds, chip->phy_addr_sel_strap + port, | |
| 1097 | + MII_BMCR, BMCR_PDOWN); | |
| 1098 | +} | |
| 1099 | + | |
| 1100 | +static int lan9303_port_bridge_join(struct dsa_switch *ds, int port, | |
| 1101 | + struct net_device *br) | |
| 1102 | +{ | |
| 1103 | + struct lan9303 *chip = ds->priv; | |
| 1104 | + | |
| 1105 | + dev_dbg(chip->dev, "%s(port %d)\n", __func__, port); | |
| 1106 | + if (dsa_to_port(ds, 1)->bridge_dev == dsa_to_port(ds, 2)->bridge_dev) { | |
| 1107 | + lan9303_bridge_ports(chip); | |
| 1108 | + chip->is_bridged = true; /* unleash stp_state_set() */ | |
| 1109 | + } | |
| 1110 | + | |
| 1111 | + return 0; | |
| 1112 | +} | |
| 1113 | + | |
| 1114 | +static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port, | |
| 1115 | + struct net_device *br) | |
| 1116 | +{ | |
| 1117 | + struct lan9303 *chip = ds->priv; | |
| 1118 | + | |
| 1119 | + dev_dbg(chip->dev, "%s(port %d)\n", __func__, port); | |
| 1120 | + if (chip->is_bridged) { | |
| 1121 | + lan9303_separate_ports(chip); | |
| 1122 | + chip->is_bridged = false; | |
| 1123 | + } | |
| 1124 | +} | |
| 1125 | + | |
| 1126 | +static void lan9303_port_stp_state_set(struct dsa_switch *ds, int port, | |
| 1127 | + u8 state) | |
| 1128 | +{ | |
| 1129 | + int portmask, portstate; | |
| 1130 | + struct lan9303 *chip = ds->priv; | |
| 1131 | + | |
| 1132 | + dev_dbg(chip->dev, "%s(port %d, state %d)\n", | |
| 1133 | + __func__, port, state); | |
| 1134 | + | |
| 1135 | + switch (state) { | |
| 1136 | + case BR_STATE_DISABLED: | |
| 1137 | + portstate = LAN9303_SWE_PORT_STATE_DISABLED_PORT0; | |
| 1138 | + break; | |
| 1139 | + case BR_STATE_BLOCKING: | |
| 1140 | + case BR_STATE_LISTENING: | |
| 1141 | + portstate = LAN9303_SWE_PORT_STATE_BLOCKING_PORT0; | |
| 1142 | + break; | |
| 1143 | + case BR_STATE_LEARNING: | |
| 1144 | + portstate = LAN9303_SWE_PORT_STATE_LEARNING_PORT0; | |
| 1145 | + break; | |
| 1146 | + case BR_STATE_FORWARDING: | |
| 1147 | + portstate = LAN9303_SWE_PORT_STATE_FORWARDING_PORT0; | |
| 793 | 1148 | break; |
| 794 | 1149 | default: |
| 795 | − dev_dbg(chip->dev, | |
| 796 | − "Error: request to power down invalid port %d\n", port); | |
| 1150 | + portstate = LAN9303_SWE_PORT_STATE_DISABLED_PORT0; | |
| 1151 | + dev_err(chip->dev, "unknown stp state: port %d, state %d\n", | |
| 1152 | + port, state); | |
| 797 | 1153 | } |
| 1154 | + | |
| 1155 | + portmask = 0x3 << (port * 2); | |
| 1156 | + portstate <<= (port * 2); | |
| 1157 | + | |
| 1158 | + chip->swe_port_state = (chip->swe_port_state & ~portmask) | portstate; | |
| 1159 | + | |
| 1160 | + if (chip->is_bridged) | |
| 1161 | + lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE, | |
| 1162 | + chip->swe_port_state); | |
| 1163 | + /* else: touching SWE_PORT_STATE would break port separation */ | |
| 1164 | +} | |
| 1165 | + | |
| 1166 | +static void lan9303_port_fast_age(struct dsa_switch *ds, int port) | |
| 1167 | +{ | |
| 1168 | + struct lan9303 *chip = ds->priv; | |
| 1169 | + struct del_port_learned_ctx del_ctx = { | |
| 1170 | + .port = port, | |
| 1171 | + }; | |
| 1172 | + | |
| 1173 | + dev_dbg(chip->dev, "%s(%d)\n", __func__, port); | |
| 1174 | + lan9303_alr_loop(chip, alr_loop_cb_del_port_learned, &del_ctx); | |
| 1175 | +} | |
| 1176 | + | |
| 1177 | +static int lan9303_port_fdb_add(struct dsa_switch *ds, int port, | |
| 1178 | + const unsigned char *addr, u16 vid) | |
| 1179 | +{ | |
| 1180 | + struct lan9303 *chip = ds->priv; | |
| 1181 | + | |
| 1182 | + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); | |
| 1183 | + if (vid) | |
| 1184 | + return -EOPNOTSUPP; | |
| 1185 | + | |
| 1186 | + return lan9303_alr_add_port(chip, addr, port, false); | |
| 1187 | +} | |
| 1188 | + | |
| 1189 | +static int lan9303_port_fdb_del(struct dsa_switch *ds, int port, | |
| 1190 | + const unsigned char *addr, u16 vid) | |
| 1191 | + | |
| 1192 | +{ | |
| 1193 | + struct lan9303 *chip = ds->priv; | |
| 1194 | + | |
| 1195 | + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); | |
| 1196 | + if (vid) | |
| 1197 | + return -EOPNOTSUPP; | |
| 1198 | + lan9303_alr_del_port(chip, addr, port); | |
| 1199 | + | |
| 1200 | + return 0; | |
| 1201 | +} | |
| 1202 | + | |
| 1203 | +static int lan9303_port_fdb_dump(struct dsa_switch *ds, int port, | |
| 1204 | + dsa_fdb_dump_cb_t *cb, void *data) | |
| 1205 | +{ | |
| 1206 | + struct lan9303 *chip = ds->priv; | |
| 1207 | + struct port_fdb_dump_ctx dump_ctx = { | |
| 1208 | + .port = port, | |
| 1209 | + .data = data, | |
| 1210 | + .cb = cb, | |
| 1211 | + }; | |
| 1212 | + | |
| 1213 | + dev_dbg(chip->dev, "%s(%d)\n", __func__, port); | |
| 1214 | + lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx); | |
| 1215 | + | |
| 1216 | + return 0; | |
| 1217 | +} | |
| 1218 | + | |
| 1219 | +static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port, | |
| 1220 | + const struct switchdev_obj_port_mdb *mdb, | |
| 1221 | + struct switchdev_trans *trans) | |
| 1222 | +{ | |
| 1223 | + struct lan9303 *chip = ds->priv; | |
| 1224 | + | |
| 1225 | + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, mdb->addr, | |
| 1226 | + mdb->vid); | |
| 1227 | + if (mdb->vid) | |
| 1228 | + return -EOPNOTSUPP; | |
| 1229 | + if (lan9303_alr_cache_find_mac(chip, mdb->addr)) | |
| 1230 | + return 0; | |
| 1231 | + if (!lan9303_alr_cache_find_free(chip)) | |
| 1232 | + return -ENOSPC; | |
| 1233 | + | |
| 1234 | + return 0; | |
| 1235 | +} | |
| 1236 | + | |
| 1237 | +static void lan9303_port_mdb_add(struct dsa_switch *ds, int port, | |
| 1238 | + const struct switchdev_obj_port_mdb *mdb, | |
| 1239 | + struct switchdev_trans *trans) | |
| 1240 | +{ | |
| 1241 | + struct lan9303 *chip = ds->priv; | |
| 1242 | + | |
| 1243 | + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, mdb->addr, | |
| 1244 | + mdb->vid); | |
| 1245 | + lan9303_alr_add_port(chip, mdb->addr, port, false); | |
| 1246 | +} | |
| 1247 | + | |
| 1248 | +static int lan9303_port_mdb_del(struct dsa_switch *ds, int port, | |
| 1249 | + const struct switchdev_obj_port_mdb *mdb) | |
| 1250 | +{ | |
| 1251 | + struct lan9303 *chip = ds->priv; | |
| 1252 | + | |
| 1253 | + dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, mdb->addr, | |
| 1254 | + mdb->vid); | |
| 1255 | + if (mdb->vid) | |
| 1256 | + return -EOPNOTSUPP; | |
| 1257 | + lan9303_alr_del_port(chip, mdb->addr, port); | |
| 1258 | + | |
| 1259 | + return 0; | |
| 798 | 1260 | } |
| 799 | 1261 | |
| 800 | 1262 | static const struct dsa_switch_ops lan9303_switch_ops = { |
| @@ -803,10 +1265,21 @@ static const struct dsa_switch_ops lan9303_switch_ops = { · 2 unmodified lines | ||
| 803 | 1265 | .get_strings = lan9303_get_strings, |
| 804 | 1266 | .phy_read = lan9303_phy_read, |
| 805 | 1267 | .phy_write = lan9303_phy_write, |
| 1268 | + .adjust_link = lan9303_adjust_link, | |
| 806 | 1269 | .get_ethtool_stats = lan9303_get_ethtool_stats, |
| 807 | 1270 | .get_sset_count = lan9303_get_sset_count, |
| 808 | 1271 | .port_enable = lan9303_port_enable, |
| 809 | 1272 | .port_disable = lan9303_port_disable, |
| 1273 | + .port_bridge_join = lan9303_port_bridge_join, | |
| 1274 | + .port_bridge_leave = lan9303_port_bridge_leave, | |
| 1275 | + .port_stp_state_set = lan9303_port_stp_state_set, | |
| 1276 | + .port_fast_age = lan9303_port_fast_age, | |
| 1277 | + .port_fdb_add = lan9303_port_fdb_add, | |
| 1278 | + .port_fdb_del = lan9303_port_fdb_del, | |
| 1279 | + .port_fdb_dump = lan9303_port_fdb_dump, | |
| 1280 | + .port_mdb_prepare = lan9303_port_mdb_prepare, | |
| 1281 | + .port_mdb_add = lan9303_port_mdb_add, | |
| 1282 | + .port_mdb_del = lan9303_port_mdb_del, | |
| 810 | 1283 | }; |
| 811 | 1284 | |
| 812 | 1285 | static int lan9303_register_switch(struct lan9303 *chip) |
| @@ -828,7 +1301,7 @@ static void lan9303_probe_reset_gpio(struct lan9303 *chip, · 15 unmodified lines | ||
| 828 | 1301 | chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset", |
| 829 | 1302 | GPIOD_OUT_LOW); |
| 830 | 1303 | |
| 831 | − if (!chip->reset_gpio) { | |
| 1304 | + if (IS_ERR(chip->reset_gpio)) { | |
| 832 | 1305 | dev_dbg(chip->dev, "No reset GPIO defined\n"); |
| 833 | 1306 | return; |
| 834 | 1307 | } |
| @@ -3,26 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/device.h> |
| 4 | 4 | #include <net/dsa.h> |
| 5 | 5 | |
| 6 | −struct lan9303; | |
| 7 | − | |
| 8 | −struct lan9303_phy_ops { | |
| 9 | − /* PHY 1 and 2 access*/ | |
| 10 | − int (*phy_read)(struct lan9303 *chip, int port, int regnum); | |
| 11 | − int (*phy_write)(struct lan9303 *chip, int port, | |
| 12 | − int regnum, u16 val); | |
| 13 | −}; | |
| 14 | − | |
| 15 | −struct lan9303 { | |
| 16 | − struct device *dev; | |
| 17 | − struct regmap *regmap; | |
| 18 | − struct regmap_irq_chip_data *irq_data; | |
| 19 | − struct gpio_desc *reset_gpio; | |
| 20 | − u32 reset_duration; /* in [ms] */ | |
| 21 | − bool phy_addr_sel_strap; | |
| 22 | − struct dsa_switch *ds; | |
| 23 | − struct mutex indirect_mutex; /* protect indexed register access */ | |
| 24 | − const struct lan9303_phy_ops *ops; | |
| 25 | −}; | |
| 6 | +#include <linux/dsa/lan9303.h> | |
| 26 | 7 | |
| 27 | 8 | extern const struct regmap_access_table lan9303_register_set; |
| 28 | 9 | extern const struct lan9303_phy_ops lan9303_indirect_phy_ops; |
| @@ -50,7 +50,7 @@ static int lan9303_i2c_probe(struct i2c_client *client, · 49 unmodified lines | ||
| 50 | 50 | return -ENOMEM; |
| 51 | 51 | |
| 52 | 52 | sw_dev->chip.regmap = devm_regmap_init_i2c(client, |
| 53 | − &lan9303_i2c_regmap_config); | |
| 53 | + &lan9303_i2c_regmap_config); | |
| 54 | 54 | if (IS_ERR(sw_dev->chip.regmap)) { |
| 55 | 55 | ret = PTR_ERR(sw_dev->chip.regmap); |
| 56 | 56 | dev_err(&client->dev, "Failed to allocate register map: %d\n", |
| @@ -67,14 +67,15 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val) · 66 unmodified lines | ||
| 67 | 67 | return 0; |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | −int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int reg, u16 val) | |
| 70 | +static int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int reg, | |
| 71 | + u16 val) | |
| 71 | 72 | { |
| 72 | 73 | struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev); |
| 73 | 74 | |
| 74 | 75 | return mdiobus_write_nested(sw_dev->device->bus, phy, reg, val); |
| 75 | 76 | } |
| 76 | 77 | |
| 77 | −int lan9303_mdio_phy_read(struct lan9303 *chip, int phy, int reg) | |
| 78 | +static int lan9303_mdio_phy_read(struct lan9303 *chip, int phy, int reg) | |
| 78 | 79 | { |
| 79 | 80 | struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev); |
| 80 | 81 | |
| @@ -115,7 +116,7 @@ static int lan9303_mdio_probe(struct mdio_device *mdiodev) · 34 unmodified lines | ||
| 115 | 116 | return -ENOMEM; |
| 116 | 117 | |
| 117 | 118 | sw_dev->chip.regmap = devm_regmap_init(&mdiodev->dev, NULL, sw_dev, |
| 118 | − &lan9303_mdio_regmap_config); | |
| 119 | + &lan9303_mdio_regmap_config); | |
| 119 | 120 | if (IS_ERR(sw_dev->chip.regmap)) { |
| 120 | 121 | ret = PTR_ERR(sw_dev->chip.regmap); |
| 121 | 122 | dev_err(&mdiodev->dev, "regmap init failed: %d\n", ret); |
| @@ -394,7 +394,8 @@ static int ksz_setup(struct dsa_switch *ds) · 393 unmodified lines | ||
| 394 | 394 | return 0; |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | −static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds) | |
| 397 | +static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds, | |
| 398 | + int port) | |
| 398 | 399 | { |
| 399 | 400 | return DSA_TAG_PROTO_KSZ; |
| 400 | 401 | } |
| @@ -564,7 +564,8 @@ static int mt7530_phy_read(struct dsa_switch *ds, int port, int regnum) · 563 unmodified lines | ||
| 564 | 564 | return mdiobus_read_nested(priv->bus, port, regnum); |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | −int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) | |
| 567 | +static int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum, | |
| 568 | + u16 val) | |
| 568 | 569 | { |
| 569 | 570 | struct mt7530_priv *priv = ds->priv; |
| 570 | 571 | |
| @@ -687,7 +688,7 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, · 116 unmodified lines | ||
| 687 | 688 | * the switch |
| 688 | 689 | */ |
| 689 | 690 | mt7530_write(priv, MT7530_PCR_P(port), |
| 690 | − PCR_MATRIX(priv->ds->enabled_port_mask)); | |
| 691 | + PCR_MATRIX(dsa_user_ports(priv->ds))); | |
| 691 | 692 | |
| 692 | 693 | return 0; |
| 693 | 694 | } |
| @@ -780,8 +781,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port, · 86 unmodified lines | ||
| 780 | 781 | * same bridge. If the port is disabled, port matrix is kept |
| 781 | 782 | * and not being setup until the port becomes enabled. |
| 782 | 783 | */ |
| 783 | − if (ds->enabled_port_mask & BIT(i) && i != port) { | |
| 784 | − if (ds->ports[i].bridge_dev != bridge) | |
| 784 | + if (dsa_is_user_port(ds, i) && i != port) { | |
| 785 | + if (dsa_to_port(ds, i)->bridge_dev != bridge) | |
| 785 | 786 | continue; |
| 786 | 787 | if (priv->ports[i].enable) |
| 787 | 788 | mt7530_set(priv, MT7530_PCR_P(i), |
| @@ -817,8 +818,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, · 29 unmodified lines | ||
| 817 | 818 | * in the same bridge. If the port is disabled, port matrix |
| 818 | 819 | * is kept and not being setup until the port becomes enabled. |
| 819 | 820 | */ |
| 820 | − if (ds->enabled_port_mask & BIT(i) && i != port) { | |
| 821 | − if (ds->ports[i].bridge_dev != bridge) | |
| 821 | + if (dsa_is_user_port(ds, i) && i != port) { | |
| 822 | + if (dsa_to_port(ds, i)->bridge_dev != bridge) | |
| 822 | 823 | continue; |
| 823 | 824 | if (priv->ports[i].enable) |
| 824 | 825 | mt7530_clear(priv, MT7530_PCR_P(i), |
| @@ -906,11 +907,11 @@ err: · 81 unmodified lines | ||
| 906 | 907 | } |
| 907 | 908 | |
| 908 | 909 | static enum dsa_tag_protocol |
| 909 | −mtk_get_tag_protocol(struct dsa_switch *ds) | |
| 910 | +mtk_get_tag_protocol(struct dsa_switch *ds, int port) | |
| 910 | 911 | { |
| 911 | 912 | struct mt7530_priv *priv = ds->priv; |
| 912 | 913 | |
| 913 | − if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) { | |
| 914 | + if (port != MT7530_CPU_PORT) { | |
| 914 | 915 | dev_warn(priv->dev, |
| 915 | 916 | "port not matched with tagging CPU port\n"); |
| 916 | 917 | return DSA_TAG_PROTO_NONE; |
| @@ -928,11 +929,11 @@ mt7530_setup(struct dsa_switch *ds) · 11 unmodified lines | ||
| 928 | 929 | struct device_node *dn; |
| 929 | 930 | struct mt7530_dummy_poll p; |
| 930 | 931 | |
| 931 | − /* The parent node of cpu_dp->netdev which holds the common system | |
| 932 | + /* The parent node of master netdev which holds the common system | |
| 932 | 933 | * controller also is the container for two GMACs nodes representing |
| 933 | 934 | * as two netdev instances. |
| 934 | 935 | */ |
| 935 | − dn = ds->dst->cpu_dp->netdev->dev.of_node->parent; | |
| 936 | + dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent; | |
| 936 | 937 | priv->ethernet = syscon_node_to_regmap(dn); |
| 937 | 938 | if (IS_ERR(priv->ethernet)) |
| 938 | 939 | return PTR_ERR(priv->ethernet); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #include <linux/delay.h> |
| 12 | +#include <linux/etherdevice.h> | |
| 12 | 13 | #include <linux/jiffies.h> |
| 13 | 14 | #include <linux/list.h> |
| 14 | 15 | #include <linux/module.h> |
| @@ -69,7 +70,8 @@ static const char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr) · 54 unmodified lines | ||
| 69 | 70 | return NULL; |
| 70 | 71 | } |
| 71 | 72 | |
| 72 | −static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds) | |
| 73 | +static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds, | |
| 74 | + int port) | |
| 73 | 75 | { |
| 74 | 76 | return DSA_TAG_PROTO_TRAILER; |
| 75 | 77 | } |
| @@ -174,9 +176,8 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p) · 98 unmodified lines | ||
| 174 | 176 | */ |
| 175 | 177 | REG_WRITE(addr, PORT_VLAN_MAP, |
| 176 | 178 | ((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) | |
| 177 | − (dsa_is_cpu_port(ds, p) ? | |
| 178 | − ds->enabled_port_mask : | |
| 179 | − BIT(ds->dst->cpu_dp->index))); | |
| 179 | + (dsa_is_cpu_port(ds, p) ? dsa_user_ports(ds) : | |
| 180 | + BIT(dsa_to_port(ds, p)->cpu_dp->index))); | |
| 180 | 181 | |
| 181 | 182 | /* Port Association Vector: when learning source addresses |
| 182 | 183 | * of packets, add the address to the address database using |
| @@ -188,6 +189,27 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p) · 5 unmodified lines | ||
| 188 | 189 | return 0; |
| 189 | 190 | } |
| 190 | 191 | |
| 192 | +static int mv88e6060_setup_addr(struct dsa_switch *ds) | |
| 193 | +{ | |
| 194 | + u8 addr[ETH_ALEN]; | |
| 195 | + u16 val; | |
| 196 | + | |
| 197 | + eth_random_addr(addr); | |
| 198 | + | |
| 199 | + val = addr[0] << 8 | addr[1]; | |
| 200 | + | |
| 201 | + /* The multicast bit is always transmitted as a zero, so the switch uses | |
| 202 | + * bit 8 for "DiffAddr", where 0 means all ports transmit the same SA. | |
| 203 | + */ | |
| 204 | + val &= 0xfeff; | |
| 205 | + | |
| 206 | + REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val); | |
| 207 | + REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); | |
| 208 | + REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); | |
| 209 | + | |
| 210 | + return 0; | |
| 211 | +} | |
| 212 | + | |
| 191 | 213 | static int mv88e6060_setup(struct dsa_switch *ds) |
| 192 | 214 | { |
| 193 | 215 | int ret; |
| @@ -203,6 +225,10 @@ static int mv88e6060_setup(struct dsa_switch *ds) · 9 unmodified lines | ||
| 203 | 225 | if (ret < 0) |
| 204 | 226 | return ret; |
| 205 | 227 | |
| 228 | + ret = mv88e6060_setup_addr(ds); | |
| 229 | + if (ret < 0) | |
| 230 | + return ret; | |
| 231 | + | |
| 206 | 232 | for (i = 0; i < MV88E6060_PORTS; i++) { |
| 207 | 233 | ret = mv88e6060_setup_port(ds, i); |
| 208 | 234 | if (ret < 0) |
| @@ -212,22 +238,6 @@ static int mv88e6060_setup(struct dsa_switch *ds) · 3 unmodified lines | ||
| 212 | 238 | return 0; |
| 213 | 239 | } |
| 214 | 240 | |
| 215 | −static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr) | |
| 216 | −{ | |
| 217 | − u16 val = addr[0] << 8 | addr[1]; | |
| 218 | − | |
| 219 | − /* The multicast bit is always transmitted as a zero, so the switch uses | |
| 220 | − * bit 8 for "DiffAddr", where 0 means all ports transmit the same SA. | |
| 221 | − */ | |
| 222 | − val &= 0xfeff; | |
| 223 | − | |
| 224 | − REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val); | |
| 225 | − REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); | |
| 226 | − REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); | |
| 227 | − | |
| 228 | − return 0; | |
| 229 | −} | |
| 230 | − | |
| 231 | 241 | static int mv88e6060_port_to_phy_addr(int port) |
| 232 | 242 | { |
| 233 | 243 | if (port >= 0 && port < MV88E6060_PORTS) |
| @@ -262,7 +272,6 @@ static const struct dsa_switch_ops mv88e6060_switch_ops = { · 28 unmodified lines | ||
| 262 | 272 | .get_tag_protocol = mv88e6060_get_tag_protocol, |
| 263 | 273 | .probe = mv88e6060_drv_probe, |
| 264 | 274 | .setup = mv88e6060_setup, |
| 265 | − .set_addr = mv88e6060_set_addr, | |
| 266 | 275 | .phy_read = mv88e6060_phy_read, |
| 267 | 276 | .phy_write = mv88e6060_phy_write, |
| 268 | 277 | }; |
| @@ -851,7 +851,7 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port) · 850 unmodified lines | ||
| 851 | 851 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) |
| 852 | 852 | if (dsa_is_cpu_port(chip->ds, i) || |
| 853 | 853 | dsa_is_dsa_port(chip->ds, i) || |
| 854 | − (br && chip->ds->ports[i].bridge_dev == br)) | |
| 854 | + (br && dsa_to_port(chip->ds, i)->bridge_dev == br)) | |
| 855 | 855 | pvlan |= BIT(i); |
| 856 | 856 | |
| 857 | 857 | return pvlan; |
| @@ -932,6 +932,19 @@ static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip) · 74 unmodified lines | ||
| 932 | 932 | return 0; |
| 933 | 933 | } |
| 934 | 934 | |
| 935 | +static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip) | |
| 936 | +{ | |
| 937 | + if (chip->info->ops->set_switch_mac) { | |
| 938 | + u8 addr[ETH_ALEN]; | |
| 939 | + | |
| 940 | + eth_random_addr(addr); | |
| 941 | + | |
| 942 | + return chip->info->ops->set_switch_mac(chip, addr); | |
| 943 | + } | |
| 944 | + | |
| 945 | + return 0; | |
| 946 | +} | |
| 947 | + | |
| 935 | 948 | static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port) |
| 936 | 949 | { |
| 937 | 950 | u16 pvlan = 0; |
| @@ -1124,23 +1137,23 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, · 186 unmodified lines | ||
| 1124 | 1137 | if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i)) |
| 1125 | 1138 | continue; |
| 1126 | 1139 | |
| 1127 | − if (!ds->ports[port].netdev) | |
| 1140 | + if (!ds->ports[i].slave) | |
| 1128 | 1141 | continue; |
| 1129 | 1142 | |
| 1130 | 1143 | if (vlan.member[i] == |
| 1131 | 1144 | MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) |
| 1132 | 1145 | continue; |
| 1133 | 1146 | |
| 1134 | − if (ds->ports[i].bridge_dev == | |
| 1147 | + if (dsa_to_port(ds, i)->bridge_dev == | |
| 1135 | 1148 | ds->ports[port].bridge_dev) |
| 1136 | 1149 | break; /* same bridge, check next VLAN */ |
| 1137 | 1150 | |
| 1138 | − if (!ds->ports[i].bridge_dev) | |
| 1151 | + if (!dsa_to_port(ds, i)->bridge_dev) | |
| 1139 | 1152 | continue; |
| 1140 | 1153 | |
| 1141 | − dev_err(ds->dev, "p%d: hw VLAN %d already used by %s\n", | |
| 1142 | − port, vlan.vid, | |
| 1143 | − netdev_name(ds->ports[i].bridge_dev)); | |
| 1154 | + dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n", | |
| 1155 | + port, vlan.vid, i, | |
| 1156 | + netdev_name(dsa_to_port(ds, i)->bridge_dev)); | |
| 1144 | 1157 | err = -EOPNOTSUPP; |
| 1145 | 1158 | goto unlock; |
| 1146 | 1159 | } |
| @@ -1195,6 +1208,73 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, · 48 unmodified lines | ||
| 1195 | 1208 | return 0; |
| 1196 | 1209 | } |
| 1197 | 1210 | |
| 1211 | +static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, | |
| 1212 | + const unsigned char *addr, u16 vid, | |
| 1213 | + u8 state) | |
| 1214 | +{ | |
| 1215 | + struct mv88e6xxx_vtu_entry vlan; | |
| 1216 | + struct mv88e6xxx_atu_entry entry; | |
| 1217 | + int err; | |
| 1218 | + | |
| 1219 | + /* Null VLAN ID corresponds to the port private database */ | |
| 1220 | + if (vid == 0) | |
| 1221 | + err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid); | |
| 1222 | + else | |
| 1223 | + err = mv88e6xxx_vtu_get(chip, vid, &vlan, false); | |
| 1224 | + if (err) | |
| 1225 | + return err; | |
| 1226 | + | |
| 1227 | + entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED; | |
| 1228 | + ether_addr_copy(entry.mac, addr); | |
| 1229 | + eth_addr_dec(entry.mac); | |
| 1230 | + | |
| 1231 | + err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry); | |
| 1232 | + if (err) | |
| 1233 | + return err; | |
| 1234 | + | |
| 1235 | + /* Initialize a fresh ATU entry if it isn't found */ | |
| 1236 | + if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED || | |
| 1237 | + !ether_addr_equal(entry.mac, addr)) { | |
| 1238 | + memset(&entry, 0, sizeof(entry)); | |
| 1239 | + ether_addr_copy(entry.mac, addr); | |
| 1240 | + } | |
| 1241 | + | |
| 1242 | + /* Purge the ATU entry only if no port is using it anymore */ | |
| 1243 | + if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) { | |
| 1244 | + entry.portvec &= ~BIT(port); | |
| 1245 | + if (!entry.portvec) | |
| 1246 | + entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED; | |
| 1247 | + } else { | |
| 1248 | + entry.portvec |= BIT(port); | |
| 1249 | + entry.state = state; | |
| 1250 | + } | |
| 1251 | + | |
| 1252 | + return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry); | |
| 1253 | +} | |
| 1254 | + | |
| 1255 | +static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port, | |
| 1256 | + u16 vid) | |
| 1257 | +{ | |
| 1258 | + const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | |
| 1259 | + u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC; | |
| 1260 | + | |
| 1261 | + return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state); | |
| 1262 | +} | |
| 1263 | + | |
| 1264 | +static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid) | |
| 1265 | +{ | |
| 1266 | + int port; | |
| 1267 | + int err; | |
| 1268 | + | |
| 1269 | + for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { | |
| 1270 | + err = mv88e6xxx_port_add_broadcast(chip, port, vid); | |
| 1271 | + if (err) | |
| 1272 | + return err; | |
| 1273 | + } | |
| 1274 | + | |
| 1275 | + return 0; | |
| 1276 | +} | |
| 1277 | + | |
| 1198 | 1278 | static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, |
| 1199 | 1279 | u16 vid, u8 member) |
| 1200 | 1280 | { |
| @@ -1207,7 +1287,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, · 6 unmodified lines | ||
| 1207 | 1287 | |
| 1208 | 1288 | vlan.member[port] = member; |
| 1209 | 1289 | |
| 1210 | − return mv88e6xxx_vtu_loadpurge(chip, &vlan); | |
| 1290 | + err = mv88e6xxx_vtu_loadpurge(chip, &vlan); | |
| 1291 | + if (err) | |
| 1292 | + return err; | |
| 1293 | + | |
| 1294 | + return mv88e6xxx_broadcast_setup(chip, vid); | |
| 1211 | 1295 | } |
| 1212 | 1296 | |
| 1213 | 1297 | static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, |
| @@ -1311,50 +1395,6 @@ unlock: · 97 unmodified lines | ||
| 1311 | 1395 | return err; |
| 1312 | 1396 | } |
| 1313 | 1397 | |
| 1314 | −static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, | |
| 1315 | − const unsigned char *addr, u16 vid, | |
| 1316 | − u8 state) | |
| 1317 | −{ | |
| 1318 | − struct mv88e6xxx_vtu_entry vlan; | |
| 1319 | − struct mv88e6xxx_atu_entry entry; | |
| 1320 | − int err; | |
| 1321 | − | |
| 1322 | − /* Null VLAN ID corresponds to the port private database */ | |
| 1323 | − if (vid == 0) | |
| 1324 | − err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid); | |
| 1325 | − else | |
| 1326 | − err = mv88e6xxx_vtu_get(chip, vid, &vlan, false); | |
| 1327 | − if (err) | |
| 1328 | − return err; | |
| 1329 | − | |
| 1330 | − entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED; | |
| 1331 | − ether_addr_copy(entry.mac, addr); | |
| 1332 | − eth_addr_dec(entry.mac); | |
| 1333 | − | |
| 1334 | − err = mv88e6xxx_g1_atu_getnext(chip, vlan.fid, &entry); | |
| 1335 | − if (err) | |
| 1336 | − return err; | |
| 1337 | − | |
| 1338 | − /* Initialize a fresh ATU entry if it isn't found */ | |
| 1339 | − if (entry.state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED || | |
| 1340 | − !ether_addr_equal(entry.mac, addr)) { | |
| 1341 | − memset(&entry, 0, sizeof(entry)); | |
| 1342 | − ether_addr_copy(entry.mac, addr); | |
| 1343 | − } | |
| 1344 | − | |
| 1345 | − /* Purge the ATU entry only if no port is using it anymore */ | |
| 1346 | − if (state == MV88E6XXX_G1_ATU_DATA_STATE_UNUSED) { | |
| 1347 | − entry.portvec &= ~BIT(port); | |
| 1348 | − if (!entry.portvec) | |
| 1349 | − entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED; | |
| 1350 | − } else { | |
| 1351 | − entry.portvec |= BIT(port); | |
| 1352 | − entry.state = state; | |
| 1353 | − } | |
| 1354 | − | |
| 1355 | − return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry); | |
| 1356 | −} | |
| 1357 | − | |
| 1358 | 1398 | static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, |
| 1359 | 1399 | const unsigned char *addr, u16 vid) |
| 1360 | 1400 | { |
| @@ -1663,7 +1703,7 @@ static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port) · 302 unmodified lines | ||
| 1663 | 1703 | if (dsa_is_dsa_port(chip->ds, port)) |
| 1664 | 1704 | return mv88e6xxx_set_port_mode_dsa(chip, port); |
| 1665 | 1705 | |
| 1666 | − if (dsa_is_normal_port(chip->ds, port)) | |
| 1706 | + if (dsa_is_user_port(chip->ds, port)) | |
| 1667 | 1707 | return mv88e6xxx_set_port_mode_normal(chip, port); |
| 1668 | 1708 | |
| 1669 | 1709 | /* Setup CPU port mode depending on its supported tag format */ |
| @@ -1964,19 +2004,7 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip) · 294 unmodified lines | ||
| 1964 | 2004 | if (err) |
| 1965 | 2005 | return err; |
| 1966 | 2006 | |
| 1967 | − /* Clear the statistics counters for all ports */ | |
| 1968 | − err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, | |
| 1969 | − MV88E6XXX_G1_STATS_OP_BUSY | | |
| 1970 | − MV88E6XXX_G1_STATS_OP_FLUSH_ALL); | |
| 1971 | − if (err) | |
| 1972 | − return err; | |
| 1973 | − | |
| 1974 | − /* Wait for the flush to complete. */ | |
| 1975 | − err = mv88e6xxx_g1_stats_wait(chip); | |
| 1976 | − if (err) | |
| 1977 | − return err; | |
| 1978 | − | |
| 1979 | − return 0; | |
| 2007 | + return mv88e6xxx_g1_stats_clear(chip); | |
| 1980 | 2008 | } |
| 1981 | 2009 | |
| 1982 | 2010 | static int mv88e6xxx_setup(struct dsa_switch *ds) |
| @@ -1992,6 +2020,9 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) · 9 unmodified lines | ||
| 1992 | 2020 | |
| 1993 | 2021 | /* Setup Switch Port Registers */ |
| 1994 | 2022 | for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { |
| 2023 | + if (dsa_is_unused_port(ds, i)) | |
| 2024 | + continue; | |
| 2025 | + | |
| 1995 | 2026 | err = mv88e6xxx_setup_port(chip, i); |
| 1996 | 2027 | if (err) |
| 1997 | 2028 | goto unlock; |
| @@ -2013,6 +2044,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) · 15 unmodified lines | ||
| 2013 | 2044 | if (err) |
| 2014 | 2045 | goto unlock; |
| 2015 | 2046 | |
| 2047 | + err = mv88e6xxx_mac_setup(chip); | |
| 2048 | + if (err) | |
| 2049 | + goto unlock; | |
| 2050 | + | |
| 2016 | 2051 | err = mv88e6xxx_phy_setup(chip); |
| 2017 | 2052 | if (err) |
| 2018 | 2053 | goto unlock; |
| @@ -2029,6 +2064,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) · 10 unmodified lines | ||
| 2029 | 2064 | if (err) |
| 2030 | 2065 | goto unlock; |
| 2031 | 2066 | |
| 2067 | + err = mv88e6xxx_broadcast_setup(chip, 0); | |
| 2068 | + if (err) | |
| 2069 | + goto unlock; | |
| 2070 | + | |
| 2032 | 2071 | err = mv88e6xxx_pot_setup(chip); |
| 2033 | 2072 | if (err) |
| 2034 | 2073 | goto unlock; |
| @@ -2043,21 +2082,6 @@ unlock: · 8 unmodified lines | ||
| 2043 | 2082 | return err; |
| 2044 | 2083 | } |
| 2045 | 2084 | |
| 2046 | −static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr) | |
| 2047 | −{ | |
| 2048 | − struct mv88e6xxx_chip *chip = ds->priv; | |
| 2049 | − int err; | |
| 2050 | − | |
| 2051 | − if (!chip->info->ops->set_switch_mac) | |
| 2052 | − return -EOPNOTSUPP; | |
| 2053 | − | |
| 2054 | − mutex_lock(&chip->reg_lock); | |
| 2055 | − err = chip->info->ops->set_switch_mac(chip, addr); | |
| 2056 | − mutex_unlock(&chip->reg_lock); | |
| 2057 | − | |
| 2058 | − return err; | |
| 2059 | −} | |
| 2060 | − | |
| 2061 | 2085 | static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg) |
| 2062 | 2086 | { |
| 2063 | 2087 | struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; |
| @@ -2263,6 +2287,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = { · 199 unmodified lines | ||
| 2263 | 2287 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2264 | 2288 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2265 | 2289 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2290 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2266 | 2291 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2267 | 2292 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2268 | 2293 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2290,6 +2315,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = { · 21 unmodified lines | ||
| 2290 | 2315 | .port_set_egress_floods = mv88e6185_port_set_egress_floods, |
| 2291 | 2316 | .port_set_upstream_port = mv88e6095_port_set_upstream_port, |
| 2292 | 2317 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2318 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2293 | 2319 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2294 | 2320 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2295 | 2321 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2320,6 +2346,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = { · 24 unmodified lines | ||
| 2320 | 2346 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2321 | 2347 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2322 | 2348 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2349 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2323 | 2350 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2324 | 2351 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2325 | 2352 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2347,6 +2374,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = { · 21 unmodified lines | ||
| 2347 | 2374 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2348 | 2375 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2349 | 2376 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2377 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2350 | 2378 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2351 | 2379 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2352 | 2380 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2377,6 +2405,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = { · 24 unmodified lines | ||
| 2377 | 2405 | .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, |
| 2378 | 2406 | .port_pause_limit = mv88e6097_port_pause_limit, |
| 2379 | 2407 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2408 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2380 | 2409 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2381 | 2410 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2382 | 2411 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2413,6 +2442,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { · 30 unmodified lines | ||
| 2413 | 2442 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2414 | 2443 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2415 | 2444 | .stats_snapshot = mv88e6390_g1_stats_snapshot, |
| 2445 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2416 | 2446 | .stats_get_sset_count = mv88e6320_stats_get_sset_count, |
| 2417 | 2447 | .stats_get_strings = mv88e6320_stats_get_strings, |
| 2418 | 2448 | .stats_get_stats = mv88e6390_stats_get_stats, |
| @@ -2445,6 +2475,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = { · 26 unmodified lines | ||
| 2445 | 2475 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2446 | 2476 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2447 | 2477 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2478 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2448 | 2479 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2449 | 2480 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2450 | 2481 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2470,6 +2501,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = { · 19 unmodified lines | ||
| 2470 | 2501 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2471 | 2502 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2472 | 2503 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2504 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2473 | 2505 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2474 | 2506 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2475 | 2507 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2503,6 +2535,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = { · 27 unmodified lines | ||
| 2503 | 2535 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2504 | 2536 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2505 | 2537 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2538 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2506 | 2539 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2507 | 2540 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2508 | 2541 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2538,6 +2571,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { · 29 unmodified lines | ||
| 2538 | 2571 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2539 | 2572 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2540 | 2573 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2574 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2541 | 2575 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2542 | 2576 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2543 | 2577 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2572,6 +2606,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = { · 28 unmodified lines | ||
| 2572 | 2606 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2573 | 2607 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2574 | 2608 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2609 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2575 | 2610 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2576 | 2611 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2577 | 2612 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2607,6 +2642,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { · 29 unmodified lines | ||
| 2607 | 2642 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2608 | 2643 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2609 | 2644 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2645 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2610 | 2646 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2611 | 2647 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2612 | 2648 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2634,6 +2670,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = { · 21 unmodified lines | ||
| 2634 | 2670 | .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting, |
| 2635 | 2671 | .port_set_upstream_port = mv88e6095_port_set_upstream_port, |
| 2636 | 2672 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 2673 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2637 | 2674 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2638 | 2675 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2639 | 2676 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2775,6 +2812,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { · 135 unmodified lines | ||
| 2775 | 2812 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2776 | 2813 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2777 | 2814 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2815 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2778 | 2816 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2779 | 2817 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2780 | 2818 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2846,6 +2884,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { · 65 unmodified lines | ||
| 2846 | 2884 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2847 | 2885 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2848 | 2886 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2887 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2849 | 2888 | .stats_get_sset_count = mv88e6320_stats_get_sset_count, |
| 2850 | 2889 | .stats_get_strings = mv88e6320_stats_get_strings, |
| 2851 | 2890 | .stats_get_stats = mv88e6320_stats_get_stats, |
| @@ -2879,6 +2918,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { · 27 unmodified lines | ||
| 2879 | 2918 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2880 | 2919 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2881 | 2920 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2921 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2882 | 2922 | .stats_get_sset_count = mv88e6320_stats_get_sset_count, |
| 2883 | 2923 | .stats_get_strings = mv88e6320_stats_get_strings, |
| 2884 | 2924 | .stats_get_stats = mv88e6320_stats_get_stats, |
| @@ -2911,6 +2951,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { · 26 unmodified lines | ||
| 2911 | 2951 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2912 | 2952 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2913 | 2953 | .stats_snapshot = mv88e6390_g1_stats_snapshot, |
| 2954 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2914 | 2955 | .stats_get_sset_count = mv88e6320_stats_get_sset_count, |
| 2915 | 2956 | .stats_get_strings = mv88e6320_stats_get_strings, |
| 2916 | 2957 | .stats_get_stats = mv88e6390_stats_get_stats, |
| @@ -2944,6 +2985,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = { · 27 unmodified lines | ||
| 2944 | 2985 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2945 | 2986 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2946 | 2987 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 2988 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2947 | 2989 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2948 | 2990 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2949 | 2991 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -2977,6 +3019,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = { · 27 unmodified lines | ||
| 2977 | 3019 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 2978 | 3020 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 2979 | 3021 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 3022 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 2980 | 3023 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 2981 | 3024 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 2982 | 3025 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -3012,6 +3055,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { · 29 unmodified lines | ||
| 3012 | 3055 | .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, |
| 3013 | 3056 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 3014 | 3057 | .stats_snapshot = mv88e6320_g1_stats_snapshot, |
| 3058 | + .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | |
| 3015 | 3059 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 3016 | 3060 | .stats_get_strings = mv88e6095_stats_get_strings, |
| 3017 | 3061 | .stats_get_stats = mv88e6095_stats_get_stats, |
| @@ -3687,7 +3731,8 @@ static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, · 669 unmodified lines | ||
| 3687 | 3731 | return 0; |
| 3688 | 3732 | } |
| 3689 | 3733 | |
| 3690 | −static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds) | |
| 3734 | +static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, | |
| 3735 | + int port) | |
| 3691 | 3736 | { |
| 3692 | 3737 | struct mv88e6xxx_chip *chip = ds->priv; |
| 3693 | 3738 | |
| @@ -3785,7 +3830,6 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = { · 91 unmodified lines | ||
| 3785 | 3830 | .probe = mv88e6xxx_drv_probe, |
| 3786 | 3831 | .get_tag_protocol = mv88e6xxx_get_tag_protocol, |
| 3787 | 3832 | .setup = mv88e6xxx_setup, |
| 3788 | − .set_addr = mv88e6xxx_set_addr, | |
| 3789 | 3833 | .adjust_link = mv88e6xxx_adjust_link, |
| 3790 | 3834 | .get_strings = mv88e6xxx_get_strings, |
| 3791 | 3835 | .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, |
| @@ -374,6 +374,22 @@ int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip) · 373 unmodified lines | ||
| 374 | 374 | MV88E6XXX_G1_STATS_OP_BUSY); |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | +int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) | |
| 378 | +{ | |
| 379 | + u16 val; | |
| 380 | + int err; | |
| 381 | + | |
| 382 | + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); | |
| 383 | + if (err) | |
| 384 | + return err; | |
| 385 | + | |
| 386 | + val |= MV88E6XXX_G1_STATS_OP_HIST_RX_TX; | |
| 387 | + | |
| 388 | + err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); | |
| 389 | + | |
| 390 | + return err; | |
| 391 | +} | |
| 392 | + | |
| 377 | 393 | int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port) |
| 378 | 394 | { |
| 379 | 395 | int err; |
| @@ -444,3 +460,22 @@ void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val) · 64 unmodified lines | ||
| 444 | 460 | |
| 445 | 461 | *val = value | reg; |
| 446 | 462 | } |
| 463 | + | |
| 464 | +int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip) | |
| 465 | +{ | |
| 466 | + int err; | |
| 467 | + u16 val; | |
| 468 | + | |
| 469 | + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val); | |
| 470 | + if (err) | |
| 471 | + return err; | |
| 472 | + | |
| 473 | + val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL; | |
| 474 | + | |
| 475 | + err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val); | |
| 476 | + if (err) | |
| 477 | + return err; | |
| 478 | + | |
| 479 | + /* Wait for the flush to complete. */ | |
| 480 | + return mv88e6xxx_g1_stats_wait(chip); | |
| 481 | +} | |
| @@ -235,8 +235,10 @@ int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip); · 234 unmodified lines | ||
| 235 | 235 | int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port); |
| 236 | 236 | int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port); |
| 237 | 237 | int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port); |
| 238 | +int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip); | |
| 238 | 239 | int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip); |
| 239 | 240 | void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val); |
| 241 | +int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip); | |
| 240 | 242 | int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port); |
| 241 | 243 | int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port); |
| 242 | 244 | int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port); |
| @@ -506,7 +506,7 @@ qca8k_setup(struct dsa_switch *ds) · 505 unmodified lines | ||
| 506 | 506 | pr_warn("regmap initialization failed"); |
| 507 | 507 | |
| 508 | 508 | /* Initialize CPU port pad mode (xMII type, delays...) */ |
| 509 | − phy_mode = of_get_phy_mode(ds->dst->cpu_dp->dn); | |
| 509 | + phy_mode = of_get_phy_mode(ds->ports[QCA8K_CPU_PORT].dn); | |
| 510 | 510 | if (phy_mode < 0) { |
| 511 | 511 | pr_err("Can't find phy-mode for master device\n"); |
| 512 | 512 | return phy_mode; |
| @@ -536,7 +536,7 @@ qca8k_setup(struct dsa_switch *ds) · 23 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | /* Disable MAC by default on all user ports */ |
| 538 | 538 | for (i = 1; i < QCA8K_NUM_PORTS; i++) |
| 539 | − if (ds->enabled_port_mask & BIT(i)) | |
| 539 | + if (dsa_is_user_port(ds, i)) | |
| 540 | 540 | qca8k_port_set_status(priv, i, 0); |
| 541 | 541 | |
| 542 | 542 | /* Forward all unknown frames to CPU port for Linux processing */ |
| @@ -551,12 +551,11 @@ qca8k_setup(struct dsa_switch *ds) · 8 unmodified lines | ||
| 551 | 551 | /* CPU port gets connected to all user ports of the switch */ |
| 552 | 552 | if (dsa_is_cpu_port(ds, i)) { |
| 553 | 553 | qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT), |
| 554 | − QCA8K_PORT_LOOKUP_MEMBER, | |
| 555 | − ds->enabled_port_mask); | |
| 554 | + QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); | |
| 556 | 555 | } |
| 557 | 556 | |
| 558 | 557 | /* Invividual user ports get connected to CPU port only */ |
| 559 | − if (ds->enabled_port_mask & BIT(i)) { | |
| 558 | + if (dsa_is_user_port(ds, i)) { | |
| 560 | 559 | int shift = 16 * (i % 2); |
| 561 | 560 | |
| 562 | 561 | qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), |
| @@ -700,7 +699,7 @@ qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) · 137 unmodified lines | ||
| 700 | 699 | int i; |
| 701 | 700 | |
| 702 | 701 | for (i = 1; i < QCA8K_NUM_PORTS; i++) { |
| 703 | − if (ds->ports[i].bridge_dev != br) | |
| 702 | + if (dsa_to_port(ds, i)->bridge_dev != br) | |
| 704 | 703 | continue; |
| 705 | 704 | /* Add this port to the portvlan mask of the other ports |
| 706 | 705 | * in the bridge |
| @@ -725,7 +724,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) · 18 unmodified lines | ||
| 725 | 724 | int i; |
| 726 | 725 | |
| 727 | 726 | for (i = 1; i < QCA8K_NUM_PORTS; i++) { |
| 728 | − if (ds->ports[i].bridge_dev != br) | |
| 727 | + if (dsa_to_port(ds, i)->bridge_dev != br) | |
| 729 | 728 | continue; |
| 730 | 729 | /* Remove this port to the portvlan mask of the other ports |
| 731 | 730 | * in the bridge |
| @@ -824,7 +823,7 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port, · 92 unmodified lines | ||
| 824 | 823 | } |
| 825 | 824 | |
| 826 | 825 | static enum dsa_tag_protocol |
| 827 | −qca8k_get_tag_protocol(struct dsa_switch *ds) | |
| 826 | +qca8k_get_tag_protocol(struct dsa_switch *ds, int port) | |
| 828 | 827 | { |
| 829 | 828 | return DSA_TAG_PROTO_QCA; |
| 830 | 829 | } |
| @@ -353,7 +353,7 @@ static void dummy_setup(struct net_device *dev) · 352 unmodified lines | ||
| 353 | 353 | eth_hw_addr_random(dev); |
| 354 | 354 | |
| 355 | 355 | dev->min_mtu = 0; |
| 356 | − dev->max_mtu = ETH_MAX_MTU; | |
| 356 | + dev->max_mtu = 0; | |
| 357 | 357 | } |
| 358 | 358 | |
| 359 | 359 | static int dummy_validate(struct nlattr *tb[], struct nlattr *data[], |
| @@ -388,7 +388,7 @@ static int __init dummy_init_one(void) · 28 unmodified lines | ||
| 388 | 388 | int err; |
| 389 | 389 | |
| 390 | 390 | dev_dummy = alloc_netdev(sizeof(struct dummy_priv), |
| 391 | − "dummy%d", NET_NAME_UNKNOWN, dummy_setup); | |
| 391 | + "dummy%d", NET_NAME_ENUM, dummy_setup); | |
| 392 | 392 | if (!dev_dummy) |
| 393 | 393 | return -ENOMEM; |
| 394 | 394 | |
| @@ -178,10 +178,8 @@ static void __init eql_setup(struct net_device *dev) · 177 unmodified lines | ||
| 178 | 178 | { |
| 179 | 179 | equalizer_t *eql = netdev_priv(dev); |
| 180 | 180 | |
| 181 | − init_timer(&eql->timer); | |
| 182 | − eql->timer.data = (unsigned long) eql; | |
| 181 | + setup_timer(&eql->timer, eql_timer, (unsigned long)eql); | |
| 183 | 182 | eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL; |
| 184 | − eql->timer.function = eql_timer; | |
| 185 | 183 | |
| 186 | 184 | spin_lock_init(&eql->queue.lock); |
| 187 | 185 | INIT_LIST_HEAD(&eql->queue.all_slaves); |
| @@ -367,7 +367,7 @@ static struct net_device *corkscrew_scan(int unit); · 366 unmodified lines | ||
| 367 | 367 | static int corkscrew_setup(struct net_device *dev, int ioaddr, |
| 368 | 368 | struct pnp_dev *idev, int card_number); |
| 369 | 369 | static int corkscrew_open(struct net_device *dev); |
| 370 | −static void corkscrew_timer(unsigned long arg); | |
| 370 | +static void corkscrew_timer(struct timer_list *t); | |
| 371 | 371 | static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb, |
| 372 | 372 | struct net_device *dev); |
| 373 | 373 | static int corkscrew_rx(struct net_device *dev); |
| @@ -627,7 +627,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, · 253 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | spin_lock_init(&vp->lock); |
| 629 | 629 | |
| 630 | − setup_timer(&vp->timer, corkscrew_timer, (unsigned long) dev); | |
| 630 | + timer_setup(&vp->timer, corkscrew_timer, 0); | |
| 631 | 631 | |
| 632 | 632 | /* Read the station address from the EEPROM. */ |
| 633 | 633 | EL3WINDOW(0); |
| @@ -869,11 +869,11 @@ static int corkscrew_open(struct net_device *dev) · 235 unmodified lines | ||
| 869 | 869 | return 0; |
| 870 | 870 | } |
| 871 | 871 | |
| 872 | −static void corkscrew_timer(unsigned long data) | |
| 872 | +static void corkscrew_timer(struct timer_list *t) | |
| 873 | 873 | { |
| 874 | 874 | #ifdef AUTOMEDIA |
| 875 | − struct net_device *dev = (struct net_device *) data; | |
| 876 | − struct corkscrew_private *vp = netdev_priv(dev); | |
| 875 | + struct corkscrew_private *vp = from_timer(vp, t, timer); | |
| 876 | + struct net_device *dev = vp->our_dev; | |
| 877 | 877 | int ioaddr = dev->base_addr; |
| 878 | 878 | unsigned long flags; |
| 879 | 879 | int ok = 0; |
| @@ -225,7 +225,7 @@ static unsigned short read_eeprom(unsigned int ioaddr, int index); · 224 unmodified lines | ||
| 225 | 225 | static void tc574_wait_for_completion(struct net_device *dev, int cmd); |
| 226 | 226 | |
| 227 | 227 | static void tc574_reset(struct net_device *dev); |
| 228 | −static void media_check(unsigned long arg); | |
| 228 | +static void media_check(struct timer_list *t); | |
| 229 | 229 | static int el3_open(struct net_device *dev); |
| 230 | 230 | static netdev_tx_t el3_start_xmit(struct sk_buff *skb, |
| 231 | 231 | struct net_device *dev); |
| @@ -377,7 +377,7 @@ static int tc574_config(struct pcmcia_device *link) · 145 unmodified lines | ||
| 377 | 377 | lp->autoselect = config & Autoselect ? 1 : 0; |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | − init_timer(&lp->media); | |
| 380 | + timer_setup(&lp->media, media_check, 0); | |
| 381 | 381 | |
| 382 | 382 | { |
| 383 | 383 | int phy; |
| @@ -681,8 +681,6 @@ static int el3_open(struct net_device *dev) · 297 unmodified lines | ||
| 681 | 681 | netif_start_queue(dev); |
| 682 | 682 | |
| 683 | 683 | tc574_reset(dev); |
| 684 | − lp->media.function = media_check; | |
| 685 | − lp->media.data = (unsigned long) dev; | |
| 686 | 684 | lp->media.expires = jiffies + HZ; |
| 687 | 685 | add_timer(&lp->media); |
| 688 | 686 | |
| @@ -859,10 +857,10 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) · 170 unmodified lines | ||
| 859 | 857 | (and as a last resort, poll the NIC for events), and to monitor |
| 860 | 858 | the MII, reporting changes in cable status. |
| 861 | 859 | */ |
| 862 | −static void media_check(unsigned long arg) | |
| 860 | +static void media_check(struct timer_list *t) | |
| 863 | 861 | { |
| 864 | − struct net_device *dev = (struct net_device *) arg; | |
| 865 | − struct el3_private *lp = netdev_priv(dev); | |
| 862 | + struct el3_private *lp = from_timer(lp, t, media); | |
| 863 | + struct net_device *dev = lp->p_dev->priv; | |
| 866 | 864 | unsigned int ioaddr = dev->base_addr; |
| 867 | 865 | unsigned long flags; |
| 868 | 866 | unsigned short /* cable, */ media, partner; |
| @@ -1048,6 +1046,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) · 179 unmodified lines | ||
| 1048 | 1046 | switch(cmd) { |
| 1049 | 1047 | case SIOCGMIIPHY: /* Get the address of the PHY in use. */ |
| 1050 | 1048 | data->phy_id = phy; |
| 1049 | + /* fall through */ | |
| 1051 | 1050 | case SIOCGMIIREG: /* Read the specified MII register. */ |
| 1052 | 1051 | { |
| 1053 | 1052 | int saved_window; |
| @@ -163,7 +163,7 @@ static void tc589_release(struct pcmcia_device *link); · 162 unmodified lines | ||
| 163 | 163 | |
| 164 | 164 | static u16 read_eeprom(unsigned int ioaddr, int index); |
| 165 | 165 | static void tc589_reset(struct net_device *dev); |
| 166 | −static void media_check(unsigned long arg); | |
| 166 | +static void media_check(struct timer_list *t); | |
| 167 | 167 | static int el3_config(struct net_device *dev, struct ifmap *map); |
| 168 | 168 | static int el3_open(struct net_device *dev); |
| 169 | 169 | static netdev_tx_t el3_start_xmit(struct sk_buff *skb, |
| @@ -517,7 +517,7 @@ static int el3_open(struct net_device *dev) · 347 unmodified lines | ||
| 517 | 517 | netif_start_queue(dev); |
| 518 | 518 | |
| 519 | 519 | tc589_reset(dev); |
| 520 | − setup_timer(&lp->media, media_check, (unsigned long)dev); | |
| 520 | + timer_setup(&lp->media, media_check, 0); | |
| 521 | 521 | mod_timer(&lp->media, jiffies + HZ); |
| 522 | 522 | |
| 523 | 523 | dev_dbg(&link->dev, "%s: opened, status %4.4x.\n", |
| @@ -676,10 +676,10 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) · 152 unmodified lines | ||
| 676 | 676 | return IRQ_RETVAL(handled); |
| 677 | 677 | } |
| 678 | 678 | |
| 679 | −static void media_check(unsigned long arg) | |
| 679 | +static void media_check(struct timer_list *t) | |
| 680 | 680 | { |
| 681 | − struct net_device *dev = (struct net_device *)(arg); | |
| 682 | − struct el3_private *lp = netdev_priv(dev); | |
| 681 | + struct el3_private *lp = from_timer(lp, t, media); | |
| 682 | + struct net_device *dev = lp->p_dev->priv; | |
| 683 | 683 | unsigned int ioaddr = dev->base_addr; |
| 684 | 684 | u16 media, errs; |
| 685 | 685 | unsigned long flags; |
| @@ -759,8 +759,8 @@ static int vortex_open(struct net_device *dev); · 758 unmodified lines | ||
| 759 | 759 | static void mdio_sync(struct vortex_private *vp, int bits); |
| 760 | 760 | static int mdio_read(struct net_device *dev, int phy_id, int location); |
| 761 | 761 | static void mdio_write(struct net_device *vp, int phy_id, int location, int value); |
| 762 | −static void vortex_timer(unsigned long arg); | |
| 763 | −static void rx_oom_timer(unsigned long arg); | |
| 762 | +static void vortex_timer(struct timer_list *t); | |
| 763 | +static void rx_oom_timer(struct timer_list *t); | |
| 764 | 764 | static netdev_tx_t vortex_start_xmit(struct sk_buff *skb, |
| 765 | 765 | struct net_device *dev); |
| 766 | 766 | static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb, |
| @@ -1599,9 +1599,9 @@ vortex_up(struct net_device *dev) · 832 unmodified lines | ||
| 1599 | 1599 | dev->name, media_tbl[dev->if_port].name); |
| 1600 | 1600 | } |
| 1601 | 1601 | |
| 1602 | − setup_timer(&vp->timer, vortex_timer, (unsigned long)dev); | |
| 1602 | + timer_setup(&vp->timer, vortex_timer, 0); | |
| 1603 | 1603 | mod_timer(&vp->timer, RUN_AT(media_tbl[dev->if_port].wait)); |
| 1604 | − setup_timer(&vp->rx_oom_timer, rx_oom_timer, (unsigned long)dev); | |
| 1604 | + timer_setup(&vp->rx_oom_timer, rx_oom_timer, 0); | |
| 1605 | 1605 | |
| 1606 | 1606 | if (vortex_debug > 1) |
| 1607 | 1607 | pr_debug("%s: Initial media type %s.\n", |
| @@ -1784,10 +1784,10 @@ out: · 176 unmodified lines | ||
| 1784 | 1784 | } |
| 1785 | 1785 | |
| 1786 | 1786 | static void |
| 1787 | −vortex_timer(unsigned long data) | |
| 1787 | +vortex_timer(struct timer_list *t) | |
| 1788 | 1788 | { |
| 1789 | − struct net_device *dev = (struct net_device *)data; | |
| 1790 | − struct vortex_private *vp = netdev_priv(dev); | |
| 1789 | + struct vortex_private *vp = from_timer(vp, t, timer); | |
| 1790 | + struct net_device *dev = vp->mii.dev; | |
| 1791 | 1791 | void __iomem *ioaddr = vp->ioaddr; |
| 1792 | 1792 | int next_tick = 60*HZ; |
| 1793 | 1793 | int ok = 0; |
| @@ -2687,10 +2687,10 @@ boomerang_rx(struct net_device *dev) · 893 unmodified lines | ||
| 2687 | 2687 | * for some memory. Otherwise there is no way to restart the rx process. |
| 2688 | 2688 | */ |
| 2689 | 2689 | static void |
| 2690 | −rx_oom_timer(unsigned long arg) | |
| 2690 | +rx_oom_timer(struct timer_list *t) | |
| 2691 | 2691 | { |
| 2692 | − struct net_device *dev = (struct net_device *)arg; | |
| 2693 | − struct vortex_private *vp = netdev_priv(dev); | |
| 2692 | + struct vortex_private *vp = from_timer(vp, t, rx_oom_timer); | |
| 2693 | + struct net_device *dev = vp->mii.dev; | |
| 2694 | 2694 | |
| 2695 | 2695 | spin_lock_irq(&vp->lock); |
| 2696 | 2696 | if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */ |
| @@ -85,7 +85,7 @@ static struct net_device_stats *get_stats(struct net_device *dev); · 84 unmodified lines | ||
| 85 | 85 | static void set_multicast_list(struct net_device *dev); |
| 86 | 86 | static void axnet_tx_timeout(struct net_device *dev); |
| 87 | 87 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); |
| 88 | −static void ei_watchdog(u_long arg); | |
| 88 | +static void ei_watchdog(struct timer_list *t); | |
| 89 | 89 | static void axnet_reset_8390(struct net_device *dev); |
| 90 | 90 | |
| 91 | 91 | static int mdio_read(unsigned int addr, int phy_id, int loc); |
| @@ -483,7 +483,7 @@ static int axnet_open(struct net_device *dev) · 391 unmodified lines | ||
| 483 | 483 | link->open++; |
| 484 | 484 | |
| 485 | 485 | info->link_status = 0x00; |
| 486 | − setup_timer(&info->watchdog, ei_watchdog, (u_long)dev); | |
| 486 | + timer_setup(&info->watchdog, ei_watchdog, 0); | |
| 487 | 487 | mod_timer(&info->watchdog, jiffies + HZ); |
| 488 | 488 | |
| 489 | 489 | return ax_open(dev); |
| @@ -547,10 +547,10 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) · 57 unmodified lines | ||
| 547 | 547 | return ax_interrupt(irq, dev_id); |
| 548 | 548 | } |
| 549 | 549 | |
| 550 | −static void ei_watchdog(u_long arg) | |
| 550 | +static void ei_watchdog(struct timer_list *t) | |
| 551 | 551 | { |
| 552 | − struct net_device *dev = (struct net_device *)(arg); | |
| 553 | − struct axnet_dev *info = PRIV(dev); | |
| 552 | + struct axnet_dev *info = from_timer(info, t, watchdog); | |
| 553 | + struct net_device *dev = info->p_dev->priv; | |
| 554 | 554 | unsigned int nic_base = dev->base_addr; |
| 555 | 555 | unsigned int mii_addr = nic_base + AXNET_MII_EEP; |
| 556 | 556 | u_short link; |
| @@ -99,7 +99,7 @@ static int pcnet_open(struct net_device *dev); · 98 unmodified lines | ||
| 99 | 99 | static int pcnet_close(struct net_device *dev); |
| 100 | 100 | static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
| 101 | 101 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); |
| 102 | −static void ei_watchdog(u_long arg); | |
| 102 | +static void ei_watchdog(struct timer_list *t); | |
| 103 | 103 | static void pcnet_reset_8390(struct net_device *dev); |
| 104 | 104 | static int set_config(struct net_device *dev, struct ifmap *map); |
| 105 | 105 | static int setup_shmem_window(struct pcmcia_device *link, int start_pg, |
| @@ -917,7 +917,7 @@ static int pcnet_open(struct net_device *dev) · 811 unmodified lines | ||
| 917 | 917 | |
| 918 | 918 | info->phy_id = info->eth_phy; |
| 919 | 919 | info->link_status = 0x00; |
| 920 | − setup_timer(&info->watchdog, ei_watchdog, (u_long)dev); | |
| 920 | + timer_setup(&info->watchdog, ei_watchdog, 0); | |
| 921 | 921 | mod_timer(&info->watchdog, jiffies + HZ); |
| 922 | 922 | |
| 923 | 923 | return ei_open(dev); |
| @@ -1006,10 +1006,10 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) · 82 unmodified lines | ||
| 1006 | 1006 | return ret; |
| 1007 | 1007 | } |
| 1008 | 1008 | |
| 1009 | −static void ei_watchdog(u_long arg) | |
| 1009 | +static void ei_watchdog(struct timer_list *t) | |
| 1010 | 1010 | { |
| 1011 | − struct net_device *dev = (struct net_device *)arg; | |
| 1012 | − struct pcnet_dev *info = PRIV(dev); | |
| 1011 | + struct pcnet_dev *info = from_timer(info, t, watchdog); | |
| 1012 | + struct net_device *dev = info->p_dev->priv; | |
| 1013 | 1013 | unsigned int nic_base = dev->base_addr; |
| 1014 | 1014 | unsigned int mii_addr = nic_base + DLINK_GPIO; |
| 1015 | 1015 | u_short link; |
| @@ -1107,6 +1107,7 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) · 91 unmodified lines | ||
| 1107 | 1107 | switch (cmd) { |
| 1108 | 1108 | case SIOCGMIIPHY: |
| 1109 | 1109 | data->phy_id = info->phy_id; |
| 1110 | + /* fall through */ | |
| 1110 | 1111 | case SIOCGMIIREG: /* Read MII PHY register. */ |
| 1111 | 1112 | data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); |
| 1112 | 1113 | return 0; |
| @@ -1650,9 +1650,8 @@ static int bfin_mac_probe(struct platform_device *pdev) · 1649 unmodified lines | ||
| 1650 | 1650 | ndev->netdev_ops = &bfin_mac_netdev_ops; |
| 1651 | 1651 | ndev->ethtool_ops = &bfin_mac_ethtool_ops; |
| 1652 | 1652 | |
| 1653 | − init_timer(&lp->tx_reclaim_timer); | |
| 1654 | − lp->tx_reclaim_timer.data = (unsigned long)lp; | |
| 1655 | − lp->tx_reclaim_timer.function = tx_reclaim_skb_timeout; | |
| 1653 | + setup_timer(&lp->tx_reclaim_timer, tx_reclaim_skb_timeout, | |
| 1654 | + (unsigned long)lp); | |
| 1656 | 1655 | |
| 1657 | 1656 | lp->flags = 0; |
| 1658 | 1657 | netif_napi_add(ndev, &lp->napi, bfin_mac_poll, CONFIG_BFIN_RX_DESC_NUM); |
| @@ -3624,11 +3624,10 @@ static int et131x_open(struct net_device *netdev) · 3623 unmodified lines | ||
| 3624 | 3624 | int result; |
| 3625 | 3625 | |
| 3626 | 3626 | /* Start the timer to track NIC errors */ |
| 3627 | − init_timer(&adapter->error_timer); | |
| 3627 | + setup_timer(&adapter->error_timer, et131x_error_timer_handler, | |
| 3628 | + (unsigned long)adapter); | |
| 3628 | 3629 | adapter->error_timer.expires = jiffies + |
| 3629 | 3630 | msecs_to_jiffies(TX_ERROR_PERIOD); |
| 3630 | − adapter->error_timer.function = et131x_error_timer_handler; | |
| 3631 | − adapter->error_timer.data = (unsigned long)adapter; | |
| 3632 | 3631 | add_timer(&adapter->error_timer); |
| 3633 | 3632 | |
| 3634 | 3633 | result = request_irq(irq, et131x_isr, |
| @@ -355,10 +355,10 @@ static void slic_xmit_complete(struct slic_device *sdev) · 354 unmodified lines | ||
| 355 | 355 | { |
| 356 | 356 | struct slic_tx_queue *txq = &sdev->txq; |
| 357 | 357 | struct net_device *dev = sdev->netdev; |
| 358 | − unsigned int idx = txq->done_idx; | |
| 359 | 358 | struct slic_tx_buffer *buff; |
| 360 | 359 | unsigned int frames = 0; |
| 361 | 360 | unsigned int bytes = 0; |
| 361 | + unsigned int idx; | |
| 362 | 362 | |
| 363 | 363 | /* Limit processing to SLIC_MAX_TX_COMPLETIONS frames to avoid that new |
| 364 | 364 | * completions during processing keeps the loop running endlessly. |
| @@ -627,6 +627,12 @@ enum ena_admin_flow_hash_proto { · 626 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | ENA_ADMIN_RSS_NOT_IP = 7, |
| 629 | 629 | |
| 630 | + /* TCPv6 with extension header */ | |
| 631 | + ENA_ADMIN_RSS_TCP6_EX = 8, | |
| 632 | + | |
| 633 | + /* IPv6 with extension header */ | |
| 634 | + ENA_ADMIN_RSS_IP6_EX = 9, | |
| 635 | + | |
| 630 | 636 | ENA_ADMIN_RSS_PROTO_NUM = 16, |
| 631 | 637 | }; |
| 632 | 638 | |
| @@ -63,6 +63,8 @@ · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | #define ENA_REGS_ADMIN_INTR_MASK 1 |
| 65 | 65 | |
| 66 | +#define ENA_POLL_MS 5 | |
| 67 | + | |
| 66 | 68 | /*****************************************************************************/ |
| 67 | 69 | /*****************************************************************************/ |
| 68 | 70 | /*****************************************************************************/ |
| @@ -315,7 +317,7 @@ static struct ena_comp_ctx *ena_com_submit_admin_cmd(struct ena_com_admin_queue · 246 unmodified lines | ||
| 315 | 317 | cmd_size_in_bytes, |
| 316 | 318 | comp, |
| 317 | 319 | comp_size_in_bytes); |
| 318 | − if (unlikely(IS_ERR(comp_ctx))) | |
| 320 | + if (IS_ERR(comp_ctx)) | |
| 319 | 321 | admin_queue->running_state = false; |
| 320 | 322 | spin_unlock_irqrestore(&admin_queue->q_lock, flags); |
| 321 | 323 | |
| @@ -533,7 +535,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c · 211 unmodified lines | ||
| 533 | 535 | goto err; |
| 534 | 536 | } |
| 535 | 537 | |
| 536 | − msleep(100); | |
| 538 | + msleep(ENA_POLL_MS); | |
| 537 | 539 | } |
| 538 | 540 | |
| 539 | 541 | if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) { |
| @@ -746,6 +748,9 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, · 206 unmodified lines | ||
| 746 | 748 | { |
| 747 | 749 | u32 val, i; |
| 748 | 750 | |
| 751 | + /* Convert timeout from resolution of 100ms to ENA_POLL_MS */ | |
| 752 | + timeout = (timeout * 100) / ENA_POLL_MS; | |
| 753 | + | |
| 749 | 754 | for (i = 0; i < timeout; i++) { |
| 750 | 755 | val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF); |
| 751 | 756 | |
| @@ -758,8 +763,7 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, · 6 unmodified lines | ||
| 758 | 763 | exp_state) |
| 759 | 764 | return 0; |
| 760 | 765 | |
| 761 | − /* The resolution of the timeout is 100ms */ | |
| 762 | − msleep(100); | |
| 766 | + msleep(ENA_POLL_MS); | |
| 763 | 767 | } |
| 764 | 768 | |
| 765 | 769 | return -ETIME; |
| @@ -1130,7 +1134,7 @@ int ena_com_execute_admin_command(struct ena_com_admin_queue *admin_queue, · 364 unmodified lines | ||
| 1130 | 1134 | |
| 1131 | 1135 | comp_ctx = ena_com_submit_admin_cmd(admin_queue, cmd, cmd_size, |
| 1132 | 1136 | comp, comp_size); |
| 1133 | − if (unlikely(IS_ERR(comp_ctx))) { | |
| 1137 | + if (IS_ERR(comp_ctx)) { | |
| 1134 | 1138 | if (comp_ctx == ERR_PTR(-ENODEV)) |
| 1135 | 1139 | pr_debug("Failed to submit command [%ld]\n", |
| 1136 | 1140 | PTR_ERR(comp_ctx)); |
| @@ -1253,7 +1257,7 @@ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev) · 116 unmodified lines | ||
| 1253 | 1257 | spin_lock_irqsave(&admin_queue->q_lock, flags); |
| 1254 | 1258 | while (atomic_read(&admin_queue->outstanding_cmds) != 0) { |
| 1255 | 1259 | spin_unlock_irqrestore(&admin_queue->q_lock, flags); |
| 1256 | − msleep(20); | |
| 1260 | + msleep(ENA_POLL_MS); | |
| 1257 | 1261 | spin_lock_irqsave(&admin_queue->q_lock, flags); |
| 1258 | 1262 | } |
| 1259 | 1263 | spin_unlock_irqrestore(&admin_queue->q_lock, flags); |
| @@ -60,8 +60,8 @@ struct ena_stats { · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | static const struct ena_stats ena_stats_global_strings[] = { |
| 62 | 62 | ENA_STAT_GLOBAL_ENTRY(tx_timeout), |
| 63 | − ENA_STAT_GLOBAL_ENTRY(io_suspend), | |
| 64 | − ENA_STAT_GLOBAL_ENTRY(io_resume), | |
| 63 | + ENA_STAT_GLOBAL_ENTRY(suspend), | |
| 64 | + ENA_STAT_GLOBAL_ENTRY(resume), | |
| 65 | 65 | ENA_STAT_GLOBAL_ENTRY(wd_expired), |
| 66 | 66 | ENA_STAT_GLOBAL_ENTRY(interface_up), |
| 67 | 67 | ENA_STAT_GLOBAL_ENTRY(interface_down), |
| @@ -81,6 +81,7 @@ static const struct ena_stats ena_stats_tx_strings[] = { · 13 unmodified lines | ||
| 81 | 81 | ENA_STAT_TX_ENTRY(doorbells), |
| 82 | 82 | ENA_STAT_TX_ENTRY(prepare_ctx_err), |
| 83 | 83 | ENA_STAT_TX_ENTRY(bad_req_id), |
| 84 | + ENA_STAT_TX_ENTRY(missed_tx), | |
| 84 | 85 | }; |
| 85 | 86 | |
| 86 | 87 | static const struct ena_stats ena_stats_rx_strings[] = { |
| @@ -2361,38 +2361,6 @@ static const struct net_device_ops ena_netdev_ops = { · 2360 unmodified lines | ||
| 2361 | 2361 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
| 2362 | 2362 | }; |
| 2363 | 2363 | |
| 2364 | −static void ena_device_io_suspend(struct work_struct *work) | |
| 2365 | −{ | |
| 2366 | − struct ena_adapter *adapter = | |
| 2367 | − container_of(work, struct ena_adapter, suspend_io_task); | |
| 2368 | − struct net_device *netdev = adapter->netdev; | |
| 2369 | − | |
| 2370 | − /* ena_napi_disable_all disables only the IO handling. | |
| 2371 | − * We are still subject to AENQ keep alive watchdog. | |
| 2372 | − */ | |
| 2373 | − u64_stats_update_begin(&adapter->syncp); | |
| 2374 | − adapter->dev_stats.io_suspend++; | |
| 2375 | − u64_stats_update_begin(&adapter->syncp); | |
| 2376 | − ena_napi_disable_all(adapter); | |
| 2377 | − netif_tx_lock(netdev); | |
| 2378 | − netif_device_detach(netdev); | |
| 2379 | − netif_tx_unlock(netdev); | |
| 2380 | −} | |
| 2381 | − | |
| 2382 | −static void ena_device_io_resume(struct work_struct *work) | |
| 2383 | −{ | |
| 2384 | − struct ena_adapter *adapter = | |
| 2385 | − container_of(work, struct ena_adapter, resume_io_task); | |
| 2386 | − struct net_device *netdev = adapter->netdev; | |
| 2387 | − | |
| 2388 | − u64_stats_update_begin(&adapter->syncp); | |
| 2389 | − adapter->dev_stats.io_resume++; | |
| 2390 | − u64_stats_update_end(&adapter->syncp); | |
| 2391 | − | |
| 2392 | − netif_device_attach(netdev); | |
| 2393 | − ena_napi_enable_all(adapter); | |
| 2394 | −} | |
| 2395 | − | |
| 2396 | 2364 | static int ena_device_validate_params(struct ena_adapter *adapter, |
| 2397 | 2365 | struct ena_com_dev_get_features_ctx *get_feat_ctx) |
| 2398 | 2366 | { |
| @@ -2561,38 +2529,31 @@ err_disable_msix: · 162 unmodified lines | ||
| 2561 | 2529 | return rc; |
| 2562 | 2530 | } |
| 2563 | 2531 | |
| 2564 | −static void ena_fw_reset_device(struct work_struct *work) | |
| 2532 | +static void ena_destroy_device(struct ena_adapter *adapter) | |
| 2565 | 2533 | { |
| 2566 | − struct ena_com_dev_get_features_ctx get_feat_ctx; | |
| 2567 | − struct ena_adapter *adapter = | |
| 2568 | − container_of(work, struct ena_adapter, reset_task); | |
| 2569 | 2534 | struct net_device *netdev = adapter->netdev; |
| 2570 | 2535 | struct ena_com_dev *ena_dev = adapter->ena_dev; |
| 2571 | − struct pci_dev *pdev = adapter->pdev; | |
| 2572 | − bool dev_up, wd_state; | |
| 2573 | − int rc; | |
| 2574 | − | |
| 2575 | − if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { | |
| 2576 | − dev_err(&pdev->dev, | |
| 2577 | − "device reset schedule while reset bit is off\n"); | |
| 2578 | − return; | |
| 2579 | − } | |
| 2536 | + bool dev_up; | |
| 2580 | 2537 | |
| 2581 | 2538 | netif_carrier_off(netdev); |
| 2582 | 2539 | |
| 2583 | 2540 | del_timer_sync(&adapter->timer_service); |
| 2584 | 2541 | |
| 2585 | − rtnl_lock(); | |
| 2586 | − | |
| 2587 | 2542 | dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); |
| 2543 | + adapter->dev_up_before_reset = dev_up; | |
| 2544 | + | |
| 2588 | 2545 | ena_com_set_admin_running_state(ena_dev, false); |
| 2589 | 2546 | |
| 2590 | − /* After calling ena_close the tx queues and the napi | |
| 2591 | − * are disabled so no one can interfere or touch the | |
| 2592 | − * data structures | |
| 2593 | − */ | |
| 2594 | 2547 | ena_close(netdev); |
| 2595 | 2548 | |
| 2549 | + /* Before releasing the ENA resources, a device reset is required. | |
| 2550 | + * (to prevent the device from accessing them). | |
| 2551 | + * In case the reset flag is set and the device is up, ena_close | |
| 2552 | + * already perform the reset, so it can be skipped. | |
| 2553 | + */ | |
| 2554 | + if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) | |
| 2555 | + ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); | |
| 2556 | + | |
| 2596 | 2557 | ena_free_mgmnt_irq(adapter); |
| 2597 | 2558 | |
| 2598 | 2559 | ena_disable_msix(adapter); |
| @@ -2606,9 +2567,17 @@ static void ena_fw_reset_device(struct work_struct *work) · 7 unmodified lines | ||
| 2606 | 2567 | ena_com_mmio_reg_read_request_destroy(ena_dev); |
| 2607 | 2568 | |
| 2608 | 2569 | adapter->reset_reason = ENA_REGS_RESET_NORMAL; |
| 2570 | + | |
| 2609 | 2571 | clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); |
| 2572 | +} | |
| 2610 | 2573 | |
| 2611 | − /* Finish with the destroy part. Start the init part */ | |
| 2574 | +static int ena_restore_device(struct ena_adapter *adapter) | |
| 2575 | +{ | |
| 2576 | + struct ena_com_dev_get_features_ctx get_feat_ctx; | |
| 2577 | + struct ena_com_dev *ena_dev = adapter->ena_dev; | |
| 2578 | + struct pci_dev *pdev = adapter->pdev; | |
| 2579 | + bool wd_state; | |
| 2580 | + int rc; | |
| 2612 | 2581 | |
| 2613 | 2582 | rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state); |
| 2614 | 2583 | if (rc) { |
| @@ -2630,7 +2599,7 @@ static void ena_fw_reset_device(struct work_struct *work) · 15 unmodified lines | ||
| 2630 | 2599 | goto err_device_destroy; |
| 2631 | 2600 | } |
| 2632 | 2601 | /* If the interface was up before the reset bring it up */ |
| 2633 | − if (dev_up) { | |
| 2602 | + if (adapter->dev_up_before_reset) { | |
| 2634 | 2603 | rc = ena_up(adapter); |
| 2635 | 2604 | if (rc) { |
| 2636 | 2605 | dev_err(&pdev->dev, "Failed to create I/O queues\n"); |
| @@ -2639,24 +2608,38 @@ static void ena_fw_reset_device(struct work_struct *work) · 2 unmodified lines | ||
| 2639 | 2608 | } |
| 2640 | 2609 | |
| 2641 | 2610 | mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); |
| 2642 | − | |
| 2643 | − rtnl_unlock(); | |
| 2644 | − | |
| 2645 | 2611 | dev_err(&pdev->dev, "Device reset completed successfully\n"); |
| 2646 | 2612 | |
| 2647 | − return; | |
| 2613 | + return rc; | |
| 2648 | 2614 | err_disable_msix: |
| 2649 | 2615 | ena_free_mgmnt_irq(adapter); |
| 2650 | 2616 | ena_disable_msix(adapter); |
| 2651 | 2617 | err_device_destroy: |
| 2652 | 2618 | ena_com_admin_destroy(ena_dev); |
| 2653 | 2619 | err: |
| 2654 | − rtnl_unlock(); | |
| 2655 | − | |
| 2656 | 2620 | clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); |
| 2657 | 2621 | |
| 2658 | 2622 | dev_err(&pdev->dev, |
| 2659 | 2623 | "Reset attempt failed. Can not reset the device\n"); |
| 2624 | + | |
| 2625 | + return rc; | |
| 2626 | +} | |
| 2627 | + | |
| 2628 | +static void ena_fw_reset_device(struct work_struct *work) | |
| 2629 | +{ | |
| 2630 | + struct ena_adapter *adapter = | |
| 2631 | + container_of(work, struct ena_adapter, reset_task); | |
| 2632 | + struct pci_dev *pdev = adapter->pdev; | |
| 2633 | + | |
| 2634 | + if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { | |
| 2635 | + dev_err(&pdev->dev, | |
| 2636 | + "device reset schedule while reset bit is off\n"); | |
| 2637 | + return; | |
| 2638 | + } | |
| 2639 | + rtnl_lock(); | |
| 2640 | + ena_destroy_device(adapter); | |
| 2641 | + ena_restore_device(adapter); | |
| 2642 | + rtnl_unlock(); | |
| 2660 | 2643 | } |
| 2661 | 2644 | |
| 2662 | 2645 | static int check_missing_comp_in_queue(struct ena_adapter *adapter, |
| @@ -2665,7 +2648,7 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter, · 2 unmodified lines | ||
| 2665 | 2648 | struct ena_tx_buffer *tx_buf; |
| 2666 | 2649 | unsigned long last_jiffies; |
| 2667 | 2650 | u32 missed_tx = 0; |
| 2668 | − int i; | |
| 2651 | + int i, rc = 0; | |
| 2669 | 2652 | |
| 2670 | 2653 | for (i = 0; i < tx_ring->ring_size; i++) { |
| 2671 | 2654 | tx_buf = &tx_ring->tx_buffer_info[i]; |
| @@ -2679,21 +2662,25 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter, · 7 unmodified lines | ||
| 2679 | 2662 | |
| 2680 | 2663 | tx_buf->print_once = 1; |
| 2681 | 2664 | missed_tx++; |
| 2682 | − | |
| 2683 | − if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) { | |
| 2684 | − netif_err(adapter, tx_err, adapter->netdev, | |
| 2685 | − "The number of lost tx completions is above the threshold (%d > %d). Reset the device\n", | |
| 2686 | − missed_tx, | |
| 2687 | − adapter->missing_tx_completion_threshold); | |
| 2688 | − adapter->reset_reason = | |
| 2689 | − ENA_REGS_RESET_MISS_TX_CMPL; | |
| 2690 | − set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | |
| 2691 | − return -EIO; | |
| 2692 | − } | |
| 2693 | 2665 | } |
| 2694 | 2666 | } |
| 2695 | 2667 | |
| 2696 | − return 0; | |
| 2668 | + if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) { | |
| 2669 | + netif_err(adapter, tx_err, adapter->netdev, | |
| 2670 | + "The number of lost tx completions is above the threshold (%d > %d). Reset the device\n", | |
| 2671 | + missed_tx, | |
| 2672 | + adapter->missing_tx_completion_threshold); | |
| 2673 | + adapter->reset_reason = | |
| 2674 | + ENA_REGS_RESET_MISS_TX_CMPL; | |
| 2675 | + set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | |
| 2676 | + rc = -EIO; | |
| 2677 | + } | |
| 2678 | + | |
| 2679 | + u64_stats_update_begin(&tx_ring->syncp); | |
| 2680 | + tx_ring->tx_stats.missed_tx = missed_tx; | |
| 2681 | + u64_stats_update_end(&tx_ring->syncp); | |
| 2682 | + | |
| 2683 | + return rc; | |
| 2697 | 2684 | } |
| 2698 | 2685 | |
| 2699 | 2686 | static void check_for_missing_tx_completions(struct ena_adapter *adapter) |
| @@ -3276,8 +3263,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 576 unmodified lines | ||
| 3276 | 3263 | goto err_rss; |
| 3277 | 3264 | } |
| 3278 | 3265 | |
| 3279 | − INIT_WORK(&adapter->suspend_io_task, ena_device_io_suspend); | |
| 3280 | − INIT_WORK(&adapter->resume_io_task, ena_device_io_resume); | |
| 3281 | 3266 | INIT_WORK(&adapter->reset_task, ena_fw_reset_device); |
| 3282 | 3267 | |
| 3283 | 3268 | adapter->last_keep_alive_jiffies = jiffies; |
| @@ -3311,8 +3296,6 @@ err_free_msix: · 27 unmodified lines | ||
| 3311 | 3296 | err_worker_destroy: |
| 3312 | 3297 | ena_com_destroy_interrupt_moderation(ena_dev); |
| 3313 | 3298 | del_timer(&adapter->timer_service); |
| 3314 | − cancel_work_sync(&adapter->suspend_io_task); | |
| 3315 | − cancel_work_sync(&adapter->resume_io_task); | |
| 3316 | 3299 | err_netdev_destroy: |
| 3317 | 3300 | free_netdev(netdev); |
| 3318 | 3301 | err_device_destroy: |
| @@ -3382,10 +3365,6 @@ static void ena_remove(struct pci_dev *pdev) · 63 unmodified lines | ||
| 3382 | 3365 | |
| 3383 | 3366 | cancel_work_sync(&adapter->reset_task); |
| 3384 | 3367 | |
| 3385 | − cancel_work_sync(&adapter->suspend_io_task); | |
| 3386 | − | |
| 3387 | − cancel_work_sync(&adapter->resume_io_task); | |
| 3388 | − | |
| 3389 | 3368 | /* Reset the device only if the device is running. */ |
| 3390 | 3369 | if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) |
| 3391 | 3370 | ena_com_dev_reset(ena_dev, adapter->reset_reason); |
| @@ -3419,11 +3398,59 @@ static void ena_remove(struct pci_dev *pdev) · 27 unmodified lines | ||
| 3419 | 3398 | vfree(ena_dev); |
| 3420 | 3399 | } |
| 3421 | 3400 | |
| 3401 | +#ifdef CONFIG_PM | |
| 3402 | +/* ena_suspend - PM suspend callback | |
| 3403 | + * @pdev: PCI device information struct | |
| 3404 | + * @state:power state | |
| 3405 | + */ | |
| 3406 | +static int ena_suspend(struct pci_dev *pdev, pm_message_t state) | |
| 3407 | +{ | |
| 3408 | + struct ena_adapter *adapter = pci_get_drvdata(pdev); | |
| 3409 | + | |
| 3410 | + u64_stats_update_begin(&adapter->syncp); | |
| 3411 | + adapter->dev_stats.suspend++; | |
| 3412 | + u64_stats_update_end(&adapter->syncp); | |
| 3413 | + | |
| 3414 | + rtnl_lock(); | |
| 3415 | + if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { | |
| 3416 | + dev_err(&pdev->dev, | |
| 3417 | + "ignoring device reset request as the device is being suspended\n"); | |
| 3418 | + clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | |
| 3419 | + } | |
| 3420 | + ena_destroy_device(adapter); | |
| 3421 | + rtnl_unlock(); | |
| 3422 | + return 0; | |
| 3423 | +} | |
| 3424 | + | |
| 3425 | +/* ena_resume - PM resume callback | |
| 3426 | + * @pdev: PCI device information struct | |
| 3427 | + * | |
| 3428 | + */ | |
| 3429 | +static int ena_resume(struct pci_dev *pdev) | |
| 3430 | +{ | |
| 3431 | + struct ena_adapter *adapter = pci_get_drvdata(pdev); | |
| 3432 | + int rc; | |
| 3433 | + | |
| 3434 | + u64_stats_update_begin(&adapter->syncp); | |
| 3435 | + adapter->dev_stats.resume++; | |
| 3436 | + u64_stats_update_end(&adapter->syncp); | |
| 3437 | + | |
| 3438 | + rtnl_lock(); | |
| 3439 | + rc = ena_restore_device(adapter); | |
| 3440 | + rtnl_unlock(); | |
| 3441 | + return rc; | |
| 3442 | +} | |
| 3443 | +#endif | |
| 3444 | + | |
| 3422 | 3445 | static struct pci_driver ena_pci_driver = { |
| 3423 | 3446 | .name = DRV_MODULE_NAME, |
| 3424 | 3447 | .id_table = ena_pci_tbl, |
| 3425 | 3448 | .probe = ena_probe, |
| 3426 | 3449 | .remove = ena_remove, |
| 3450 | +#ifdef CONFIG_PM | |
| 3451 | + .suspend = ena_suspend, | |
| 3452 | + .resume = ena_resume, | |
| 3453 | +#endif | |
| 3427 | 3454 | .sriov_configure = ena_sriov_configure, |
| 3428 | 3455 | }; |
| 3429 | 3456 | |
| @@ -3504,16 +3531,6 @@ static void ena_notification(void *adapter_data, · 74 unmodified lines | ||
| 3504 | 3531 | ENA_ADMIN_NOTIFICATION); |
| 3505 | 3532 | |
| 3506 | 3533 | switch (aenq_e->aenq_common_desc.syndrom) { |
| 3507 | − case ENA_ADMIN_SUSPEND: | |
| 3508 | − /* Suspend just the IO queues. | |
| 3509 | − * We deliberately don't suspend admin so the timer and | |
| 3510 | − * the keep_alive events should remain. | |
| 3511 | − */ | |
| 3512 | − queue_work(ena_wq, &adapter->suspend_io_task); | |
| 3513 | − break; | |
| 3514 | − case ENA_ADMIN_RESUME: | |
| 3515 | − queue_work(ena_wq, &adapter->resume_io_task); | |
| 3516 | − break; | |
| 3517 | 3534 | case ENA_ADMIN_UPDATE_HINTS: |
| 3518 | 3535 | hints = (struct ena_admin_ena_hw_hints *) |
| 3519 | 3536 | (&aenq_e->inline_data_w4); |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #include "ena_eth_com.h" |
| 45 | 45 | |
| 46 | 46 | #define DRV_MODULE_VER_MAJOR 1 |
| 47 | −#define DRV_MODULE_VER_MINOR 2 | |
| 47 | +#define DRV_MODULE_VER_MINOR 3 | |
| 48 | 48 | #define DRV_MODULE_VER_SUBMINOR 0 |
| 49 | 49 | |
| 50 | 50 | #define DRV_MODULE_NAME "ena" |
| @@ -52,7 +52,7 @@ · 1 unmodified line | ||
| 52 | 52 | #define DRV_MODULE_VERSION \ |
| 53 | 53 | __stringify(DRV_MODULE_VER_MAJOR) "." \ |
| 54 | 54 | __stringify(DRV_MODULE_VER_MINOR) "." \ |
| 55 | − __stringify(DRV_MODULE_VER_SUBMINOR) "k" | |
| 55 | + __stringify(DRV_MODULE_VER_SUBMINOR) "K" | |
| 56 | 56 | #endif |
| 57 | 57 | |
| 58 | 58 | #define DEVICE_NAME "Elastic Network Adapter (ENA)" |
| @@ -185,6 +185,7 @@ struct ena_stats_tx { · 126 unmodified lines | ||
| 185 | 185 | u64 tx_poll; |
| 186 | 186 | u64 doorbells; |
| 187 | 187 | u64 bad_req_id; |
| 188 | + u64 missed_tx; | |
| 188 | 189 | }; |
| 189 | 190 | |
| 190 | 191 | struct ena_stats_rx { |
| @@ -257,8 +258,8 @@ struct ena_ring { · 66 unmodified lines | ||
| 257 | 258 | |
| 258 | 259 | struct ena_stats_dev { |
| 259 | 260 | u64 tx_timeout; |
| 260 | − u64 io_suspend; | |
| 261 | − u64 io_resume; | |
| 261 | + u64 suspend; | |
| 262 | + u64 resume; | |
| 262 | 263 | u64 wd_expired; |
| 263 | 264 | u64 interface_up; |
| 264 | 265 | u64 interface_down; |
| @@ -326,11 +327,10 @@ struct ena_adapter { · 61 unmodified lines | ||
| 326 | 327 | |
| 327 | 328 | /* timer service */ |
| 328 | 329 | struct work_struct reset_task; |
| 329 | − struct work_struct suspend_io_task; | |
| 330 | − struct work_struct resume_io_task; | |
| 331 | 330 | struct timer_list timer_service; |
| 332 | 331 | |
| 333 | 332 | bool wd_state; |
| 333 | + bool dev_up_before_reset; | |
| 334 | 334 | unsigned long last_keep_alive_jiffies; |
| 335 | 335 | |
| 336 | 336 | struct u64_stats_sync syncp; |
| @@ -123,6 +123,7 @@ struct lance_private { · 122 unmodified lines | ||
| 123 | 123 | int burst_sizes; /* ledma SBus burst sizes */ |
| 124 | 124 | #endif |
| 125 | 125 | struct timer_list multicast_timer; |
| 126 | + struct net_device *dev; | |
| 126 | 127 | }; |
| 127 | 128 | |
| 128 | 129 | #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) |
| @@ -638,6 +639,13 @@ static void lance_set_multicast(struct net_device *dev) · 509 unmodified lines | ||
| 638 | 639 | netif_wake_queue(dev); |
| 639 | 640 | } |
| 640 | 641 | |
| 642 | +static void lance_set_multicast_retry(struct timer_list *t) | |
| 643 | +{ | |
| 644 | + struct lance_private *lp = from_timer(lp, t, multicast_timer); | |
| 645 | + | |
| 646 | + lance_set_multicast(lp->dev); | |
| 647 | +} | |
| 648 | + | |
| 641 | 649 | static int a2065_init_one(struct zorro_dev *z, |
| 642 | 650 | const struct zorro_device_id *ent); |
| 643 | 651 | static void a2065_remove_one(struct zorro_dev *z); |
| @@ -728,15 +736,13 @@ static int a2065_init_one(struct zorro_dev *z, · 84 unmodified lines | ||
| 728 | 736 | priv->lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; |
| 729 | 737 | priv->rx_ring_mod_mask = RX_RING_MOD_MASK; |
| 730 | 738 | priv->tx_ring_mod_mask = TX_RING_MOD_MASK; |
| 739 | + priv->dev = dev; | |
| 731 | 740 | |
| 732 | 741 | dev->netdev_ops = &lance_netdev_ops; |
| 733 | 742 | dev->watchdog_timeo = 5*HZ; |
| 734 | 743 | dev->dma = 0; |
| 735 | 744 | |
| 736 | − init_timer(&priv->multicast_timer); | |
| 737 | − priv->multicast_timer.data = (unsigned long) dev; | |
| 738 | − priv->multicast_timer.function = | |
| 739 | − (void (*)(unsigned long))lance_set_multicast; | |
| 745 | + timer_setup(&priv->multicast_timer, lance_set_multicast_retry, 0); | |
| 740 | 746 | |
| 741 | 747 | err = register_netdev(dev); |
| 742 | 748 | if (err) { |
| @@ -302,10 +302,10 @@ am79c961_init_for_open(struct net_device *dev) · 301 unmodified lines | ||
| 302 | 302 | write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT); |
| 303 | 303 | } |
| 304 | 304 | |
| 305 | −static void am79c961_timer(unsigned long data) | |
| 305 | +static void am79c961_timer(struct timer_list *t) | |
| 306 | 306 | { |
| 307 | − struct net_device *dev = (struct net_device *)data; | |
| 308 | − struct dev_priv *priv = netdev_priv(dev); | |
| 307 | + struct dev_priv *priv = from_timer(priv, t, timer); | |
| 308 | + struct net_device *dev = priv->dev; | |
| 309 | 309 | unsigned int lnkstat, carrier; |
| 310 | 310 | unsigned long flags; |
| 311 | 311 | |
| @@ -728,9 +728,8 @@ static int am79c961_probe(struct platform_device *pdev) · 416 unmodified lines | ||
| 728 | 728 | am79c961_banner(); |
| 729 | 729 | |
| 730 | 730 | spin_lock_init(&priv->chip_lock); |
| 731 | − init_timer(&priv->timer); | |
| 732 | − priv->timer.data = (unsigned long)dev; | |
| 733 | − priv->timer.function = am79c961_timer; | |
| 731 | + priv->dev = dev; | |
| 732 | + timer_setup(&priv->timer, am79c961_timer, 0); | |
| 734 | 733 | |
| 735 | 734 | if (am79c961_hw_init(dev)) |
| 736 | 735 | goto release; |
| @@ -140,6 +140,7 @@ struct dev_priv { · 139 unmodified lines | ||
| 140 | 140 | unsigned long txhdr; |
| 141 | 141 | spinlock_t chip_lock; |
| 142 | 142 | struct timer_list timer; |
| 143 | + struct net_device *dev; | |
| 143 | 144 | }; |
| 144 | 145 | |
| 145 | 146 | #endif |
| @@ -1669,9 +1669,9 @@ static int amd8111e_resume(struct pci_dev *pci_dev) · 1668 unmodified lines | ||
| 1669 | 1669 | return 0; |
| 1670 | 1670 | } |
| 1671 | 1671 | |
| 1672 | −static void amd8111e_config_ipg(struct net_device *dev) | |
| 1672 | +static void amd8111e_config_ipg(struct timer_list *t) | |
| 1673 | 1673 | { |
| 1674 | − struct amd8111e_priv *lp = netdev_priv(dev); | |
| 1674 | + struct amd8111e_priv *lp = from_timer(lp, t, ipg_data.ipg_timer); | |
| 1675 | 1675 | struct ipg_info *ipg_data = &lp->ipg_data; |
| 1676 | 1676 | void __iomem *mmio = lp->mmio; |
| 1677 | 1677 | unsigned int prev_col_cnt = ipg_data->col_cnt; |
| @@ -1883,9 +1883,7 @@ static int amd8111e_probe_one(struct pci_dev *pdev, · 205 unmodified lines | ||
| 1883 | 1883 | |
| 1884 | 1884 | /* Initialize software ipg timer */ |
| 1885 | 1885 | if(lp->options & OPTION_DYN_IPG_ENABLE){ |
| 1886 | − init_timer(&lp->ipg_data.ipg_timer); | |
| 1887 | − lp->ipg_data.ipg_timer.data = (unsigned long) dev; | |
| 1888 | − lp->ipg_data.ipg_timer.function = (void *)&amd8111e_config_ipg; | |
| 1886 | + timer_setup(&lp->ipg_data.ipg_timer, amd8111e_config_ipg, 0); | |
| 1889 | 1887 | lp->ipg_data.ipg_timer.expires = jiffies + |
| 1890 | 1888 | IPG_CONVERGE_JIFFIES; |
| 1891 | 1889 | lp->ipg_data.ipg = DEFAULT_IPG; |
| @@ -260,6 +260,7 @@ struct lance_private { · 259 unmodified lines | ||
| 260 | 260 | unsigned short busmaster_regval; |
| 261 | 261 | |
| 262 | 262 | struct timer_list multicast_timer; |
| 263 | + struct net_device *dev; | |
| 263 | 264 | |
| 264 | 265 | /* Pointers to the ring buffers as seen from the CPU */ |
| 265 | 266 | char *rx_buf_ptr_cpu[RX_RING_SIZE]; |
| @@ -1000,9 +1001,10 @@ static void lance_set_multicast(struct net_device *dev) · 734 unmodified lines | ||
| 1000 | 1001 | netif_wake_queue(dev); |
| 1001 | 1002 | } |
| 1002 | 1003 | |
| 1003 | −static void lance_set_multicast_retry(unsigned long _opaque) | |
| 1004 | +static void lance_set_multicast_retry(struct timer_list *t) | |
| 1004 | 1005 | { |
| 1005 | − struct net_device *dev = (struct net_device *) _opaque; | |
| 1006 | + struct lance_private *lp = from_timer(lp, t, multicast_timer); | |
| 1007 | + struct net_device *dev = lp->dev; | |
| 1006 | 1008 | |
| 1007 | 1009 | lance_set_multicast(dev); |
| 1008 | 1010 | } |
| @@ -1246,9 +1248,9 @@ static int dec_lance_probe(struct device *bdev, const int type) · 237 unmodified lines | ||
| 1246 | 1248 | * can occur from interrupts (ex. IPv6). So we |
| 1247 | 1249 | * use a timer to try again later when necessary. -DaveM |
| 1248 | 1250 | */ |
| 1249 | − init_timer(&lp->multicast_timer); | |
| 1250 | − lp->multicast_timer.data = (unsigned long) dev; | |
| 1251 | − lp->multicast_timer.function = lance_set_multicast_retry; | |
| 1251 | + lp->dev = dev; | |
| 1252 | + timer_setup(&lp->multicast_timer, lance_set_multicast_retry, 0); | |
| 1253 | + | |
| 1252 | 1254 | |
| 1253 | 1255 | ret = register_netdev(dev); |
| 1254 | 1256 | if (ret) { |
| @@ -321,7 +321,7 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *); · 320 unmodified lines | ||
| 321 | 321 | static void pcnet32_load_multicast(struct net_device *dev); |
| 322 | 322 | static void pcnet32_set_multicast_list(struct net_device *); |
| 323 | 323 | static int pcnet32_ioctl(struct net_device *, struct ifreq *, int); |
| 324 | −static void pcnet32_watchdog(struct net_device *); | |
| 324 | +static void pcnet32_watchdog(struct timer_list *); | |
| 325 | 325 | static int mdio_read(struct net_device *dev, int phy_id, int reg_num); |
| 326 | 326 | static void mdio_write(struct net_device *dev, int phy_id, int reg_num, |
| 327 | 327 | int val); |
| @@ -1970,9 +1970,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) · 1642 unmodified lines | ||
| 1970 | 1970 | lp->options |= PCNET32_PORT_MII; |
| 1971 | 1971 | } |
| 1972 | 1972 | |
| 1973 | − init_timer(&lp->watchdog_timer); | |
| 1974 | − lp->watchdog_timer.data = (unsigned long)dev; | |
| 1975 | − lp->watchdog_timer.function = (void *)&pcnet32_watchdog; | |
| 1973 | + timer_setup(&lp->watchdog_timer, pcnet32_watchdog, 0); | |
| 1976 | 1974 | |
| 1977 | 1975 | /* The PCNET32-specific entries in the device structure. */ |
| 1978 | 1976 | dev->netdev_ops = &pcnet32_netdev_ops; |
| @@ -2902,9 +2900,10 @@ static void pcnet32_check_media(struct net_device *dev, int verbose) · 923 unmodified lines | ||
| 2902 | 2900 | * Could possibly be changed to use mii_check_media instead. |
| 2903 | 2901 | */ |
| 2904 | 2902 | |
| 2905 | −static void pcnet32_watchdog(struct net_device *dev) | |
| 2903 | +static void pcnet32_watchdog(struct timer_list *t) | |
| 2906 | 2904 | { |
| 2907 | − struct pcnet32_private *lp = netdev_priv(dev); | |
| 2905 | + struct pcnet32_private *lp = from_timer(lp, t, watchdog_timer); | |
| 2906 | + struct net_device *dev = lp->dev; | |
| 2908 | 2907 | unsigned long flags; |
| 2909 | 2908 | |
| 2910 | 2909 | /* Print the link status if it has changed */ |
| @@ -1248,9 +1248,10 @@ static void lance_set_multicast(struct net_device *dev) · 1247 unmodified lines | ||
| 1248 | 1248 | netif_wake_queue(dev); |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | −static void lance_set_multicast_retry(unsigned long _opaque) | |
| 1251 | +static void lance_set_multicast_retry(struct timer_list *t) | |
| 1252 | 1252 | { |
| 1253 | − struct net_device *dev = (struct net_device *) _opaque; | |
| 1253 | + struct lance_private *lp = from_timer(lp, t, multicast_timer); | |
| 1254 | + struct net_device *dev = lp->dev; | |
| 1254 | 1255 | |
| 1255 | 1256 | lance_set_multicast(dev); |
| 1256 | 1257 | } |
| @@ -1459,9 +1460,7 @@ no_link_test: · 202 unmodified lines | ||
| 1459 | 1460 | * can occur from interrupts (ex. IPv6). So we |
| 1460 | 1461 | * use a timer to try again later when necessary. -DaveM |
| 1461 | 1462 | */ |
| 1462 | − init_timer(&lp->multicast_timer); | |
| 1463 | − lp->multicast_timer.data = (unsigned long) dev; | |
| 1464 | − lp->multicast_timer.function = lance_set_multicast_retry; | |
| 1463 | + timer_setup(&lp->multicast_timer, lance_set_multicast_retry, 0); | |
| 1465 | 1464 | |
| 1466 | 1465 | if (register_netdev(dev)) { |
| 1467 | 1466 | printk(KERN_ERR "SunLance: Cannot register device.\n"); |
| @@ -642,9 +642,9 @@ static irqreturn_t xgbe_dma_isr(int irq, void *data) · 641 unmodified lines | ||
| 642 | 642 | return IRQ_HANDLED; |
| 643 | 643 | } |
| 644 | 644 | |
| 645 | −static void xgbe_tx_timer(unsigned long data) | |
| 645 | +static void xgbe_tx_timer(struct timer_list *t) | |
| 646 | 646 | { |
| 647 | − struct xgbe_channel *channel = (struct xgbe_channel *)data; | |
| 647 | + struct xgbe_channel *channel = from_timer(channel, t, tx_timer); | |
| 648 | 648 | struct xgbe_prv_data *pdata = channel->pdata; |
| 649 | 649 | struct napi_struct *napi; |
| 650 | 650 | |
| @@ -680,9 +680,9 @@ static void xgbe_service(struct work_struct *work) · 29 unmodified lines | ||
| 680 | 680 | pdata->phy_if.phy_status(pdata); |
| 681 | 681 | } |
| 682 | 682 | |
| 683 | −static void xgbe_service_timer(unsigned long data) | |
| 683 | +static void xgbe_service_timer(struct timer_list *t) | |
| 684 | 684 | { |
| 685 | − struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; | |
| 685 | + struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer); | |
| 686 | 686 | |
| 687 | 687 | queue_work(pdata->dev_workqueue, &pdata->service_work); |
| 688 | 688 | |
| @@ -694,16 +694,14 @@ static void xgbe_init_timers(struct xgbe_prv_data *pdata) · 5 unmodified lines | ||
| 694 | 694 | struct xgbe_channel *channel; |
| 695 | 695 | unsigned int i; |
| 696 | 696 | |
| 697 | − setup_timer(&pdata->service_timer, xgbe_service_timer, | |
| 698 | − (unsigned long)pdata); | |
| 697 | + timer_setup(&pdata->service_timer, xgbe_service_timer, 0); | |
| 699 | 698 | |
| 700 | 699 | for (i = 0; i < pdata->channel_count; i++) { |
| 701 | 700 | channel = pdata->channel[i]; |
| 702 | 701 | if (!channel->tx_ring) |
| 703 | 702 | break; |
| 704 | 703 | |
| 705 | − setup_timer(&channel->tx_timer, xgbe_tx_timer, | |
| 706 | − (unsigned long)channel); | |
| 704 | + timer_setup(&channel->tx_timer, xgbe_tx_timer, 0); | |
| 707 | 705 | } |
| 708 | 706 | } |
| 709 | 707 | |
| @@ -2208,7 +2206,7 @@ static int xgbe_setup_tc(struct net_device *netdev, enum tc_setup_type type, · 1498 unmodified lines | ||
| 2208 | 2206 | struct tc_mqprio_qopt *mqprio = type_data; |
| 2209 | 2207 | u8 tc; |
| 2210 | 2208 | |
| 2211 | − if (type != TC_SETUP_MQPRIO) | |
| 2209 | + if (type != TC_SETUP_QDISC_MQPRIO) | |
| 2212 | 2210 | return -EOPNOTSUPP; |
| 2213 | 2211 | |
| 2214 | 2212 | mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; |
| @@ -157,7 +157,7 @@ static irqreturn_t bmac_misc_intr(int irq, void *dev_id); · 156 unmodified lines | ||
| 157 | 157 | static irqreturn_t bmac_txdma_intr(int irq, void *dev_id); |
| 158 | 158 | static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id); |
| 159 | 159 | static void bmac_set_timeout(struct net_device *dev); |
| 160 | −static void bmac_tx_timeout(unsigned long data); | |
| 160 | +static void bmac_tx_timeout(struct timer_list *t); | |
| 161 | 161 | static int bmac_output(struct sk_buff *skb, struct net_device *dev); |
| 162 | 162 | static void bmac_start(struct net_device *dev); |
| 163 | 163 | |
| @@ -555,8 +555,6 @@ static inline void bmac_set_timeout(struct net_device *dev) · 391 unmodified lines | ||
| 555 | 555 | if (bp->timeout_active) |
| 556 | 556 | del_timer(&bp->tx_timeout); |
| 557 | 557 | bp->tx_timeout.expires = jiffies + TX_TIMEOUT; |
| 558 | − bp->tx_timeout.function = bmac_tx_timeout; | |
| 559 | − bp->tx_timeout.data = (unsigned long) dev; | |
| 560 | 558 | add_timer(&bp->tx_timeout); |
| 561 | 559 | bp->timeout_active = 1; |
| 562 | 560 | spin_unlock_irqrestore(&bp->lock, flags); |
| @@ -1321,7 +1319,7 @@ static int bmac_probe(struct macio_dev *mdev, const struct of_device_id *match) · 758 unmodified lines | ||
| 1321 | 1319 | bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1); |
| 1322 | 1320 | skb_queue_head_init(bp->queue); |
| 1323 | 1321 | |
| 1324 | − init_timer(&bp->tx_timeout); | |
| 1322 | + timer_setup(&bp->tx_timeout, bmac_tx_timeout, 0); | |
| 1325 | 1323 | |
| 1326 | 1324 | ret = request_irq(dev->irq, bmac_misc_intr, 0, "BMAC-misc", dev); |
| 1327 | 1325 | if (ret) { |
| @@ -1471,10 +1469,10 @@ bmac_output(struct sk_buff *skb, struct net_device *dev) · 143 unmodified lines | ||
| 1471 | 1469 | return NETDEV_TX_OK; |
| 1472 | 1470 | } |
| 1473 | 1471 | |
| 1474 | −static void bmac_tx_timeout(unsigned long data) | |
| 1472 | +static void bmac_tx_timeout(struct timer_list *t) | |
| 1475 | 1473 | { |
| 1476 | − struct net_device *dev = (struct net_device *) data; | |
| 1477 | − struct bmac_data *bp = netdev_priv(dev); | |
| 1474 | + struct bmac_data *bp = from_timer(bp, t, tx_timeout); | |
| 1475 | + struct net_device *dev = macio_get_drvdata(bp->mdev); | |
| 1478 | 1476 | volatile struct dbdma_regs __iomem *td = bp->tx_dma; |
| 1479 | 1477 | volatile struct dbdma_regs __iomem *rd = bp->rx_dma; |
| 1480 | 1478 | volatile struct dbdma_cmd *cp; |
| @@ -86,7 +86,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id); · 85 unmodified lines | ||
| 86 | 86 | static irqreturn_t mace_txdma_intr(int irq, void *dev_id); |
| 87 | 87 | static irqreturn_t mace_rxdma_intr(int irq, void *dev_id); |
| 88 | 88 | static void mace_set_timeout(struct net_device *dev); |
| 89 | −static void mace_tx_timeout(unsigned long data); | |
| 89 | +static void mace_tx_timeout(struct timer_list *t); | |
| 90 | 90 | static inline void dbdma_reset(volatile struct dbdma_regs __iomem *dma); |
| 91 | 91 | static inline void mace_clean_rings(struct mace_data *mp); |
| 92 | 92 | static void __mace_set_address(struct net_device *dev, void *addr); |
| @@ -196,7 +196,7 @@ static int mace_probe(struct macio_dev *mdev, const struct of_device_id *match) · 103 unmodified lines | ||
| 196 | 196 | |
| 197 | 197 | memset((char *) mp->tx_cmds, 0, |
| 198 | 198 | (NCMDS_TX*N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd)); |
| 199 | − init_timer(&mp->tx_timeout); | |
| 199 | + timer_setup(&mp->tx_timeout, mace_tx_timeout, 0); | |
| 200 | 200 | spin_lock_init(&mp->lock); |
| 201 | 201 | mp->timeout_active = 0; |
| 202 | 202 | |
| @@ -521,8 +521,6 @@ static inline void mace_set_timeout(struct net_device *dev) · 318 unmodified lines | ||
| 521 | 521 | if (mp->timeout_active) |
| 522 | 522 | del_timer(&mp->tx_timeout); |
| 523 | 523 | mp->tx_timeout.expires = jiffies + TX_TIMEOUT; |
| 524 | − mp->tx_timeout.function = mace_tx_timeout; | |
| 525 | − mp->tx_timeout.data = (unsigned long) dev; | |
| 526 | 524 | add_timer(&mp->tx_timeout); |
| 527 | 525 | mp->timeout_active = 1; |
| 528 | 526 | } |
| @@ -801,10 +799,10 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) · 272 unmodified lines | ||
| 801 | 799 | return IRQ_HANDLED; |
| 802 | 800 | } |
| 803 | 801 | |
| 804 | −static void mace_tx_timeout(unsigned long data) | |
| 802 | +static void mace_tx_timeout(struct timer_list *t) | |
| 805 | 803 | { |
| 806 | − struct net_device *dev = (struct net_device *) data; | |
| 807 | − struct mace_data *mp = netdev_priv(dev); | |
| 804 | + struct mace_data *mp = from_timer(mp, t, tx_timeout); | |
| 805 | + struct net_device *dev = macio_get_drvdata(mp->mdev); | |
| 808 | 806 | volatile struct mace __iomem *mb = mp->mace; |
| 809 | 807 | volatile struct dbdma_regs __iomem *td = mp->tx_dma; |
| 810 | 808 | volatile struct dbdma_regs __iomem *rd = mp->rx_dma; |
| @@ -221,8 +221,8 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev, · 220 unmodified lines | ||
| 221 | 221 | return err; |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | −int aq_ethtool_get_coalesce(struct net_device *ndev, | |
| 225 | − struct ethtool_coalesce *coal) | |
| 224 | +static int aq_ethtool_get_coalesce(struct net_device *ndev, | |
| 225 | + struct ethtool_coalesce *coal) | |
| 226 | 226 | { |
| 227 | 227 | struct aq_nic_s *aq_nic = netdev_priv(ndev); |
| 228 | 228 | struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); |
| @@ -242,8 +242,8 @@ int aq_ethtool_get_coalesce(struct net_device *ndev, · 13 unmodified lines | ||
| 242 | 242 | return 0; |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | −int aq_ethtool_set_coalesce(struct net_device *ndev, | |
| 246 | − struct ethtool_coalesce *coal) | |
| 245 | +static int aq_ethtool_set_coalesce(struct net_device *ndev, | |
| 246 | + struct ethtool_coalesce *coal) | |
| 247 | 247 | { |
| 248 | 248 | struct aq_nic_s *aq_nic = netdev_priv(ndev); |
| 249 | 249 | struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); |
| @@ -184,6 +184,7 @@ config BGMAC_PLATFORM · 183 unmodified lines | ||
| 184 | 184 | config SYSTEMPORT |
| 185 | 185 | tristate "Broadcom SYSTEMPORT internal MAC support" |
| 186 | 186 | depends on OF |
| 187 | + depends on NET_DSA || !NET_DSA | |
| 187 | 188 | select MII |
| 188 | 189 | select PHYLIB |
| 189 | 190 | select FIXED_PHY |
| @@ -1474,10 +1474,8 @@ static int b44_open(struct net_device *dev) · 1473 unmodified lines | ||
| 1474 | 1474 | goto out; |
| 1475 | 1475 | } |
| 1476 | 1476 | |
| 1477 | − init_timer(&bp->timer); | |
| 1477 | + setup_timer(&bp->timer, b44_timer, (unsigned long)bp); | |
| 1478 | 1478 | bp->timer.expires = jiffies + HZ; |
| 1479 | − bp->timer.data = (unsigned long) bp; | |
| 1480 | − bp->timer.function = b44_timer; | |
| 1481 | 1479 | add_timer(&bp->timer); |
| 1482 | 1480 | |
| 1483 | 1481 | b44_enable_ints(bp); |
| @@ -295,16 +295,13 @@ static int bcm_enet_refill_rx(struct net_device *dev) · 294 unmodified lines | ||
| 295 | 295 | /* |
| 296 | 296 | * timer callback to defer refill rx queue in case we're OOM |
| 297 | 297 | */ |
| 298 | −static void bcm_enet_refill_rx_timer(unsigned long data) | |
| 298 | +static void bcm_enet_refill_rx_timer(struct timer_list *t) | |
| 299 | 299 | { |
| 300 | − struct net_device *dev; | |
| 301 | − struct bcm_enet_priv *priv; | |
| 302 | − | |
| 303 | − dev = (struct net_device *)data; | |
| 304 | − priv = netdev_priv(dev); | |
| 300 | + struct bcm_enet_priv *priv = from_timer(priv, t, rx_timeout); | |
| 301 | + struct net_device *dev = priv->net_dev; | |
| 305 | 302 | |
| 306 | 303 | spin_lock(&priv->rx_lock); |
| 307 | − bcm_enet_refill_rx((struct net_device *)data); | |
| 304 | + bcm_enet_refill_rx(dev); | |
| 308 | 305 | spin_unlock(&priv->rx_lock); |
| 309 | 306 | } |
| 310 | 307 | |
| @@ -1062,7 +1059,8 @@ static int bcm_enet_open(struct net_device *dev) · 751 unmodified lines | ||
| 1062 | 1059 | val = enet_readl(priv, ENET_CTL_REG); |
| 1063 | 1060 | val |= ENET_CTL_ENABLE_MASK; |
| 1064 | 1061 | enet_writel(priv, val, ENET_CTL_REG); |
| 1065 | − enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); | |
| 1062 | + if (priv->dma_has_sram) | |
| 1063 | + enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); | |
| 1066 | 1064 | enet_dmac_writel(priv, priv->dma_chan_en_mask, |
| 1067 | 1065 | ENETDMAC_CHANCFG, priv->rx_chan); |
| 1068 | 1066 | |
| @@ -1721,10 +1719,8 @@ static int bcm_enet_probe(struct platform_device *pdev) · 652 unmodified lines | ||
| 1721 | 1719 | const char *clk_name; |
| 1722 | 1720 | int i, ret; |
| 1723 | 1721 | |
| 1724 | − /* stop if shared driver failed, assume driver->probe will be | |
| 1725 | − * called in the same order we register devices (correct ?) */ | |
| 1726 | 1722 | if (!bcm_enet_shared_base[0]) |
| 1727 | − return -ENODEV; | |
| 1723 | + return -EPROBE_DEFER; | |
| 1728 | 1724 | |
| 1729 | 1725 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 1730 | 1726 | res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1); |
| @@ -1768,12 +1764,14 @@ static int bcm_enet_probe(struct platform_device *pdev) · 37 unmodified lines | ||
| 1768 | 1764 | clk_name = "enet1"; |
| 1769 | 1765 | } |
| 1770 | 1766 | |
| 1771 | − priv->mac_clk = clk_get(&pdev->dev, clk_name); | |
| 1767 | + priv->mac_clk = devm_clk_get(&pdev->dev, clk_name); | |
| 1772 | 1768 | if (IS_ERR(priv->mac_clk)) { |
| 1773 | 1769 | ret = PTR_ERR(priv->mac_clk); |
| 1774 | 1770 | goto out; |
| 1775 | 1771 | } |
| 1776 | − clk_prepare_enable(priv->mac_clk); | |
| 1772 | + ret = clk_prepare_enable(priv->mac_clk); | |
| 1773 | + if (ret) | |
| 1774 | + goto out; | |
| 1777 | 1775 | |
| 1778 | 1776 | /* initialize default and fetch platform data */ |
| 1779 | 1777 | priv->rx_ring_size = BCMENET_DEF_RX_DESC; |
| @@ -1801,13 +1799,15 @@ static int bcm_enet_probe(struct platform_device *pdev) · 21 unmodified lines | ||
| 1801 | 1799 | |
| 1802 | 1800 | if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) { |
| 1803 | 1801 | /* using internal PHY, enable clock */ |
| 1804 | − priv->phy_clk = clk_get(&pdev->dev, "ephy"); | |
| 1802 | + priv->phy_clk = devm_clk_get(&pdev->dev, "ephy"); | |
| 1805 | 1803 | if (IS_ERR(priv->phy_clk)) { |
| 1806 | 1804 | ret = PTR_ERR(priv->phy_clk); |
| 1807 | 1805 | priv->phy_clk = NULL; |
| 1808 | − goto out_put_clk_mac; | |
| 1806 | + goto out_disable_clk_mac; | |
| 1809 | 1807 | } |
| 1810 | − clk_prepare_enable(priv->phy_clk); | |
| 1808 | + ret = clk_prepare_enable(priv->phy_clk); | |
| 1809 | + if (ret) | |
| 1810 | + goto out_disable_clk_mac; | |
| 1811 | 1811 | } |
| 1812 | 1812 | |
| 1813 | 1813 | /* do minimal hardware init to be able to probe mii bus */ |
| @@ -1857,9 +1857,7 @@ static int bcm_enet_probe(struct platform_device *pdev) · 43 unmodified lines | ||
| 1857 | 1857 | spin_lock_init(&priv->rx_lock); |
| 1858 | 1858 | |
| 1859 | 1859 | /* init rx timeout (used for oom) */ |
| 1860 | − init_timer(&priv->rx_timeout); | |
| 1861 | − priv->rx_timeout.function = bcm_enet_refill_rx_timer; | |
| 1862 | − priv->rx_timeout.data = (unsigned long)dev; | |
| 1860 | + timer_setup(&priv->rx_timeout, bcm_enet_refill_rx_timer, 0); | |
| 1863 | 1861 | |
| 1864 | 1862 | /* init the mib update lock&work */ |
| 1865 | 1863 | mutex_init(&priv->mib_update_lock); |
| @@ -1901,14 +1899,10 @@ out_free_mdio: · 35 unmodified lines | ||
| 1901 | 1899 | out_uninit_hw: |
| 1902 | 1900 | /* turn off mdc clock */ |
| 1903 | 1901 | enet_writel(priv, 0, ENET_MIISC_REG); |
| 1904 | − if (priv->phy_clk) { | |
| 1905 | − clk_disable_unprepare(priv->phy_clk); | |
| 1906 | − clk_put(priv->phy_clk); | |
| 1907 | − } | |
| 1902 | + clk_disable_unprepare(priv->phy_clk); | |
| 1908 | 1903 | |
| 1909 | −out_put_clk_mac: | |
| 1904 | +out_disable_clk_mac: | |
| 1910 | 1905 | clk_disable_unprepare(priv->mac_clk); |
| 1911 | − clk_put(priv->mac_clk); | |
| 1912 | 1906 | out: |
| 1913 | 1907 | free_netdev(dev); |
| 1914 | 1908 | return ret; |
| @@ -1944,12 +1938,8 @@ static int bcm_enet_remove(struct platform_device *pdev) · 29 unmodified lines | ||
| 1944 | 1938 | } |
| 1945 | 1939 | |
| 1946 | 1940 | /* disable hw block clocks */ |
| 1947 | − if (priv->phy_clk) { | |
| 1948 | − clk_disable_unprepare(priv->phy_clk); | |
| 1949 | − clk_put(priv->phy_clk); | |
| 1950 | − } | |
| 1941 | + clk_disable_unprepare(priv->phy_clk); | |
| 1951 | 1942 | clk_disable_unprepare(priv->mac_clk); |
| 1952 | − clk_put(priv->mac_clk); | |
| 1953 | 1943 | |
| 1954 | 1944 | free_netdev(dev); |
| 1955 | 1945 | return 0; |
| @@ -2021,9 +2011,9 @@ static inline int bcm_enet_port_is_rgmii(int portid) · 65 unmodified lines | ||
| 2021 | 2011 | /* |
| 2022 | 2012 | * enet sw PHY polling |
| 2023 | 2013 | */ |
| 2024 | −static void swphy_poll_timer(unsigned long data) | |
| 2014 | +static void swphy_poll_timer(struct timer_list *t) | |
| 2025 | 2015 | { |
| 2026 | − struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data; | |
| 2016 | + struct bcm_enet_priv *priv = from_timer(priv, t, swphy_poll); | |
| 2027 | 2017 | unsigned int i; |
| 2028 | 2018 | |
| 2029 | 2019 | for (i = 0; i < priv->num_ports; i++) { |
| @@ -2332,11 +2322,8 @@ static int bcm_enetsw_open(struct net_device *dev) · 302 unmodified lines | ||
| 2332 | 2322 | } |
| 2333 | 2323 | |
| 2334 | 2324 | /* start phy polling timer */ |
| 2335 | − init_timer(&priv->swphy_poll); | |
| 2336 | − priv->swphy_poll.function = swphy_poll_timer; | |
| 2337 | − priv->swphy_poll.data = (unsigned long)priv; | |
| 2338 | − priv->swphy_poll.expires = jiffies; | |
| 2339 | − add_timer(&priv->swphy_poll); | |
| 2325 | + timer_setup(&priv->swphy_poll, swphy_poll_timer, 0); | |
| 2326 | + mod_timer(&priv->swphy_poll, jiffies); | |
| 2340 | 2327 | return 0; |
| 2341 | 2328 | |
| 2342 | 2329 | out: |
| @@ -2692,11 +2679,8 @@ static int bcm_enetsw_probe(struct platform_device *pdev) · 349 unmodified lines | ||
| 2692 | 2679 | struct resource *res_mem; |
| 2693 | 2680 | int ret, irq_rx, irq_tx; |
| 2694 | 2681 | |
| 2695 | − /* stop if shared driver failed, assume driver->probe will be | |
| 2696 | − * called in the same order we register devices (correct ?) | |
| 2697 | − */ | |
| 2698 | 2682 | if (!bcm_enet_shared_base[0]) |
| 2699 | − return -ENODEV; | |
| 2683 | + return -EPROBE_DEFER; | |
| 2700 | 2684 | |
| 2701 | 2685 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2702 | 2686 | irq_rx = platform_get_irq(pdev, 0); |
| @@ -2735,33 +2719,27 @@ static int bcm_enetsw_probe(struct platform_device *pdev) · 32 unmodified lines | ||
| 2735 | 2719 | if (ret) |
| 2736 | 2720 | goto out; |
| 2737 | 2721 | |
| 2738 | − if (!request_mem_region(res_mem->start, resource_size(res_mem), | |
| 2739 | − "bcm63xx_enetsw")) { | |
| 2740 | − ret = -EBUSY; | |
| 2722 | + priv->base = devm_ioremap_resource(&pdev->dev, res_mem); | |
| 2723 | + if (IS_ERR(priv->base)) { | |
| 2724 | + ret = PTR_ERR(priv->base); | |
| 2741 | 2725 | goto out; |
| 2742 | 2726 | } |
| 2743 | 2727 | |
| 2744 | − priv->base = ioremap(res_mem->start, resource_size(res_mem)); | |
| 2745 | − if (priv->base == NULL) { | |
| 2746 | − ret = -ENOMEM; | |
| 2747 | − goto out_release_mem; | |
| 2748 | − } | |
| 2749 | − | |
| 2750 | − priv->mac_clk = clk_get(&pdev->dev, "enetsw"); | |
| 2728 | + priv->mac_clk = devm_clk_get(&pdev->dev, "enetsw"); | |
| 2751 | 2729 | if (IS_ERR(priv->mac_clk)) { |
| 2752 | 2730 | ret = PTR_ERR(priv->mac_clk); |
| 2753 | − goto out_unmap; | |
| 2731 | + goto out; | |
| 2754 | 2732 | } |
| 2755 | − clk_enable(priv->mac_clk); | |
| 2733 | + ret = clk_prepare_enable(priv->mac_clk); | |
| 2734 | + if (ret) | |
| 2735 | + goto out; | |
| 2756 | 2736 | |
| 2757 | 2737 | priv->rx_chan = 0; |
| 2758 | 2738 | priv->tx_chan = 1; |
| 2759 | 2739 | spin_lock_init(&priv->rx_lock); |
| 2760 | 2740 | |
| 2761 | 2741 | /* init rx timeout (used for oom) */ |
| 2762 | − init_timer(&priv->rx_timeout); | |
| 2763 | − priv->rx_timeout.function = bcm_enet_refill_rx_timer; | |
| 2764 | − priv->rx_timeout.data = (unsigned long)dev; | |
| 2742 | + timer_setup(&priv->rx_timeout, bcm_enet_refill_rx_timer, 0); | |
| 2765 | 2743 | |
| 2766 | 2744 | /* register netdevice */ |
| 2767 | 2745 | dev->netdev_ops = &bcm_enetsw_ops; |
| @@ -2773,7 +2751,7 @@ static int bcm_enetsw_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 2773 | 2751 | |
| 2774 | 2752 | ret = register_netdev(dev); |
| 2775 | 2753 | if (ret) |
| 2776 | − goto out_put_clk; | |
| 2754 | + goto out_disable_clk; | |
| 2777 | 2755 | |
| 2778 | 2756 | netif_carrier_off(dev); |
| 2779 | 2757 | platform_set_drvdata(pdev, dev); |
| @@ -2782,14 +2760,8 @@ static int bcm_enetsw_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 2782 | 2760 | |
| 2783 | 2761 | return 0; |
| 2784 | 2762 | |
| 2785 | −out_put_clk: | |
| 2786 | − clk_put(priv->mac_clk); | |
| 2787 | − | |
| 2788 | −out_unmap: | |
| 2789 | − iounmap(priv->base); | |
| 2790 | − | |
| 2791 | −out_release_mem: | |
| 2792 | − release_mem_region(res_mem->start, resource_size(res_mem)); | |
| 2763 | +out_disable_clk: | |
| 2764 | + clk_disable_unprepare(priv->mac_clk); | |
| 2793 | 2765 | out: |
| 2794 | 2766 | free_netdev(dev); |
| 2795 | 2767 | return ret; |
| @@ -2801,17 +2773,13 @@ static int bcm_enetsw_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 2801 | 2773 | { |
| 2802 | 2774 | struct bcm_enet_priv *priv; |
| 2803 | 2775 | struct net_device *dev; |
| 2804 | − struct resource *res; | |
| 2805 | 2776 | |
| 2806 | 2777 | /* stop netdevice */ |
| 2807 | 2778 | dev = platform_get_drvdata(pdev); |
| 2808 | 2779 | priv = netdev_priv(dev); |
| 2809 | 2780 | unregister_netdev(dev); |
| 2810 | 2781 | |
| 2811 | − /* release device resources */ | |
| 2812 | − iounmap(priv->base); | |
| 2813 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 2814 | − release_mem_region(res->start, resource_size(res)); | |
| 2782 | + clk_disable_unprepare(priv->mac_clk); | |
| 2815 | 2783 | |
| 2816 | 2784 | free_netdev(dev); |
| 2817 | 2785 | return 0; |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/platform_device.h> |
| 10 | 10 | |
| 11 | 11 | #include <bcm63xx_regs.h> |
| 12 | −#include <bcm63xx_irq.h> | |
| 13 | 12 | #include <bcm63xx_io.h> |
| 14 | 13 | #include <bcm63xx_iudma.h> |
| 15 | 14 | |
| @@ -1416,9 +1416,24 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, · 1415 unmodified lines | ||
| 1416 | 1416 | tdma_writel(priv, 0, TDMA_DESC_RING_COUNT(index)); |
| 1417 | 1417 | tdma_writel(priv, 1, TDMA_DESC_RING_INTR_CONTROL(index)); |
| 1418 | 1418 | tdma_writel(priv, 0, TDMA_DESC_RING_PROD_CONS_INDEX(index)); |
| 1419 | − tdma_writel(priv, RING_IGNORE_STATUS, TDMA_DESC_RING_MAPPING(index)); | |
| 1419 | + | |
| 1420 | + /* Configure QID and port mapping */ | |
| 1421 | + reg = tdma_readl(priv, TDMA_DESC_RING_MAPPING(index)); | |
| 1422 | + reg &= ~(RING_QID_MASK | RING_PORT_ID_MASK << RING_PORT_ID_SHIFT); | |
| 1423 | + if (ring->inspect) { | |
| 1424 | + reg |= ring->switch_queue & RING_QID_MASK; | |
| 1425 | + reg |= ring->switch_port << RING_PORT_ID_SHIFT; | |
| 1426 | + } else { | |
| 1427 | + reg |= RING_IGNORE_STATUS; | |
| 1428 | + } | |
| 1429 | + tdma_writel(priv, reg, TDMA_DESC_RING_MAPPING(index)); | |
| 1420 | 1430 | tdma_writel(priv, 0, TDMA_DESC_RING_PCP_DEI_VID(index)); |
| 1421 | 1431 | |
| 1432 | + /* Enable ACB algorithm 2 */ | |
| 1433 | + reg = tdma_readl(priv, TDMA_CONTROL); | |
| 1434 | + reg |= tdma_control_bit(priv, ACB_ALGO); | |
| 1435 | + tdma_writel(priv, reg, TDMA_CONTROL); | |
| 1436 | + | |
| 1422 | 1437 | /* Do not use tdma_control_bit() here because TSB_SWAP1 collides |
| 1423 | 1438 | * with the original definition of ACB_ALGO |
| 1424 | 1439 | */ |
| @@ -1447,8 +1462,9 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, · 22 unmodified lines | ||
| 1447 | 1462 | napi_enable(&ring->napi); |
| 1448 | 1463 | |
| 1449 | 1464 | netif_dbg(priv, hw, priv->netdev, |
| 1450 | − "TDMA cfg, size=%d, desc_cpu=%p\n", | |
| 1451 | − ring->size, ring->desc_cpu); | |
| 1465 | + "TDMA cfg, size=%d, desc_cpu=%p switch q=%d,port=%d\n", | |
| 1466 | + ring->size, ring->desc_cpu, ring->switch_queue, | |
| 1467 | + ring->switch_port); | |
| 1452 | 1468 | |
| 1453 | 1469 | return 0; |
| 1454 | 1470 | } |
| @@ -2013,6 +2029,29 @@ static const struct ethtool_ops bcm_sysport_ethtool_ops = { · 558 unmodified lines | ||
| 2013 | 2029 | .set_link_ksettings = phy_ethtool_set_link_ksettings, |
| 2014 | 2030 | }; |
| 2015 | 2031 | |
| 2032 | +static u16 bcm_sysport_select_queue(struct net_device *dev, struct sk_buff *skb, | |
| 2033 | + void *accel_priv, | |
| 2034 | + select_queue_fallback_t fallback) | |
| 2035 | +{ | |
| 2036 | + struct bcm_sysport_priv *priv = netdev_priv(dev); | |
| 2037 | + u16 queue = skb_get_queue_mapping(skb); | |
| 2038 | + struct bcm_sysport_tx_ring *tx_ring; | |
| 2039 | + unsigned int q, port; | |
| 2040 | + | |
| 2041 | + if (!netdev_uses_dsa(dev)) | |
| 2042 | + return fallback(dev, skb); | |
| 2043 | + | |
| 2044 | + /* DSA tagging layer will have configured the correct queue */ | |
| 2045 | + q = BRCM_TAG_GET_QUEUE(queue); | |
| 2046 | + port = BRCM_TAG_GET_PORT(queue); | |
| 2047 | + tx_ring = priv->ring_map[q + port * priv->per_port_num_tx_queues]; | |
| 2048 | + | |
| 2049 | + if (unlikely(!tx_ring)) | |
| 2050 | + return fallback(dev, skb); | |
| 2051 | + | |
| 2052 | + return tx_ring->index; | |
| 2053 | +} | |
| 2054 | + | |
| 2016 | 2055 | static const struct net_device_ops bcm_sysport_netdev_ops = { |
| 2017 | 2056 | .ndo_start_xmit = bcm_sysport_xmit, |
| 2018 | 2057 | .ndo_tx_timeout = bcm_sysport_tx_timeout, |
| @@ -2025,8 +2064,79 @@ static const struct net_device_ops bcm_sysport_netdev_ops = { · 6 unmodified lines | ||
| 2025 | 2064 | .ndo_poll_controller = bcm_sysport_poll_controller, |
| 2026 | 2065 | #endif |
| 2027 | 2066 | .ndo_get_stats64 = bcm_sysport_get_stats64, |
| 2067 | + .ndo_select_queue = bcm_sysport_select_queue, | |
| 2028 | 2068 | }; |
| 2029 | 2069 | |
| 2070 | +static int bcm_sysport_map_queues(struct net_device *dev, | |
| 2071 | + struct dsa_notifier_register_info *info) | |
| 2072 | +{ | |
| 2073 | + struct bcm_sysport_priv *priv = netdev_priv(dev); | |
| 2074 | + struct bcm_sysport_tx_ring *ring; | |
| 2075 | + struct net_device *slave_dev; | |
| 2076 | + unsigned int num_tx_queues; | |
| 2077 | + unsigned int q, start, port; | |
| 2078 | + | |
| 2079 | + /* We can't be setting up queue inspection for non directly attached | |
| 2080 | + * switches | |
| 2081 | + */ | |
| 2082 | + if (info->switch_number) | |
| 2083 | + return 0; | |
| 2084 | + | |
| 2085 | + if (dev->netdev_ops != &bcm_sysport_netdev_ops) | |
| 2086 | + return 0; | |
| 2087 | + | |
| 2088 | + port = info->port_number; | |
| 2089 | + slave_dev = info->info.dev; | |
| 2090 | + | |
| 2091 | + /* On SYSTEMPORT Lite we have twice as less queues, so we cannot do a | |
| 2092 | + * 1:1 mapping, we can only do a 2:1 mapping. By reducing the number of | |
| 2093 | + * per-port (slave_dev) network devices queue, we achieve just that. | |
| 2094 | + * This need to happen now before any slave network device is used such | |
| 2095 | + * it accurately reflects the number of real TX queues. | |
| 2096 | + */ | |
| 2097 | + if (priv->is_lite) | |
| 2098 | + netif_set_real_num_tx_queues(slave_dev, | |
| 2099 | + slave_dev->num_tx_queues / 2); | |
| 2100 | + num_tx_queues = slave_dev->real_num_tx_queues; | |
| 2101 | + | |
| 2102 | + if (priv->per_port_num_tx_queues && | |
| 2103 | + priv->per_port_num_tx_queues != num_tx_queues) | |
| 2104 | + netdev_warn(slave_dev, "asymetric number of per-port queues\n"); | |
| 2105 | + | |
| 2106 | + priv->per_port_num_tx_queues = num_tx_queues; | |
| 2107 | + | |
| 2108 | + start = find_first_zero_bit(&priv->queue_bitmap, dev->num_tx_queues); | |
| 2109 | + for (q = 0; q < num_tx_queues; q++) { | |
| 2110 | + ring = &priv->tx_rings[q + start]; | |
| 2111 | + | |
| 2112 | + /* Just remember the mapping actual programming done | |
| 2113 | + * during bcm_sysport_init_tx_ring | |
| 2114 | + */ | |
| 2115 | + ring->switch_queue = q; | |
| 2116 | + ring->switch_port = port; | |
| 2117 | + ring->inspect = true; | |
| 2118 | + priv->ring_map[q + port * num_tx_queues] = ring; | |
| 2119 | + | |
| 2120 | + /* Set all queues as being used now */ | |
| 2121 | + set_bit(q + start, &priv->queue_bitmap); | |
| 2122 | + } | |
| 2123 | + | |
| 2124 | + return 0; | |
| 2125 | +} | |
| 2126 | + | |
| 2127 | +static int bcm_sysport_dsa_notifier(struct notifier_block *unused, | |
| 2128 | + unsigned long event, void *ptr) | |
| 2129 | +{ | |
| 2130 | + struct dsa_notifier_register_info *info; | |
| 2131 | + | |
| 2132 | + if (event != DSA_PORT_REGISTER) | |
| 2133 | + return NOTIFY_DONE; | |
| 2134 | + | |
| 2135 | + info = ptr; | |
| 2136 | + | |
| 2137 | + return notifier_from_errno(bcm_sysport_map_queues(info->master, info)); | |
| 2138 | +} | |
| 2139 | + | |
| 2030 | 2140 | #define REV_FMT "v%2x.%02x" |
| 2031 | 2141 | |
| 2032 | 2142 | static const struct bcm_sysport_hw_params bcm_sysport_params[] = { |
| @@ -2174,10 +2284,18 @@ static int bcm_sysport_probe(struct platform_device *pdev) · 141 unmodified lines | ||
| 2174 | 2284 | |
| 2175 | 2285 | u64_stats_init(&priv->syncp); |
| 2176 | 2286 | |
| 2287 | + priv->dsa_notifier.notifier_call = bcm_sysport_dsa_notifier; | |
| 2288 | + | |
| 2289 | + ret = register_dsa_notifier(&priv->dsa_notifier); | |
| 2290 | + if (ret) { | |
| 2291 | + dev_err(&pdev->dev, "failed to register DSA notifier\n"); | |
| 2292 | + goto err_deregister_fixed_link; | |
| 2293 | + } | |
| 2294 | + | |
| 2177 | 2295 | ret = register_netdev(dev); |
| 2178 | 2296 | if (ret) { |
| 2179 | 2297 | dev_err(&pdev->dev, "failed to register net_device\n"); |
| 2180 | − goto err_deregister_fixed_link; | |
| 2298 | + goto err_deregister_notifier; | |
| 2181 | 2299 | } |
| 2182 | 2300 | |
| 2183 | 2301 | priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK; |
| @@ -2190,6 +2308,8 @@ static int bcm_sysport_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 2190 | 2308 | |
| 2191 | 2309 | return 0; |
| 2192 | 2310 | |
| 2311 | +err_deregister_notifier: | |
| 2312 | + unregister_dsa_notifier(&priv->dsa_notifier); | |
| 2193 | 2313 | err_deregister_fixed_link: |
| 2194 | 2314 | if (of_phy_is_fixed_link(dn)) |
| 2195 | 2315 | of_phy_deregister_fixed_link(dn); |
| @@ -2201,11 +2321,13 @@ err_free_netdev: · 5 unmodified lines | ||
| 2201 | 2321 | static int bcm_sysport_remove(struct platform_device *pdev) |
| 2202 | 2322 | { |
| 2203 | 2323 | struct net_device *dev = dev_get_drvdata(&pdev->dev); |
| 2324 | + struct bcm_sysport_priv *priv = netdev_priv(dev); | |
| 2204 | 2325 | struct device_node *dn = pdev->dev.of_node; |
| 2205 | 2326 | |
| 2206 | 2327 | /* Not much to do, ndo_close has been called |
| 2207 | 2328 | * and we use managed allocations |
| 2208 | 2329 | */ |
| 2330 | + unregister_dsa_notifier(&priv->dsa_notifier); | |
| 2209 | 2331 | unregister_netdev(dev); |
| 2210 | 2332 | if (of_phy_is_fixed_link(dn)) |
| 2211 | 2333 | of_phy_deregister_fixed_link(dn); |
| @@ -404,7 +404,7 @@ struct bcm_rsb { · 403 unmodified lines | ||
| 404 | 404 | #define RING_CONS_INDEX_MASK 0xffff |
| 405 | 405 | |
| 406 | 406 | #define RING_MAPPING 0x14 |
| 407 | −#define RING_QID_MASK 0x3 | |
| 407 | +#define RING_QID_MASK 0x7 | |
| 408 | 408 | #define RING_PORT_ID_SHIFT 3 |
| 409 | 409 | #define RING_PORT_ID_MASK 0x7 |
| 410 | 410 | #define RING_IGNORE_STATUS (1 << 6) |
| @@ -712,6 +712,9 @@ struct bcm_sysport_tx_ring { · 301 unmodified lines | ||
| 712 | 712 | struct bcm_sysport_priv *priv; /* private context backpointer */ |
| 713 | 713 | unsigned long packets; /* packets statistics */ |
| 714 | 714 | unsigned long bytes; /* bytes statistics */ |
| 715 | + unsigned int switch_queue; /* switch port queue number */ | |
| 716 | + unsigned int switch_port; /* switch port queue number */ | |
| 717 | + bool inspect; /* inspect switch port and queue */ | |
| 715 | 718 | }; |
| 716 | 719 | |
| 717 | 720 | /* Driver private structure */ |
| @@ -765,5 +768,12 @@ struct bcm_sysport_priv { · 47 unmodified lines | ||
| 765 | 768 | |
| 766 | 769 | /* For atomic update generic 64bit value on 32bit Machine */ |
| 767 | 770 | struct u64_stats_sync syncp; |
| 771 | + | |
| 772 | + /* map information between switch port queues and local queues */ | |
| 773 | + struct notifier_block dsa_notifier; | |
| 774 | + unsigned int per_port_num_tx_queues; | |
| 775 | + unsigned long queue_bitmap; | |
| 776 | + struct bcm_sysport_tx_ring *ring_map[DSA_MAX_PORTS * 8]; | |
| 777 | + | |
| 768 | 778 | }; |
| 769 | 779 | #endif /* __BCM_SYSPORT_H */ |
| @@ -184,13 +184,19 @@ static int bgmac_probe(struct bcma_device *core) · 183 unmodified lines | ||
| 184 | 184 | |
| 185 | 185 | if (!bgmac_is_bcm4707_family(core) && |
| 186 | 186 | !(ci->id == BCMA_CHIP_ID_BCM53573 && core->core_unit == 1)) { |
| 187 | + struct phy_device *phydev; | |
| 188 | + | |
| 187 | 189 | mii_bus = bcma_mdio_mii_register(bgmac); |
| 188 | 190 | if (IS_ERR(mii_bus)) { |
| 189 | 191 | err = PTR_ERR(mii_bus); |
| 190 | 192 | goto err; |
| 191 | 193 | } |
| 192 | − | |
| 193 | 194 | bgmac->mii_bus = mii_bus; |
| 195 | + | |
| 196 | + phydev = mdiobus_get_phy(bgmac->mii_bus, bgmac->phyaddr); | |
| 197 | + if (ci->id == BCMA_CHIP_ID_BCM53573 && phydev && | |
| 198 | + (phydev->drv->phy_id & phydev->drv->phy_id_mask) == PHY_ID_BCM54210E) | |
| 199 | + phydev->dev_flags |= PHY_BRCM_EN_MASTER_MODE; | |
| 194 | 200 | } |
| 195 | 201 | |
| 196 | 202 | if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { |
| @@ -131,6 +131,7 @@ static void bgmac_nicpm_speed_set(struct net_device *net_dev) · 130 unmodified lines | ||
| 131 | 131 | switch (bgmac->net_dev->phydev->speed) { |
| 132 | 132 | default: |
| 133 | 133 | netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n"); |
| 134 | + /* fall through */ | |
| 134 | 135 | case SPEED_1000: |
| 135 | 136 | val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT; |
| 136 | 137 | break; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/bcm47xx_nvram.h> |
| 16 | 16 | #include <linux/phy.h> |
| 17 | 17 | #include <linux/phy_fixed.h> |
| 18 | +#include <net/dsa.h> | |
| 18 | 19 | #include "bgmac.h" |
| 19 | 20 | |
| 20 | 21 | static bool bgmac_wait_value(struct bgmac *bgmac, u16 reg, u32 mask, |
| @@ -127,6 +128,8 @@ bgmac_dma_tx_add_buf(struct bgmac *bgmac, struct bgmac_dma_ring *ring, · 106 unmodified lines | ||
| 127 | 128 | dma_desc->ctl1 = cpu_to_le32(ctl1); |
| 128 | 129 | } |
| 129 | 130 | |
| 131 | +#define ENET_BRCM_TAG_LEN 4 | |
| 132 | + | |
| 130 | 133 | static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, |
| 131 | 134 | struct bgmac_dma_ring *ring, |
| 132 | 135 | struct sk_buff *skb) |
| @@ -139,6 +142,18 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, · 6 unmodified lines | ||
| 139 | 142 | u32 flags; |
| 140 | 143 | int i; |
| 141 | 144 | |
| 145 | + /* The Ethernet switch we are interfaced with needs packets to be at | |
| 146 | + * least 64 bytes (including FCS) otherwise they will be discarded when | |
| 147 | + * they enter the switch port logic. When Broadcom tags are enabled, we | |
| 148 | + * need to make sure that packets are at least 68 bytes | |
| 149 | + * (including FCS and tag) because the length verification is done after | |
| 150 | + * the Broadcom tag is stripped off the ingress packet. | |
| 151 | + */ | |
| 152 | + if (netdev_uses_dsa(net_dev)) { | |
| 153 | + if (skb_put_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) | |
| 154 | + goto err_stats; | |
| 155 | + } | |
| 156 | + | |
| 142 | 157 | if (skb->len > BGMAC_DESC_CTL1_LEN) { |
| 143 | 158 | netdev_err(bgmac->net_dev, "Too long skb (%d)\n", skb->len); |
| 144 | 159 | goto err_drop; |
| @@ -225,6 +240,7 @@ err_dma_head: · 80 unmodified lines | ||
| 225 | 240 | |
| 226 | 241 | err_drop: |
| 227 | 242 | dev_kfree_skb(skb); |
| 243 | +err_stats: | |
| 228 | 244 | net_dev->stats.tx_dropped++; |
| 229 | 245 | net_dev->stats.tx_errors++; |
| 230 | 246 | return NETDEV_TX_OK; |
| @@ -8462,10 +8462,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) · 8461 unmodified lines | ||
| 8462 | 8462 | bnx2_set_default_link(bp); |
| 8463 | 8463 | bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; |
| 8464 | 8464 | |
| 8465 | − init_timer(&bp->timer); | |
| 8465 | + setup_timer(&bp->timer, bnx2_timer, (unsigned long)bp); | |
| 8466 | 8466 | bp->timer.expires = RUN_AT(BNX2_TIMER_INTERVAL); |
| 8467 | − bp->timer.data = (unsigned long) bp; | |
| 8468 | − bp->timer.function = bnx2_timer; | |
| 8469 | 8467 | |
| 8470 | 8468 | #ifdef BCM_CNIC |
| 8471 | 8469 | if (bnx2_shmem_rd(bp, BNX2_ISCSI_INITIATOR) & BNX2_ISCSI_INITIATOR_EN) |
| @@ -4289,7 +4289,7 @@ int __bnx2x_setup_tc(struct net_device *dev, enum tc_setup_type type, · 4288 unmodified lines | ||
| 4289 | 4289 | { |
| 4290 | 4290 | struct tc_mqprio_qopt *mqprio = type_data; |
| 4291 | 4291 | |
| 4292 | − if (type != TC_SETUP_MQPRIO) | |
| 4292 | + if (type != TC_SETUP_QDISC_MQPRIO) | |
| 4293 | 4293 | return -EOPNOTSUPP; |
| 4294 | 4294 | |
| 4295 | 4295 | mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; |
| @@ -9332,7 +9332,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link) · 9331 unmodified lines | ||
| 9332 | 9332 | /* Schedule the rx_mode command */ |
| 9333 | 9333 | if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) |
| 9334 | 9334 | set_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state); |
| 9335 | − else | |
| 9335 | + else if (bp->slowpath) | |
| 9336 | 9336 | bnx2x_set_storm_rx_mode(bp); |
| 9337 | 9337 | |
| 9338 | 9338 | /* Cleanup multicast configuration */ |
| @@ -10271,8 +10271,15 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work) · 932 unmodified lines | ||
| 10271 | 10271 | smp_mb(); |
| 10272 | 10272 | |
| 10273 | 10273 | bnx2x_nic_unload(bp, UNLOAD_NORMAL, true); |
| 10274 | − bnx2x_nic_load(bp, LOAD_NORMAL); | |
| 10275 | − | |
| 10274 | + /* When ret value shows failure of allocation failure, | |
| 10275 | + * the nic is rebooted again. If open still fails, a error | |
| 10276 | + * message to notify the user. | |
| 10277 | + */ | |
| 10278 | + if (bnx2x_nic_load(bp, LOAD_NORMAL) == -ENOMEM) { | |
| 10279 | + bnx2x_nic_unload(bp, UNLOAD_NORMAL, true); | |
| 10280 | + if (bnx2x_nic_load(bp, LOAD_NORMAL)) | |
| 10281 | + BNX2X_ERR("Open the NIC fails again!\n"); | |
| 10282 | + } | |
| 10276 | 10283 | rtnl_unlock(); |
| 10277 | 10284 | return; |
| 10278 | 10285 | } |
| @@ -12414,10 +12421,8 @@ static int bnx2x_init_bp(struct bnx2x *bp) · 2135 unmodified lines | ||
| 12414 | 12421 | |
| 12415 | 12422 | bp->current_interval = CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ; |
| 12416 | 12423 | |
| 12417 | − init_timer(&bp->timer); | |
| 12424 | + setup_timer(&bp->timer, bnx2x_timer, (unsigned long)bp); | |
| 12418 | 12425 | bp->timer.expires = jiffies + bp->current_interval; |
| 12419 | − bp->timer.data = (unsigned long) bp; | |
| 12420 | − bp->timer.function = bnx2x_timer; | |
| 12421 | 12426 | |
| 12422 | 12427 | if (SHMEM2_HAS(bp, dcbx_lldp_params_offset) && |
| 12423 | 12428 | SHMEM2_HAS(bp, dcbx_lldp_dcbx_stat_offset) && |
| @@ -1074,11 +1074,6 @@ static void bnx2x_vf_set_bars(struct bnx2x *bp, struct bnx2x_virtf *vf) · 1073 unmodified lines | ||
| 1074 | 1074 | } |
| 1075 | 1075 | } |
| 1076 | 1076 | |
| 1077 | −static int bnx2x_ari_enabled(struct pci_dev *dev) | |
| 1078 | −{ | |
| 1079 | − return dev->bus->self && dev->bus->self->ari_enabled; | |
| 1080 | −} | |
| 1081 | − | |
| 1082 | 1077 | static int |
| 1083 | 1078 | bnx2x_get_vf_igu_cam_info(struct bnx2x *bp) |
| 1084 | 1079 | { |
| @@ -1212,7 +1207,7 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, · 127 unmodified lines | ||
| 1212 | 1207 | |
| 1213 | 1208 | err = -EIO; |
| 1214 | 1209 | /* verify ari is enabled */ |
| 1215 | − if (!bnx2x_ari_enabled(bp->pdev)) { | |
| 1210 | + if (!pci_ari_enabled(bp->pdev->bus)) { | |
| 1216 | 1211 | BNX2X_ERR("ARI not supported (check pci bridge ARI forwarding), SRIOV can not be enabled\n"); |
| 1217 | 1212 | return 0; |
| 1218 | 1213 | } |
| @@ -1,3 +1,4 @@ | ||
| 1 | 1 | obj-$(CONFIG_BNXT) += bnxt_en.o |
| 2 | 2 | |
| 3 | −bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_tc.o | |
| 3 | +bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o | |
| 4 | +bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o | |
| @@ -61,6 +61,7 @@ · 60 unmodified lines | ||
| 61 | 61 | #include "bnxt_xdp.h" |
| 62 | 62 | #include "bnxt_vfr.h" |
| 63 | 63 | #include "bnxt_tc.h" |
| 64 | +#include "bnxt_devlink.h" | |
| 64 | 65 | |
| 65 | 66 | #define BNXT_TX_TIMEOUT (5 * HZ) |
| 66 | 67 | |
| @@ -107,9 +108,11 @@ enum board_idx { · 40 unmodified lines | ||
| 107 | 108 | BCM57452, |
| 108 | 109 | BCM57454, |
| 109 | 110 | BCM58802, |
| 111 | + BCM58804, | |
| 110 | 112 | BCM58808, |
| 111 | 113 | NETXTREME_E_VF, |
| 112 | 114 | NETXTREME_C_VF, |
| 115 | + NETXTREME_S_VF, | |
| 113 | 116 | }; |
| 114 | 117 | |
| 115 | 118 | /* indexed by enum above */ |
| @@ -145,9 +148,11 @@ static const struct { · 29 unmodified lines | ||
| 145 | 148 | [BCM57452] = { "Broadcom BCM57452 NetXtreme-E 10Gb/25Gb/40Gb/50Gb Ethernet" }, |
| 146 | 149 | [BCM57454] = { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, |
| 147 | 150 | [BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" }, |
| 151 | + [BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, | |
| 148 | 152 | [BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, |
| 149 | 153 | [NETXTREME_E_VF] = { "Broadcom NetXtreme-E Ethernet Virtual Function" }, |
| 150 | 154 | [NETXTREME_C_VF] = { "Broadcom NetXtreme-C Ethernet Virtual Function" }, |
| 155 | + [NETXTREME_S_VF] = { "Broadcom NetXtreme-S Ethernet Virtual Function" }, | |
| 151 | 156 | }; |
| 152 | 157 | |
| 153 | 158 | static const struct pci_device_id bnxt_pci_tbl[] = { |
| @@ -185,6 +190,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = { · 31 unmodified lines | ||
| 185 | 190 | { PCI_VDEVICE(BROADCOM, 0x16f0), .driver_data = BCM58808 }, |
| 186 | 191 | { PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 }, |
| 187 | 192 | { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 }, |
| 193 | + { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 }, | |
| 188 | 194 | #ifdef CONFIG_BNXT_SRIOV |
| 189 | 195 | { PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF }, |
| 190 | 196 | { PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF }, |
| @@ -194,6 +200,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = { · 3 unmodified lines | ||
| 194 | 200 | { PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = NETXTREME_E_VF }, |
| 195 | 201 | { PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = NETXTREME_C_VF }, |
| 196 | 202 | { PCI_VDEVICE(BROADCOM, 0x16e5), .driver_data = NETXTREME_C_VF }, |
| 203 | + { PCI_VDEVICE(BROADCOM, 0xd800), .driver_data = NETXTREME_S_VF }, | |
| 197 | 204 | #endif |
| 198 | 205 | { 0 } |
| 199 | 206 | }; |
| @@ -218,7 +225,8 @@ static struct workqueue_struct *bnxt_pf_wq; · 18 unmodified lines | ||
| 218 | 225 | |
| 219 | 226 | static bool bnxt_vf_pciid(enum board_idx idx) |
| 220 | 227 | { |
| 221 | − return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF); | |
| 228 | + return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF || | |
| 229 | + idx == NETXTREME_S_VF); | |
| 222 | 230 | } |
| 223 | 231 | |
| 224 | 232 | #define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID) |
| @@ -1509,7 +1517,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons, · 1284 unmodified lines | ||
| 1509 | 1517 | (struct rx_tpa_end_cmp *)rxcmp, |
| 1510 | 1518 | (struct rx_tpa_end_cmp_ext *)rxcmp1, event); |
| 1511 | 1519 | |
| 1512 | − if (unlikely(IS_ERR(skb))) | |
| 1520 | + if (IS_ERR(skb)) | |
| 1513 | 1521 | return -EBUSY; |
| 1514 | 1522 | |
| 1515 | 1523 | rc = -ENOMEM; |
| @@ -2827,7 +2835,8 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) · 1311 unmodified lines | ||
| 2827 | 2835 | if (page_mode) { |
| 2828 | 2836 | if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) |
| 2829 | 2837 | return -EOPNOTSUPP; |
| 2830 | − bp->dev->max_mtu = BNXT_MAX_PAGE_MODE_MTU; | |
| 2838 | + bp->dev->max_mtu = | |
| 2839 | + min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); | |
| 2831 | 2840 | bp->flags &= ~BNXT_FLAG_AGG_RINGS; |
| 2832 | 2841 | bp->flags |= BNXT_FLAG_NO_AGG_RINGS | BNXT_FLAG_RX_PAGE_MODE; |
| 2833 | 2842 | bp->dev->hw_features &= ~NETIF_F_LRO; |
| @@ -2835,7 +2844,7 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) · 1 unmodified line | ||
| 2835 | 2844 | bp->rx_dir = DMA_BIDIRECTIONAL; |
| 2836 | 2845 | bp->rx_skb_func = bnxt_rx_page_skb; |
| 2837 | 2846 | } else { |
| 2838 | − bp->dev->max_mtu = BNXT_MAX_MTU; | |
| 2847 | + bp->dev->max_mtu = bp->max_mtu; | |
| 2839 | 2848 | bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE; |
| 2840 | 2849 | bp->rx_dir = DMA_FROM_DEVICE; |
| 2841 | 2850 | bp->rx_skb_func = bnxt_rx_skb; |
| @@ -4528,19 +4537,46 @@ static int bnxt_hwrm_check_tx_rings(struct bnxt *bp, int tx_rings) · 1686 unmodified lines | ||
| 4528 | 4537 | return 0; |
| 4529 | 4538 | } |
| 4530 | 4539 | |
| 4531 | −static void bnxt_hwrm_set_coal_params(struct bnxt *bp, u32 max_bufs, | |
| 4532 | − u32 buf_tmrs, u16 flags, | |
| 4540 | +static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, | |
| 4533 | 4541 | struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req) |
| 4534 | 4542 | { |
| 4543 | + u16 val, tmr, max, flags; | |
| 4544 | + | |
| 4545 | + max = hw_coal->bufs_per_record * 128; | |
| 4546 | + if (hw_coal->budget) | |
| 4547 | + max = hw_coal->bufs_per_record * hw_coal->budget; | |
| 4548 | + | |
| 4549 | + val = clamp_t(u16, hw_coal->coal_bufs, 1, max); | |
| 4550 | + req->num_cmpl_aggr_int = cpu_to_le16(val); | |
| 4551 | + | |
| 4552 | + /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */ | |
| 4553 | + val = min_t(u16, val, 63); | |
| 4554 | + req->num_cmpl_dma_aggr = cpu_to_le16(val); | |
| 4555 | + | |
| 4556 | + /* This is a 6-bit value and must not be 0, or we'll get non stop IRQ */ | |
| 4557 | + val = clamp_t(u16, hw_coal->coal_bufs_irq, 1, 63); | |
| 4558 | + req->num_cmpl_dma_aggr_during_int = cpu_to_le16(val); | |
| 4559 | + | |
| 4560 | + tmr = BNXT_USEC_TO_COAL_TIMER(hw_coal->coal_ticks); | |
| 4561 | + tmr = max_t(u16, tmr, 1); | |
| 4562 | + req->int_lat_tmr_max = cpu_to_le16(tmr); | |
| 4563 | + | |
| 4564 | + /* min timer set to 1/2 of interrupt timer */ | |
| 4565 | + val = tmr / 2; | |
| 4566 | + req->int_lat_tmr_min = cpu_to_le16(val); | |
| 4567 | + | |
| 4568 | + /* buf timer set to 1/4 of interrupt timer */ | |
| 4569 | + val = max_t(u16, tmr / 4, 1); | |
| 4570 | + req->cmpl_aggr_dma_tmr = cpu_to_le16(val); | |
| 4571 | + | |
| 4572 | + tmr = BNXT_USEC_TO_COAL_TIMER(hw_coal->coal_ticks_irq); | |
| 4573 | + tmr = max_t(u16, tmr, 1); | |
| 4574 | + req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(tmr); | |
| 4575 | + | |
| 4576 | + flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; | |
| 4577 | + if (hw_coal->idle_thresh && hw_coal->coal_ticks < hw_coal->idle_thresh) | |
| 4578 | + flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; | |
| 4535 | 4579 | req->flags = cpu_to_le16(flags); |
| 4536 | − req->num_cmpl_dma_aggr = cpu_to_le16((u16)max_bufs); | |
| 4537 | − req->num_cmpl_dma_aggr_during_int = cpu_to_le16(max_bufs >> 16); | |
| 4538 | − req->cmpl_aggr_dma_tmr = cpu_to_le16((u16)buf_tmrs); | |
| 4539 | − req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(buf_tmrs >> 16); | |
| 4540 | − /* Minimum time between 2 interrupts set to buf_tmr x 2 */ | |
| 4541 | − req->int_lat_tmr_min = cpu_to_le16((u16)buf_tmrs * 2); | |
| 4542 | − req->int_lat_tmr_max = cpu_to_le16((u16)buf_tmrs * 4); | |
| 4543 | − req->num_cmpl_aggr_int = cpu_to_le16((u16)max_bufs * 4); | |
| 4544 | 4580 | } |
| 4545 | 4581 | |
| 4546 | 4582 | int bnxt_hwrm_set_coal(struct bnxt *bp) |
| @@ -4548,51 +4584,14 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) · 1 unmodified line | ||
| 4548 | 4584 | int i, rc = 0; |
| 4549 | 4585 | struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0}, |
| 4550 | 4586 | req_tx = {0}, *req; |
| 4551 | − u16 max_buf, max_buf_irq; | |
| 4552 | − u16 buf_tmr, buf_tmr_irq; | |
| 4553 | − u32 flags; | |
| 4554 | 4587 | |
| 4555 | 4588 | bnxt_hwrm_cmd_hdr_init(bp, &req_rx, |
| 4556 | 4589 | HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); |
| 4557 | 4590 | bnxt_hwrm_cmd_hdr_init(bp, &req_tx, |
| 4558 | 4591 | HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); |
| 4559 | 4592 | |
| 4560 | − /* Each rx completion (2 records) should be DMAed immediately. | |
| 4561 | − * DMA 1/4 of the completion buffers at a time. | |
| 4562 | − */ | |
| 4563 | − max_buf = min_t(u16, bp->rx_coal_bufs / 4, 2); | |
| 4564 | − /* max_buf must not be zero */ | |
| 4565 | − max_buf = clamp_t(u16, max_buf, 1, 63); | |
| 4566 | − max_buf_irq = clamp_t(u16, bp->rx_coal_bufs_irq, 1, 63); | |
| 4567 | − buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks); | |
| 4568 | − /* buf timer set to 1/4 of interrupt timer */ | |
| 4569 | − buf_tmr = max_t(u16, buf_tmr / 4, 1); | |
| 4570 | − buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks_irq); | |
| 4571 | − buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); | |
| 4572 | − | |
| 4573 | − flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; | |
| 4574 | − | |
| 4575 | − /* RING_IDLE generates more IRQs for lower latency. Enable it only | |
| 4576 | − * if coal_ticks is less than 25 us. | |
| 4577 | − */ | |
| 4578 | − if (bp->rx_coal_ticks < 25) | |
| 4579 | − flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; | |
| 4580 | − | |
| 4581 | − bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, | |
| 4582 | − buf_tmr_irq << 16 | buf_tmr, flags, &req_rx); | |
| 4583 | − | |
| 4584 | − /* max_buf must not be zero */ | |
| 4585 | − max_buf = clamp_t(u16, bp->tx_coal_bufs, 1, 63); | |
| 4586 | − max_buf_irq = clamp_t(u16, bp->tx_coal_bufs_irq, 1, 63); | |
| 4587 | − buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks); | |
| 4588 | − /* buf timer set to 1/4 of interrupt timer */ | |
| 4589 | − buf_tmr = max_t(u16, buf_tmr / 4, 1); | |
| 4590 | − buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks_irq); | |
| 4591 | − buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); | |
| 4592 | − | |
| 4593 | − flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; | |
| 4594 | − bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, | |
| 4595 | − buf_tmr_irq << 16 | buf_tmr, flags, &req_tx); | |
| 4593 | + bnxt_hwrm_set_coal_params(&bp->rx_coal, &req_rx); | |
| 4594 | + bnxt_hwrm_set_coal_params(&bp->tx_coal, &req_tx); | |
| 4596 | 4595 | |
| 4597 | 4596 | mutex_lock(&bp->hwrm_cmd_lock); |
| 4598 | 4597 | for (i = 0; i < bp->cp_nr_rings; i++) { |
| @@ -4724,6 +4723,10 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp) · 125 unmodified lines | ||
| 4724 | 4723 | else |
| 4725 | 4724 | bp->br_mode = BRIDGE_MODE_UNDEF; |
| 4726 | 4725 | |
| 4726 | + bp->max_mtu = le16_to_cpu(resp->max_mtu_configured); | |
| 4727 | + if (!bp->max_mtu) | |
| 4728 | + bp->max_mtu = BNXT_MAX_MTU; | |
| 4729 | + | |
| 4727 | 4730 | func_qcfg_exit: |
| 4728 | 4731 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 4729 | 4732 | return rc; |
| @@ -4884,9 +4887,9 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) · 154 unmodified lines | ||
| 4884 | 4887 | resp->hwrm_intf_upd); |
| 4885 | 4888 | netdev_warn(bp->dev, "Please update firmware with HWRM interface 1.0.0 or newer.\n"); |
| 4886 | 4889 | } |
| 4887 | − snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d/%d.%d.%d", | |
| 4890 | + snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d", | |
| 4888 | 4891 | resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld, |
| 4889 | − resp->hwrm_intf_maj, resp->hwrm_intf_min, resp->hwrm_intf_upd); | |
| 4892 | + resp->hwrm_fw_rsvd); | |
| 4890 | 4893 | |
| 4891 | 4894 | bp->hwrm_cmd_timeout = le16_to_cpu(resp->def_req_timeout); |
| 4892 | 4895 | if (!bp->hwrm_cmd_timeout) |
| @@ -4912,16 +4915,14 @@ hwrm_ver_get_exit: · 19 unmodified lines | ||
| 4912 | 4915 | |
| 4913 | 4916 | int bnxt_hwrm_fw_set_time(struct bnxt *bp) |
| 4914 | 4917 | { |
| 4915 | −#if IS_ENABLED(CONFIG_RTC_LIB) | |
| 4916 | 4918 | struct hwrm_fw_set_time_input req = {0}; |
| 4917 | − struct rtc_time tm; | |
| 4918 | − struct timeval tv; | |
| 4919 | + struct tm tm; | |
| 4920 | + time64_t now = ktime_get_real_seconds(); | |
| 4919 | 4921 | |
| 4920 | 4922 | if (bp->hwrm_spec_code < 0x10400) |
| 4921 | 4923 | return -EOPNOTSUPP; |
| 4922 | 4924 | |
| 4923 | − do_gettimeofday(&tv); | |
| 4924 | − rtc_time_to_tm(tv.tv_sec, &tm); | |
| 4925 | + time64_to_tm(now, 0, &tm); | |
| 4925 | 4926 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_SET_TIME, -1, -1); |
| 4926 | 4927 | req.year = cpu_to_le16(1900 + tm.tm_year); |
| 4927 | 4928 | req.month = 1 + tm.tm_mon; |
| @@ -4930,9 +4931,6 @@ int bnxt_hwrm_fw_set_time(struct bnxt *bp) · 2 unmodified lines | ||
| 4930 | 4931 | req.minute = tm.tm_min; |
| 4931 | 4932 | req.second = tm.tm_sec; |
| 4932 | 4933 | return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 4933 | −#else | |
| 4934 | − return -EOPNOTSUPP; | |
| 4935 | −#endif | |
| 4936 | 4934 | } |
| 4937 | 4935 | |
| 4938 | 4936 | static int bnxt_hwrm_port_qstats(struct bnxt *bp) |
| @@ -6980,6 +6978,11 @@ static void bnxt_timer(unsigned long data) · 2041 unmodified lines | ||
| 6980 | 6978 | set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event); |
| 6981 | 6979 | bnxt_queue_sp_work(bp); |
| 6982 | 6980 | } |
| 6981 | + | |
| 6982 | + if (bnxt_tc_flower_enabled(bp)) { | |
| 6983 | + set_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event); | |
| 6984 | + bnxt_queue_sp_work(bp); | |
| 6985 | + } | |
| 6983 | 6986 | bnxt_restart_timer: |
| 6984 | 6987 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
| 6985 | 6988 | } |
| @@ -7070,6 +7073,10 @@ static void bnxt_sp_task(struct work_struct *work) · 84 unmodified lines | ||
| 7070 | 7073 | bnxt_get_port_module_status(bp); |
| 7071 | 7074 | mutex_unlock(&bp->link_lock); |
| 7072 | 7075 | } |
| 7076 | + | |
| 7077 | + if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event)) | |
| 7078 | + bnxt_tc_flow_stats_work(bp); | |
| 7079 | + | |
| 7073 | 7080 | /* These functions below will clear BNXT_STATE_IN_SP_TASK. They |
| 7074 | 7081 | * must be the last functions to be called before exiting. |
| 7075 | 7082 | */ |
| @@ -7133,6 +7140,32 @@ static void bnxt_cleanup_pci(struct bnxt *bp) · 57 unmodified lines | ||
| 7133 | 7140 | pci_disable_device(bp->pdev); |
| 7134 | 7141 | } |
| 7135 | 7142 | |
| 7143 | +static void bnxt_init_dflt_coal(struct bnxt *bp) | |
| 7144 | +{ | |
| 7145 | + struct bnxt_coal *coal; | |
| 7146 | + | |
| 7147 | + /* Tick values in micro seconds. | |
| 7148 | + * 1 coal_buf x bufs_per_record = 1 completion record. | |
| 7149 | + */ | |
| 7150 | + coal = &bp->rx_coal; | |
| 7151 | + coal->coal_ticks = 14; | |
| 7152 | + coal->coal_bufs = 30; | |
| 7153 | + coal->coal_ticks_irq = 1; | |
| 7154 | + coal->coal_bufs_irq = 2; | |
| 7155 | + coal->idle_thresh = 25; | |
| 7156 | + coal->bufs_per_record = 2; | |
| 7157 | + coal->budget = 64; /* NAPI budget */ | |
| 7158 | + | |
| 7159 | + coal = &bp->tx_coal; | |
| 7160 | + coal->coal_ticks = 28; | |
| 7161 | + coal->coal_bufs = 30; | |
| 7162 | + coal->coal_ticks_irq = 2; | |
| 7163 | + coal->coal_bufs_irq = 2; | |
| 7164 | + coal->bufs_per_record = 1; | |
| 7165 | + | |
| 7166 | + bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; | |
| 7167 | +} | |
| 7168 | + | |
| 7136 | 7169 | static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) |
| 7137 | 7170 | { |
| 7138 | 7171 | int rc; |
| @@ -7201,22 +7234,9 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) · 62 unmodified lines | ||
| 7201 | 7234 | bp->rx_ring_size = BNXT_DEFAULT_RX_RING_SIZE; |
| 7202 | 7235 | bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE; |
| 7203 | 7236 | |
| 7204 | − /* tick values in micro seconds */ | |
| 7205 | − bp->rx_coal_ticks = 12; | |
| 7206 | − bp->rx_coal_bufs = 30; | |
| 7207 | − bp->rx_coal_ticks_irq = 1; | |
| 7208 | − bp->rx_coal_bufs_irq = 2; | |
| 7237 | + bnxt_init_dflt_coal(bp); | |
| 7209 | 7238 | |
| 7210 | − bp->tx_coal_ticks = 25; | |
| 7211 | − bp->tx_coal_bufs = 30; | |
| 7212 | − bp->tx_coal_ticks_irq = 2; | |
| 7213 | − bp->tx_coal_bufs_irq = 2; | |
| 7214 | − | |
| 7215 | − bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; | |
| 7216 | − | |
| 7217 | − init_timer(&bp->timer); | |
| 7218 | − bp->timer.data = (unsigned long)bp; | |
| 7219 | − bp->timer.function = bnxt_timer; | |
| 7239 | + setup_timer(&bp->timer, bnxt_timer, (unsigned long)bp); | |
| 7220 | 7240 | bp->current_interval = BNXT_TIMER_INTERVAL; |
| 7221 | 7241 | |
| 7222 | 7242 | clear_bit(BNXT_STATE_OPEN, &bp->state); |
| @@ -7243,13 +7263,13 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p) · 20 unmodified lines | ||
| 7243 | 7263 | if (!is_valid_ether_addr(addr->sa_data)) |
| 7244 | 7264 | return -EADDRNOTAVAIL; |
| 7245 | 7265 | |
| 7266 | + if (ether_addr_equal(addr->sa_data, dev->dev_addr)) | |
| 7267 | + return 0; | |
| 7268 | + | |
| 7246 | 7269 | rc = bnxt_approve_mac(bp, addr->sa_data); |
| 7247 | 7270 | if (rc) |
| 7248 | 7271 | return rc; |
| 7249 | 7272 | |
| 7250 | − if (ether_addr_equal(addr->sa_data, dev->dev_addr)) | |
| 7251 | − return 0; | |
| 7252 | − | |
| 7253 | 7273 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
| 7254 | 7274 | if (netif_running(dev)) { |
| 7255 | 7275 | bnxt_close_nic(bp, false, false); |
| @@ -7321,24 +7341,49 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc) · 65 unmodified lines | ||
| 7321 | 7341 | return 0; |
| 7322 | 7342 | } |
| 7323 | 7343 | |
| 7324 | −static int bnxt_setup_flower(struct net_device *dev, | |
| 7325 | − struct tc_cls_flower_offload *cls_flower) | |
| 7344 | +static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data, | |
| 7345 | + void *cb_priv) | |
| 7346 | +{ | |
| 7347 | + struct bnxt *bp = cb_priv; | |
| 7348 | + | |
| 7349 | + if (!bnxt_tc_flower_enabled(bp) || !tc_can_offload(bp->dev)) | |
| 7350 | + return -EOPNOTSUPP; | |
| 7351 | + | |
| 7352 | + switch (type) { | |
| 7353 | + case TC_SETUP_CLSFLOWER: | |
| 7354 | + return bnxt_tc_setup_flower(bp, bp->pf.fw_fid, type_data); | |
| 7355 | + default: | |
| 7356 | + return -EOPNOTSUPP; | |
| 7357 | + } | |
| 7358 | +} | |
| 7359 | + | |
| 7360 | +static int bnxt_setup_tc_block(struct net_device *dev, | |
| 7361 | + struct tc_block_offload *f) | |
| 7326 | 7362 | { |
| 7327 | 7363 | struct bnxt *bp = netdev_priv(dev); |
| 7328 | 7364 | |
| 7329 | − if (BNXT_VF(bp)) | |
| 7365 | + if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) | |
| 7330 | 7366 | return -EOPNOTSUPP; |
| 7331 | 7367 | |
| 7332 | − return bnxt_tc_setup_flower(bp, bp->pf.fw_fid, cls_flower); | |
| 7368 | + switch (f->command) { | |
| 7369 | + case TC_BLOCK_BIND: | |
| 7370 | + return tcf_block_cb_register(f->block, bnxt_setup_tc_block_cb, | |
| 7371 | + bp, bp); | |
| 7372 | + case TC_BLOCK_UNBIND: | |
| 7373 | + tcf_block_cb_unregister(f->block, bnxt_setup_tc_block_cb, bp); | |
| 7374 | + return 0; | |
| 7375 | + default: | |
| 7376 | + return -EOPNOTSUPP; | |
| 7377 | + } | |
| 7333 | 7378 | } |
| 7334 | 7379 | |
| 7335 | 7380 | static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type, |
| 7336 | 7381 | void *type_data) |
| 7337 | 7382 | { |
| 7338 | 7383 | switch (type) { |
| 7339 | − case TC_SETUP_CLSFLOWER: | |
| 7340 | − return bnxt_setup_flower(dev, type_data); | |
| 7341 | − case TC_SETUP_MQPRIO: { | |
| 7384 | + case TC_SETUP_BLOCK: | |
| 7385 | + return bnxt_setup_tc_block(dev, type_data); | |
| 7386 | + case TC_SETUP_QDISC_MQPRIO: { | |
| 7342 | 7387 | struct tc_mqprio_qopt *mqprio = type_data; |
| 7343 | 7388 | |
| 7344 | 7389 | mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; |
| @@ -7725,7 +7770,7 @@ static const struct net_device_ops bnxt_netdev_ops = { · 380 unmodified lines | ||
| 7725 | 7770 | #endif |
| 7726 | 7771 | .ndo_udp_tunnel_add = bnxt_udp_tunnel_add, |
| 7727 | 7772 | .ndo_udp_tunnel_del = bnxt_udp_tunnel_del, |
| 7728 | − .ndo_xdp = bnxt_xdp, | |
| 7773 | + .ndo_bpf = bnxt_xdp, | |
| 7729 | 7774 | .ndo_bridge_getlink = bnxt_bridge_getlink, |
| 7730 | 7775 | .ndo_bridge_setlink = bnxt_bridge_setlink, |
| 7731 | 7776 | .ndo_get_phys_port_name = bnxt_get_phys_port_name |
| @@ -8064,10 +8109,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 332 unmodified lines | ||
| 8064 | 8109 | dev->features |= dev->hw_features | NETIF_F_HIGHDMA; |
| 8065 | 8110 | dev->priv_flags |= IFF_UNICAST_FLT; |
| 8066 | 8111 | |
| 8067 | − /* MTU range: 60 - 9500 */ | |
| 8068 | − dev->min_mtu = ETH_ZLEN; | |
| 8069 | − dev->max_mtu = BNXT_MAX_MTU; | |
| 8070 | − | |
| 8071 | 8112 | #ifdef CONFIG_BNXT_SRIOV |
| 8072 | 8113 | init_waitqueue_head(&bp->sriov_cfg_wait); |
| 8073 | 8114 | mutex_init(&bp->sriov_lock); |
| @@ -8115,6 +8156,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 41 unmodified lines | ||
| 8115 | 8156 | bnxt_ethtool_init(bp); |
| 8116 | 8157 | bnxt_dcb_init(bp); |
| 8117 | 8158 | |
| 8159 | + /* MTU range: 60 - FW defined max */ | |
| 8160 | + dev->min_mtu = ETH_ZLEN; | |
| 8161 | + dev->max_mtu = bp->max_mtu; | |
| 8162 | + | |
| 8118 | 8163 | rc = bnxt_probe_phy(bp); |
| 8119 | 8164 | if (rc) |
| 8120 | 8165 | goto init_err_pci_clean; |
| @@ -944,6 +944,22 @@ struct bnxt_test_info { · 943 unmodified lines | ||
| 944 | 944 | #define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 |
| 945 | 945 | #define BNXT_CAG_REG_BASE 0x300000 |
| 946 | 946 | |
| 947 | +struct bnxt_coal { | |
| 948 | + u16 coal_ticks; | |
| 949 | + u16 coal_ticks_irq; | |
| 950 | + u16 coal_bufs; | |
| 951 | + u16 coal_bufs_irq; | |
| 952 | + /* RING_IDLE enabled when coal ticks < idle_thresh */ | |
| 953 | + u16 idle_thresh; | |
| 954 | + u8 bufs_per_record; | |
| 955 | + u8 budget; | |
| 956 | +}; | |
| 957 | + | |
| 958 | +struct bnxt_tc_flow_stats { | |
| 959 | + u64 packets; | |
| 960 | + u64 bytes; | |
| 961 | +}; | |
| 962 | + | |
| 947 | 963 | struct bnxt_tc_info { |
| 948 | 964 | bool enabled; |
| 949 | 965 | |
| @@ -954,12 +970,29 @@ struct bnxt_tc_info { · 4 unmodified lines | ||
| 954 | 970 | /* hash table to store L2 keys of TC flows */ |
| 955 | 971 | struct rhashtable l2_table; |
| 956 | 972 | struct rhashtable_params l2_ht_params; |
| 973 | + /* hash table to store L2 keys for TC tunnel decap */ | |
| 974 | + struct rhashtable decap_l2_table; | |
| 975 | + struct rhashtable_params decap_l2_ht_params; | |
| 976 | + /* hash table to store tunnel decap entries */ | |
| 977 | + struct rhashtable decap_table; | |
| 978 | + struct rhashtable_params decap_ht_params; | |
| 979 | + /* hash table to store tunnel encap entries */ | |
| 980 | + struct rhashtable encap_table; | |
| 981 | + struct rhashtable_params encap_ht_params; | |
| 957 | 982 | |
| 958 | 983 | /* lock to atomically add/del an l2 node when a flow is |
| 959 | 984 | * added or deleted. |
| 960 | 985 | */ |
| 961 | 986 | struct mutex lock; |
| 962 | 987 | |
| 988 | + /* Fields used for batching stats query */ | |
| 989 | + struct rhashtable_iter iter; | |
| 990 | +#define BNXT_FLOW_STATS_BATCH_MAX 10 | |
| 991 | + struct bnxt_tc_stats_batch { | |
| 992 | + void *flow_node; | |
| 993 | + struct bnxt_tc_flow_stats hw_stats; | |
| 994 | + } stats_batch[BNXT_FLOW_STATS_BATCH_MAX]; | |
| 995 | + | |
| 963 | 996 | /* Stat counter mask (width) */ |
| 964 | 997 | u64 bytes_mask; |
| 965 | 998 | u64 packets_mask; |
| @@ -1013,6 +1046,7 @@ struct bnxt { · 47 unmodified lines | ||
| 1013 | 1046 | #define CHIP_NUM_5745X 0xd730 |
| 1014 | 1047 | |
| 1015 | 1048 | #define CHIP_NUM_58802 0xd802 |
| 1049 | +#define CHIP_NUM_58804 0xd804 | |
| 1016 | 1050 | #define CHIP_NUM_58808 0xd808 |
| 1017 | 1051 | |
| 1018 | 1052 | #define BNXT_CHIP_NUM_5730X(chip_num) \ |
| @@ -1048,6 +1082,7 @@ struct bnxt { · 29 unmodified lines | ||
| 1048 | 1082 | |
| 1049 | 1083 | #define BNXT_CHIP_NUM_588XX(chip_num) \ |
| 1050 | 1084 | ((chip_num) == CHIP_NUM_58802 || \ |
| 1085 | + (chip_num) == CHIP_NUM_58804 || \ | |
| 1051 | 1086 | (chip_num) == CHIP_NUM_58808) |
| 1052 | 1087 | |
| 1053 | 1088 | struct net_device *dev; |
| @@ -1170,6 +1205,7 @@ struct bnxt { · 116 unmodified lines | ||
| 1170 | 1205 | int nr_vnics; |
| 1171 | 1206 | u32 rss_hash_cfg; |
| 1172 | 1207 | |
| 1208 | + u16 max_mtu; | |
| 1173 | 1209 | u8 max_tc; |
| 1174 | 1210 | u8 max_lltc; /* lossless TCs */ |
| 1175 | 1211 | struct bnxt_queue_info q_info[BNXT_MAX_QUEUE]; |
| @@ -1232,14 +1268,8 @@ struct bnxt { · 56 unmodified lines | ||
| 1232 | 1268 | u8 port_count; |
| 1233 | 1269 | u16 br_mode; |
| 1234 | 1270 | |
| 1235 | − u16 rx_coal_ticks; | |
| 1236 | − u16 rx_coal_ticks_irq; | |
| 1237 | − u16 rx_coal_bufs; | |
| 1238 | − u16 rx_coal_bufs_irq; | |
| 1239 | − u16 tx_coal_ticks; | |
| 1240 | − u16 tx_coal_ticks_irq; | |
| 1241 | − u16 tx_coal_bufs; | |
| 1242 | − u16 tx_coal_bufs_irq; | |
| 1271 | + struct bnxt_coal rx_coal; | |
| 1272 | + struct bnxt_coal tx_coal; | |
| 1243 | 1273 | |
| 1244 | 1274 | #define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2) |
| 1245 | 1275 | |
| @@ -1265,6 +1295,7 @@ struct bnxt { · 19 unmodified lines | ||
| 1265 | 1295 | #define BNXT_GENEVE_ADD_PORT_SP_EVENT 12 |
| 1266 | 1296 | #define BNXT_GENEVE_DEL_PORT_SP_EVENT 13 |
| 1267 | 1297 | #define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 |
| 1298 | +#define BNXT_FLOW_STATS_SP_EVENT 15 | |
| 1268 | 1299 | |
| 1269 | 1300 | struct bnxt_pf_info pf; |
| 1270 | 1301 | #ifdef CONFIG_BNXT_SRIOV |
| @@ -1315,7 +1346,7 @@ struct bnxt { · 44 unmodified lines | ||
| 1315 | 1346 | enum devlink_eswitch_mode eswitch_mode; |
| 1316 | 1347 | struct bnxt_vf_rep **vf_reps; /* array of vf-rep ptrs */ |
| 1317 | 1348 | u16 *cfa_code_map; /* cfa_code -> vf_idx map */ |
| 1318 | − struct bnxt_tc_info tc_info; | |
| 1349 | + struct bnxt_tc_info *tc_info; | |
| 1319 | 1350 | }; |
| 1320 | 1351 | |
| 1321 | 1352 | #define BNXT_RX_STATS_OFFSET(counter) \ |
| @@ -0,0 +1,65 @@ | ||
| 1 | +/* Broadcom NetXtreme-C/E network driver. | |
| 2 | + * | |
| 3 | + * Copyright (c) 2017 Broadcom Limited | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License as published by | |
| 7 | + * the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/pci.h> | |
| 11 | +#include <linux/netdevice.h> | |
| 12 | +#include "bnxt_hsi.h" | |
| 13 | +#include "bnxt.h" | |
| 14 | +#include "bnxt_vfr.h" | |
| 15 | +#include "bnxt_devlink.h" | |
| 16 | + | |
| 17 | +static const struct devlink_ops bnxt_dl_ops = { | |
| 18 | +#ifdef CONFIG_BNXT_SRIOV | |
| 19 | + .eswitch_mode_set = bnxt_dl_eswitch_mode_set, | |
| 20 | + .eswitch_mode_get = bnxt_dl_eswitch_mode_get, | |
| 21 | +#endif /* CONFIG_BNXT_SRIOV */ | |
| 22 | +}; | |
| 23 | + | |
| 24 | +int bnxt_dl_register(struct bnxt *bp) | |
| 25 | +{ | |
| 26 | + struct devlink *dl; | |
| 27 | + int rc; | |
| 28 | + | |
| 29 | + if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) | |
| 30 | + return 0; | |
| 31 | + | |
| 32 | + if (bp->hwrm_spec_code < 0x10803) { | |
| 33 | + netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); | |
| 34 | + return -ENOTSUPP; | |
| 35 | + } | |
| 36 | + | |
| 37 | + dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); | |
| 38 | + if (!dl) { | |
| 39 | + netdev_warn(bp->dev, "devlink_alloc failed"); | |
| 40 | + return -ENOMEM; | |
| 41 | + } | |
| 42 | + | |
| 43 | + bnxt_link_bp_to_dl(bp, dl); | |
| 44 | + bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; | |
| 45 | + rc = devlink_register(dl, &bp->pdev->dev); | |
| 46 | + if (rc) { | |
| 47 | + bnxt_link_bp_to_dl(bp, NULL); | |
| 48 | + devlink_free(dl); | |
| 49 | + netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc); | |
| 50 | + return rc; | |
| 51 | + } | |
| 52 | + | |
| 53 | + return 0; | |
| 54 | +} | |
| 55 | + | |
| 56 | +void bnxt_dl_unregister(struct bnxt *bp) | |
| 57 | +{ | |
| 58 | + struct devlink *dl = bp->dl; | |
| 59 | + | |
| 60 | + if (!dl) | |
| 61 | + return; | |
| 62 | + | |
| 63 | + devlink_unregister(dl); | |
| 64 | + devlink_free(dl); | |
| 65 | +} | |
| @@ -0,0 +1,39 @@ | ||
| 1 | +/* Broadcom NetXtreme-C/E network driver. | |
| 2 | + * | |
| 3 | + * Copyright (c) 2017 Broadcom Limited | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License as published by | |
| 7 | + * the Free Software Foundation. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef BNXT_DEVLINK_H | |
| 11 | +#define BNXT_DEVLINK_H | |
| 12 | + | |
| 13 | +/* Struct to hold housekeeping info needed by devlink interface */ | |
| 14 | +struct bnxt_dl { | |
| 15 | + struct bnxt *bp; /* back ptr to the controlling dev */ | |
| 16 | +}; | |
| 17 | + | |
| 18 | +static inline struct bnxt *bnxt_get_bp_from_dl(struct devlink *dl) | |
| 19 | +{ | |
| 20 | + return ((struct bnxt_dl *)devlink_priv(dl))->bp; | |
| 21 | +} | |
| 22 | + | |
| 23 | +/* To clear devlink pointer from bp, pass NULL dl */ | |
| 24 | +static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) | |
| 25 | +{ | |
| 26 | + bp->dl = dl; | |
| 27 | + | |
| 28 | + /* add a back pointer in dl to bp */ | |
| 29 | + if (dl) { | |
| 30 | + struct bnxt_dl *bp_dl = devlink_priv(dl); | |
| 31 | + | |
| 32 | + bp_dl->bp = bp; | |
| 33 | + } | |
| 34 | +} | |
| 35 | + | |
| 36 | +int bnxt_dl_register(struct bnxt *bp); | |
| 37 | +void bnxt_dl_unregister(struct bnxt *bp); | |
| 38 | + | |
| 39 | +#endif /* BNXT_DEVLINK_H */ | |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #define FLASH_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200) |
| 27 | 27 | #define INSTALL_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200) |
| 28 | 28 | |
| 29 | −static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen); | |
| 30 | − | |
| 31 | 29 | static u32 bnxt_get_msglevel(struct net_device *dev) |
| 32 | 30 | { |
| 33 | 31 | struct bnxt *bp = netdev_priv(dev); |
| @@ -46,19 +44,24 @@ static int bnxt_get_coalesce(struct net_device *dev, · 12 unmodified lines | ||
| 46 | 44 | struct ethtool_coalesce *coal) |
| 47 | 45 | { |
| 48 | 46 | struct bnxt *bp = netdev_priv(dev); |
| 47 | + struct bnxt_coal *hw_coal; | |
| 48 | + u16 mult; | |
| 49 | 49 | |
| 50 | 50 | memset(coal, 0, sizeof(*coal)); |
| 51 | 51 | |
| 52 | − coal->rx_coalesce_usecs = bp->rx_coal_ticks; | |
| 53 | − /* 2 completion records per rx packet */ | |
| 54 | − coal->rx_max_coalesced_frames = bp->rx_coal_bufs / 2; | |
| 55 | − coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; | |
| 56 | − coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; | |
| 52 | + hw_coal = &bp->rx_coal; | |
| 53 | + mult = hw_coal->bufs_per_record; | |
| 54 | + coal->rx_coalesce_usecs = hw_coal->coal_ticks; | |
| 55 | + coal->rx_max_coalesced_frames = hw_coal->coal_bufs / mult; | |
| 56 | + coal->rx_coalesce_usecs_irq = hw_coal->coal_ticks_irq; | |
| 57 | + coal->rx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult; | |
| 57 | 58 | |
| 58 | − coal->tx_coalesce_usecs = bp->tx_coal_ticks; | |
| 59 | − coal->tx_max_coalesced_frames = bp->tx_coal_bufs; | |
| 60 | − coal->tx_coalesce_usecs_irq = bp->tx_coal_ticks_irq; | |
| 61 | − coal->tx_max_coalesced_frames_irq = bp->tx_coal_bufs_irq; | |
| 59 | + hw_coal = &bp->tx_coal; | |
| 60 | + mult = hw_coal->bufs_per_record; | |
| 61 | + coal->tx_coalesce_usecs = hw_coal->coal_ticks; | |
| 62 | + coal->tx_max_coalesced_frames = hw_coal->coal_bufs / mult; | |
| 63 | + coal->tx_coalesce_usecs_irq = hw_coal->coal_ticks_irq; | |
| 64 | + coal->tx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult; | |
| 62 | 65 | |
| 63 | 66 | coal->stats_block_coalesce_usecs = bp->stats_coal_ticks; |
| 64 | 67 | |
| @@ -70,18 +73,23 @@ static int bnxt_set_coalesce(struct net_device *dev, · 5 unmodified lines | ||
| 70 | 73 | { |
| 71 | 74 | struct bnxt *bp = netdev_priv(dev); |
| 72 | 75 | bool update_stats = false; |
| 76 | + struct bnxt_coal *hw_coal; | |
| 73 | 77 | int rc = 0; |
| 74 | − | |
| 75 | − bp->rx_coal_ticks = coal->rx_coalesce_usecs; | |
| 76 | − /* 2 completion records per rx packet */ | |
| 77 | − bp->rx_coal_bufs = coal->rx_max_coalesced_frames * 2; | |
| 78 | − bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; | |
| 79 | − bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; | |
| 80 | − | |
| 81 | − bp->tx_coal_ticks = coal->tx_coalesce_usecs; | |
| 82 | − bp->tx_coal_bufs = coal->tx_max_coalesced_frames; | |
| 83 | − bp->tx_coal_ticks_irq = coal->tx_coalesce_usecs_irq; | |
| 84 | − bp->tx_coal_bufs_irq = coal->tx_max_coalesced_frames_irq; | |
| 78 | + u16 mult; | |
| 79 | + | |
| 80 | + hw_coal = &bp->rx_coal; | |
| 81 | + mult = hw_coal->bufs_per_record; | |
| 82 | + hw_coal->coal_ticks = coal->rx_coalesce_usecs; | |
| 83 | + hw_coal->coal_bufs = coal->rx_max_coalesced_frames * mult; | |
| 84 | + hw_coal->coal_ticks_irq = coal->rx_coalesce_usecs_irq; | |
| 85 | + hw_coal->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * mult; | |
| 86 | + | |
| 87 | + hw_coal = &bp->tx_coal; | |
| 88 | + mult = hw_coal->bufs_per_record; | |
| 89 | + hw_coal->coal_ticks = coal->tx_coalesce_usecs; | |
| 90 | + hw_coal->coal_bufs = coal->tx_max_coalesced_frames * mult; | |
| 91 | + hw_coal->coal_ticks_irq = coal->tx_coalesce_usecs_irq; | |
| 92 | + hw_coal->coal_bufs_irq = coal->tx_max_coalesced_frames_irq * mult; | |
| 85 | 93 | |
| 86 | 94 | if (bp->stats_coal_ticks != coal->stats_block_coalesce_usecs) { |
| 87 | 95 | u32 stats_ticks = coal->stats_block_coalesce_usecs; |
| @@ -822,20 +830,10 @@ static void bnxt_get_drvinfo(struct net_device *dev, · 734 unmodified lines | ||
| 822 | 830 | struct ethtool_drvinfo *info) |
| 823 | 831 | { |
| 824 | 832 | struct bnxt *bp = netdev_priv(dev); |
| 825 | − char *pkglog; | |
| 826 | − char *pkgver = NULL; | |
| 827 | 833 | |
| 828 | − pkglog = kmalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL); | |
| 829 | − if (pkglog) | |
| 830 | − pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH); | |
| 831 | 834 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
| 832 | 835 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
| 833 | − if (pkgver && *pkgver != 0 && isdigit(*pkgver)) | |
| 834 | − snprintf(info->fw_version, sizeof(info->fw_version) - 1, | |
| 835 | − "%s pkg %s", bp->fw_ver_str, pkgver); | |
| 836 | − else | |
| 837 | − strlcpy(info->fw_version, bp->fw_ver_str, | |
| 838 | − sizeof(info->fw_version)); | |
| 836 | + strlcpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version)); | |
| 839 | 837 | strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); |
| 840 | 838 | info->n_stats = bnxt_get_num_stats(bp); |
| 841 | 839 | info->testinfo_len = bp->num_tests; |
| @@ -843,7 +841,6 @@ static void bnxt_get_drvinfo(struct net_device *dev, · 1 unmodified line | ||
| 843 | 841 | info->eedump_len = 0; |
| 844 | 842 | /* TODO CHIMP FW: reg dump details */ |
| 845 | 843 | info->regdump_len = 0; |
| 846 | − kfree(pkglog); | |
| 847 | 844 | } |
| 848 | 845 | |
| 849 | 846 | static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
| @@ -1350,7 +1347,6 @@ static int bnxt_firmware_reset(struct net_device *dev, · 500 unmodified lines | ||
| 1350 | 1347 | |
| 1351 | 1348 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_RESET, -1, -1); |
| 1352 | 1349 | |
| 1353 | − /* TODO: Support ASAP ChiMP self-reset (e.g. upon PF driver unload) */ | |
| 1354 | 1350 | /* TODO: Address self-reset of APE/KONG/BONO/TANG or ungraceful reset */ |
| 1355 | 1351 | /* (e.g. when firmware isn't already running) */ |
| 1356 | 1352 | switch (dir_type) { |
| @@ -1376,6 +1372,10 @@ static int bnxt_firmware_reset(struct net_device *dev, · 19 unmodified lines | ||
| 1376 | 1372 | case BNX_DIR_TYPE_BONO_PATCH: |
| 1377 | 1373 | req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_ROCE; |
| 1378 | 1374 | break; |
| 1375 | + case BNXT_FW_RESET_CHIP: | |
| 1376 | + req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP; | |
| 1377 | + req.selfrst_status = FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP; | |
| 1378 | + break; | |
| 1379 | 1379 | default: |
| 1380 | 1380 | return -EINVAL; |
| 1381 | 1381 | } |
| @@ -1773,6 +1773,9 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset, · 391 unmodified lines | ||
| 1773 | 1773 | dma_addr_t dma_handle; |
| 1774 | 1774 | struct hwrm_nvm_read_input req = {0}; |
| 1775 | 1775 | |
| 1776 | + if (!length) | |
| 1777 | + return -EINVAL; | |
| 1778 | + | |
| 1776 | 1779 | buf = dma_alloc_coherent(&bp->pdev->dev, length, &dma_handle, |
| 1777 | 1780 | GFP_KERNEL); |
| 1778 | 1781 | if (!buf) { |
| @@ -2495,13 +2498,59 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, · 716 unmodified lines | ||
| 2495 | 2498 | } |
| 2496 | 2499 | } |
| 2497 | 2500 | |
| 2501 | +static int bnxt_reset(struct net_device *dev, u32 *flags) | |
| 2502 | +{ | |
| 2503 | + struct bnxt *bp = netdev_priv(dev); | |
| 2504 | + int rc = 0; | |
| 2505 | + | |
| 2506 | + if (!BNXT_PF(bp)) { | |
| 2507 | + netdev_err(dev, "Reset is not supported from a VF\n"); | |
| 2508 | + return -EOPNOTSUPP; | |
| 2509 | + } | |
| 2510 | + | |
| 2511 | + if (pci_vfs_assigned(bp->pdev)) { | |
| 2512 | + netdev_err(dev, | |
| 2513 | + "Reset not allowed when VFs are assigned to VMs\n"); | |
| 2514 | + return -EBUSY; | |
| 2515 | + } | |
| 2516 | + | |
| 2517 | + if (*flags == ETH_RESET_ALL) { | |
| 2518 | + /* This feature is not supported in older firmware versions */ | |
| 2519 | + if (bp->hwrm_spec_code < 0x10803) | |
| 2520 | + return -EOPNOTSUPP; | |
| 2521 | + | |
| 2522 | + rc = bnxt_firmware_reset(dev, BNXT_FW_RESET_CHIP); | |
| 2523 | + if (!rc) | |
| 2524 | + netdev_info(dev, "Reset request successful. Reload driver to complete reset\n"); | |
| 2525 | + } else { | |
| 2526 | + rc = -EINVAL; | |
| 2527 | + } | |
| 2528 | + | |
| 2529 | + return rc; | |
| 2530 | +} | |
| 2531 | + | |
| 2498 | 2532 | void bnxt_ethtool_init(struct bnxt *bp) |
| 2499 | 2533 | { |
| 2500 | 2534 | struct hwrm_selftest_qlist_output *resp = bp->hwrm_cmd_resp_addr; |
| 2501 | 2535 | struct hwrm_selftest_qlist_input req = {0}; |
| 2502 | 2536 | struct bnxt_test_info *test_info; |
| 2537 | + struct net_device *dev = bp->dev; | |
| 2538 | + char *pkglog; | |
| 2503 | 2539 | int i, rc; |
| 2504 | 2540 | |
| 2541 | + pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL); | |
| 2542 | + if (pkglog) { | |
| 2543 | + char *pkgver; | |
| 2544 | + int len; | |
| 2545 | + | |
| 2546 | + pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH); | |
| 2547 | + if (pkgver && *pkgver != 0 && isdigit(*pkgver)) { | |
| 2548 | + len = strlen(bp->fw_ver_str); | |
| 2549 | + snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1, | |
| 2550 | + "/pkg %s", pkgver); | |
| 2551 | + } | |
| 2552 | + kfree(pkglog); | |
| 2553 | + } | |
| 2505 | 2554 | if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp)) |
| 2506 | 2555 | return; |
| 2507 | 2556 | |
| @@ -2592,4 +2641,5 @@ const struct ethtool_ops bnxt_ethtool_ops = { · 84 unmodified lines | ||
| 2592 | 2641 | .nway_reset = bnxt_nway_reset, |
| 2593 | 2642 | .set_phys_id = bnxt_set_phys_id, |
| 2594 | 2643 | .self_test = bnxt_self_test, |
| 2644 | + .reset = bnxt_reset, | |
| 2595 | 2645 | }; |
| @@ -34,6 +34,8 @@ struct bnxt_led_cfg { · 33 unmodified lines | ||
| 34 | 34 | #define BNXT_LED_DFLT_ENABLES(x) \ |
| 35 | 35 | cpu_to_le32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x))) |
| 36 | 36 | |
| 37 | +#define BNXT_FW_RESET_CHIP 0xffff | |
| 38 | + | |
| 37 | 39 | extern const struct ethtool_ops bnxt_ethtool_ops; |
| 38 | 40 | |
| 39 | 41 | u32 _bnxt_fw_to_ethtool_adv_spds(u16, u8); |
| @@ -11,21 +11,21 @@ · 10 unmodified lines | ||
| 11 | 11 | #ifndef BNXT_HSI_H |
| 12 | 12 | #define BNXT_HSI_H |
| 13 | 13 | |
| 14 | −/* HSI and HWRM Specification 1.8.1 */ | |
| 14 | +/* HSI and HWRM Specification 1.8.3 */ | |
| 15 | 15 | #define HWRM_VERSION_MAJOR 1 |
| 16 | 16 | #define HWRM_VERSION_MINOR 8 |
| 17 | −#define HWRM_VERSION_UPDATE 1 | |
| 17 | +#define HWRM_VERSION_UPDATE 3 | |
| 18 | 18 | |
| 19 | −#define HWRM_VERSION_RSVD 4 /* non-zero means beta version */ | |
| 19 | +#define HWRM_VERSION_RSVD 1 /* non-zero means beta version */ | |
| 20 | 20 | |
| 21 | −#define HWRM_VERSION_STR "1.8.1.4" | |
| 21 | +#define HWRM_VERSION_STR "1.8.3.1" | |
| 22 | 22 | /* |
| 23 | 23 | * Following is the signature for HWRM message field that indicates not |
| 24 | 24 | * applicable (All F's). Need to cast it the size of the field if needed. |
| 25 | 25 | */ |
| 26 | 26 | #define HWRM_NA_SIGNATURE ((__le32)(-1)) |
| 27 | 27 | #define HWRM_MAX_REQ_LEN (128) /* hwrm_func_buf_rgtr */ |
| 28 | −#define HWRM_MAX_RESP_LEN (248) /* hwrm_selftest_qlist */ | |
| 28 | +#define HWRM_MAX_RESP_LEN (280) /* hwrm_selftest_qlist */ | |
| 29 | 29 | #define HW_HASH_INDEX_SIZE 0x80 /* 7 bit indirection table index. */ |
| 30 | 30 | #define HW_HASH_KEY_SIZE 40 |
| 31 | 31 | #define HWRM_RESP_VALID_KEY 1 /* valid key for HWRM response */ |
| @@ -111,6 +111,7 @@ struct hwrm_async_event_cmpl { · 79 unmodified lines | ||
| 111 | 111 | #define ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE 0x31UL |
| 112 | 112 | #define ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE 0x32UL |
| 113 | 113 | #define ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE 0x33UL |
| 114 | + #define ASYNC_EVENT_CMPL_EVENT_ID_LLFC_PFC_CHANGE 0x34UL | |
| 114 | 115 | #define ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR 0xffUL |
| 115 | 116 | __le32 event_data2; |
| 116 | 117 | u8 opaque_v; |
| @@ -835,8 +836,7 @@ struct hwrm_func_qcfg_output { · 718 unmodified lines | ||
| 835 | 836 | u8 port_pf_cnt; |
| 836 | 837 | #define FUNC_QCFG_RESP_PORT_PF_CNT_UNAVAIL 0x0UL |
| 837 | 838 | __le16 dflt_vnic_id; |
| 838 | − u8 unused_0; | |
| 839 | − u8 unused_1; | |
| 839 | + __le16 max_mtu_configured; | |
| 840 | 840 | __le32 min_bw; |
| 841 | 841 | #define FUNC_QCFG_RESP_MIN_BW_BW_VALUE_MASK 0xfffffffUL |
| 842 | 842 | #define FUNC_QCFG_RESP_MIN_BW_BW_VALUE_SFT 0 |
| @@ -873,12 +873,12 @@ struct hwrm_func_qcfg_output { · 30 unmodified lines | ||
| 873 | 873 | #define FUNC_QCFG_RESP_EVB_MODE_NO_EVB 0x0UL |
| 874 | 874 | #define FUNC_QCFG_RESP_EVB_MODE_VEB 0x1UL |
| 875 | 875 | #define FUNC_QCFG_RESP_EVB_MODE_VEPA 0x2UL |
| 876 | − u8 unused_2; | |
| 876 | + u8 unused_0; | |
| 877 | 877 | __le16 alloc_vfs; |
| 878 | 878 | __le32 alloc_mcast_filters; |
| 879 | 879 | __le32 alloc_hw_ring_grps; |
| 880 | 880 | __le16 alloc_sp_tx_rings; |
| 881 | − u8 unused_3; | |
| 881 | + u8 unused_1; | |
| 882 | 882 | u8 valid; |
| 883 | 883 | }; |
| 884 | 884 | |
| @@ -3407,6 +3407,7 @@ struct hwrm_vnic_cfg_input { · 2522 unmodified lines | ||
| 3407 | 3407 | #define VNIC_CFG_REQ_FLAGS_ROCE_DUAL_VNIC_MODE 0x8UL |
| 3408 | 3408 | #define VNIC_CFG_REQ_FLAGS_ROCE_ONLY_VNIC_MODE 0x10UL |
| 3409 | 3409 | #define VNIC_CFG_REQ_FLAGS_RSS_DFLT_CR_MODE 0x20UL |
| 3410 | + #define VNIC_CFG_REQ_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_MODE 0x40UL | |
| 3410 | 3411 | __le32 enables; |
| 3411 | 3412 | #define VNIC_CFG_REQ_ENABLES_DFLT_RING_GRP 0x1UL |
| 3412 | 3413 | #define VNIC_CFG_REQ_ENABLES_RSS_RULE 0x2UL |
| @@ -3463,6 +3464,7 @@ struct hwrm_vnic_qcaps_output { · 50 unmodified lines | ||
| 3463 | 3464 | #define VNIC_QCAPS_RESP_FLAGS_ROCE_DUAL_VNIC_CAP 0x8UL |
| 3464 | 3465 | #define VNIC_QCAPS_RESP_FLAGS_ROCE_ONLY_VNIC_CAP 0x10UL |
| 3465 | 3466 | #define VNIC_QCAPS_RESP_FLAGS_RSS_DFLT_CR_CAP 0x20UL |
| 3467 | + #define VNIC_QCAPS_RESP_FLAGS_ROCE_MIRROING_CAPABLE_VNIC_CAP 0x40UL | |
| 3466 | 3468 | __le32 unused_2; |
| 3467 | 3469 | u8 unused_3; |
| 3468 | 3470 | u8 unused_4; |
| @@ -3994,6 +3996,7 @@ struct hwrm_cfa_l2_filter_alloc_input { · 525 unmodified lines | ||
| 3994 | 3996 | #define CFA_L2_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL |
| 3995 | 3997 | #define CFA_L2_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL |
| 3996 | 3998 | #define CFA_L2_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL |
| 3999 | + #define CFA_L2_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 3997 | 4000 | #define CFA_L2_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL |
| 3998 | 4001 | u8 unused_7; |
| 3999 | 4002 | __le16 dst_id; |
| @@ -4122,6 +4125,14 @@ struct hwrm_cfa_l2_set_rx_mask_output { · 122 unmodified lines | ||
| 4122 | 4125 | u8 valid; |
| 4123 | 4126 | }; |
| 4124 | 4127 | |
| 4128 | +/* Command specific Error Codes (8 bytes) */ | |
| 4129 | +struct hwrm_cfa_l2_set_rx_mask_cmd_err { | |
| 4130 | + u8 code; | |
| 4131 | + #define CFA_L2_SET_RX_MASK_CMD_ERR_CODE_UNKNOWN 0x0UL | |
| 4132 | + #define CFA_L2_SET_RX_MASK_CMD_ERR_CODE_NTUPLE_FILTER_CONFLICT_ERR 0x1UL | |
| 4133 | + u8 unused_0[7]; | |
| 4134 | +}; | |
| 4135 | + | |
| 4125 | 4136 | /* hwrm_cfa_tunnel_filter_alloc */ |
| 4126 | 4137 | /* Input (88 bytes) */ |
| 4127 | 4138 | struct hwrm_cfa_tunnel_filter_alloc_input { |
| @@ -4161,6 +4172,7 @@ struct hwrm_cfa_tunnel_filter_alloc_input { · 33 unmodified lines | ||
| 4161 | 4172 | #define CFA_TUNNEL_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL |
| 4162 | 4173 | #define CFA_TUNNEL_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL |
| 4163 | 4174 | #define CFA_TUNNEL_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL |
| 4175 | + #define CFA_TUNNEL_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4164 | 4176 | #define CFA_TUNNEL_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL |
| 4165 | 4177 | u8 unused_0; |
| 4166 | 4178 | __le32 vni; |
| @@ -4323,6 +4335,7 @@ struct hwrm_cfa_ntuple_filter_alloc_input { · 156 unmodified lines | ||
| 4323 | 4335 | #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL |
| 4324 | 4336 | #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL |
| 4325 | 4337 | #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL |
| 4338 | + #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4326 | 4339 | #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL |
| 4327 | 4340 | u8 pri_hint; |
| 4328 | 4341 | #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_NO_PREFER 0x0UL |
| @@ -4355,6 +4368,14 @@ struct hwrm_cfa_ntuple_filter_alloc_output { · 26 unmodified lines | ||
| 4355 | 4368 | u8 valid; |
| 4356 | 4369 | }; |
| 4357 | 4370 | |
| 4371 | +/* Command specific Error Codes (8 bytes) */ | |
| 4372 | +struct hwrm_cfa_ntuple_filter_alloc_cmd_err { | |
| 4373 | + u8 code; | |
| 4374 | + #define CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_UNKNOWN 0x0UL | |
| 4375 | + #define CFA_NTUPLE_FILTER_ALLOC_CMD_ERR_CODE_RX_MASK_VLAN_CONFLICT_ERR 0x1UL | |
| 4376 | + u8 unused_0[7]; | |
| 4377 | +}; | |
| 4378 | + | |
| 4358 | 4379 | /* hwrm_cfa_ntuple_filter_free */ |
| 4359 | 4380 | /* Input (24 bytes) */ |
| 4360 | 4381 | struct hwrm_cfa_ntuple_filter_free_input { |
| @@ -4413,6 +4434,116 @@ struct hwrm_cfa_ntuple_filter_cfg_output { · 52 unmodified lines | ||
| 4413 | 4434 | u8 valid; |
| 4414 | 4435 | }; |
| 4415 | 4436 | |
| 4437 | +/* hwrm_cfa_decap_filter_alloc */ | |
| 4438 | +/* Input (104 bytes) */ | |
| 4439 | +struct hwrm_cfa_decap_filter_alloc_input { | |
| 4440 | + __le16 req_type; | |
| 4441 | + __le16 cmpl_ring; | |
| 4442 | + __le16 seq_id; | |
| 4443 | + __le16 target_id; | |
| 4444 | + __le64 resp_addr; | |
| 4445 | + __le32 flags; | |
| 4446 | + #define CFA_DECAP_FILTER_ALLOC_REQ_FLAGS_OVS_TUNNEL 0x1UL | |
| 4447 | + __le32 enables; | |
| 4448 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE 0x1UL | |
| 4449 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_ID 0x2UL | |
| 4450 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR 0x4UL | |
| 4451 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR 0x8UL | |
| 4452 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_OVLAN_VID 0x10UL | |
| 4453 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IVLAN_VID 0x20UL | |
| 4454 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_T_OVLAN_VID 0x40UL | |
| 4455 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_T_IVLAN_VID 0x80UL | |
| 4456 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE 0x100UL | |
| 4457 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR 0x200UL | |
| 4458 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR 0x400UL | |
| 4459 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE 0x800UL | |
| 4460 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL 0x1000UL | |
| 4461 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_PORT 0x2000UL | |
| 4462 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_PORT 0x4000UL | |
| 4463 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_ID 0x8000UL | |
| 4464 | + #define CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_MIRROR_VNIC_ID 0x10000UL | |
| 4465 | + __be32 tunnel_id; | |
| 4466 | + u8 tunnel_type; | |
| 4467 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_NONTUNNEL 0x0UL | |
| 4468 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL | |
| 4469 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE 0x2UL | |
| 4470 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_L2GRE 0x3UL | |
| 4471 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPIP 0x4UL | |
| 4472 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL | |
| 4473 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL | |
| 4474 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL | |
| 4475 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL | |
| 4476 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4477 | + #define CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL | |
| 4478 | + u8 unused_0; | |
| 4479 | + __le16 unused_1; | |
| 4480 | + u8 src_macaddr[6]; | |
| 4481 | + u8 unused_2; | |
| 4482 | + u8 unused_3; | |
| 4483 | + u8 dst_macaddr[6]; | |
| 4484 | + __be16 ovlan_vid; | |
| 4485 | + __be16 ivlan_vid; | |
| 4486 | + __be16 t_ovlan_vid; | |
| 4487 | + __be16 t_ivlan_vid; | |
| 4488 | + __be16 ethertype; | |
| 4489 | + u8 ip_addr_type; | |
| 4490 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_UNKNOWN 0x0UL | |
| 4491 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4 0x4UL | |
| 4492 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6 0x6UL | |
| 4493 | + u8 ip_protocol; | |
| 4494 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_UNKNOWN 0x0UL | |
| 4495 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_TCP 0x6UL | |
| 4496 | + #define CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP 0x11UL | |
| 4497 | + u8 unused_4; | |
| 4498 | + u8 unused_5; | |
| 4499 | + u8 unused_6[3]; | |
| 4500 | + u8 unused_7; | |
| 4501 | + __be32 src_ipaddr[4]; | |
| 4502 | + __be32 dst_ipaddr[4]; | |
| 4503 | + __be16 src_port; | |
| 4504 | + __be16 dst_port; | |
| 4505 | + __le16 dst_id; | |
| 4506 | + __le16 l2_ctxt_ref_id; | |
| 4507 | +}; | |
| 4508 | + | |
| 4509 | +/* Output (16 bytes) */ | |
| 4510 | +struct hwrm_cfa_decap_filter_alloc_output { | |
| 4511 | + __le16 error_code; | |
| 4512 | + __le16 req_type; | |
| 4513 | + __le16 seq_id; | |
| 4514 | + __le16 resp_len; | |
| 4515 | + __le32 decap_filter_id; | |
| 4516 | + u8 unused_0; | |
| 4517 | + u8 unused_1; | |
| 4518 | + u8 unused_2; | |
| 4519 | + u8 valid; | |
| 4520 | +}; | |
| 4521 | + | |
| 4522 | +/* hwrm_cfa_decap_filter_free */ | |
| 4523 | +/* Input (24 bytes) */ | |
| 4524 | +struct hwrm_cfa_decap_filter_free_input { | |
| 4525 | + __le16 req_type; | |
| 4526 | + __le16 cmpl_ring; | |
| 4527 | + __le16 seq_id; | |
| 4528 | + __le16 target_id; | |
| 4529 | + __le64 resp_addr; | |
| 4530 | + __le32 decap_filter_id; | |
| 4531 | + __le32 unused_0; | |
| 4532 | +}; | |
| 4533 | + | |
| 4534 | +/* Output (16 bytes) */ | |
| 4535 | +struct hwrm_cfa_decap_filter_free_output { | |
| 4536 | + __le16 error_code; | |
| 4537 | + __le16 req_type; | |
| 4538 | + __le16 seq_id; | |
| 4539 | + __le16 resp_len; | |
| 4540 | + __le32 unused_0; | |
| 4541 | + u8 unused_1; | |
| 4542 | + u8 unused_2; | |
| 4543 | + u8 unused_3; | |
| 4544 | + u8 valid; | |
| 4545 | +}; | |
| 4546 | + | |
| 4416 | 4547 | /* hwrm_cfa_flow_alloc */ |
| 4417 | 4548 | /* Input (128 bytes) */ |
| 4418 | 4549 | struct hwrm_cfa_flow_alloc_input { |
| @@ -4634,6 +4765,7 @@ struct hwrm_tunnel_dst_port_query_input { · 215 unmodified lines | ||
| 4634 | 4765 | u8 tunnel_type; |
| 4635 | 4766 | #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN 0x1UL |
| 4636 | 4767 | #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_GENEVE 0x5UL |
| 4768 | + #define TUNNEL_DST_PORT_QUERY_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4637 | 4769 | u8 unused_0[7]; |
| 4638 | 4770 | }; |
| 4639 | 4771 | |
| @@ -4662,9 +4794,10 @@ struct hwrm_tunnel_dst_port_alloc_input { · 22 unmodified lines | ||
| 4662 | 4794 | u8 tunnel_type; |
| 4663 | 4795 | #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL |
| 4664 | 4796 | #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL |
| 4797 | + #define TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4665 | 4798 | u8 unused_0; |
| 4666 | 4799 | __be16 tunnel_dst_port_val; |
| 4667 | − __le32 unused_1; | |
| 4800 | + __be32 unused_1; | |
| 4668 | 4801 | }; |
| 4669 | 4802 | |
| 4670 | 4803 | /* Output (16 bytes) */ |
| @@ -4693,6 +4826,7 @@ struct hwrm_tunnel_dst_port_free_input { · 22 unmodified lines | ||
| 4693 | 4826 | u8 tunnel_type; |
| 4694 | 4827 | #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN 0x1UL |
| 4695 | 4828 | #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE 0x5UL |
| 4829 | + #define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL | |
| 4696 | 4830 | u8 unused_0; |
| 4697 | 4831 | __le16 tunnel_dst_port_id; |
| 4698 | 4832 | __le32 unused_1; |
| @@ -4848,6 +4982,8 @@ struct hwrm_fw_reset_input { · 149 unmodified lines | ||
| 4848 | 4982 | #define FW_RESET_REQ_EMBEDDED_PROC_TYPE_NETCTRL 0x2UL |
| 4849 | 4983 | #define FW_RESET_REQ_EMBEDDED_PROC_TYPE_ROCE 0x3UL |
| 4850 | 4984 | #define FW_RESET_REQ_EMBEDDED_PROC_TYPE_HOST 0x4UL |
| 4985 | + #define FW_RESET_REQ_EMBEDDED_PROC_TYPE_AP 0x5UL | |
| 4986 | + #define FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP 0x6UL | |
| 4851 | 4987 | u8 selfrst_status; |
| 4852 | 4988 | #define FW_RESET_REQ_SELFRST_STATUS_SELFRSTNONE 0x0UL |
| 4853 | 4989 | #define FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP 0x1UL |
| @@ -4888,6 +5024,8 @@ struct hwrm_fw_qstatus_input { · 34 unmodified lines | ||
| 4888 | 5024 | #define FW_QSTATUS_REQ_EMBEDDED_PROC_TYPE_NETCTRL 0x2UL |
| 4889 | 5025 | #define FW_QSTATUS_REQ_EMBEDDED_PROC_TYPE_ROCE 0x3UL |
| 4890 | 5026 | #define FW_QSTATUS_REQ_EMBEDDED_PROC_TYPE_HOST 0x4UL |
| 5027 | + #define FW_QSTATUS_REQ_EMBEDDED_PROC_TYPE_AP 0x5UL | |
| 5028 | + #define FW_QSTATUS_REQ_EMBEDDED_PROC_TYPE_CHIP 0x6UL | |
| 4891 | 5029 | u8 unused_0[7]; |
| 4892 | 5030 | }; |
| 4893 | 5031 | |
| @@ -5324,6 +5462,32 @@ struct hwrm_wol_reason_qcfg_output { · 430 unmodified lines | ||
| 5324 | 5462 | u8 valid; |
| 5325 | 5463 | }; |
| 5326 | 5464 | |
| 5465 | +/* hwrm_dbg_read_direct */ | |
| 5466 | +/* Input (32 bytes) */ | |
| 5467 | +struct hwrm_dbg_read_direct_input { | |
| 5468 | + __le16 req_type; | |
| 5469 | + __le16 cmpl_ring; | |
| 5470 | + __le16 seq_id; | |
| 5471 | + __le16 target_id; | |
| 5472 | + __le64 resp_addr; | |
| 5473 | + __le64 host_dest_addr; | |
| 5474 | + __le32 read_addr; | |
| 5475 | + __le32 read_len32; | |
| 5476 | +}; | |
| 5477 | + | |
| 5478 | +/* Output (16 bytes) */ | |
| 5479 | +struct hwrm_dbg_read_direct_output { | |
| 5480 | + __le16 error_code; | |
| 5481 | + __le16 req_type; | |
| 5482 | + __le16 seq_id; | |
| 5483 | + __le16 resp_len; | |
| 5484 | + __le32 unused_0; | |
| 5485 | + u8 unused_1; | |
| 5486 | + u8 unused_2; | |
| 5487 | + u8 unused_3; | |
| 5488 | + u8 valid; | |
| 5489 | +}; | |
| 5490 | + | |
| 5327 | 5491 | /* hwrm_nvm_read */ |
| 5328 | 5492 | /* Input (40 bytes) */ |
| 5329 | 5493 | struct hwrm_nvm_read_input { |
| @@ -5676,6 +5840,105 @@ struct hwrm_nvm_install_update_cmd_err { · 346 unmodified lines | ||
| 5676 | 5840 | u8 unused_0[7]; |
| 5677 | 5841 | }; |
| 5678 | 5842 | |
| 5843 | +/* hwrm_nvm_get_variable */ | |
| 5844 | +/* Input (40 bytes) */ | |
| 5845 | +struct hwrm_nvm_get_variable_input { | |
| 5846 | + __le16 req_type; | |
| 5847 | + __le16 cmpl_ring; | |
| 5848 | + __le16 seq_id; | |
| 5849 | + __le16 target_id; | |
| 5850 | + __le64 resp_addr; | |
| 5851 | + __le64 dest_data_addr; | |
| 5852 | + __le16 data_len; | |
| 5853 | + __le16 option_num; | |
| 5854 | + #define NVM_GET_VARIABLE_REQ_OPTION_NUM_RSVD_0 0x0UL | |
| 5855 | + #define NVM_GET_VARIABLE_REQ_OPTION_NUM_RSVD_FFFF 0xffffUL | |
| 5856 | + __le16 dimensions; | |
| 5857 | + __le16 index_0; | |
| 5858 | + __le16 index_1; | |
| 5859 | + __le16 index_2; | |
| 5860 | + __le16 index_3; | |
| 5861 | + u8 flags; | |
| 5862 | + #define NVM_GET_VARIABLE_REQ_FLAGS_FACTORY_DFLT 0x1UL | |
| 5863 | + u8 unused_0; | |
| 5864 | +}; | |
| 5865 | + | |
| 5866 | +/* Output (16 bytes) */ | |
| 5867 | +struct hwrm_nvm_get_variable_output { | |
| 5868 | + __le16 error_code; | |
| 5869 | + __le16 req_type; | |
| 5870 | + __le16 seq_id; | |
| 5871 | + __le16 resp_len; | |
| 5872 | + __le16 data_len; | |
| 5873 | + __le16 option_num; | |
| 5874 | + #define NVM_GET_VARIABLE_RESP_OPTION_NUM_RSVD_0 0x0UL | |
| 5875 | + #define NVM_GET_VARIABLE_RESP_OPTION_NUM_RSVD_FFFF 0xffffUL | |
| 5876 | + u8 unused_0; | |
| 5877 | + u8 unused_1; | |
| 5878 | + u8 unused_2; | |
| 5879 | + u8 valid; | |
| 5880 | +}; | |
| 5881 | + | |
| 5882 | +/* Command specific Error Codes (8 bytes) */ | |
| 5883 | +struct hwrm_nvm_get_variable_cmd_err { | |
| 5884 | + u8 code; | |
| 5885 | + #define NVM_GET_VARIABLE_CMD_ERR_CODE_UNKNOWN 0x0UL | |
| 5886 | + #define NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST 0x1UL | |
| 5887 | + #define NVM_GET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR 0x2UL | |
| 5888 | + #define NVM_GET_VARIABLE_CMD_ERR_CODE_LEN_TOO_SHORT 0x3UL | |
| 5889 | + u8 unused_0[7]; | |
| 5890 | +}; | |
| 5891 | + | |
| 5892 | +/* hwrm_nvm_set_variable */ | |
| 5893 | +/* Input (40 bytes) */ | |
| 5894 | +struct hwrm_nvm_set_variable_input { | |
| 5895 | + __le16 req_type; | |
| 5896 | + __le16 cmpl_ring; | |
| 5897 | + __le16 seq_id; | |
| 5898 | + __le16 target_id; | |
| 5899 | + __le64 resp_addr; | |
| 5900 | + __le64 src_data_addr; | |
| 5901 | + __le16 data_len; | |
| 5902 | + __le16 option_num; | |
| 5903 | + #define NVM_SET_VARIABLE_REQ_OPTION_NUM_RSVD_0 0x0UL | |
| 5904 | + #define NVM_SET_VARIABLE_REQ_OPTION_NUM_RSVD_FFFF 0xffffUL | |
| 5905 | + __le16 dimensions; | |
| 5906 | + __le16 index_0; | |
| 5907 | + __le16 index_1; | |
| 5908 | + __le16 index_2; | |
| 5909 | + __le16 index_3; | |
| 5910 | + u8 flags; | |
| 5911 | + #define NVM_SET_VARIABLE_REQ_FLAGS_FORCE_FLUSH 0x1UL | |
| 5912 | + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_MASK 0xeUL | |
| 5913 | + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_SFT 1 | |
| 5914 | + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_NONE (0x0UL << 1) | |
| 5915 | + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_HMAC_SHA1 (0x1UL << 1) | |
| 5916 | + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_LAST NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_HMAC_SHA1 | |
| 5917 | + u8 unused_0; | |
| 5918 | +}; | |
| 5919 | + | |
| 5920 | +/* Output (16 bytes) */ | |
| 5921 | +struct hwrm_nvm_set_variable_output { | |
| 5922 | + __le16 error_code; | |
| 5923 | + __le16 req_type; | |
| 5924 | + __le16 seq_id; | |
| 5925 | + __le16 resp_len; | |
| 5926 | + __le32 unused_0; | |
| 5927 | + u8 unused_1; | |
| 5928 | + u8 unused_2; | |
| 5929 | + u8 unused_3; | |
| 5930 | + u8 valid; | |
| 5931 | +}; | |
| 5932 | + | |
| 5933 | +/* Command specific Error Codes (8 bytes) */ | |
| 5934 | +struct hwrm_nvm_set_variable_cmd_err { | |
| 5935 | + u8 code; | |
| 5936 | + #define NVM_SET_VARIABLE_CMD_ERR_CODE_UNKNOWN 0x0UL | |
| 5937 | + #define NVM_SET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST 0x1UL | |
| 5938 | + #define NVM_SET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR 0x2UL | |
| 5939 | + u8 unused_0[7]; | |
| 5940 | +}; | |
| 5941 | + | |
| 5679 | 5942 | /* hwrm_selftest_qlist */ |
| 5680 | 5943 | /* Input (16 bytes) */ |
| 5681 | 5944 | struct hwrm_selftest_qlist_input { |
| @@ -5686,7 +5949,7 @@ struct hwrm_selftest_qlist_input { · 4 unmodified lines | ||
| 5686 | 5949 | __le64 resp_addr; |
| 5687 | 5950 | }; |
| 5688 | 5951 | |
| 5689 | −/* Output (248 bytes) */ | |
| 5952 | +/* Output (280 bytes) */ | |
| 5690 | 5953 | struct hwrm_selftest_qlist_output { |
| 5691 | 5954 | __le16 error_code; |
| 5692 | 5955 | __le16 req_type; |
| @@ -5698,15 +5961,15 @@ struct hwrm_selftest_qlist_output { · 5 unmodified lines | ||
| 5698 | 5961 | #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_LINK_TEST 0x2UL |
| 5699 | 5962 | #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_REGISTER_TEST 0x4UL |
| 5700 | 5963 | #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_MEMORY_TEST 0x8UL |
| 5701 | − #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_PCIE_EYE_TEST 0x10UL | |
| 5702 | − #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_ETHERNET_EYE_TEST 0x20UL | |
| 5964 | + #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_PCIE_SERDES_TEST 0x10UL | |
| 5965 | + #define SELFTEST_QLIST_RESP_AVAILABLE_TESTS_ETHERNET_SERDES_TEST 0x20UL | |
| 5703 | 5966 | u8 offline_tests; |
| 5704 | 5967 | #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_NVM_TEST 0x1UL |
| 5705 | 5968 | #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_LINK_TEST 0x2UL |
| 5706 | 5969 | #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_REGISTER_TEST 0x4UL |
| 5707 | 5970 | #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_MEMORY_TEST 0x8UL |
| 5708 | − #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_PCIE_EYE_TEST 0x10UL | |
| 5709 | − #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_ETHERNET_EYE_TEST 0x20UL | |
| 5971 | + #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_PCIE_SERDES_TEST 0x10UL | |
| 5972 | + #define SELFTEST_QLIST_RESP_OFFLINE_TESTS_ETHERNET_SERDES_TEST 0x20UL | |
| 5710 | 5973 | u8 unused_0; |
| 5711 | 5974 | __le16 test_timeout; |
| 5712 | 5975 | u8 unused_1; |
| @@ -5719,6 +5982,11 @@ struct hwrm_selftest_qlist_output { · 6 unmodified lines | ||
| 5719 | 5982 | char test5_name[32]; |
| 5720 | 5983 | char test6_name[32]; |
| 5721 | 5984 | char test7_name[32]; |
| 5985 | + __le32 unused_3; | |
| 5986 | + u8 unused_4; | |
| 5987 | + u8 unused_5; | |
| 5988 | + u8 unused_6; | |
| 5989 | + u8 valid; | |
| 5722 | 5990 | }; |
| 5723 | 5991 | |
| 5724 | 5992 | /* hwrm_selftest_exec */ |
| @@ -5734,8 +6002,8 @@ struct hwrm_selftest_exec_input { · 9 unmodified lines | ||
| 5734 | 6002 | #define SELFTEST_EXEC_REQ_FLAGS_LINK_TEST 0x2UL |
| 5735 | 6003 | #define SELFTEST_EXEC_REQ_FLAGS_REGISTER_TEST 0x4UL |
| 5736 | 6004 | #define SELFTEST_EXEC_REQ_FLAGS_MEMORY_TEST 0x8UL |
| 5737 | − #define SELFTEST_EXEC_REQ_FLAGS_PCIE_EYE_TEST 0x10UL | |
| 5738 | − #define SELFTEST_EXEC_REQ_FLAGS_ETHERNET_EYE_TEST 0x20UL | |
| 6005 | + #define SELFTEST_EXEC_REQ_FLAGS_PCIE_SERDES_TEST 0x10UL | |
| 6006 | + #define SELFTEST_EXEC_REQ_FLAGS_ETHERNET_SERDES_TEST 0x20UL | |
| 5739 | 6007 | u8 unused_0[7]; |
| 5740 | 6008 | }; |
| 5741 | 6009 | |
| @@ -5750,16 +6018,21 @@ struct hwrm_selftest_exec_output { · 8 unmodified lines | ||
| 5750 | 6018 | #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_LINK_TEST 0x2UL |
| 5751 | 6019 | #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_REGISTER_TEST 0x4UL |
| 5752 | 6020 | #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_MEMORY_TEST 0x8UL |
| 5753 | − #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_PCIE_EYE_TEST 0x10UL | |
| 5754 | − #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_ETHERNET_EYE_TEST 0x20UL | |
| 6021 | + #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_PCIE_SERDES_TEST 0x10UL | |
| 6022 | + #define SELFTEST_EXEC_RESP_REQUESTED_TESTS_ETHERNET_SERDES_TEST 0x20UL | |
| 5755 | 6023 | u8 test_success; |
| 5756 | 6024 | #define SELFTEST_EXEC_RESP_TEST_SUCCESS_NVM_TEST 0x1UL |
| 5757 | 6025 | #define SELFTEST_EXEC_RESP_TEST_SUCCESS_LINK_TEST 0x2UL |
| 5758 | 6026 | #define SELFTEST_EXEC_RESP_TEST_SUCCESS_REGISTER_TEST 0x4UL |
| 5759 | 6027 | #define SELFTEST_EXEC_RESP_TEST_SUCCESS_MEMORY_TEST 0x8UL |
| 5760 | − #define SELFTEST_EXEC_RESP_TEST_SUCCESS_PCIE_EYE_TEST 0x10UL | |
| 5761 | − #define SELFTEST_EXEC_RESP_TEST_SUCCESS_ETHERNET_EYE_TEST 0x20UL | |
| 5762 | − __le16 unused_0[3]; | |
| 6028 | + #define SELFTEST_EXEC_RESP_TEST_SUCCESS_PCIE_SERDES_TEST 0x10UL | |
| 6029 | + #define SELFTEST_EXEC_RESP_TEST_SUCCESS_ETHERNET_SERDES_TEST 0x20UL | |
| 6030 | + u8 unused_0; | |
| 6031 | + u8 unused_1; | |
| 6032 | + u8 unused_2; | |
| 6033 | + u8 unused_3; | |
| 6034 | + u8 unused_4; | |
| 6035 | + u8 valid; | |
| 5763 | 6036 | }; |
| 5764 | 6037 | |
| 5765 | 6038 | /* hwrm_selftest_irq */ |
| @@ -5772,12 +6045,50 @@ struct hwrm_selftest_irq_input { · 6 unmodified lines | ||
| 5772 | 6045 | __le64 resp_addr; |
| 5773 | 6046 | }; |
| 5774 | 6047 | |
| 5775 | −/* Output (8 bytes) */ | |
| 6048 | +/* Output (16 bytes) */ | |
| 5776 | 6049 | struct hwrm_selftest_irq_output { |
| 5777 | 6050 | __le16 error_code; |
| 5778 | 6051 | __le16 req_type; |
| 5779 | 6052 | __le16 seq_id; |
| 5780 | 6053 | __le16 resp_len; |
| 6054 | + __le32 unused_0; | |
| 6055 | + u8 unused_1; | |
| 6056 | + u8 unused_2; | |
| 6057 | + u8 unused_3; | |
| 6058 | + u8 valid; | |
| 6059 | +}; | |
| 6060 | + | |
| 6061 | +/* hwrm_selftest_retrieve_serdes_data */ | |
| 6062 | +/* Input (32 bytes) */ | |
| 6063 | +struct hwrm_selftest_retrieve_serdes_data_input { | |
| 6064 | + __le16 req_type; | |
| 6065 | + __le16 cmpl_ring; | |
| 6066 | + __le16 seq_id; | |
| 6067 | + __le16 target_id; | |
| 6068 | + __le64 resp_addr; | |
| 6069 | + __le64 resp_data_addr; | |
| 6070 | + __le32 resp_data_offset; | |
| 6071 | + __le16 data_len; | |
| 6072 | + u8 flags; | |
| 6073 | + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_UNUSED_TEST_MASK 0xfUL | |
| 6074 | + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_UNUSED_TEST_SFT 0 | |
| 6075 | + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_PCIE_SERDES_TEST 0x10UL | |
| 6076 | + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_ETHERNET_SERDES_TEST 0x20UL | |
| 6077 | + u8 unused_0; | |
| 6078 | +}; | |
| 6079 | + | |
| 6080 | +/* Output (16 bytes) */ | |
| 6081 | +struct hwrm_selftest_retrieve_serdes_data_output { | |
| 6082 | + __le16 error_code; | |
| 6083 | + __le16 req_type; | |
| 6084 | + __le16 seq_id; | |
| 6085 | + __le16 resp_len; | |
| 6086 | + __le16 total_data_len; | |
| 6087 | + __le16 copied_data_len; | |
| 6088 | + u8 unused_0; | |
| 6089 | + u8 unused_1; | |
| 6090 | + u8 unused_2; | |
| 6091 | + u8 valid; | |
| 5781 | 6092 | }; |
| 5782 | 6093 | |
| 5783 | 6094 | /* Hardware Resource Manager Specification */ |
| @@ -5938,10 +6249,16 @@ struct cmd_nums { · 154 unmodified lines | ||
| 5938 | 6249 | #define HWRM_CFA_DECAP_FILTER_ALLOC (0x108UL) |
| 5939 | 6250 | #define HWRM_CFA_DECAP_FILTER_FREE (0x109UL) |
| 5940 | 6251 | #define HWRM_CFA_VLAN_ANTISPOOF_QCFG (0x10aUL) |
| 6252 | + #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_ALLOC (0x10bUL) | |
| 6253 | + #define HWRM_CFA_REDIRECT_TUNNEL_TYPE_FREE (0x10cUL) | |
| 6254 | + #define HWRM_CFA_PAIR_ALLOC (0x10dUL) | |
| 6255 | + #define HWRM_CFA_PAIR_FREE (0x10eUL) | |
| 6256 | + #define HWRM_CFA_PAIR_INFO (0x10fUL) | |
| 6257 | + #define HWRM_FW_IPC_MSG (0x110UL) | |
| 5941 | 6258 | #define HWRM_SELFTEST_QLIST (0x200UL) |
| 5942 | 6259 | #define HWRM_SELFTEST_EXEC (0x201UL) |
| 5943 | 6260 | #define HWRM_SELFTEST_IRQ (0x202UL) |
| 5944 | − #define HWRM_SELFTEST_RETREIVE_EYE_DATA (0x203UL) | |
| 6261 | + #define HWRM_SELFTEST_RETRIEVE_SERDES_DATA (0x203UL) | |
| 5945 | 6262 | #define HWRM_DBG_READ_DIRECT (0xff10UL) |
| 5946 | 6263 | #define HWRM_DBG_READ_INDIRECT (0xff11UL) |
| 5947 | 6264 | #define HWRM_DBG_WRITE_DIRECT (0xff12UL) |
| @@ -5949,6 +6266,9 @@ struct cmd_nums { · 1 unmodified line | ||
| 5949 | 6266 | #define HWRM_DBG_DUMP (0xff14UL) |
| 5950 | 6267 | #define HWRM_DBG_ERASE_NVM (0xff15UL) |
| 5951 | 6268 | #define HWRM_DBG_CFG (0xff16UL) |
| 6269 | + #define HWRM_DBG_COREDUMP_LIST (0xff17UL) | |
| 6270 | + #define HWRM_DBG_COREDUMP_INITIATE (0xff18UL) | |
| 6271 | + #define HWRM_DBG_COREDUMP_RETRIEVE (0xff19UL) | |
| 5952 | 6272 | #define HWRM_NVM_FACTORY_DEFAULTS (0xffeeUL) |
| 5953 | 6273 | #define HWRM_NVM_VALIDATE_OPTION (0xffefUL) |
| 5954 | 6274 | #define HWRM_NVM_FLUSH (0xfff0UL) |
| @@ -6123,6 +6443,58 @@ struct rx_port_stats { · 168 unmodified lines | ||
| 6123 | 6443 | __le64 rx_stat_err; |
| 6124 | 6444 | }; |
| 6125 | 6445 | |
| 6446 | +/* VXLAN IPv4 encapsulation structure (16 bytes) */ | |
| 6447 | +struct hwrm_vxlan_ipv4_hdr { | |
| 6448 | + u8 ver_hlen; | |
| 6449 | + #define VXLAN_IPV4_HDR_VER_HLEN_HEADER_LENGTH_MASK 0xfUL | |
| 6450 | + #define VXLAN_IPV4_HDR_VER_HLEN_HEADER_LENGTH_SFT 0 | |
| 6451 | + #define VXLAN_IPV4_HDR_VER_HLEN_VERSION_MASK 0xf0UL | |
| 6452 | + #define VXLAN_IPV4_HDR_VER_HLEN_VERSION_SFT 4 | |
| 6453 | + u8 tos; | |
| 6454 | + __be16 ip_id; | |
| 6455 | + __be16 flags_frag_offset; | |
| 6456 | + u8 ttl; | |
| 6457 | + u8 protocol; | |
| 6458 | + __be32 src_ip_addr; | |
| 6459 | + __be32 dest_ip_addr; | |
| 6460 | +}; | |
| 6461 | + | |
| 6462 | +/* VXLAN IPv6 encapsulation structure (32 bytes) */ | |
| 6463 | +struct hwrm_vxlan_ipv6_hdr { | |
| 6464 | + __be32 ver_tc_flow_label; | |
| 6465 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_VER_SFT 0x1cUL | |
| 6466 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_VER_MASK 0xf0000000UL | |
| 6467 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_TC_SFT 0x14UL | |
| 6468 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_TC_MASK 0xff00000UL | |
| 6469 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_FLOW_LABEL_SFT 0x0UL | |
| 6470 | + #define VXLAN_IPV6_HDR_VER_TC_FLOW_LABEL_FLOW_LABEL_MASK 0xfffffUL | |
| 6471 | + __be16 payload_len; | |
| 6472 | + u8 next_hdr; | |
| 6473 | + u8 ttl; | |
| 6474 | + __be32 src_ip_addr[4]; | |
| 6475 | + __be32 dest_ip_addr[4]; | |
| 6476 | +}; | |
| 6477 | + | |
| 6478 | +/* VXLAN encapsulation structure (72 bytes) */ | |
| 6479 | +struct hwrm_cfa_encap_data_vxlan { | |
| 6480 | + u8 src_mac_addr[6]; | |
| 6481 | + __le16 unused_0; | |
| 6482 | + u8 dst_mac_addr[6]; | |
| 6483 | + u8 num_vlan_tags; | |
| 6484 | + u8 unused_1; | |
| 6485 | + __be16 ovlan_tpid; | |
| 6486 | + __be16 ovlan_tci; | |
| 6487 | + __be16 ivlan_tpid; | |
| 6488 | + __be16 ivlan_tci; | |
| 6489 | + __le32 l3[10]; | |
| 6490 | + #define CFA_ENCAP_DATA_VXLAN_L3_VER_MASK 0xfUL | |
| 6491 | + #define CFA_ENCAP_DATA_VXLAN_L3_VER_IPV4 0x4UL | |
| 6492 | + #define CFA_ENCAP_DATA_VXLAN_L3_VER_IPV6 0x6UL | |
| 6493 | + __be16 src_port; | |
| 6494 | + __be16 dst_port; | |
| 6495 | + __be32 vni; | |
| 6496 | +}; | |
| 6497 | + | |
| 6126 | 6498 | /* Periodic Statistics Context DMA to host (160 bytes) */ |
| 6127 | 6499 | struct ctx_hw_stats { |
| 6128 | 6500 | __le64 rx_ucast_pkts; |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <net/tc_act/tc_skbedit.h> |
| 17 | 17 | #include <net/tc_act/tc_mirred.h> |
| 18 | 18 | #include <net/tc_act/tc_vlan.h> |
| 19 | +#include <net/tc_act/tc_tunnel_key.h> | |
| 19 | 20 | |
| 20 | 21 | #include "bnxt_hsi.h" |
| 21 | 22 | #include "bnxt.h" |
| @@ -23,8 +24,6 @@ · 1 unmodified line | ||
| 23 | 24 | #include "bnxt_tc.h" |
| 24 | 25 | #include "bnxt_vfr.h" |
| 25 | 26 | |
| 26 | −#ifdef CONFIG_BNXT_FLOWER_OFFLOAD | |
| 27 | − | |
| 28 | 27 | #define BNXT_FID_INVALID 0xffff |
| 29 | 28 | #define VLAN_TCI(vid, prio) ((vid) | ((prio) << VLAN_PRIO_SHIFT)) |
| 30 | 29 | |
| @@ -91,6 +90,23 @@ static void bnxt_tc_parse_vlan(struct bnxt *bp, · 60 unmodified lines | ||
| 91 | 90 | } |
| 92 | 91 | } |
| 93 | 92 | |
| 93 | +static int bnxt_tc_parse_tunnel_set(struct bnxt *bp, | |
| 94 | + struct bnxt_tc_actions *actions, | |
| 95 | + const struct tc_action *tc_act) | |
| 96 | +{ | |
| 97 | + struct ip_tunnel_info *tun_info = tcf_tunnel_info(tc_act); | |
| 98 | + struct ip_tunnel_key *tun_key = &tun_info->key; | |
| 99 | + | |
| 100 | + if (ip_tunnel_info_af(tun_info) != AF_INET) { | |
| 101 | + netdev_info(bp->dev, "only IPv4 tunnel-encap is supported"); | |
| 102 | + return -EOPNOTSUPP; | |
| 103 | + } | |
| 104 | + | |
| 105 | + actions->tun_encap_key = *tun_key; | |
| 106 | + actions->flags |= BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP; | |
| 107 | + return 0; | |
| 108 | +} | |
| 109 | + | |
| 94 | 110 | static int bnxt_tc_parse_actions(struct bnxt *bp, |
| 95 | 111 | struct bnxt_tc_actions *actions, |
| 96 | 112 | struct tcf_exts *tc_exts) |
| @@ -125,9 +141,35 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, · 28 unmodified lines | ||
| 125 | 141 | bnxt_tc_parse_vlan(bp, actions, tc_act); |
| 126 | 142 | continue; |
| 127 | 143 | } |
| 144 | + | |
| 145 | + /* Tunnel encap */ | |
| 146 | + if (is_tcf_tunnel_set(tc_act)) { | |
| 147 | + rc = bnxt_tc_parse_tunnel_set(bp, actions, tc_act); | |
| 148 | + if (rc) | |
| 149 | + return rc; | |
| 150 | + continue; | |
| 151 | + } | |
| 152 | + | |
| 153 | + /* Tunnel decap */ | |
| 154 | + if (is_tcf_tunnel_release(tc_act)) { | |
| 155 | + actions->flags |= BNXT_TC_ACTION_FLAG_TUNNEL_DECAP; | |
| 156 | + continue; | |
| 157 | + } | |
| 128 | 158 | } |
| 129 | 159 | |
| 130 | − return 0; | |
| 160 | + if (rc) | |
| 161 | + return rc; | |
| 162 | + | |
| 163 | + /* Tunnel encap/decap action must be accompanied by a redirect action */ | |
| 164 | + if ((actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP || | |
| 165 | + actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) && | |
| 166 | + !(actions->flags & BNXT_TC_ACTION_FLAG_FWD)) { | |
| 167 | + netdev_info(bp->dev, | |
| 168 | + "error: no redir action along with encap/decap"); | |
| 169 | + return -EINVAL; | |
| 170 | + } | |
| 171 | + | |
| 172 | + return rc; | |
| 131 | 173 | } |
| 132 | 174 | |
| 133 | 175 | #define GET_KEY(flow_cmd, key_type) \ |
| @@ -254,6 +296,54 @@ static int bnxt_tc_parse_flow(struct bnxt *bp, · 120 unmodified lines | ||
| 254 | 296 | flow->l4_mask.icmp.code = mask->code; |
| 255 | 297 | } |
| 256 | 298 | |
| 299 | + if (dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL)) { | |
| 300 | + struct flow_dissector_key_control *key = | |
| 301 | + GET_KEY(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_CONTROL); | |
| 302 | + | |
| 303 | + addr_type = key->addr_type; | |
| 304 | + } | |
| 305 | + | |
| 306 | + if (dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) { | |
| 307 | + struct flow_dissector_key_ipv4_addrs *key = | |
| 308 | + GET_KEY(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS); | |
| 309 | + struct flow_dissector_key_ipv4_addrs *mask = | |
| 310 | + GET_MASK(tc_flow_cmd, | |
| 311 | + FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS); | |
| 312 | + | |
| 313 | + flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS; | |
| 314 | + flow->tun_key.u.ipv4.dst = key->dst; | |
| 315 | + flow->tun_mask.u.ipv4.dst = mask->dst; | |
| 316 | + flow->tun_key.u.ipv4.src = key->src; | |
| 317 | + flow->tun_mask.u.ipv4.src = mask->src; | |
| 318 | + } else if (dissector_uses_key(dissector, | |
| 319 | + FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) { | |
| 320 | + return -EOPNOTSUPP; | |
| 321 | + } | |
| 322 | + | |
| 323 | + if (dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) { | |
| 324 | + struct flow_dissector_key_keyid *key = | |
| 325 | + GET_KEY(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_KEYID); | |
| 326 | + struct flow_dissector_key_keyid *mask = | |
| 327 | + GET_MASK(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_KEYID); | |
| 328 | + | |
| 329 | + flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ID; | |
| 330 | + flow->tun_key.tun_id = key32_to_tunnel_id(key->keyid); | |
| 331 | + flow->tun_mask.tun_id = key32_to_tunnel_id(mask->keyid); | |
| 332 | + } | |
| 333 | + | |
| 334 | + if (dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) { | |
| 335 | + struct flow_dissector_key_ports *key = | |
| 336 | + GET_KEY(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_PORTS); | |
| 337 | + struct flow_dissector_key_ports *mask = | |
| 338 | + GET_MASK(tc_flow_cmd, FLOW_DISSECTOR_KEY_ENC_PORTS); | |
| 339 | + | |
| 340 | + flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_PORTS; | |
| 341 | + flow->tun_key.tp_dst = key->dst; | |
| 342 | + flow->tun_mask.tp_dst = mask->dst; | |
| 343 | + flow->tun_key.tp_src = key->src; | |
| 344 | + flow->tun_mask.tp_src = mask->src; | |
| 345 | + } | |
| 346 | + | |
| 257 | 347 | return bnxt_tc_parse_actions(bp, &flow->actions, tc_flow_cmd->exts); |
| 258 | 348 | } |
| 259 | 349 | |
| @@ -295,7 +385,8 @@ static bool is_wildcard(void *mask, int len) · 35 unmodified lines | ||
| 295 | 385 | } |
| 296 | 386 | |
| 297 | 387 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, |
| 298 | − __le16 ref_flow_handle, __le16 *flow_handle) | |
| 388 | + __le16 ref_flow_handle, | |
| 389 | + __le32 tunnel_handle, __le16 *flow_handle) | |
| 299 | 390 | { |
| 300 | 391 | struct hwrm_cfa_flow_alloc_output *resp = bp->hwrm_cmd_resp_addr; |
| 301 | 392 | struct bnxt_tc_actions *actions = &flow->actions; |
| @@ -309,6 +400,14 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, · 7 unmodified lines | ||
| 309 | 400 | |
| 310 | 401 | req.src_fid = cpu_to_le16(flow->src_fid); |
| 311 | 402 | req.ref_flow_handle = ref_flow_handle; |
| 403 | + | |
| 404 | + if (actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP || | |
| 405 | + actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) { | |
| 406 | + req.tunnel_handle = tunnel_handle; | |
| 407 | + flow_flags |= CFA_FLOW_ALLOC_REQ_FLAGS_TUNNEL; | |
| 408 | + action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_TUNNEL; | |
| 409 | + } | |
| 410 | + | |
| 312 | 411 | req.ethertype = flow->l2_key.ether_type; |
| 313 | 412 | req.ip_proto = flow->l4_key.ip_proto; |
| 314 | 413 | |
| @@ -405,78 +504,153 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, · 90 unmodified lines | ||
| 405 | 504 | return rc; |
| 406 | 505 | } |
| 407 | 506 | |
| 408 | −/* Add val to accum while handling a possible wraparound | |
| 409 | − * of val. Eventhough val is of type u64, its actual width | |
| 410 | − * is denoted by mask and will wrap-around beyond that width. | |
| 411 | − */ | |
| 412 | −static void accumulate_val(u64 *accum, u64 val, u64 mask) | |
| 507 | +static int hwrm_cfa_decap_filter_alloc(struct bnxt *bp, | |
| 508 | + struct bnxt_tc_flow *flow, | |
| 509 | + struct bnxt_tc_l2_key *l2_info, | |
| 510 | + __le32 ref_decap_handle, | |
| 511 | + __le32 *decap_filter_handle) | |
| 413 | 512 | { |
| 414 | −#define low_bits(x, mask) ((x) & (mask)) | |
| 415 | −#define high_bits(x, mask) ((x) & ~(mask)) | |
| 416 | − bool wrapped = val < low_bits(*accum, mask); | |
| 513 | + struct hwrm_cfa_decap_filter_alloc_output *resp = | |
| 514 | + bp->hwrm_cmd_resp_addr; | |
| 515 | + struct hwrm_cfa_decap_filter_alloc_input req = { 0 }; | |
| 516 | + struct ip_tunnel_key *tun_key = &flow->tun_key; | |
| 517 | + u32 enables = 0; | |
| 518 | + int rc; | |
| 417 | 519 | |
| 418 | − *accum = high_bits(*accum, mask) + val; | |
| 419 | − if (wrapped) | |
| 420 | − *accum += (mask + 1); | |
| 421 | −} | |
| 520 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_DECAP_FILTER_ALLOC, -1, -1); | |
| 422 | 521 | |
| 423 | −/* The HW counters' width is much less than 64bits. | |
| 424 | − * Handle possible wrap-around while updating the stat counters | |
| 425 | − */ | |
| 426 | −static void bnxt_flow_stats_fix_wraparound(struct bnxt_tc_info *tc_info, | |
| 427 | − struct bnxt_tc_flow_stats *stats, | |
| 428 | − struct bnxt_tc_flow_stats *hw_stats) | |
| 429 | −{ | |
| 430 | − accumulate_val(&stats->bytes, hw_stats->bytes, tc_info->bytes_mask); | |
| 431 | − accumulate_val(&stats->packets, hw_stats->packets, | |
| 432 | − tc_info->packets_mask); | |
| 522 | + req.flags = cpu_to_le32(CFA_DECAP_FILTER_ALLOC_REQ_FLAGS_OVS_TUNNEL); | |
| 523 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE | | |
| 524 | + CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL; | |
| 525 | + req.tunnel_type = CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN; | |
| 526 | + req.ip_protocol = CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP; | |
| 527 | + | |
| 528 | + if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ID) { | |
| 529 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_ID; | |
| 530 | + /* tunnel_id is wrongly defined in hsi defn. as __le32 */ | |
| 531 | + req.tunnel_id = tunnel_id_to_key32(tun_key->tun_id); | |
| 532 | + } | |
| 533 | + | |
| 534 | + if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS) { | |
| 535 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR | | |
| 536 | + CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR; | |
| 537 | + ether_addr_copy(req.dst_macaddr, l2_info->dmac); | |
| 538 | + ether_addr_copy(req.src_macaddr, l2_info->smac); | |
| 539 | + } | |
| 540 | + if (l2_info->num_vlans) { | |
| 541 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_T_IVLAN_VID; | |
| 542 | + req.t_ivlan_vid = l2_info->inner_vlan_tci; | |
| 543 | + } | |
| 544 | + | |
| 545 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE; | |
| 546 | + req.ethertype = htons(ETH_P_IP); | |
| 547 | + | |
| 548 | + if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS) { | |
| 549 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR | | |
| 550 | + CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR | | |
| 551 | + CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE; | |
| 552 | + req.ip_addr_type = CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4; | |
| 553 | + req.dst_ipaddr[0] = tun_key->u.ipv4.dst; | |
| 554 | + req.src_ipaddr[0] = tun_key->u.ipv4.src; | |
| 555 | + } | |
| 556 | + | |
| 557 | + if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_PORTS) { | |
| 558 | + enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_PORT; | |
| 559 | + req.dst_port = tun_key->tp_dst; | |
| 560 | + } | |
| 561 | + | |
| 562 | + /* Eventhough the decap_handle returned by hwrm_cfa_decap_filter_alloc | |
| 563 | + * is defined as __le32, l2_ctxt_ref_id is defined in HSI as __le16. | |
| 564 | + */ | |
| 565 | + req.l2_ctxt_ref_id = (__force __le16)ref_decap_handle; | |
| 566 | + req.enables = cpu_to_le32(enables); | |
| 567 | + | |
| 568 | + mutex_lock(&bp->hwrm_cmd_lock); | |
| 569 | + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 570 | + if (!rc) | |
| 571 | + *decap_filter_handle = resp->decap_filter_id; | |
| 572 | + else | |
| 573 | + netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 574 | + mutex_unlock(&bp->hwrm_cmd_lock); | |
| 575 | + | |
| 576 | + return rc; | |
| 433 | 577 | } |
| 434 | 578 | |
| 435 | −/* Fix possible wraparound of the stats queried from HW, calculate | |
| 436 | − * the delta from prev_stats, and also update the prev_stats. | |
| 437 | − * The HW flow stats are fetched under the hwrm_cmd_lock mutex. | |
| 438 | − * This routine is best called while under the mutex so that the | |
| 439 | − * stats processing happens atomically. | |
| 440 | − */ | |
| 441 | −static void bnxt_flow_stats_calc(struct bnxt_tc_info *tc_info, | |
| 442 | − struct bnxt_tc_flow *flow, | |
| 443 | − struct bnxt_tc_flow_stats *stats) | |
| 579 | +static int hwrm_cfa_decap_filter_free(struct bnxt *bp, | |
| 580 | + __le32 decap_filter_handle) | |
| 444 | 581 | { |
| 445 | − struct bnxt_tc_flow_stats *acc_stats, *prev_stats; | |
| 582 | + struct hwrm_cfa_decap_filter_free_input req = { 0 }; | |
| 583 | + int rc; | |
| 446 | 584 | |
| 447 | − acc_stats = &flow->stats; | |
| 448 | − bnxt_flow_stats_fix_wraparound(tc_info, acc_stats, stats); | |
| 585 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_DECAP_FILTER_FREE, -1, -1); | |
| 586 | + req.decap_filter_id = decap_filter_handle; | |
| 449 | 587 | |
| 450 | − prev_stats = &flow->prev_stats; | |
| 451 | − stats->bytes = acc_stats->bytes - prev_stats->bytes; | |
| 452 | − stats->packets = acc_stats->packets - prev_stats->packets; | |
| 453 | − *prev_stats = *acc_stats; | |
| 588 | + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 589 | + if (rc) | |
| 590 | + netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 591 | + return rc; | |
| 454 | 592 | } |
| 455 | 593 | |
| 456 | −static int bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, | |
| 457 | − __le16 flow_handle, | |
| 458 | − struct bnxt_tc_flow *flow, | |
| 459 | − struct bnxt_tc_flow_stats *stats) | |
| 594 | +static int hwrm_cfa_encap_record_alloc(struct bnxt *bp, | |
| 595 | + struct ip_tunnel_key *encap_key, | |
| 596 | + struct bnxt_tc_l2_key *l2_info, | |
| 597 | + __le32 *encap_record_handle) | |
| 460 | 598 | { |
| 461 | − struct hwrm_cfa_flow_stats_output *resp = bp->hwrm_cmd_resp_addr; | |
| 462 | − struct hwrm_cfa_flow_stats_input req = { 0 }; | |
| 599 | + struct hwrm_cfa_encap_record_alloc_output *resp = | |
| 600 | + bp->hwrm_cmd_resp_addr; | |
| 601 | + struct hwrm_cfa_encap_record_alloc_input req = { 0 }; | |
| 602 | + struct hwrm_cfa_encap_data_vxlan *encap = | |
| 603 | + (struct hwrm_cfa_encap_data_vxlan *)&req.encap_data; | |
| 604 | + struct hwrm_vxlan_ipv4_hdr *encap_ipv4 = | |
| 605 | + (struct hwrm_vxlan_ipv4_hdr *)encap->l3; | |
| 463 | 606 | int rc; |
| 464 | 607 | |
| 465 | − bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_STATS, -1, -1); | |
| 466 | − req.num_flows = cpu_to_le16(1); | |
| 467 | − req.flow_handle_0 = flow_handle; | |
| 608 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_ENCAP_RECORD_ALLOC, -1, -1); | |
| 468 | 609 | |
| 469 | − mutex_lock(&bp->hwrm_cmd_lock); | |
| 470 | − rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 471 | − if (!rc) { | |
| 472 | − stats->packets = le64_to_cpu(resp->packet_0); | |
| 473 | − stats->bytes = le64_to_cpu(resp->byte_0); | |
| 474 | − bnxt_flow_stats_calc(&bp->tc_info, flow, stats); | |
| 475 | − } else { | |
| 476 | − netdev_info(bp->dev, "error rc=%d", rc); | |
| 610 | + req.encap_type = CFA_ENCAP_RECORD_ALLOC_REQ_ENCAP_TYPE_VXLAN; | |
| 611 | + | |
| 612 | + ether_addr_copy(encap->dst_mac_addr, l2_info->dmac); | |
| 613 | + ether_addr_copy(encap->src_mac_addr, l2_info->smac); | |
| 614 | + if (l2_info->num_vlans) { | |
| 615 | + encap->num_vlan_tags = l2_info->num_vlans; | |
| 616 | + encap->ovlan_tci = l2_info->inner_vlan_tci; | |
| 617 | + encap->ovlan_tpid = l2_info->inner_vlan_tpid; | |
| 477 | 618 | } |
| 478 | 619 | |
| 620 | + encap_ipv4->ver_hlen = 4 << VXLAN_IPV4_HDR_VER_HLEN_VERSION_SFT; | |
| 621 | + encap_ipv4->ver_hlen |= 5 << VXLAN_IPV4_HDR_VER_HLEN_HEADER_LENGTH_SFT; | |
| 622 | + encap_ipv4->ttl = encap_key->ttl; | |
| 623 | + | |
| 624 | + encap_ipv4->dest_ip_addr = encap_key->u.ipv4.dst; | |
| 625 | + encap_ipv4->src_ip_addr = encap_key->u.ipv4.src; | |
| 626 | + encap_ipv4->protocol = IPPROTO_UDP; | |
| 627 | + | |
| 628 | + encap->dst_port = encap_key->tp_dst; | |
| 629 | + encap->vni = tunnel_id_to_key32(encap_key->tun_id); | |
| 630 | + | |
| 631 | + mutex_lock(&bp->hwrm_cmd_lock); | |
| 632 | + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 633 | + if (!rc) | |
| 634 | + *encap_record_handle = resp->encap_record_id; | |
| 635 | + else | |
| 636 | + netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 479 | 637 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 638 | + | |
| 639 | + return rc; | |
| 640 | +} | |
| 641 | + | |
| 642 | +static int hwrm_cfa_encap_record_free(struct bnxt *bp, | |
| 643 | + __le32 encap_record_handle) | |
| 644 | +{ | |
| 645 | + struct hwrm_cfa_encap_record_free_input req = { 0 }; | |
| 646 | + int rc; | |
| 647 | + | |
| 648 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_ENCAP_RECORD_FREE, -1, -1); | |
| 649 | + req.encap_record_id = encap_record_handle; | |
| 650 | + | |
| 651 | + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 652 | + if (rc) | |
| 653 | + netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 480 | 654 | return rc; |
| 481 | 655 | } |
| 482 | 656 | |
| @@ -484,7 +658,7 @@ static int bnxt_tc_put_l2_node(struct bnxt *bp, · 1 unmodified line | ||
| 484 | 658 | struct bnxt_tc_flow_node *flow_node) |
| 485 | 659 | { |
| 486 | 660 | struct bnxt_tc_l2_node *l2_node = flow_node->l2_node; |
| 487 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 661 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 488 | 662 | int rc; |
| 489 | 663 | |
| 490 | 664 | /* remove flow_node from the L2 shared flow list */ |
| @@ -521,7 +695,7 @@ bnxt_tc_get_l2_node(struct bnxt *bp, struct rhashtable *l2_table, · 30 unmodified lines | ||
| 521 | 695 | rc = rhashtable_insert_fast(l2_table, &l2_node->node, |
| 522 | 696 | ht_params); |
| 523 | 697 | if (rc) { |
| 524 | − kfree(l2_node); | |
| 698 | + kfree_rcu(l2_node, rcu); | |
| 525 | 699 | netdev_err(bp->dev, |
| 526 | 700 | "Error: %s: rhashtable_insert_fast: %d", |
| 527 | 701 | __func__, rc); |
| @@ -540,7 +714,7 @@ bnxt_tc_get_ref_flow_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, · 12 unmodified lines | ||
| 540 | 714 | struct bnxt_tc_flow_node *flow_node, |
| 541 | 715 | __le16 *ref_flow_handle) |
| 542 | 716 | { |
| 543 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 717 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 544 | 718 | struct bnxt_tc_flow_node *ref_flow_node; |
| 545 | 719 | struct bnxt_tc_l2_node *l2_node; |
| 546 | 720 | |
| @@ -590,10 +764,386 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) · 43 unmodified lines | ||
| 590 | 764 | return true; |
| 591 | 765 | } |
| 592 | 766 | |
| 767 | +/* Returns the final refcount of the node on success | |
| 768 | + * or a -ve error code on failure | |
| 769 | + */ | |
| 770 | +static int bnxt_tc_put_tunnel_node(struct bnxt *bp, | |
| 771 | + struct rhashtable *tunnel_table, | |
| 772 | + struct rhashtable_params *ht_params, | |
| 773 | + struct bnxt_tc_tunnel_node *tunnel_node) | |
| 774 | +{ | |
| 775 | + int rc; | |
| 776 | + | |
| 777 | + if (--tunnel_node->refcount == 0) { | |
| 778 | + rc = rhashtable_remove_fast(tunnel_table, &tunnel_node->node, | |
| 779 | + *ht_params); | |
| 780 | + if (rc) { | |
| 781 | + netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc); | |
| 782 | + rc = -1; | |
| 783 | + } | |
| 784 | + kfree_rcu(tunnel_node, rcu); | |
| 785 | + return rc; | |
| 786 | + } else { | |
| 787 | + return tunnel_node->refcount; | |
| 788 | + } | |
| 789 | +} | |
| 790 | + | |
| 791 | +/* Get (or add) either encap or decap tunnel node from/to the supplied | |
| 792 | + * hash table. | |
| 793 | + */ | |
| 794 | +static struct bnxt_tc_tunnel_node * | |
| 795 | +bnxt_tc_get_tunnel_node(struct bnxt *bp, struct rhashtable *tunnel_table, | |
| 796 | + struct rhashtable_params *ht_params, | |
| 797 | + struct ip_tunnel_key *tun_key) | |
| 798 | +{ | |
| 799 | + struct bnxt_tc_tunnel_node *tunnel_node; | |
| 800 | + int rc; | |
| 801 | + | |
| 802 | + tunnel_node = rhashtable_lookup_fast(tunnel_table, tun_key, *ht_params); | |
| 803 | + if (!tunnel_node) { | |
| 804 | + tunnel_node = kzalloc(sizeof(*tunnel_node), GFP_KERNEL); | |
| 805 | + if (!tunnel_node) { | |
| 806 | + rc = -ENOMEM; | |
| 807 | + goto err; | |
| 808 | + } | |
| 809 | + | |
| 810 | + tunnel_node->key = *tun_key; | |
| 811 | + tunnel_node->tunnel_handle = INVALID_TUNNEL_HANDLE; | |
| 812 | + rc = rhashtable_insert_fast(tunnel_table, &tunnel_node->node, | |
| 813 | + *ht_params); | |
| 814 | + if (rc) { | |
| 815 | + kfree_rcu(tunnel_node, rcu); | |
| 816 | + goto err; | |
| 817 | + } | |
| 818 | + } | |
| 819 | + tunnel_node->refcount++; | |
| 820 | + return tunnel_node; | |
| 821 | +err: | |
| 822 | + netdev_info(bp->dev, "error rc=%d", rc); | |
| 823 | + return NULL; | |
| 824 | +} | |
| 825 | + | |
| 826 | +static int bnxt_tc_get_ref_decap_handle(struct bnxt *bp, | |
| 827 | + struct bnxt_tc_flow *flow, | |
| 828 | + struct bnxt_tc_l2_key *l2_key, | |
| 829 | + struct bnxt_tc_flow_node *flow_node, | |
| 830 | + __le32 *ref_decap_handle) | |
| 831 | +{ | |
| 832 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 833 | + struct bnxt_tc_flow_node *ref_flow_node; | |
| 834 | + struct bnxt_tc_l2_node *decap_l2_node; | |
| 835 | + | |
| 836 | + decap_l2_node = bnxt_tc_get_l2_node(bp, &tc_info->decap_l2_table, | |
| 837 | + tc_info->decap_l2_ht_params, | |
| 838 | + l2_key); | |
| 839 | + if (!decap_l2_node) | |
| 840 | + return -1; | |
| 841 | + | |
| 842 | + /* If any other flow is using this decap_l2_node, use it's decap_handle | |
| 843 | + * as the ref_decap_handle | |
| 844 | + */ | |
| 845 | + if (decap_l2_node->refcount > 0) { | |
| 846 | + ref_flow_node = | |
| 847 | + list_first_entry(&decap_l2_node->common_l2_flows, | |
| 848 | + struct bnxt_tc_flow_node, | |
| 849 | + decap_l2_list_node); | |
| 850 | + *ref_decap_handle = ref_flow_node->decap_node->tunnel_handle; | |
| 851 | + } else { | |
| 852 | + *ref_decap_handle = INVALID_TUNNEL_HANDLE; | |
| 853 | + } | |
| 854 | + | |
| 855 | + /* Insert the l2_node into the flow_node so that subsequent flows | |
| 856 | + * with a matching decap l2 key can use the decap_filter_handle of | |
| 857 | + * this flow as their ref_decap_handle | |
| 858 | + */ | |
| 859 | + flow_node->decap_l2_node = decap_l2_node; | |
| 860 | + list_add(&flow_node->decap_l2_list_node, | |
| 861 | + &decap_l2_node->common_l2_flows); | |
| 862 | + decap_l2_node->refcount++; | |
| 863 | + return 0; | |
| 864 | +} | |
| 865 | + | |
| 866 | +static void bnxt_tc_put_decap_l2_node(struct bnxt *bp, | |
| 867 | + struct bnxt_tc_flow_node *flow_node) | |
| 868 | +{ | |
| 869 | + struct bnxt_tc_l2_node *decap_l2_node = flow_node->decap_l2_node; | |
| 870 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 871 | + int rc; | |
| 872 | + | |
| 873 | + /* remove flow_node from the decap L2 sharing flow list */ | |
| 874 | + list_del(&flow_node->decap_l2_list_node); | |
| 875 | + if (--decap_l2_node->refcount == 0) { | |
| 876 | + rc = rhashtable_remove_fast(&tc_info->decap_l2_table, | |
| 877 | + &decap_l2_node->node, | |
| 878 | + tc_info->decap_l2_ht_params); | |
| 879 | + if (rc) | |
| 880 | + netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc); | |
| 881 | + kfree_rcu(decap_l2_node, rcu); | |
| 882 | + } | |
| 883 | +} | |
| 884 | + | |
| 885 | +static void bnxt_tc_put_decap_handle(struct bnxt *bp, | |
| 886 | + struct bnxt_tc_flow_node *flow_node) | |
| 887 | +{ | |
| 888 | + __le32 decap_handle = flow_node->decap_node->tunnel_handle; | |
| 889 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 890 | + int rc; | |
| 891 | + | |
| 892 | + if (flow_node->decap_l2_node) | |
| 893 | + bnxt_tc_put_decap_l2_node(bp, flow_node); | |
| 894 | + | |
| 895 | + rc = bnxt_tc_put_tunnel_node(bp, &tc_info->decap_table, | |
| 896 | + &tc_info->decap_ht_params, | |
| 897 | + flow_node->decap_node); | |
| 898 | + if (!rc && decap_handle != INVALID_TUNNEL_HANDLE) | |
| 899 | + hwrm_cfa_decap_filter_free(bp, decap_handle); | |
| 900 | +} | |
| 901 | + | |
| 902 | +static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, | |
| 903 | + struct ip_tunnel_key *tun_key, | |
| 904 | + struct bnxt_tc_l2_key *l2_info, | |
| 905 | + struct net_device *real_dst_dev) | |
| 906 | +{ | |
| 907 | +#ifdef CONFIG_INET | |
| 908 | + struct flowi4 flow = { {0} }; | |
| 909 | + struct net_device *dst_dev; | |
| 910 | + struct neighbour *nbr; | |
| 911 | + struct rtable *rt; | |
| 912 | + int rc; | |
| 913 | + | |
| 914 | + flow.flowi4_proto = IPPROTO_UDP; | |
| 915 | + flow.fl4_dport = tun_key->tp_dst; | |
| 916 | + flow.daddr = tun_key->u.ipv4.dst; | |
| 917 | + | |
| 918 | + rt = ip_route_output_key(dev_net(real_dst_dev), &flow); | |
| 919 | + if (IS_ERR(rt)) { | |
| 920 | + netdev_info(bp->dev, "no route to %pI4b", &flow.daddr); | |
| 921 | + return -EOPNOTSUPP; | |
| 922 | + } | |
| 923 | + | |
| 924 | + /* The route must either point to the real_dst_dev or a dst_dev that | |
| 925 | + * uses the real_dst_dev. | |
| 926 | + */ | |
| 927 | + dst_dev = rt->dst.dev; | |
| 928 | + if (is_vlan_dev(dst_dev)) { | |
| 929 | +#if IS_ENABLED(CONFIG_VLAN_8021Q) | |
| 930 | + struct vlan_dev_priv *vlan = vlan_dev_priv(dst_dev); | |
| 931 | + | |
| 932 | + if (vlan->real_dev != real_dst_dev) { | |
| 933 | + netdev_info(bp->dev, | |
| 934 | + "dst_dev(%s) doesn't use PF-if(%s)", | |
| 935 | + netdev_name(dst_dev), | |
| 936 | + netdev_name(real_dst_dev)); | |
| 937 | + rc = -EOPNOTSUPP; | |
| 938 | + goto put_rt; | |
| 939 | + } | |
| 940 | + l2_info->inner_vlan_tci = htons(vlan->vlan_id); | |
| 941 | + l2_info->inner_vlan_tpid = vlan->vlan_proto; | |
| 942 | + l2_info->num_vlans = 1; | |
| 943 | +#endif | |
| 944 | + } else if (dst_dev != real_dst_dev) { | |
| 945 | + netdev_info(bp->dev, | |
| 946 | + "dst_dev(%s) for %pI4b is not PF-if(%s)", | |
| 947 | + netdev_name(dst_dev), &flow.daddr, | |
| 948 | + netdev_name(real_dst_dev)); | |
| 949 | + rc = -EOPNOTSUPP; | |
| 950 | + goto put_rt; | |
| 951 | + } | |
| 952 | + | |
| 953 | + nbr = dst_neigh_lookup(&rt->dst, &flow.daddr); | |
| 954 | + if (!nbr) { | |
| 955 | + netdev_info(bp->dev, "can't lookup neighbor for %pI4b", | |
| 956 | + &flow.daddr); | |
| 957 | + rc = -EOPNOTSUPP; | |
| 958 | + goto put_rt; | |
| 959 | + } | |
| 960 | + | |
| 961 | + tun_key->u.ipv4.src = flow.saddr; | |
| 962 | + tun_key->ttl = ip4_dst_hoplimit(&rt->dst); | |
| 963 | + neigh_ha_snapshot(l2_info->dmac, nbr, dst_dev); | |
| 964 | + ether_addr_copy(l2_info->smac, dst_dev->dev_addr); | |
| 965 | + neigh_release(nbr); | |
| 966 | + ip_rt_put(rt); | |
| 967 | + | |
| 968 | + return 0; | |
| 969 | +put_rt: | |
| 970 | + ip_rt_put(rt); | |
| 971 | + return rc; | |
| 972 | +#else | |
| 973 | + return -EOPNOTSUPP; | |
| 974 | +#endif | |
| 975 | +} | |
| 976 | + | |
| 977 | +static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |
| 978 | + struct bnxt_tc_flow_node *flow_node, | |
| 979 | + __le32 *decap_filter_handle) | |
| 980 | +{ | |
| 981 | + struct ip_tunnel_key *decap_key = &flow->tun_key; | |
| 982 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 983 | + struct bnxt_tc_l2_key l2_info = { {0} }; | |
| 984 | + struct bnxt_tc_tunnel_node *decap_node; | |
| 985 | + struct ip_tunnel_key tun_key = { 0 }; | |
| 986 | + struct bnxt_tc_l2_key *decap_l2_info; | |
| 987 | + __le32 ref_decap_handle; | |
| 988 | + int rc; | |
| 989 | + | |
| 990 | + /* Check if there's another flow using the same tunnel decap. | |
| 991 | + * If not, add this tunnel to the table and resolve the other | |
| 992 | + * tunnel header fileds | |
| 993 | + */ | |
| 994 | + decap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->decap_table, | |
| 995 | + &tc_info->decap_ht_params, | |
| 996 | + decap_key); | |
| 997 | + if (!decap_node) | |
| 998 | + return -ENOMEM; | |
| 999 | + | |
| 1000 | + flow_node->decap_node = decap_node; | |
| 1001 | + | |
| 1002 | + if (decap_node->tunnel_handle != INVALID_TUNNEL_HANDLE) | |
| 1003 | + goto done; | |
| 1004 | + | |
| 1005 | + /* Resolve the L2 fields for tunnel decap | |
| 1006 | + * Resolve the route for remote vtep (saddr) of the decap key | |
| 1007 | + * Find it's next-hop mac addrs | |
| 1008 | + */ | |
| 1009 | + tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; | |
| 1010 | + tun_key.tp_dst = flow->tun_key.tp_dst; | |
| 1011 | + rc = bnxt_tc_resolve_tunnel_hdrs(bp, &tun_key, &l2_info, bp->dev); | |
| 1012 | + if (rc) | |
| 1013 | + goto put_decap; | |
| 1014 | + | |
| 1015 | + decap_key->ttl = tun_key.ttl; | |
| 1016 | + decap_l2_info = &decap_node->l2_info; | |
| 1017 | + ether_addr_copy(decap_l2_info->dmac, l2_info.smac); | |
| 1018 | + ether_addr_copy(decap_l2_info->smac, l2_info.dmac); | |
| 1019 | + if (l2_info.num_vlans) { | |
| 1020 | + decap_l2_info->num_vlans = l2_info.num_vlans; | |
| 1021 | + decap_l2_info->inner_vlan_tpid = l2_info.inner_vlan_tpid; | |
| 1022 | + decap_l2_info->inner_vlan_tci = l2_info.inner_vlan_tci; | |
| 1023 | + } | |
| 1024 | + flow->flags |= BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS; | |
| 1025 | + | |
| 1026 | + /* For getting a decap_filter_handle we first need to check if | |
| 1027 | + * there are any other decap flows that share the same tunnel L2 | |
| 1028 | + * key and if so, pass that flow's decap_filter_handle as the | |
| 1029 | + * ref_decap_handle for this flow. | |
| 1030 | + */ | |
| 1031 | + rc = bnxt_tc_get_ref_decap_handle(bp, flow, decap_l2_info, flow_node, | |
| 1032 | + &ref_decap_handle); | |
| 1033 | + if (rc) | |
| 1034 | + goto put_decap; | |
| 1035 | + | |
| 1036 | + /* Issue the hwrm cmd to allocate a decap filter handle */ | |
| 1037 | + rc = hwrm_cfa_decap_filter_alloc(bp, flow, decap_l2_info, | |
| 1038 | + ref_decap_handle, | |
| 1039 | + &decap_node->tunnel_handle); | |
| 1040 | + if (rc) | |
| 1041 | + goto put_decap_l2; | |
| 1042 | + | |
| 1043 | +done: | |
| 1044 | + *decap_filter_handle = decap_node->tunnel_handle; | |
| 1045 | + return 0; | |
| 1046 | + | |
| 1047 | +put_decap_l2: | |
| 1048 | + bnxt_tc_put_decap_l2_node(bp, flow_node); | |
| 1049 | +put_decap: | |
| 1050 | + bnxt_tc_put_tunnel_node(bp, &tc_info->decap_table, | |
| 1051 | + &tc_info->decap_ht_params, | |
| 1052 | + flow_node->decap_node); | |
| 1053 | + return rc; | |
| 1054 | +} | |
| 1055 | + | |
| 1056 | +static void bnxt_tc_put_encap_handle(struct bnxt *bp, | |
| 1057 | + struct bnxt_tc_tunnel_node *encap_node) | |
| 1058 | +{ | |
| 1059 | + __le32 encap_handle = encap_node->tunnel_handle; | |
| 1060 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 1061 | + int rc; | |
| 1062 | + | |
| 1063 | + rc = bnxt_tc_put_tunnel_node(bp, &tc_info->encap_table, | |
| 1064 | + &tc_info->encap_ht_params, encap_node); | |
| 1065 | + if (!rc && encap_handle != INVALID_TUNNEL_HANDLE) | |
| 1066 | + hwrm_cfa_encap_record_free(bp, encap_handle); | |
| 1067 | +} | |
| 1068 | + | |
| 1069 | +/* Lookup the tunnel encap table and check if there's an encap_handle | |
| 1070 | + * alloc'd already. | |
| 1071 | + * If not, query L2 info via a route lookup and issue an encap_record_alloc | |
| 1072 | + * cmd to FW. | |
| 1073 | + */ | |
| 1074 | +static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |
| 1075 | + struct bnxt_tc_flow_node *flow_node, | |
| 1076 | + __le32 *encap_handle) | |
| 1077 | +{ | |
| 1078 | + struct ip_tunnel_key *encap_key = &flow->actions.tun_encap_key; | |
| 1079 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 1080 | + struct bnxt_tc_tunnel_node *encap_node; | |
| 1081 | + int rc; | |
| 1082 | + | |
| 1083 | + /* Check if there's another flow using the same tunnel encap. | |
| 1084 | + * If not, add this tunnel to the table and resolve the other | |
| 1085 | + * tunnel header fileds | |
| 1086 | + */ | |
| 1087 | + encap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->encap_table, | |
| 1088 | + &tc_info->encap_ht_params, | |
| 1089 | + encap_key); | |
| 1090 | + if (!encap_node) | |
| 1091 | + return -ENOMEM; | |
| 1092 | + | |
| 1093 | + flow_node->encap_node = encap_node; | |
| 1094 | + | |
| 1095 | + if (encap_node->tunnel_handle != INVALID_TUNNEL_HANDLE) | |
| 1096 | + goto done; | |
| 1097 | + | |
| 1098 | + rc = bnxt_tc_resolve_tunnel_hdrs(bp, encap_key, &encap_node->l2_info, | |
| 1099 | + flow->actions.dst_dev); | |
| 1100 | + if (rc) | |
| 1101 | + goto put_encap; | |
| 1102 | + | |
| 1103 | + /* Allocate a new tunnel encap record */ | |
| 1104 | + rc = hwrm_cfa_encap_record_alloc(bp, encap_key, &encap_node->l2_info, | |
| 1105 | + &encap_node->tunnel_handle); | |
| 1106 | + if (rc) | |
| 1107 | + goto put_encap; | |
| 1108 | + | |
| 1109 | +done: | |
| 1110 | + *encap_handle = encap_node->tunnel_handle; | |
| 1111 | + return 0; | |
| 1112 | + | |
| 1113 | +put_encap: | |
| 1114 | + bnxt_tc_put_tunnel_node(bp, &tc_info->encap_table, | |
| 1115 | + &tc_info->encap_ht_params, encap_node); | |
| 1116 | + return rc; | |
| 1117 | +} | |
| 1118 | + | |
| 1119 | +static void bnxt_tc_put_tunnel_handle(struct bnxt *bp, | |
| 1120 | + struct bnxt_tc_flow *flow, | |
| 1121 | + struct bnxt_tc_flow_node *flow_node) | |
| 1122 | +{ | |
| 1123 | + if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) | |
| 1124 | + bnxt_tc_put_decap_handle(bp, flow_node); | |
| 1125 | + else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) | |
| 1126 | + bnxt_tc_put_encap_handle(bp, flow_node->encap_node); | |
| 1127 | +} | |
| 1128 | + | |
| 1129 | +static int bnxt_tc_get_tunnel_handle(struct bnxt *bp, | |
| 1130 | + struct bnxt_tc_flow *flow, | |
| 1131 | + struct bnxt_tc_flow_node *flow_node, | |
| 1132 | + __le32 *tunnel_handle) | |
| 1133 | +{ | |
| 1134 | + if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) | |
| 1135 | + return bnxt_tc_get_decap_handle(bp, flow, flow_node, | |
| 1136 | + tunnel_handle); | |
| 1137 | + else if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) | |
| 1138 | + return bnxt_tc_get_encap_handle(bp, flow, flow_node, | |
| 1139 | + tunnel_handle); | |
| 1140 | + else | |
| 1141 | + return 0; | |
| 1142 | +} | |
| 593 | 1143 | static int __bnxt_tc_del_flow(struct bnxt *bp, |
| 594 | 1144 | struct bnxt_tc_flow_node *flow_node) |
| 595 | 1145 | { |
| 596 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1146 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 597 | 1147 | int rc; |
| 598 | 1148 | |
| 599 | 1149 | /* send HWRM cmd to free the flow-id */ |
| @@ -601,6 +1151,9 @@ static int __bnxt_tc_del_flow(struct bnxt *bp, · 1 unmodified line | ||
| 601 | 1151 | |
| 602 | 1152 | mutex_lock(&tc_info->lock); |
| 603 | 1153 | |
| 1154 | + /* release references to any tunnel encap/decap nodes */ | |
| 1155 | + bnxt_tc_put_tunnel_handle(bp, &flow_node->flow, flow_node); | |
| 1156 | + | |
| 604 | 1157 | /* release reference to l2 node */ |
| 605 | 1158 | bnxt_tc_put_l2_node(bp, flow_node); |
| 606 | 1159 | |
| @@ -633,8 +1186,9 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, · 26 unmodified lines | ||
| 633 | 1186 | struct tc_cls_flower_offload *tc_flow_cmd) |
| 634 | 1187 | { |
| 635 | 1188 | struct bnxt_tc_flow_node *new_node, *old_node; |
| 636 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1189 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 637 | 1190 | struct bnxt_tc_flow *flow; |
| 1191 | + __le32 tunnel_handle = 0; | |
| 638 | 1192 | __le16 ref_flow_handle; |
| 639 | 1193 | int rc; |
| 640 | 1194 | |
| @@ -672,12 +1226,19 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, · 31 unmodified lines | ||
| 672 | 1226 | if (rc) |
| 673 | 1227 | goto unlock; |
| 674 | 1228 | |
| 1229 | + /* If the flow involves tunnel encap/decap, get tunnel_handle */ | |
| 1230 | + rc = bnxt_tc_get_tunnel_handle(bp, flow, new_node, &tunnel_handle); | |
| 1231 | + if (rc) | |
| 1232 | + goto put_l2; | |
| 1233 | + | |
| 675 | 1234 | /* send HWRM cmd to alloc the flow */ |
| 676 | 1235 | rc = bnxt_hwrm_cfa_flow_alloc(bp, flow, ref_flow_handle, |
| 677 | − &new_node->flow_handle); | |
| 1236 | + tunnel_handle, &new_node->flow_handle); | |
| 678 | 1237 | if (rc) |
| 679 | − goto put_l2; | |
| 1238 | + goto put_tunnel; | |
| 680 | 1239 | |
| 1240 | + flow->lastused = jiffies; | |
| 1241 | + spin_lock_init(&flow->stats_lock); | |
| 681 | 1242 | /* add new flow to flow-table */ |
| 682 | 1243 | rc = rhashtable_insert_fast(&tc_info->flow_table, &new_node->node, |
| 683 | 1244 | tc_info->flow_ht_params); |
| @@ -689,12 +1250,14 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, · 5 unmodified lines | ||
| 689 | 1250 | |
| 690 | 1251 | hwrm_flow_free: |
| 691 | 1252 | bnxt_hwrm_cfa_flow_free(bp, new_node->flow_handle); |
| 1253 | +put_tunnel: | |
| 1254 | + bnxt_tc_put_tunnel_handle(bp, flow, new_node); | |
| 692 | 1255 | put_l2: |
| 693 | 1256 | bnxt_tc_put_l2_node(bp, new_node); |
| 694 | 1257 | unlock: |
| 695 | 1258 | mutex_unlock(&tc_info->lock); |
| 696 | 1259 | free_node: |
| 697 | − kfree(new_node); | |
| 1260 | + kfree_rcu(new_node, rcu); | |
| 698 | 1261 | done: |
| 699 | 1262 | netdev_err(bp->dev, "Error: %s: cookie=0x%lx error=%d", |
| 700 | 1263 | __func__, tc_flow_cmd->cookie, rc); |
| @@ -704,7 +1267,7 @@ done: · 3 unmodified lines | ||
| 704 | 1267 | static int bnxt_tc_del_flow(struct bnxt *bp, |
| 705 | 1268 | struct tc_cls_flower_offload *tc_flow_cmd) |
| 706 | 1269 | { |
| 707 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1270 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 708 | 1271 | struct bnxt_tc_flow_node *flow_node; |
| 709 | 1272 | |
| 710 | 1273 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, |
| @@ -722,10 +1285,11 @@ static int bnxt_tc_del_flow(struct bnxt *bp, · 11 unmodified lines | ||
| 722 | 1285 | static int bnxt_tc_get_flow_stats(struct bnxt *bp, |
| 723 | 1286 | struct tc_cls_flower_offload *tc_flow_cmd) |
| 724 | 1287 | { |
| 725 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1288 | + struct bnxt_tc_flow_stats stats, *curr_stats, *prev_stats; | |
| 1289 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 726 | 1290 | struct bnxt_tc_flow_node *flow_node; |
| 727 | − struct bnxt_tc_flow_stats stats; | |
| 728 | − int rc; | |
| 1291 | + struct bnxt_tc_flow *flow; | |
| 1292 | + unsigned long lastused; | |
| 729 | 1293 | |
| 730 | 1294 | flow_node = rhashtable_lookup_fast(&tc_info->flow_table, |
| 731 | 1295 | &tc_flow_cmd->cookie, |
| @@ -736,22 +1300,189 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp, · 4 unmodified lines | ||
| 736 | 1300 | return -1; |
| 737 | 1301 | } |
| 738 | 1302 | |
| 739 | − rc = bnxt_hwrm_cfa_flow_stats_get(bp, flow_node->flow_handle, | |
| 740 | − &flow_node->flow, &stats); | |
| 1303 | + flow = &flow_node->flow; | |
| 1304 | + curr_stats = &flow->stats; | |
| 1305 | + prev_stats = &flow->prev_stats; | |
| 1306 | + | |
| 1307 | + spin_lock(&flow->stats_lock); | |
| 1308 | + stats.packets = curr_stats->packets - prev_stats->packets; | |
| 1309 | + stats.bytes = curr_stats->bytes - prev_stats->bytes; | |
| 1310 | + *prev_stats = *curr_stats; | |
| 1311 | + lastused = flow->lastused; | |
| 1312 | + spin_unlock(&flow->stats_lock); | |
| 1313 | + | |
| 1314 | + tcf_exts_stats_update(tc_flow_cmd->exts, stats.bytes, stats.packets, | |
| 1315 | + lastused); | |
| 1316 | + return 0; | |
| 1317 | +} | |
| 1318 | + | |
| 1319 | +static int | |
| 1320 | +bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows, | |
| 1321 | + struct bnxt_tc_stats_batch stats_batch[]) | |
| 1322 | +{ | |
| 1323 | + struct hwrm_cfa_flow_stats_output *resp = bp->hwrm_cmd_resp_addr; | |
| 1324 | + struct hwrm_cfa_flow_stats_input req = { 0 }; | |
| 1325 | + __le16 *req_flow_handles = &req.flow_handle_0; | |
| 1326 | + int rc, i; | |
| 1327 | + | |
| 1328 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_STATS, -1, -1); | |
| 1329 | + req.num_flows = cpu_to_le16(num_flows); | |
| 1330 | + for (i = 0; i < num_flows; i++) { | |
| 1331 | + struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node; | |
| 1332 | + | |
| 1333 | + req_flow_handles[i] = flow_node->flow_handle; | |
| 1334 | + } | |
| 1335 | + | |
| 1336 | + mutex_lock(&bp->hwrm_cmd_lock); | |
| 1337 | + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | |
| 1338 | + if (!rc) { | |
| 1339 | + __le64 *resp_packets = &resp->packet_0; | |
| 1340 | + __le64 *resp_bytes = &resp->byte_0; | |
| 1341 | + | |
| 1342 | + for (i = 0; i < num_flows; i++) { | |
| 1343 | + stats_batch[i].hw_stats.packets = | |
| 1344 | + le64_to_cpu(resp_packets[i]); | |
| 1345 | + stats_batch[i].hw_stats.bytes = | |
| 1346 | + le64_to_cpu(resp_bytes[i]); | |
| 1347 | + } | |
| 1348 | + } else { | |
| 1349 | + netdev_info(bp->dev, "error rc=%d", rc); | |
| 1350 | + } | |
| 1351 | + | |
| 1352 | + mutex_unlock(&bp->hwrm_cmd_lock); | |
| 1353 | + return rc; | |
| 1354 | +} | |
| 1355 | + | |
| 1356 | +/* Add val to accum while handling a possible wraparound | |
| 1357 | + * of val. Eventhough val is of type u64, its actual width | |
| 1358 | + * is denoted by mask and will wrap-around beyond that width. | |
| 1359 | + */ | |
| 1360 | +static void accumulate_val(u64 *accum, u64 val, u64 mask) | |
| 1361 | +{ | |
| 1362 | +#define low_bits(x, mask) ((x) & (mask)) | |
| 1363 | +#define high_bits(x, mask) ((x) & ~(mask)) | |
| 1364 | + bool wrapped = val < low_bits(*accum, mask); | |
| 1365 | + | |
| 1366 | + *accum = high_bits(*accum, mask) + val; | |
| 1367 | + if (wrapped) | |
| 1368 | + *accum += (mask + 1); | |
| 1369 | +} | |
| 1370 | + | |
| 1371 | +/* The HW counters' width is much less than 64bits. | |
| 1372 | + * Handle possible wrap-around while updating the stat counters | |
| 1373 | + */ | |
| 1374 | +static void bnxt_flow_stats_accum(struct bnxt_tc_info *tc_info, | |
| 1375 | + struct bnxt_tc_flow_stats *acc_stats, | |
| 1376 | + struct bnxt_tc_flow_stats *hw_stats) | |
| 1377 | +{ | |
| 1378 | + accumulate_val(&acc_stats->bytes, hw_stats->bytes, tc_info->bytes_mask); | |
| 1379 | + accumulate_val(&acc_stats->packets, hw_stats->packets, | |
| 1380 | + tc_info->packets_mask); | |
| 1381 | +} | |
| 1382 | + | |
| 1383 | +static int | |
| 1384 | +bnxt_tc_flow_stats_batch_update(struct bnxt *bp, int num_flows, | |
| 1385 | + struct bnxt_tc_stats_batch stats_batch[]) | |
| 1386 | +{ | |
| 1387 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 1388 | + int rc, i; | |
| 1389 | + | |
| 1390 | + rc = bnxt_hwrm_cfa_flow_stats_get(bp, num_flows, stats_batch); | |
| 741 | 1391 | if (rc) |
| 742 | 1392 | return rc; |
| 743 | 1393 | |
| 744 | − tcf_exts_stats_update(tc_flow_cmd->exts, stats.bytes, stats.packets, 0); | |
| 1394 | + for (i = 0; i < num_flows; i++) { | |
| 1395 | + struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node; | |
| 1396 | + struct bnxt_tc_flow *flow = &flow_node->flow; | |
| 1397 | + | |
| 1398 | + spin_lock(&flow->stats_lock); | |
| 1399 | + bnxt_flow_stats_accum(tc_info, &flow->stats, | |
| 1400 | + &stats_batch[i].hw_stats); | |
| 1401 | + if (flow->stats.packets != flow->prev_stats.packets) | |
| 1402 | + flow->lastused = jiffies; | |
| 1403 | + spin_unlock(&flow->stats_lock); | |
| 1404 | + } | |
| 1405 | + | |
| 745 | 1406 | return 0; |
| 746 | 1407 | } |
| 747 | 1408 | |
| 1409 | +static int | |
| 1410 | +bnxt_tc_flow_stats_batch_prep(struct bnxt *bp, | |
| 1411 | + struct bnxt_tc_stats_batch stats_batch[], | |
| 1412 | + int *num_flows) | |
| 1413 | +{ | |
| 1414 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 1415 | + struct rhashtable_iter *iter = &tc_info->iter; | |
| 1416 | + void *flow_node; | |
| 1417 | + int rc, i; | |
| 1418 | + | |
| 1419 | + rc = rhashtable_walk_start(iter); | |
| 1420 | + if (rc && rc != -EAGAIN) { | |
| 1421 | + i = 0; | |
| 1422 | + goto done; | |
| 1423 | + } | |
| 1424 | + | |
| 1425 | + rc = 0; | |
| 1426 | + for (i = 0; i < BNXT_FLOW_STATS_BATCH_MAX; i++) { | |
| 1427 | + flow_node = rhashtable_walk_next(iter); | |
| 1428 | + if (IS_ERR(flow_node)) { | |
| 1429 | + i = 0; | |
| 1430 | + if (PTR_ERR(flow_node) == -EAGAIN) { | |
| 1431 | + continue; | |
| 1432 | + } else { | |
| 1433 | + rc = PTR_ERR(flow_node); | |
| 1434 | + goto done; | |
| 1435 | + } | |
| 1436 | + } | |
| 1437 | + | |
| 1438 | + /* No more flows */ | |
| 1439 | + if (!flow_node) | |
| 1440 | + goto done; | |
| 1441 | + | |
| 1442 | + stats_batch[i].flow_node = flow_node; | |
| 1443 | + } | |
| 1444 | +done: | |
| 1445 | + rhashtable_walk_stop(iter); | |
| 1446 | + *num_flows = i; | |
| 1447 | + return rc; | |
| 1448 | +} | |
| 1449 | + | |
| 1450 | +void bnxt_tc_flow_stats_work(struct bnxt *bp) | |
| 1451 | +{ | |
| 1452 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 1453 | + int num_flows, rc; | |
| 1454 | + | |
| 1455 | + num_flows = atomic_read(&tc_info->flow_table.nelems); | |
| 1456 | + if (!num_flows) | |
| 1457 | + return; | |
| 1458 | + | |
| 1459 | + rhashtable_walk_enter(&tc_info->flow_table, &tc_info->iter); | |
| 1460 | + | |
| 1461 | + for (;;) { | |
| 1462 | + rc = bnxt_tc_flow_stats_batch_prep(bp, tc_info->stats_batch, | |
| 1463 | + &num_flows); | |
| 1464 | + if (rc) { | |
| 1465 | + if (rc == -EAGAIN) | |
| 1466 | + continue; | |
| 1467 | + break; | |
| 1468 | + } | |
| 1469 | + | |
| 1470 | + if (!num_flows) | |
| 1471 | + break; | |
| 1472 | + | |
| 1473 | + bnxt_tc_flow_stats_batch_update(bp, num_flows, | |
| 1474 | + tc_info->stats_batch); | |
| 1475 | + } | |
| 1476 | + | |
| 1477 | + rhashtable_walk_exit(&tc_info->iter); | |
| 1478 | +} | |
| 1479 | + | |
| 748 | 1480 | int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, |
| 749 | 1481 | struct tc_cls_flower_offload *cls_flower) |
| 750 | 1482 | { |
| 751 | 1483 | int rc = 0; |
| 752 | 1484 | |
| 753 | − if (!is_classid_clsact_ingress(cls_flower->common.classid) || | |
| 754 | − cls_flower->common.chain_index) | |
| 1485 | + if (cls_flower->common.chain_index) | |
| 755 | 1486 | return -EOPNOTSUPP; |
| 756 | 1487 | |
| 757 | 1488 | switch (cls_flower->command) { |
| @@ -784,19 +1515,37 @@ static const struct rhashtable_params bnxt_tc_l2_ht_params = { · 26 unmodified lines | ||
| 784 | 1515 | .automatic_shrinking = true |
| 785 | 1516 | }; |
| 786 | 1517 | |
| 1518 | +static const struct rhashtable_params bnxt_tc_decap_l2_ht_params = { | |
| 1519 | + .head_offset = offsetof(struct bnxt_tc_l2_node, node), | |
| 1520 | + .key_offset = offsetof(struct bnxt_tc_l2_node, key), | |
| 1521 | + .key_len = BNXT_TC_L2_KEY_LEN, | |
| 1522 | + .automatic_shrinking = true | |
| 1523 | +}; | |
| 1524 | + | |
| 1525 | +static const struct rhashtable_params bnxt_tc_tunnel_ht_params = { | |
| 1526 | + .head_offset = offsetof(struct bnxt_tc_tunnel_node, node), | |
| 1527 | + .key_offset = offsetof(struct bnxt_tc_tunnel_node, key), | |
| 1528 | + .key_len = sizeof(struct ip_tunnel_key), | |
| 1529 | + .automatic_shrinking = true | |
| 1530 | +}; | |
| 1531 | + | |
| 787 | 1532 | /* convert counter width in bits to a mask */ |
| 788 | 1533 | #define mask(width) ((u64)~0 >> (64 - (width))) |
| 789 | 1534 | |
| 790 | 1535 | int bnxt_init_tc(struct bnxt *bp) |
| 791 | 1536 | { |
| 792 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1537 | + struct bnxt_tc_info *tc_info; | |
| 793 | 1538 | int rc; |
| 794 | 1539 | |
| 795 | − if (bp->hwrm_spec_code < 0x10800) { | |
| 1540 | + if (bp->hwrm_spec_code < 0x10803) { | |
| 796 | 1541 | netdev_warn(bp->dev, |
| 797 | 1542 | "Firmware does not support TC flower offload.\n"); |
| 798 | 1543 | return -ENOTSUPP; |
| 799 | 1544 | } |
| 1545 | + | |
| 1546 | + tc_info = kzalloc(sizeof(*tc_info), GFP_KERNEL); | |
| 1547 | + if (!tc_info) | |
| 1548 | + return -ENOMEM; | |
| 800 | 1549 | mutex_init(&tc_info->lock); |
| 801 | 1550 | |
| 802 | 1551 | /* Counter widths are programmed by FW */ |
| @@ -806,33 +1555,62 @@ int bnxt_init_tc(struct bnxt *bp) · 3 unmodified lines | ||
| 806 | 1555 | tc_info->flow_ht_params = bnxt_tc_flow_ht_params; |
| 807 | 1556 | rc = rhashtable_init(&tc_info->flow_table, &tc_info->flow_ht_params); |
| 808 | 1557 | if (rc) |
| 809 | − return rc; | |
| 1558 | + goto free_tc_info; | |
| 810 | 1559 | |
| 811 | 1560 | tc_info->l2_ht_params = bnxt_tc_l2_ht_params; |
| 812 | 1561 | rc = rhashtable_init(&tc_info->l2_table, &tc_info->l2_ht_params); |
| 813 | 1562 | if (rc) |
| 814 | 1563 | goto destroy_flow_table; |
| 815 | 1564 | |
| 1565 | + tc_info->decap_l2_ht_params = bnxt_tc_decap_l2_ht_params; | |
| 1566 | + rc = rhashtable_init(&tc_info->decap_l2_table, | |
| 1567 | + &tc_info->decap_l2_ht_params); | |
| 1568 | + if (rc) | |
| 1569 | + goto destroy_l2_table; | |
| 1570 | + | |
| 1571 | + tc_info->decap_ht_params = bnxt_tc_tunnel_ht_params; | |
| 1572 | + rc = rhashtable_init(&tc_info->decap_table, | |
| 1573 | + &tc_info->decap_ht_params); | |
| 1574 | + if (rc) | |
| 1575 | + goto destroy_decap_l2_table; | |
| 1576 | + | |
| 1577 | + tc_info->encap_ht_params = bnxt_tc_tunnel_ht_params; | |
| 1578 | + rc = rhashtable_init(&tc_info->encap_table, | |
| 1579 | + &tc_info->encap_ht_params); | |
| 1580 | + if (rc) | |
| 1581 | + goto destroy_decap_table; | |
| 1582 | + | |
| 816 | 1583 | tc_info->enabled = true; |
| 817 | 1584 | bp->dev->hw_features |= NETIF_F_HW_TC; |
| 818 | 1585 | bp->dev->features |= NETIF_F_HW_TC; |
| 1586 | + bp->tc_info = tc_info; | |
| 819 | 1587 | return 0; |
| 820 | 1588 | |
| 1589 | +destroy_decap_table: | |
| 1590 | + rhashtable_destroy(&tc_info->decap_table); | |
| 1591 | +destroy_decap_l2_table: | |
| 1592 | + rhashtable_destroy(&tc_info->decap_l2_table); | |
| 1593 | +destroy_l2_table: | |
| 1594 | + rhashtable_destroy(&tc_info->l2_table); | |
| 821 | 1595 | destroy_flow_table: |
| 822 | 1596 | rhashtable_destroy(&tc_info->flow_table); |
| 1597 | +free_tc_info: | |
| 1598 | + kfree(tc_info); | |
| 823 | 1599 | return rc; |
| 824 | 1600 | } |
| 825 | 1601 | |
| 826 | 1602 | void bnxt_shutdown_tc(struct bnxt *bp) |
| 827 | 1603 | { |
| 828 | − struct bnxt_tc_info *tc_info = &bp->tc_info; | |
| 1604 | + struct bnxt_tc_info *tc_info = bp->tc_info; | |
| 829 | 1605 | |
| 830 | − if (!tc_info->enabled) | |
| 1606 | + if (!bnxt_tc_flower_enabled(bp)) | |
| 831 | 1607 | return; |
| 832 | 1608 | |
| 833 | 1609 | rhashtable_destroy(&tc_info->flow_table); |
| 834 | 1610 | rhashtable_destroy(&tc_info->l2_table); |
| 1611 | + rhashtable_destroy(&tc_info->decap_l2_table); | |
| 1612 | + rhashtable_destroy(&tc_info->decap_table); | |
| 1613 | + rhashtable_destroy(&tc_info->encap_table); | |
| 1614 | + kfree(tc_info); | |
| 1615 | + bp->tc_info = NULL; | |
| 835 | 1616 | } |
| 836 | − | |
| 837 | −#else | |
| 838 | −#endif | |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #ifdef CONFIG_BNXT_FLOWER_OFFLOAD |
| 14 | 14 | |
| 15 | +#include <net/ip_tunnels.h> | |
| 16 | + | |
| 15 | 17 | /* Structs used for storing the filter/actions of the TC cmd. |
| 16 | 18 | */ |
| 17 | 19 | struct bnxt_tc_l2_key { |
| @@ -50,6 +52,13 @@ struct bnxt_tc_l4_key { · 32 unmodified lines | ||
| 50 | 52 | }; |
| 51 | 53 | }; |
| 52 | 54 | |
| 55 | +struct bnxt_tc_tunnel_key { | |
| 56 | + struct bnxt_tc_l2_key l2; | |
| 57 | + struct bnxt_tc_l3_key l3; | |
| 58 | + struct bnxt_tc_l4_key l4; | |
| 59 | + __be32 id; | |
| 60 | +}; | |
| 61 | + | |
| 53 | 62 | struct bnxt_tc_actions { |
| 54 | 63 | u32 flags; |
| 55 | 64 | #define BNXT_TC_ACTION_FLAG_FWD BIT(0) |
| @@ -57,16 +66,16 @@ struct bnxt_tc_actions { · 1 unmodified line | ||
| 57 | 66 | #define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3) |
| 58 | 67 | #define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4) |
| 59 | 68 | #define BNXT_TC_ACTION_FLAG_DROP BIT(5) |
| 69 | +#define BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP BIT(6) | |
| 70 | +#define BNXT_TC_ACTION_FLAG_TUNNEL_DECAP BIT(7) | |
| 60 | 71 | |
| 61 | 72 | u16 dst_fid; |
| 62 | 73 | struct net_device *dst_dev; |
| 63 | 74 | __be16 push_vlan_tpid; |
| 64 | 75 | __be16 push_vlan_tci; |
| 65 | −}; | |
| 66 | 76 | |
| 67 | −struct bnxt_tc_flow_stats { | |
| 68 | − u64 packets; | |
| 69 | − u64 bytes; | |
| 77 | + /* tunnel encap */ | |
| 78 | + struct ip_tunnel_key tun_encap_key; | |
| 70 | 79 | }; |
| 71 | 80 | |
| 72 | 81 | struct bnxt_tc_flow { |
| @@ -76,6 +85,16 @@ struct bnxt_tc_flow { · 3 unmodified lines | ||
| 76 | 85 | #define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3) |
| 77 | 86 | #define BNXT_TC_FLOW_FLAGS_PORTS BIT(4) |
| 78 | 87 | #define BNXT_TC_FLOW_FLAGS_ICMP BIT(5) |
| 88 | +#define BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS BIT(6) | |
| 89 | +#define BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS BIT(7) | |
| 90 | +#define BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS BIT(8) | |
| 91 | +#define BNXT_TC_FLOW_FLAGS_TUNL_PORTS BIT(9) | |
| 92 | +#define BNXT_TC_FLOW_FLAGS_TUNL_ID BIT(10) | |
| 93 | +#define BNXT_TC_FLOW_FLAGS_TUNNEL (BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS | \ | |
| 94 | + BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS | \ | |
| 95 | + BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS |\ | |
| 96 | + BNXT_TC_FLOW_FLAGS_TUNL_PORTS |\ | |
| 97 | + BNXT_TC_FLOW_FLAGS_TUNL_ID) | |
| 79 | 98 | |
| 80 | 99 | /* flow applicable to pkts ingressing on this fid */ |
| 81 | 100 | u16 src_fid; |
| @@ -85,6 +104,8 @@ struct bnxt_tc_flow { · 3 unmodified lines | ||
| 85 | 104 | struct bnxt_tc_l3_key l3_mask; |
| 86 | 105 | struct bnxt_tc_l4_key l4_key; |
| 87 | 106 | struct bnxt_tc_l4_key l4_mask; |
| 107 | + struct ip_tunnel_key tun_key; | |
| 108 | + struct ip_tunnel_key tun_mask; | |
| 88 | 109 | |
| 89 | 110 | struct bnxt_tc_actions actions; |
| 90 | 111 | |
| @@ -93,13 +114,39 @@ struct bnxt_tc_flow { · 2 unmodified lines | ||
| 93 | 114 | /* previous snap-shot of stats */ |
| 94 | 115 | struct bnxt_tc_flow_stats prev_stats; |
| 95 | 116 | unsigned long lastused; /* jiffies */ |
| 117 | + /* for calculating delta from prev_stats and | |
| 118 | + * updating prev_stats atomically. | |
| 119 | + */ | |
| 120 | + spinlock_t stats_lock; | |
| 121 | +}; | |
| 122 | + | |
| 123 | +/* Tunnel encap/decap hash table | |
| 124 | + * This table is used to maintain a list of flows that use | |
| 125 | + * the same tunnel encap/decap params (ip_daddrs, vni, udp_dport) | |
| 126 | + * and the FW returned handle. | |
| 127 | + * A separate table is maintained for encap and decap | |
| 128 | + */ | |
| 129 | +struct bnxt_tc_tunnel_node { | |
| 130 | + struct ip_tunnel_key key; | |
| 131 | + struct rhash_head node; | |
| 132 | + | |
| 133 | + /* tunnel l2 info */ | |
| 134 | + struct bnxt_tc_l2_key l2_info; | |
| 135 | + | |
| 136 | +#define INVALID_TUNNEL_HANDLE cpu_to_le32(0xffffffff) | |
| 137 | + /* tunnel handle returned by FW */ | |
| 138 | + __le32 tunnel_handle; | |
| 139 | + | |
| 140 | + u32 refcount; | |
| 141 | + struct rcu_head rcu; | |
| 96 | 142 | }; |
| 97 | 143 | |
| 98 | 144 | /* L2 hash table |
| 99 | − * This data-struct is used for L2-flow table. | |
| 100 | − * The L2 part of a flow is stored in a hash table. | |
| 145 | + * The same data-struct is used for L2-flow table and L2-tunnel table. | |
| 146 | + * The L2 part of a flow or tunnel is stored in a hash table. | |
| 101 | 147 | * A flow that shares the same L2 key/mask with an |
| 102 | − * already existing flow must refer to it's flow handle. | |
| 148 | + * already existing flow/tunnel must refer to it's flow handle or | |
| 149 | + * decap_filter_id respectively. | |
| 103 | 150 | */ |
| 104 | 151 | struct bnxt_tc_l2_node { |
| 105 | 152 | /* hash key: first 16b of key */ |
| @@ -110,7 +157,7 @@ struct bnxt_tc_l2_node { · 4 unmodified lines | ||
| 110 | 157 | /* a linked list of flows that share the same l2 key */ |
| 111 | 158 | struct list_head common_l2_flows; |
| 112 | 159 | |
| 113 | − /* number of flows sharing the l2 key */ | |
| 160 | + /* number of flows/tunnels sharing the l2 key */ | |
| 114 | 161 | u16 refcount; |
| 115 | 162 | |
| 116 | 163 | struct rcu_head rcu; |
| @@ -130,6 +177,16 @@ struct bnxt_tc_flow_node { · 13 unmodified lines | ||
| 130 | 177 | /* for the shared_flows list maintained in l2_node */ |
| 131 | 178 | struct list_head l2_list_node; |
| 132 | 179 | |
| 180 | + /* tunnel encap related */ | |
| 181 | + struct bnxt_tc_tunnel_node *encap_node; | |
| 182 | + | |
| 183 | + /* tunnel decap related */ | |
| 184 | + struct bnxt_tc_tunnel_node *decap_node; | |
| 185 | + /* L2 node in tunnel-l2 hashtable that shares flow's tunnel l2 key */ | |
| 186 | + struct bnxt_tc_l2_node *decap_l2_node; | |
| 187 | + /* for the shared_flows list maintained in tunnel decap l2_node */ | |
| 188 | + struct list_head decap_l2_list_node; | |
| 189 | + | |
| 133 | 190 | struct rcu_head rcu; |
| 134 | 191 | }; |
| 135 | 192 | |
| @@ -137,6 +194,12 @@ int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, · 1 unmodified line | ||
| 137 | 194 | struct tc_cls_flower_offload *cls_flower); |
| 138 | 195 | int bnxt_init_tc(struct bnxt *bp); |
| 139 | 196 | void bnxt_shutdown_tc(struct bnxt *bp); |
| 197 | +void bnxt_tc_flow_stats_work(struct bnxt *bp); | |
| 198 | + | |
| 199 | +static inline bool bnxt_tc_flower_enabled(struct bnxt *bp) | |
| 200 | +{ | |
| 201 | + return bp->tc_info && bp->tc_info->enabled; | |
| 202 | +} | |
| 140 | 203 | |
| 141 | 204 | #else /* CONFIG_BNXT_FLOWER_OFFLOAD */ |
| 142 | 205 | |
| @@ -154,5 +217,14 @@ static inline int bnxt_init_tc(struct bnxt *bp) · 11 unmodified lines | ||
| 154 | 217 | static inline void bnxt_shutdown_tc(struct bnxt *bp) |
| 155 | 218 | { |
| 156 | 219 | } |
| 220 | + | |
| 221 | +static inline void bnxt_tc_flow_stats_work(struct bnxt *bp) | |
| 222 | +{ | |
| 223 | +} | |
| 224 | + | |
| 225 | +static inline bool bnxt_tc_flower_enabled(struct bnxt *bp) | |
| 226 | +{ | |
| 227 | + return false; | |
| 228 | +} | |
| 157 | 229 | #endif /* CONFIG_BNXT_FLOWER_OFFLOAD */ |
| 158 | 230 | #endif /* BNXT_TC_H */ |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include "bnxt_hsi.h" |
| 17 | 17 | #include "bnxt.h" |
| 18 | 18 | #include "bnxt_vfr.h" |
| 19 | +#include "bnxt_devlink.h" | |
| 19 | 20 | #include "bnxt_tc.h" |
| 20 | 21 | |
| 21 | 22 | #ifdef CONFIG_BNXT_SRIOV |
| @@ -115,13 +116,17 @@ bnxt_vf_rep_get_stats64(struct net_device *dev, · 93 unmodified lines | ||
| 115 | 116 | stats->tx_bytes = vf_rep->tx_stats.bytes; |
| 116 | 117 | } |
| 117 | 118 | |
| 118 | −static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, | |
| 119 | − void *type_data) | |
| 119 | +static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type, | |
| 120 | + void *type_data, | |
| 121 | + void *cb_priv) | |
| 120 | 122 | { |
| 121 | − struct bnxt_vf_rep *vf_rep = netdev_priv(dev); | |
| 123 | + struct bnxt_vf_rep *vf_rep = cb_priv; | |
| 122 | 124 | struct bnxt *bp = vf_rep->bp; |
| 123 | 125 | int vf_fid = bp->pf.vf[vf_rep->vf_idx].fw_fid; |
| 124 | 126 | |
| 127 | + if (!bnxt_tc_flower_enabled(vf_rep->bp) || !tc_can_offload(bp->dev)) | |
| 128 | + return -EOPNOTSUPP; | |
| 129 | + | |
| 125 | 130 | switch (type) { |
| 126 | 131 | case TC_SETUP_CLSFLOWER: |
| 127 | 132 | return bnxt_tc_setup_flower(bp, vf_fid, type_data); |
| @@ -130,6 +135,39 @@ static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, · 2 unmodified lines | ||
| 130 | 135 | } |
| 131 | 136 | } |
| 132 | 137 | |
| 138 | +static int bnxt_vf_rep_setup_tc_block(struct net_device *dev, | |
| 139 | + struct tc_block_offload *f) | |
| 140 | +{ | |
| 141 | + struct bnxt_vf_rep *vf_rep = netdev_priv(dev); | |
| 142 | + | |
| 143 | + if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) | |
| 144 | + return -EOPNOTSUPP; | |
| 145 | + | |
| 146 | + switch (f->command) { | |
| 147 | + case TC_BLOCK_BIND: | |
| 148 | + return tcf_block_cb_register(f->block, | |
| 149 | + bnxt_vf_rep_setup_tc_block_cb, | |
| 150 | + vf_rep, vf_rep); | |
| 151 | + case TC_BLOCK_UNBIND: | |
| 152 | + tcf_block_cb_unregister(f->block, | |
| 153 | + bnxt_vf_rep_setup_tc_block_cb, vf_rep); | |
| 154 | + return 0; | |
| 155 | + default: | |
| 156 | + return -EOPNOTSUPP; | |
| 157 | + } | |
| 158 | +} | |
| 159 | + | |
| 160 | +static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, | |
| 161 | + void *type_data) | |
| 162 | +{ | |
| 163 | + switch (type) { | |
| 164 | + case TC_SETUP_BLOCK: | |
| 165 | + return bnxt_vf_rep_setup_tc_block(dev, type_data); | |
| 166 | + default: | |
| 167 | + return -EOPNOTSUPP; | |
| 168 | + } | |
| 169 | +} | |
| 170 | + | |
| 133 | 171 | struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code) |
| 134 | 172 | { |
| 135 | 173 | u16 vf_idx; |
| @@ -416,7 +454,7 @@ err: · 280 unmodified lines | ||
| 416 | 454 | } |
| 417 | 455 | |
| 418 | 456 | /* Devlink related routines */ |
| 419 | −static int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) | |
| 457 | +int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) | |
| 420 | 458 | { |
| 421 | 459 | struct bnxt *bp = bnxt_get_bp_from_dl(devlink); |
| 422 | 460 | |
| @@ -424,7 +462,7 @@ static int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) · 1 unmodified line | ||
| 424 | 462 | return 0; |
| 425 | 463 | } |
| 426 | 464 | |
| 427 | −static int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode) | |
| 465 | +int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode) | |
| 428 | 466 | { |
| 429 | 467 | struct bnxt *bp = bnxt_get_bp_from_dl(devlink); |
| 430 | 468 | int rc = 0; |
| @@ -462,52 +500,4 @@ done: · 31 unmodified lines | ||
| 462 | 500 | return rc; |
| 463 | 501 | } |
| 464 | 502 | |
| 465 | −static const struct devlink_ops bnxt_dl_ops = { | |
| 466 | − .eswitch_mode_set = bnxt_dl_eswitch_mode_set, | |
| 467 | − .eswitch_mode_get = bnxt_dl_eswitch_mode_get | |
| 468 | −}; | |
| 469 | − | |
| 470 | −int bnxt_dl_register(struct bnxt *bp) | |
| 471 | −{ | |
| 472 | − struct devlink *dl; | |
| 473 | − int rc; | |
| 474 | − | |
| 475 | − if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) | |
| 476 | − return 0; | |
| 477 | − | |
| 478 | − if (bp->hwrm_spec_code < 0x10800) { | |
| 479 | − netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); | |
| 480 | − return -ENOTSUPP; | |
| 481 | − } | |
| 482 | − | |
| 483 | − dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); | |
| 484 | − if (!dl) { | |
| 485 | − netdev_warn(bp->dev, "devlink_alloc failed"); | |
| 486 | − return -ENOMEM; | |
| 487 | − } | |
| 488 | − | |
| 489 | − bnxt_link_bp_to_dl(bp, dl); | |
| 490 | − bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; | |
| 491 | − rc = devlink_register(dl, &bp->pdev->dev); | |
| 492 | − if (rc) { | |
| 493 | − bnxt_link_bp_to_dl(bp, NULL); | |
| 494 | − devlink_free(dl); | |
| 495 | − netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc); | |
| 496 | − return rc; | |
| 497 | − } | |
| 498 | − | |
| 499 | − return 0; | |
| 500 | −} | |
| 501 | − | |
| 502 | −void bnxt_dl_unregister(struct bnxt *bp) | |
| 503 | −{ | |
| 504 | − struct devlink *dl = bp->dl; | |
| 505 | − | |
| 506 | − if (!dl) | |
| 507 | − return; | |
| 508 | − | |
| 509 | − devlink_unregister(dl); | |
| 510 | − devlink_free(dl); | |
| 511 | −} | |
| 512 | − | |
| 513 | 503 | #endif |
| @@ -14,31 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #define MAX_CFA_CODE 65536 |
| 16 | 16 | |
| 17 | −/* Struct to hold housekeeping info needed by devlink interface */ | |
| 18 | −struct bnxt_dl { | |
| 19 | − struct bnxt *bp; /* back ptr to the controlling dev */ | |
| 20 | −}; | |
| 21 | − | |
| 22 | −static inline struct bnxt *bnxt_get_bp_from_dl(struct devlink *dl) | |
| 23 | −{ | |
| 24 | − return ((struct bnxt_dl *)devlink_priv(dl))->bp; | |
| 25 | −} | |
| 26 | − | |
| 27 | −/* To clear devlink pointer from bp, pass NULL dl */ | |
| 28 | −static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) | |
| 29 | −{ | |
| 30 | − bp->dl = dl; | |
| 31 | − | |
| 32 | − /* add a back pointer in dl to bp */ | |
| 33 | − if (dl) { | |
| 34 | − struct bnxt_dl *bp_dl = devlink_priv(dl); | |
| 35 | − | |
| 36 | − bp_dl->bp = bp; | |
| 37 | − } | |
| 38 | −} | |
| 39 | − | |
| 40 | −int bnxt_dl_register(struct bnxt *bp); | |
| 41 | −void bnxt_dl_unregister(struct bnxt *bp); | |
| 42 | 17 | void bnxt_vf_reps_destroy(struct bnxt *bp); |
| 43 | 18 | void bnxt_vf_reps_close(struct bnxt *bp); |
| 44 | 19 | void bnxt_vf_reps_open(struct bnxt *bp); |
| @@ -53,16 +28,10 @@ static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev) · 8 unmodified lines | ||
| 53 | 28 | return bp->pf.vf[vf_rep->vf_idx].fw_fid; |
| 54 | 29 | } |
| 55 | 30 | |
| 56 | −#else | |
| 57 | − | |
| 58 | −static inline int bnxt_dl_register(struct bnxt *bp) | |
| 59 | −{ | |
| 60 | − return 0; | |
| 61 | −} | |
| 31 | +int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode); | |
| 32 | +int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode); | |
| 62 | 33 | |
| 63 | −static inline void bnxt_dl_unregister(struct bnxt *bp) | |
| 64 | −{ | |
| 65 | −} | |
| 34 | +#else | |
| 66 | 35 | |
| 67 | 36 | static inline void bnxt_vf_reps_close(struct bnxt *bp) |
| 68 | 37 | { |
| @@ -94,6 +94,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | xdp.data_hard_start = *data_ptr - offset; |
| 96 | 96 | xdp.data = *data_ptr; |
| 97 | + xdp_set_data_meta_invalid(&xdp); | |
| 97 | 98 | xdp.data_end = *data_ptr + *len; |
| 98 | 99 | orig_data = xdp.data; |
| 99 | 100 | mapping = rx_buf->mapping - bp->rx_dma_offset; |
| @@ -207,7 +208,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog) · 107 unmodified lines | ||
| 207 | 208 | return 0; |
| 208 | 209 | } |
| 209 | 210 | |
| 210 | −int bnxt_xdp(struct net_device *dev, struct netdev_xdp *xdp) | |
| 211 | +int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp) | |
| 211 | 212 | { |
| 212 | 213 | struct bnxt *bp = netdev_priv(dev); |
| 213 | 214 | int rc; |
| @@ -16,6 +16,6 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts); · 15 unmodified lines | ||
| 16 | 16 | bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, |
| 17 | 17 | struct page *page, u8 **data_ptr, unsigned int *len, |
| 18 | 18 | u8 *event); |
| 19 | −int bnxt_xdp(struct net_device *dev, struct netdev_xdp *xdp); | |
| 19 | +int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp); | |
| 20 | 20 | |
| 21 | 21 | #endif |
| @@ -488,15 +488,13 @@ static void bcmgenet_complete(struct net_device *dev) · 487 unmodified lines | ||
| 488 | 488 | static int bcmgenet_get_link_ksettings(struct net_device *dev, |
| 489 | 489 | struct ethtool_link_ksettings *cmd) |
| 490 | 490 | { |
| 491 | − struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 492 | − | |
| 493 | 491 | if (!netif_running(dev)) |
| 494 | 492 | return -EINVAL; |
| 495 | 493 | |
| 496 | − if (!priv->phydev) | |
| 494 | + if (!dev->phydev) | |
| 497 | 495 | return -ENODEV; |
| 498 | 496 | |
| 499 | − phy_ethtool_ksettings_get(priv->phydev, cmd); | |
| 497 | + phy_ethtool_ksettings_get(dev->phydev, cmd); | |
| 500 | 498 | |
| 501 | 499 | return 0; |
| 502 | 500 | } |
| @@ -504,15 +502,13 @@ static int bcmgenet_get_link_ksettings(struct net_device *dev, · 1 unmodified line | ||
| 504 | 502 | static int bcmgenet_set_link_ksettings(struct net_device *dev, |
| 505 | 503 | const struct ethtool_link_ksettings *cmd) |
| 506 | 504 | { |
| 507 | − struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 508 | − | |
| 509 | 505 | if (!netif_running(dev)) |
| 510 | 506 | return -EINVAL; |
| 511 | 507 | |
| 512 | − if (!priv->phydev) | |
| 508 | + if (!dev->phydev) | |
| 513 | 509 | return -ENODEV; |
| 514 | 510 | |
| 515 | − return phy_ethtool_ksettings_set(priv->phydev, cmd); | |
| 511 | + return phy_ethtool_ksettings_set(dev->phydev, cmd); | |
| 516 | 512 | } |
| 517 | 513 | |
| 518 | 514 | static int bcmgenet_set_rx_csum(struct net_device *dev, |
| @@ -1042,11 +1038,14 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e) · 523 unmodified lines | ||
| 1042 | 1038 | if (GENET_IS_V1(priv)) |
| 1043 | 1039 | return -EOPNOTSUPP; |
| 1044 | 1040 | |
| 1041 | + if (!dev->phydev) | |
| 1042 | + return -ENODEV; | |
| 1043 | + | |
| 1045 | 1044 | e->eee_enabled = p->eee_enabled; |
| 1046 | 1045 | e->eee_active = p->eee_active; |
| 1047 | 1046 | e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER); |
| 1048 | 1047 | |
| 1049 | − return phy_ethtool_get_eee(priv->phydev, e); | |
| 1048 | + return phy_ethtool_get_eee(dev->phydev, e); | |
| 1050 | 1049 | } |
| 1051 | 1050 | |
| 1052 | 1051 | static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e) |
| @@ -1058,12 +1057,15 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e) · 5 unmodified lines | ||
| 1058 | 1057 | if (GENET_IS_V1(priv)) |
| 1059 | 1058 | return -EOPNOTSUPP; |
| 1060 | 1059 | |
| 1060 | + if (!dev->phydev) | |
| 1061 | + return -ENODEV; | |
| 1062 | + | |
| 1061 | 1063 | p->eee_enabled = e->eee_enabled; |
| 1062 | 1064 | |
| 1063 | 1065 | if (!p->eee_enabled) { |
| 1064 | 1066 | bcmgenet_eee_enable_set(dev, false); |
| 1065 | 1067 | } else { |
| 1066 | − ret = phy_init_eee(priv->phydev, 0); | |
| 1068 | + ret = phy_init_eee(dev->phydev, 0); | |
| 1067 | 1069 | if (ret) { |
| 1068 | 1070 | netif_err(priv, hw, dev, "EEE initialization failed\n"); |
| 1069 | 1071 | return ret; |
| @@ -1073,7 +1075,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e) · 3 unmodified lines | ||
| 1073 | 1075 | bcmgenet_eee_enable_set(dev, true); |
| 1074 | 1076 | } |
| 1075 | 1077 | |
| 1076 | − return phy_ethtool_set_eee(priv->phydev, e); | |
| 1078 | + return phy_ethtool_set_eee(dev->phydev, e); | |
| 1077 | 1079 | } |
| 1078 | 1080 | |
| 1079 | 1081 | /* standard ethtool support functions. */ |
| @@ -1107,7 +1109,7 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv, · 27 unmodified lines | ||
| 1107 | 1109 | |
| 1108 | 1110 | switch (mode) { |
| 1109 | 1111 | case GENET_POWER_CABLE_SENSE: |
| 1110 | − phy_detach(priv->phydev); | |
| 1112 | + phy_detach(priv->dev->phydev); | |
| 1111 | 1113 | break; |
| 1112 | 1114 | |
| 1113 | 1115 | case GENET_POWER_WOL_MAGIC: |
| @@ -1172,7 +1174,6 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv, · 58 unmodified lines | ||
| 1172 | 1174 | } |
| 1173 | 1175 | bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); |
| 1174 | 1176 | bcmgenet_phy_power_set(priv->dev, true); |
| 1175 | − bcmgenet_mii_reset(priv->dev); | |
| 1176 | 1177 | break; |
| 1177 | 1178 | |
| 1178 | 1179 | case GENET_POWER_CABLE_SENSE: |
| @@ -1193,15 +1194,13 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv, · 14 unmodified lines | ||
| 1193 | 1194 | /* ioctl handle special commands that are not present in ethtool. */ |
| 1194 | 1195 | static int bcmgenet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
| 1195 | 1196 | { |
| 1196 | − struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 1197 | − | |
| 1198 | 1197 | if (!netif_running(dev)) |
| 1199 | 1198 | return -EINVAL; |
| 1200 | 1199 | |
| 1201 | − if (!priv->phydev) | |
| 1200 | + if (!dev->phydev) | |
| 1202 | 1201 | return -ENODEV; |
| 1203 | 1202 | |
| 1204 | − return phy_mii_ioctl(priv->phydev, rq, cmd); | |
| 1203 | + return phy_mii_ioctl(dev->phydev, rq, cmd); | |
| 1205 | 1204 | } |
| 1206 | 1205 | |
| 1207 | 1206 | static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv, |
| @@ -1405,11 +1404,10 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, · 197 unmodified lines | ||
| 1405 | 1404 | struct bcmgenet_tx_ring *ring) |
| 1406 | 1405 | { |
| 1407 | 1406 | unsigned int released; |
| 1408 | − unsigned long flags; | |
| 1409 | 1407 | |
| 1410 | − spin_lock_irqsave(&ring->lock, flags); | |
| 1408 | + spin_lock_bh(&ring->lock); | |
| 1411 | 1409 | released = __bcmgenet_tx_reclaim(dev, ring); |
| 1412 | − spin_unlock_irqrestore(&ring->lock, flags); | |
| 1410 | + spin_unlock_bh(&ring->lock); | |
| 1413 | 1411 | |
| 1414 | 1412 | return released; |
| 1415 | 1413 | } |
| @@ -1420,15 +1418,14 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget) · 4 unmodified lines | ||
| 1420 | 1418 | container_of(napi, struct bcmgenet_tx_ring, napi); |
| 1421 | 1419 | unsigned int work_done = 0; |
| 1422 | 1420 | struct netdev_queue *txq; |
| 1423 | − unsigned long flags; | |
| 1424 | 1421 | |
| 1425 | − spin_lock_irqsave(&ring->lock, flags); | |
| 1422 | + spin_lock(&ring->lock); | |
| 1426 | 1423 | work_done = __bcmgenet_tx_reclaim(ring->priv->dev, ring); |
| 1427 | 1424 | if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { |
| 1428 | 1425 | txq = netdev_get_tx_queue(ring->priv->dev, ring->queue); |
| 1429 | 1426 | netif_tx_wake_queue(txq); |
| 1430 | 1427 | } |
| 1431 | − spin_unlock_irqrestore(&ring->lock, flags); | |
| 1428 | + spin_unlock(&ring->lock); | |
| 1432 | 1429 | |
| 1433 | 1430 | if (work_done == 0) { |
| 1434 | 1431 | napi_complete(napi); |
| @@ -1523,7 +1520,6 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 88 unmodified lines | ||
| 1523 | 1520 | struct bcmgenet_tx_ring *ring = NULL; |
| 1524 | 1521 | struct enet_cb *tx_cb_ptr; |
| 1525 | 1522 | struct netdev_queue *txq; |
| 1526 | − unsigned long flags = 0; | |
| 1527 | 1523 | int nr_frags, index; |
| 1528 | 1524 | dma_addr_t mapping; |
| 1529 | 1525 | unsigned int size; |
| @@ -1550,7 +1546,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 20 unmodified lines | ||
| 1550 | 1546 | |
| 1551 | 1547 | nr_frags = skb_shinfo(skb)->nr_frags; |
| 1552 | 1548 | |
| 1553 | − spin_lock_irqsave(&ring->lock, flags); | |
| 1549 | + spin_lock(&ring->lock); | |
| 1554 | 1550 | if (ring->free_bds <= (nr_frags + 1)) { |
| 1555 | 1551 | if (!netif_tx_queue_stopped(txq)) { |
| 1556 | 1552 | netif_tx_stop_queue(txq); |
| @@ -1584,8 +1580,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 27 unmodified lines | ||
| 1584 | 1580 | for (i = 0; i <= nr_frags; i++) { |
| 1585 | 1581 | tx_cb_ptr = bcmgenet_get_txcb(priv, ring); |
| 1586 | 1582 | |
| 1587 | − if (unlikely(!tx_cb_ptr)) | |
| 1588 | − BUG(); | |
| 1583 | + BUG_ON(!tx_cb_ptr); | |
| 1589 | 1584 | |
| 1590 | 1585 | if (!i) { |
| 1591 | 1586 | /* Transmit single SKB or head of fragment list */ |
| @@ -1645,7 +1640,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 53 unmodified lines | ||
| 1645 | 1640 | bcmgenet_tdma_ring_writel(priv, ring->index, |
| 1646 | 1641 | ring->prod_index, TDMA_PROD_INDEX); |
| 1647 | 1642 | out: |
| 1648 | − spin_unlock_irqrestore(&ring->lock, flags); | |
| 1643 | + spin_unlock(&ring->lock); | |
| 1649 | 1644 | |
| 1650 | 1645 | return ret; |
| 1651 | 1646 | |
| @@ -1935,12 +1930,8 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable) · 283 unmodified lines | ||
| 1935 | 1930 | usleep_range(1000, 2000); |
| 1936 | 1931 | } |
| 1937 | 1932 | |
| 1938 | −static int reset_umac(struct bcmgenet_priv *priv) | |
| 1933 | +static void reset_umac(struct bcmgenet_priv *priv) | |
| 1939 | 1934 | { |
| 1940 | − struct device *kdev = &priv->pdev->dev; | |
| 1941 | − unsigned int timeout = 0; | |
| 1942 | − u32 reg; | |
| 1943 | − | |
| 1944 | 1935 | /* 7358a0/7552a0: bad default in RBUF_FLUSH_CTRL.umac_sw_rst */ |
| 1945 | 1936 | bcmgenet_rbuf_ctrl_set(priv, 0); |
| 1946 | 1937 | udelay(10); |
| @@ -1948,23 +1939,10 @@ static int reset_umac(struct bcmgenet_priv *priv) · 1 unmodified line | ||
| 1948 | 1939 | /* disable MAC while updating its registers */ |
| 1949 | 1940 | bcmgenet_umac_writel(priv, 0, UMAC_CMD); |
| 1950 | 1941 | |
| 1951 | − /* issue soft reset, wait for it to complete */ | |
| 1952 | − bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); | |
| 1953 | − while (timeout++ < 1000) { | |
| 1954 | − reg = bcmgenet_umac_readl(priv, UMAC_CMD); | |
| 1955 | − if (!(reg & CMD_SW_RESET)) | |
| 1956 | − return 0; | |
| 1957 | − | |
| 1958 | − udelay(1); | |
| 1959 | − } | |
| 1960 | − | |
| 1961 | − if (timeout == 1000) { | |
| 1962 | − dev_err(kdev, | |
| 1963 | − "timeout waiting for MAC to come out of reset\n"); | |
| 1964 | − return -ETIMEDOUT; | |
| 1965 | − } | |
| 1966 | − | |
| 1967 | − return 0; | |
| 1942 | + /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */ | |
| 1943 | + bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD); | |
| 1944 | + udelay(2); | |
| 1945 | + bcmgenet_umac_writel(priv, 0, UMAC_CMD); | |
| 1968 | 1946 | } |
| 1969 | 1947 | |
| 1970 | 1948 | static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) |
| @@ -1994,20 +1972,16 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv) · 23 unmodified lines | ||
| 1994 | 1972 | bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); |
| 1995 | 1973 | } |
| 1996 | 1974 | |
| 1997 | −static int init_umac(struct bcmgenet_priv *priv) | |
| 1975 | +static void init_umac(struct bcmgenet_priv *priv) | |
| 1998 | 1976 | { |
| 1999 | 1977 | struct device *kdev = &priv->pdev->dev; |
| 2000 | − int ret; | |
| 2001 | 1978 | u32 reg; |
| 2002 | 1979 | u32 int0_enable = 0; |
| 2003 | 1980 | |
| 2004 | 1981 | dev_dbg(&priv->pdev->dev, "bcmgenet: init_umac\n"); |
| 2005 | 1982 | |
| 2006 | − ret = reset_umac(priv); | |
| 2007 | − if (ret) | |
| 2008 | − return ret; | |
| 1983 | + reset_umac(priv); | |
| 2009 | 1984 | |
| 2010 | − bcmgenet_umac_writel(priv, 0, UMAC_CMD); | |
| 2011 | 1985 | /* clear tx/rx counter */ |
| 2012 | 1986 | bcmgenet_umac_writel(priv, |
| 2013 | 1987 | MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT, |
| @@ -2046,8 +2020,6 @@ static int init_umac(struct bcmgenet_priv *priv) · 32 unmodified lines | ||
| 2046 | 2020 | bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); |
| 2047 | 2021 | |
| 2048 | 2022 | dev_dbg(kdev, "done init umac\n"); |
| 2049 | − | |
| 2050 | − return 0; | |
| 2051 | 2023 | } |
| 2052 | 2024 | |
| 2053 | 2025 | /* Initialize a Tx ring along with corresponding hardware registers */ |
| @@ -2104,6 +2076,10 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, · 50 unmodified lines | ||
| 2104 | 2076 | TDMA_WRITE_PTR); |
| 2105 | 2077 | bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1, |
| 2106 | 2078 | DMA_END_ADDR); |
| 2079 | + | |
| 2080 | + /* Initialize Tx NAPI */ | |
| 2081 | + netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, | |
| 2082 | + NAPI_POLL_WEIGHT); | |
| 2107 | 2083 | } |
| 2108 | 2084 | |
| 2109 | 2085 | /* Initialize a RDMA ring */ |
| @@ -2135,6 +2111,10 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, · 25 unmodified lines | ||
| 2135 | 2111 | if (ret) |
| 2136 | 2112 | return ret; |
| 2137 | 2113 | |
| 2114 | + /* Initialize Rx NAPI */ | |
| 2115 | + netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, | |
| 2116 | + NAPI_POLL_WEIGHT); | |
| 2117 | + | |
| 2138 | 2118 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); |
| 2139 | 2119 | bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); |
| 2140 | 2120 | bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); |
| @@ -2159,50 +2139,27 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, · 18 unmodified lines | ||
| 2159 | 2139 | return ret; |
| 2160 | 2140 | } |
| 2161 | 2141 | |
| 2162 | −static void bcmgenet_init_tx_napi(struct bcmgenet_priv *priv) | |
| 2163 | −{ | |
| 2164 | − unsigned int i; | |
| 2165 | − struct bcmgenet_tx_ring *ring; | |
| 2166 | − | |
| 2167 | − for (i = 0; i < priv->hw_params->tx_queues; ++i) { | |
| 2168 | − ring = &priv->tx_rings[i]; | |
| 2169 | − netif_tx_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); | |
| 2170 | − } | |
| 2171 | − | |
| 2172 | − ring = &priv->tx_rings[DESC_INDEX]; | |
| 2173 | − netif_tx_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, 64); | |
| 2174 | −} | |
| 2175 | − | |
| 2176 | 2142 | static void bcmgenet_enable_tx_napi(struct bcmgenet_priv *priv) |
| 2177 | 2143 | { |
| 2178 | 2144 | unsigned int i; |
| 2179 | − u32 int0_enable = UMAC_IRQ_TXDMA_DONE; | |
| 2180 | − u32 int1_enable = 0; | |
| 2181 | 2145 | struct bcmgenet_tx_ring *ring; |
| 2182 | 2146 | |
| 2183 | 2147 | for (i = 0; i < priv->hw_params->tx_queues; ++i) { |
| 2184 | 2148 | ring = &priv->tx_rings[i]; |
| 2185 | 2149 | napi_enable(&ring->napi); |
| 2186 | − int1_enable |= (1 << i); | |
| 2150 | + ring->int_enable(ring); | |
| 2187 | 2151 | } |
| 2188 | 2152 | |
| 2189 | 2153 | ring = &priv->tx_rings[DESC_INDEX]; |
| 2190 | 2154 | napi_enable(&ring->napi); |
| 2191 | − | |
| 2192 | − bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); | |
| 2193 | − bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR); | |
| 2155 | + ring->int_enable(ring); | |
| 2194 | 2156 | } |
| 2195 | 2157 | |
| 2196 | 2158 | static void bcmgenet_disable_tx_napi(struct bcmgenet_priv *priv) |
| 2197 | 2159 | { |
| 2198 | 2160 | unsigned int i; |
| 2199 | − u32 int0_disable = UMAC_IRQ_TXDMA_DONE; | |
| 2200 | − u32 int1_disable = 0xffff; | |
| 2201 | 2161 | struct bcmgenet_tx_ring *ring; |
| 2202 | 2162 | |
| 2203 | − bcmgenet_intrl2_0_writel(priv, int0_disable, INTRL2_CPU_MASK_SET); | |
| 2204 | − bcmgenet_intrl2_1_writel(priv, int1_disable, INTRL2_CPU_MASK_SET); | |
| 2205 | − | |
| 2206 | 2163 | for (i = 0; i < priv->hw_params->tx_queues; ++i) { |
| 2207 | 2164 | ring = &priv->tx_rings[i]; |
| 2208 | 2165 | napi_disable(&ring->napi); |
| @@ -2286,9 +2243,6 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) · 77 unmodified lines | ||
| 2286 | 2243 | bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1); |
| 2287 | 2244 | bcmgenet_tdma_writel(priv, dma_priority[2], DMA_PRIORITY_2); |
| 2288 | 2245 | |
| 2289 | − /* Initialize Tx NAPI */ | |
| 2290 | − bcmgenet_init_tx_napi(priv); | |
| 2291 | − | |
| 2292 | 2246 | /* Enable Tx queues */ |
| 2293 | 2247 | bcmgenet_tdma_writel(priv, ring_cfg, DMA_RING_CFG); |
| 2294 | 2248 | |
| @@ -2298,50 +2252,27 @@ static void bcmgenet_init_tx_queues(struct net_device *dev) · 3 unmodified lines | ||
| 2298 | 2252 | bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL); |
| 2299 | 2253 | } |
| 2300 | 2254 | |
| 2301 | −static void bcmgenet_init_rx_napi(struct bcmgenet_priv *priv) | |
| 2302 | −{ | |
| 2303 | − unsigned int i; | |
| 2304 | − struct bcmgenet_rx_ring *ring; | |
| 2305 | − | |
| 2306 | − for (i = 0; i < priv->hw_params->rx_queues; ++i) { | |
| 2307 | − ring = &priv->rx_rings[i]; | |
| 2308 | − netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, 64); | |
| 2309 | − } | |
| 2310 | − | |
| 2311 | − ring = &priv->rx_rings[DESC_INDEX]; | |
| 2312 | − netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, 64); | |
| 2313 | −} | |
| 2314 | − | |
| 2315 | 2255 | static void bcmgenet_enable_rx_napi(struct bcmgenet_priv *priv) |
| 2316 | 2256 | { |
| 2317 | 2257 | unsigned int i; |
| 2318 | − u32 int0_enable = UMAC_IRQ_RXDMA_DONE; | |
| 2319 | − u32 int1_enable = 0; | |
| 2320 | 2258 | struct bcmgenet_rx_ring *ring; |
| 2321 | 2259 | |
| 2322 | 2260 | for (i = 0; i < priv->hw_params->rx_queues; ++i) { |
| 2323 | 2261 | ring = &priv->rx_rings[i]; |
| 2324 | 2262 | napi_enable(&ring->napi); |
| 2325 | − int1_enable |= (1 << (UMAC_IRQ1_RX_INTR_SHIFT + i)); | |
| 2263 | + ring->int_enable(ring); | |
| 2326 | 2264 | } |
| 2327 | 2265 | |
| 2328 | 2266 | ring = &priv->rx_rings[DESC_INDEX]; |
| 2329 | 2267 | napi_enable(&ring->napi); |
| 2330 | − | |
| 2331 | − bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR); | |
| 2332 | − bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR); | |
| 2268 | + ring->int_enable(ring); | |
| 2333 | 2269 | } |
| 2334 | 2270 | |
| 2335 | 2271 | static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv) |
| 2336 | 2272 | { |
| 2337 | 2273 | unsigned int i; |
| 2338 | − u32 int0_disable = UMAC_IRQ_RXDMA_DONE; | |
| 2339 | − u32 int1_disable = 0xffff << UMAC_IRQ1_RX_INTR_SHIFT; | |
| 2340 | 2274 | struct bcmgenet_rx_ring *ring; |
| 2341 | 2275 | |
| 2342 | − bcmgenet_intrl2_0_writel(priv, int0_disable, INTRL2_CPU_MASK_SET); | |
| 2343 | − bcmgenet_intrl2_1_writel(priv, int1_disable, INTRL2_CPU_MASK_SET); | |
| 2344 | − | |
| 2345 | 2276 | for (i = 0; i < priv->hw_params->rx_queues; ++i) { |
| 2346 | 2277 | ring = &priv->rx_rings[i]; |
| 2347 | 2278 | napi_disable(&ring->napi); |
| @@ -2414,9 +2345,6 @@ static int bcmgenet_init_rx_queues(struct net_device *dev) · 66 unmodified lines | ||
| 2414 | 2345 | ring_cfg |= (1 << DESC_INDEX); |
| 2415 | 2346 | dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT)); |
| 2416 | 2347 | |
| 2417 | − /* Initialize Rx NAPI */ | |
| 2418 | − bcmgenet_init_rx_napi(priv); | |
| 2419 | − | |
| 2420 | 2348 | /* Enable rings */ |
| 2421 | 2349 | bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG); |
| 2422 | 2350 | |
| @@ -2505,9 +2433,6 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv) · 82 unmodified lines | ||
| 2505 | 2433 | bcmgenet_fini_rx_napi(priv); |
| 2506 | 2434 | bcmgenet_fini_tx_napi(priv); |
| 2507 | 2435 | |
| 2508 | − /* disable DMA */ | |
| 2509 | − bcmgenet_dma_teardown(priv); | |
| 2510 | − | |
| 2511 | 2436 | for (i = 0; i < priv->num_tx_bds; i++) { |
| 2512 | 2437 | cb = priv->tx_cbs + i; |
| 2513 | 2438 | skb = bcmgenet_free_tx_cb(&priv->pdev->dev, cb); |
| @@ -2590,27 +2515,20 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) · 76 unmodified lines | ||
| 2590 | 2515 | /* Interrupt bottom half */ |
| 2591 | 2516 | static void bcmgenet_irq_task(struct work_struct *work) |
| 2592 | 2517 | { |
| 2593 | − unsigned long flags; | |
| 2594 | 2518 | unsigned int status; |
| 2595 | 2519 | struct bcmgenet_priv *priv = container_of( |
| 2596 | 2520 | work, struct bcmgenet_priv, bcmgenet_irq_work); |
| 2597 | 2521 | |
| 2598 | 2522 | netif_dbg(priv, intr, priv->dev, "%s\n", __func__); |
| 2599 | 2523 | |
| 2600 | − spin_lock_irqsave(&priv->lock, flags); | |
| 2524 | + spin_lock_irq(&priv->lock); | |
| 2601 | 2525 | status = priv->irq0_stat; |
| 2602 | 2526 | priv->irq0_stat = 0; |
| 2603 | − spin_unlock_irqrestore(&priv->lock, flags); | |
| 2604 | − | |
| 2605 | − if (status & UMAC_IRQ_MPD_R) { | |
| 2606 | − netif_dbg(priv, wol, priv->dev, | |
| 2607 | − "magic packet detected, waking up\n"); | |
| 2608 | − bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); | |
| 2609 | − } | |
| 2527 | + spin_unlock_irq(&priv->lock); | |
| 2610 | 2528 | |
| 2611 | 2529 | /* Link UP/DOWN event */ |
| 2612 | 2530 | if (status & UMAC_IRQ_LINK_EVENT) |
| 2613 | − phy_mac_interrupt(priv->phydev, | |
| 2531 | + phy_mac_interrupt(priv->dev->phydev, | |
| 2614 | 2532 | !!(status & UMAC_IRQ_LINK_UP)); |
| 2615 | 2533 | } |
| 2616 | 2534 | |
| @@ -2698,23 +2616,13 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) · 81 unmodified lines | ||
| 2698 | 2616 | } |
| 2699 | 2617 | } |
| 2700 | 2618 | |
| 2701 | − if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R | | |
| 2702 | − UMAC_IRQ_PHY_DET_F | | |
| 2703 | − UMAC_IRQ_LINK_EVENT | | |
| 2704 | − UMAC_IRQ_HFB_SM | | |
| 2705 | − UMAC_IRQ_HFB_MM)) { | |
| 2706 | − /* all other interested interrupts handled in bottom half */ | |
| 2707 | − schedule_work(&priv->bcmgenet_irq_work); | |
| 2708 | − } | |
| 2709 | − | |
| 2710 | 2619 | if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && |
| 2711 | 2620 | status & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) { |
| 2712 | 2621 | wake_up(&priv->wq); |
| 2713 | 2622 | } |
| 2714 | 2623 | |
| 2715 | 2624 | /* all other interested interrupts handled in bottom half */ |
| 2716 | − status &= (UMAC_IRQ_LINK_EVENT | | |
| 2717 | − UMAC_IRQ_MPD_R); | |
| 2625 | + status &= UMAC_IRQ_LINK_EVENT; | |
| 2718 | 2626 | if (status) { |
| 2719 | 2627 | /* Save irq status for bottom-half processing. */ |
| 2720 | 2628 | spin_lock_irqsave(&priv->lock, flags); |
| @@ -2849,16 +2757,16 @@ static void bcmgenet_netif_start(struct net_device *dev) · 128 unmodified lines | ||
| 2849 | 2757 | |
| 2850 | 2758 | /* Start the network engine */ |
| 2851 | 2759 | bcmgenet_enable_rx_napi(priv); |
| 2852 | − bcmgenet_enable_tx_napi(priv); | |
| 2853 | 2760 | |
| 2854 | 2761 | umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); |
| 2855 | 2762 | |
| 2856 | 2763 | netif_tx_start_all_queues(dev); |
| 2764 | + bcmgenet_enable_tx_napi(priv); | |
| 2857 | 2765 | |
| 2858 | 2766 | /* Monitor link interrupts now */ |
| 2859 | 2767 | bcmgenet_link_intr_enable(priv); |
| 2860 | 2768 | |
| 2861 | − phy_start(priv->phydev); | |
| 2769 | + phy_start(dev->phydev); | |
| 2862 | 2770 | } |
| 2863 | 2771 | |
| 2864 | 2772 | static int bcmgenet_open(struct net_device *dev) |
| @@ -2882,12 +2790,7 @@ static int bcmgenet_open(struct net_device *dev) · 17 unmodified lines | ||
| 2882 | 2790 | /* take MAC out of reset */ |
| 2883 | 2791 | bcmgenet_umac_reset(priv); |
| 2884 | 2792 | |
| 2885 | − ret = init_umac(priv); | |
| 2886 | − if (ret) | |
| 2887 | − goto err_clk_disable; | |
| 2888 | − | |
| 2889 | − /* disable ethernet MAC while updating its registers */ | |
| 2890 | − umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false); | |
| 2793 | + init_umac(priv); | |
| 2891 | 2794 | |
| 2892 | 2795 | /* Make sure we reflect the value of CRC_CMD_FWD */ |
| 2893 | 2796 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| @@ -2946,6 +2849,7 @@ err_irq1: · 52 unmodified lines | ||
| 2946 | 2849 | err_irq0: |
| 2947 | 2850 | free_irq(priv->irq0, priv); |
| 2948 | 2851 | err_fini_dma: |
| 2852 | + bcmgenet_dma_teardown(priv); | |
| 2949 | 2853 | bcmgenet_fini_dma(priv); |
| 2950 | 2854 | err_clk_disable: |
| 2951 | 2855 | if (priv->internal_phy) |
| @@ -2958,11 +2862,20 @@ static void bcmgenet_netif_stop(struct net_device *dev) · 6 unmodified lines | ||
| 2958 | 2862 | { |
| 2959 | 2863 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 2960 | 2864 | |
| 2865 | + bcmgenet_disable_tx_napi(priv); | |
| 2961 | 2866 | netif_tx_stop_all_queues(dev); |
| 2962 | − phy_stop(priv->phydev); | |
| 2963 | − bcmgenet_intr_disable(priv); | |
| 2867 | + | |
| 2868 | + /* Disable MAC receive */ | |
| 2869 | + umac_enable_set(priv, CMD_RX_EN, false); | |
| 2870 | + | |
| 2871 | + bcmgenet_dma_teardown(priv); | |
| 2872 | + | |
| 2873 | + /* Disable MAC transmit. TX DMA disabled must be done before this */ | |
| 2874 | + umac_enable_set(priv, CMD_TX_EN, false); | |
| 2875 | + | |
| 2876 | + phy_stop(dev->phydev); | |
| 2964 | 2877 | bcmgenet_disable_rx_napi(priv); |
| 2965 | − bcmgenet_disable_tx_napi(priv); | |
| 2878 | + bcmgenet_intr_disable(priv); | |
| 2966 | 2879 | |
| 2967 | 2880 | /* Wait for pending work items to complete. Since interrupts are |
| 2968 | 2881 | * disabled no new work will be scheduled. |
| @@ -2973,33 +2886,23 @@ static void bcmgenet_netif_stop(struct net_device *dev) · 4 unmodified lines | ||
| 2973 | 2886 | priv->old_speed = -1; |
| 2974 | 2887 | priv->old_duplex = -1; |
| 2975 | 2888 | priv->old_pause = -1; |
| 2889 | + | |
| 2890 | + /* tx reclaim */ | |
| 2891 | + bcmgenet_tx_reclaim_all(dev); | |
| 2892 | + bcmgenet_fini_dma(priv); | |
| 2976 | 2893 | } |
| 2977 | 2894 | |
| 2978 | 2895 | static int bcmgenet_close(struct net_device *dev) |
| 2979 | 2896 | { |
| 2980 | 2897 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 2981 | − int ret; | |
| 2898 | + int ret = 0; | |
| 2982 | 2899 | |
| 2983 | 2900 | netif_dbg(priv, ifdown, dev, "bcmgenet_close\n"); |
| 2984 | 2901 | |
| 2985 | 2902 | bcmgenet_netif_stop(dev); |
| 2986 | 2903 | |
| 2987 | 2904 | /* Really kill the PHY state machine and disconnect from it */ |
| 2988 | − phy_disconnect(priv->phydev); | |
| 2989 | − | |
| 2990 | − /* Disable MAC receive */ | |
| 2991 | − umac_enable_set(priv, CMD_RX_EN, false); | |
| 2992 | − | |
| 2993 | − ret = bcmgenet_dma_teardown(priv); | |
| 2994 | − if (ret) | |
| 2995 | − return ret; | |
| 2996 | − | |
| 2997 | − /* Disable MAC transmit. TX DMA disabled must be done before this */ | |
| 2998 | − umac_enable_set(priv, CMD_TX_EN, false); | |
| 2999 | − | |
| 3000 | − /* tx reclaim */ | |
| 3001 | − bcmgenet_tx_reclaim_all(dev); | |
| 3002 | − bcmgenet_fini_dma(priv); | |
| 2905 | + phy_disconnect(dev->phydev); | |
| 3003 | 2906 | |
| 3004 | 2907 | free_irq(priv->irq0, priv); |
| 3005 | 2908 | free_irq(priv->irq1, priv); |
| @@ -3018,7 +2921,6 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring) · 12 unmodified lines | ||
| 3018 | 2921 | u32 p_index, c_index, intsts, intmsk; |
| 3019 | 2922 | struct netdev_queue *txq; |
| 3020 | 2923 | unsigned int free_bds; |
| 3021 | − unsigned long flags; | |
| 3022 | 2924 | bool txq_stopped; |
| 3023 | 2925 | |
| 3024 | 2926 | if (!netif_msg_tx_err(priv)) |
| @@ -3026,7 +2928,7 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring) · 1 unmodified line | ||
| 3026 | 2928 | |
| 3027 | 2929 | txq = netdev_get_tx_queue(priv->dev, ring->queue); |
| 3028 | 2930 | |
| 3029 | − spin_lock_irqsave(&ring->lock, flags); | |
| 2931 | + spin_lock(&ring->lock); | |
| 3030 | 2932 | if (ring->index == DESC_INDEX) { |
| 3031 | 2933 | intsts = ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS); |
| 3032 | 2934 | intmsk = UMAC_IRQ_TXDMA_DONE | UMAC_IRQ_TXDMA_MBDONE; |
| @@ -3038,7 +2940,7 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring) · 5 unmodified lines | ||
| 3038 | 2940 | p_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_PROD_INDEX); |
| 3039 | 2941 | txq_stopped = netif_tx_queue_stopped(txq); |
| 3040 | 2942 | free_bds = ring->free_bds; |
| 3041 | − spin_unlock_irqrestore(&ring->lock, flags); | |
| 2943 | + spin_unlock(&ring->lock); | |
| 3042 | 2944 | |
| 3043 | 2945 | netif_err(priv, tx_err, priv->dev, "Ring %d queue %d status summary\n" |
| 3044 | 2946 | "TX queue status: %s, interrupts: %s\n" |
| @@ -3564,9 +3466,7 @@ static int bcmgenet_probe(struct platform_device *pdev) · 519 unmodified lines | ||
| 3564 | 3466 | !strcasecmp(phy_mode_str, "internal")) |
| 3565 | 3467 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); |
| 3566 | 3468 | |
| 3567 | − err = reset_umac(priv); | |
| 3568 | − if (err) | |
| 3569 | − goto err_clk_disable; | |
| 3469 | + reset_umac(priv); | |
| 3570 | 3470 | |
| 3571 | 3471 | err = bcmgenet_mii_init(dev); |
| 3572 | 3472 | if (err) |
| @@ -3614,7 +3514,7 @@ static int bcmgenet_suspend(struct device *d) · 41 unmodified lines | ||
| 3614 | 3514 | { |
| 3615 | 3515 | struct net_device *dev = dev_get_drvdata(d); |
| 3616 | 3516 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 3617 | − int ret; | |
| 3517 | + int ret = 0; | |
| 3618 | 3518 | |
| 3619 | 3519 | if (!netif_running(dev)) |
| 3620 | 3520 | return 0; |
| @@ -3622,24 +3522,10 @@ static int bcmgenet_suspend(struct device *d) · 1 unmodified line | ||
| 3622 | 3522 | bcmgenet_netif_stop(dev); |
| 3623 | 3523 | |
| 3624 | 3524 | if (!device_may_wakeup(d)) |
| 3625 | − phy_suspend(priv->phydev); | |
| 3525 | + phy_suspend(dev->phydev); | |
| 3626 | 3526 | |
| 3627 | 3527 | netif_device_detach(dev); |
| 3628 | 3528 | |
| 3629 | − /* Disable MAC receive */ | |
| 3630 | − umac_enable_set(priv, CMD_RX_EN, false); | |
| 3631 | − | |
| 3632 | − ret = bcmgenet_dma_teardown(priv); | |
| 3633 | − if (ret) | |
| 3634 | − return ret; | |
| 3635 | − | |
| 3636 | − /* Disable MAC transmit. TX DMA disabled must be done before this */ | |
| 3637 | − umac_enable_set(priv, CMD_TX_EN, false); | |
| 3638 | − | |
| 3639 | − /* tx reclaim */ | |
| 3640 | − bcmgenet_tx_reclaim_all(dev); | |
| 3641 | − bcmgenet_fini_dma(priv); | |
| 3642 | − | |
| 3643 | 3529 | /* Prepare the device for Wake-on-LAN and switch to the slow clock */ |
| 3644 | 3530 | if (device_may_wakeup(d) && priv->wolopts) { |
| 3645 | 3531 | ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); |
| @@ -3678,21 +3564,17 @@ static int bcmgenet_resume(struct device *d) · 32 unmodified lines | ||
| 3678 | 3564 | |
| 3679 | 3565 | bcmgenet_umac_reset(priv); |
| 3680 | 3566 | |
| 3681 | − ret = init_umac(priv); | |
| 3682 | − if (ret) | |
| 3683 | − goto out_clk_disable; | |
| 3567 | + init_umac(priv); | |
| 3684 | 3568 | |
| 3685 | 3569 | /* From WOL-enabled suspend, switch to regular clock */ |
| 3686 | 3570 | if (priv->wolopts) |
| 3687 | 3571 | clk_disable_unprepare(priv->clk_wol); |
| 3688 | 3572 | |
| 3689 | − phy_init_hw(priv->phydev); | |
| 3573 | + phy_init_hw(dev->phydev); | |
| 3574 | + | |
| 3690 | 3575 | /* Speed settings must be restored */ |
| 3691 | 3576 | bcmgenet_mii_config(priv->dev, false); |
| 3692 | 3577 | |
| 3693 | − /* disable ethernet MAC while updating its registers */ | |
| 3694 | − umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false); | |
| 3695 | − | |
| 3696 | 3578 | bcmgenet_set_hw_addr(priv, dev->dev_addr); |
| 3697 | 3579 | |
| 3698 | 3580 | if (priv->internal_phy) { |
| @@ -3720,7 +3602,7 @@ static int bcmgenet_resume(struct device *d) · 21 unmodified lines | ||
| 3720 | 3602 | netif_device_attach(dev); |
| 3721 | 3603 | |
| 3722 | 3604 | if (!device_may_wakeup(d)) |
| 3723 | − phy_resume(priv->phydev); | |
| 3605 | + phy_resume(dev->phydev); | |
| 3724 | 3606 | |
| 3725 | 3607 | if (priv->eee.eee_enabled) |
| 3726 | 3608 | bcmgenet_eee_enable_set(dev, true); |
| @@ -617,7 +617,6 @@ struct bcmgenet_priv { · 616 unmodified lines | ||
| 617 | 617 | |
| 618 | 618 | /* MDIO bus variables */ |
| 619 | 619 | wait_queue_head_t wq; |
| 620 | − struct phy_device *phydev; | |
| 621 | 620 | bool internal_phy; |
| 622 | 621 | struct device_node *phy_dn; |
| 623 | 622 | struct device_node *mdio_dn; |
| @@ -711,7 +710,6 @@ int bcmgenet_mii_init(struct net_device *dev); · 87 unmodified lines | ||
| 711 | 710 | int bcmgenet_mii_config(struct net_device *dev, bool init); |
| 712 | 711 | int bcmgenet_mii_probe(struct net_device *dev); |
| 713 | 712 | void bcmgenet_mii_exit(struct net_device *dev); |
| 714 | −void bcmgenet_mii_reset(struct net_device *dev); | |
| 715 | 713 | void bcmgenet_phy_power_set(struct net_device *dev, bool enable); |
| 716 | 714 | void bcmgenet_mii_setup(struct net_device *dev); |
| 717 | 715 | |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | void bcmgenet_mii_setup(struct net_device *dev) |
| 35 | 35 | { |
| 36 | 36 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 37 | − struct phy_device *phydev = priv->phydev; | |
| 37 | + struct phy_device *phydev = dev->phydev; | |
| 38 | 38 | u32 reg, cmd_bits = 0; |
| 39 | 39 | bool status_changed = false; |
| 40 | 40 | |
| @@ -121,22 +121,6 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev, · 80 unmodified lines | ||
| 121 | 121 | return 0; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | −/* Perform a voluntary PHY software reset, since the EPHY is very finicky about | |
| 125 | − * not doing it and will start corrupting packets | |
| 126 | − */ | |
| 127 | −void bcmgenet_mii_reset(struct net_device *dev) | |
| 128 | −{ | |
| 129 | − struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 130 | − | |
| 131 | − if (GENET_IS_V4(priv)) | |
| 132 | − return; | |
| 133 | − | |
| 134 | − if (priv->phydev) { | |
| 135 | − phy_init_hw(priv->phydev); | |
| 136 | − phy_start_aneg(priv->phydev); | |
| 137 | − } | |
| 138 | −} | |
| 139 | − | |
| 140 | 124 | void bcmgenet_phy_power_set(struct net_device *dev, bool enable) |
| 141 | 125 | { |
| 142 | 126 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| @@ -182,14 +166,14 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) · 39 unmodified lines | ||
| 182 | 166 | } |
| 183 | 167 | |
| 184 | 168 | if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) |
| 185 | − fixed_phy_set_link_update(priv->phydev, | |
| 169 | + fixed_phy_set_link_update(priv->dev->phydev, | |
| 186 | 170 | bcmgenet_fixed_phy_link_update); |
| 187 | 171 | } |
| 188 | 172 | |
| 189 | 173 | int bcmgenet_mii_config(struct net_device *dev, bool init) |
| 190 | 174 | { |
| 191 | 175 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 192 | − struct phy_device *phydev = priv->phydev; | |
| 176 | + struct phy_device *phydev = dev->phydev; | |
| 193 | 177 | struct device *kdev = &priv->pdev->dev; |
| 194 | 178 | const char *phy_name = NULL; |
| 195 | 179 | u32 id_mode_dis = 0; |
| @@ -236,7 +220,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 40 unmodified lines | ||
| 236 | 220 | * capabilities, use that knowledge to also configure the |
| 237 | 221 | * Reverse MII interface correctly. |
| 238 | 222 | */ |
| 239 | − if ((priv->phydev->supported & PHY_BASIC_FEATURES) == | |
| 223 | + if ((dev->phydev->supported & PHY_BASIC_FEATURES) == | |
| 240 | 224 | PHY_BASIC_FEATURES) |
| 241 | 225 | port_ctrl = PORT_MODE_EXT_RVMII_25; |
| 242 | 226 | else |
| @@ -306,7 +290,7 @@ int bcmgenet_mii_probe(struct net_device *dev) · 63 unmodified lines | ||
| 306 | 290 | return -ENODEV; |
| 307 | 291 | } |
| 308 | 292 | } else { |
| 309 | − phydev = priv->phydev; | |
| 293 | + phydev = dev->phydev; | |
| 310 | 294 | phydev->dev_flags = phy_flags; |
| 311 | 295 | |
| 312 | 296 | ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, |
| @@ -317,8 +301,6 @@ int bcmgenet_mii_probe(struct net_device *dev) · 4 unmodified lines | ||
| 317 | 301 | } |
| 318 | 302 | } |
| 319 | 303 | |
| 320 | − priv->phydev = phydev; | |
| 321 | − | |
| 322 | 304 | /* Configure port multiplexer based on what the probed PHY device since |
| 323 | 305 | * reading the 'max-speed' property determines the maximum supported |
| 324 | 306 | * PHY speed which is needed for bcmgenet_mii_config() to configure |
| @@ -326,7 +308,7 @@ int bcmgenet_mii_probe(struct net_device *dev) · 1 unmodified line | ||
| 326 | 308 | */ |
| 327 | 309 | ret = bcmgenet_mii_config(dev, true); |
| 328 | 310 | if (ret) { |
| 329 | − phy_disconnect(priv->phydev); | |
| 311 | + phy_disconnect(dev->phydev); | |
| 330 | 312 | return ret; |
| 331 | 313 | } |
| 332 | 314 | |
| @@ -336,7 +318,7 @@ int bcmgenet_mii_probe(struct net_device *dev) · 3 unmodified lines | ||
| 336 | 318 | * Ethernet MAC ISRs |
| 337 | 319 | */ |
| 338 | 320 | if (priv->internal_phy) |
| 339 | − priv->phydev->irq = PHY_IGNORE_INTERRUPT; | |
| 321 | + dev->phydev->irq = PHY_IGNORE_INTERRUPT; | |
| 340 | 322 | |
| 341 | 323 | return 0; |
| 342 | 324 | } |
| @@ -545,7 +527,6 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) · 202 unmodified lines | ||
| 545 | 527 | |
| 546 | 528 | } |
| 547 | 529 | |
| 548 | − priv->phydev = phydev; | |
| 549 | 530 | priv->phy_interface = pd->phy_interface; |
| 550 | 531 | |
| 551 | 532 | return 0; |
| @@ -590,5 +571,4 @@ void bcmgenet_mii_exit(struct net_device *dev) · 38 unmodified lines | ||
| 590 | 571 | of_phy_deregister_fixed_link(dn); |
| 591 | 572 | of_node_put(priv->phy_dn); |
| 592 | 573 | platform_device_unregister(priv->mii_pdev); |
| 593 | − platform_device_put(priv->mii_pdev); | |
| 594 | 574 | } |
| @@ -11087,9 +11087,7 @@ static void tg3_timer_init(struct tg3 *tp) · 11086 unmodified lines | ||
| 11087 | 11087 | tp->asf_multiplier = (HZ / tp->timer_offset) * |
| 11088 | 11088 | TG3_FW_UPDATE_FREQ_SEC; |
| 11089 | 11089 | |
| 11090 | − init_timer(&tp->timer); | |
| 11091 | − tp->timer.data = (unsigned long) tp; | |
| 11092 | − tp->timer.function = tg3_timer; | |
| 11090 | + setup_timer(&tp->timer, tg3_timer, (unsigned long)tp); | |
| 11093 | 11091 | } |
| 11094 | 11092 | |
| 11095 | 11093 | static void tg3_timer_start(struct tg3 *tp) |
| @@ -1693,9 +1693,9 @@ err_return: · 1692 unmodified lines | ||
| 1693 | 1693 | /* Timer callbacks */ |
| 1694 | 1694 | /* a) IOC timer */ |
| 1695 | 1695 | static void |
| 1696 | −bnad_ioc_timeout(unsigned long data) | |
| 1696 | +bnad_ioc_timeout(struct timer_list *t) | |
| 1697 | 1697 | { |
| 1698 | − struct bnad *bnad = (struct bnad *)data; | |
| 1698 | + struct bnad *bnad = from_timer(bnad, t, bna.ioceth.ioc.ioc_timer); | |
| 1699 | 1699 | unsigned long flags; |
| 1700 | 1700 | |
| 1701 | 1701 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| @@ -1704,9 +1704,9 @@ bnad_ioc_timeout(unsigned long data) · 2 unmodified lines | ||
| 1704 | 1704 | } |
| 1705 | 1705 | |
| 1706 | 1706 | static void |
| 1707 | −bnad_ioc_hb_check(unsigned long data) | |
| 1707 | +bnad_ioc_hb_check(struct timer_list *t) | |
| 1708 | 1708 | { |
| 1709 | − struct bnad *bnad = (struct bnad *)data; | |
| 1709 | + struct bnad *bnad = from_timer(bnad, t, bna.ioceth.ioc.hb_timer); | |
| 1710 | 1710 | unsigned long flags; |
| 1711 | 1711 | |
| 1712 | 1712 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| @@ -1715,9 +1715,9 @@ bnad_ioc_hb_check(unsigned long data) · 2 unmodified lines | ||
| 1715 | 1715 | } |
| 1716 | 1716 | |
| 1717 | 1717 | static void |
| 1718 | −bnad_iocpf_timeout(unsigned long data) | |
| 1718 | +bnad_iocpf_timeout(struct timer_list *t) | |
| 1719 | 1719 | { |
| 1720 | − struct bnad *bnad = (struct bnad *)data; | |
| 1720 | + struct bnad *bnad = from_timer(bnad, t, bna.ioceth.ioc.iocpf_timer); | |
| 1721 | 1721 | unsigned long flags; |
| 1722 | 1722 | |
| 1723 | 1723 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| @@ -1726,9 +1726,9 @@ bnad_iocpf_timeout(unsigned long data) · 2 unmodified lines | ||
| 1726 | 1726 | } |
| 1727 | 1727 | |
| 1728 | 1728 | static void |
| 1729 | −bnad_iocpf_sem_timeout(unsigned long data) | |
| 1729 | +bnad_iocpf_sem_timeout(struct timer_list *t) | |
| 1730 | 1730 | { |
| 1731 | − struct bnad *bnad = (struct bnad *)data; | |
| 1731 | + struct bnad *bnad = from_timer(bnad, t, bna.ioceth.ioc.sem_timer); | |
| 1732 | 1732 | unsigned long flags; |
| 1733 | 1733 | |
| 1734 | 1734 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| @@ -1748,9 +1748,9 @@ bnad_iocpf_sem_timeout(unsigned long data) · 13 unmodified lines | ||
| 1748 | 1748 | |
| 1749 | 1749 | /* b) Dynamic Interrupt Moderation Timer */ |
| 1750 | 1750 | static void |
| 1751 | −bnad_dim_timeout(unsigned long data) | |
| 1751 | +bnad_dim_timeout(struct timer_list *t) | |
| 1752 | 1752 | { |
| 1753 | − struct bnad *bnad = (struct bnad *)data; | |
| 1753 | + struct bnad *bnad = from_timer(bnad, t, dim_timer); | |
| 1754 | 1754 | struct bnad_rx_info *rx_info; |
| 1755 | 1755 | struct bnad_rx_ctrl *rx_ctrl; |
| 1756 | 1756 | int i, j; |
| @@ -1781,9 +1781,9 @@ bnad_dim_timeout(unsigned long data) · 24 unmodified lines | ||
| 1781 | 1781 | |
| 1782 | 1782 | /* c) Statistics Timer */ |
| 1783 | 1783 | static void |
| 1784 | −bnad_stats_timeout(unsigned long data) | |
| 1784 | +bnad_stats_timeout(struct timer_list *t) | |
| 1785 | 1785 | { |
| 1786 | − struct bnad *bnad = (struct bnad *)data; | |
| 1786 | + struct bnad *bnad = from_timer(bnad, t, stats_timer); | |
| 1787 | 1787 | unsigned long flags; |
| 1788 | 1788 | |
| 1789 | 1789 | if (!netif_running(bnad->netdev) || |
| @@ -1804,8 +1804,7 @@ bnad_dim_timer_start(struct bnad *bnad) · 14 unmodified lines | ||
| 1804 | 1804 | { |
| 1805 | 1805 | if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED && |
| 1806 | 1806 | !test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) { |
| 1807 | − setup_timer(&bnad->dim_timer, bnad_dim_timeout, | |
| 1808 | − (unsigned long)bnad); | |
| 1807 | + timer_setup(&bnad->dim_timer, bnad_dim_timeout, 0); | |
| 1809 | 1808 | set_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags); |
| 1810 | 1809 | mod_timer(&bnad->dim_timer, |
| 1811 | 1810 | jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ)); |
| @@ -1823,8 +1822,7 @@ bnad_stats_timer_start(struct bnad *bnad) · 11 unmodified lines | ||
| 1823 | 1822 | |
| 1824 | 1823 | spin_lock_irqsave(&bnad->bna_lock, flags); |
| 1825 | 1824 | if (!test_and_set_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) { |
| 1826 | − setup_timer(&bnad->stats_timer, bnad_stats_timeout, | |
| 1827 | − (unsigned long)bnad); | |
| 1825 | + timer_setup(&bnad->stats_timer, bnad_stats_timeout, 0); | |
| 1828 | 1826 | mod_timer(&bnad->stats_timer, |
| 1829 | 1827 | jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); |
| 1830 | 1828 | } |
| @@ -3692,14 +3690,11 @@ bnad_pci_probe(struct pci_dev *pdev, · 1861 unmodified lines | ||
| 3692 | 3690 | goto res_free; |
| 3693 | 3691 | |
| 3694 | 3692 | /* Set up timers */ |
| 3695 | − setup_timer(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout, | |
| 3696 | − (unsigned long)bnad); | |
| 3697 | − setup_timer(&bnad->bna.ioceth.ioc.hb_timer, bnad_ioc_hb_check, | |
| 3698 | − (unsigned long)bnad); | |
| 3699 | − setup_timer(&bnad->bna.ioceth.ioc.iocpf_timer, bnad_iocpf_timeout, | |
| 3700 | − (unsigned long)bnad); | |
| 3701 | − setup_timer(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout, | |
| 3702 | − (unsigned long)bnad); | |
| 3693 | + timer_setup(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout, 0); | |
| 3694 | + timer_setup(&bnad->bna.ioceth.ioc.hb_timer, bnad_ioc_hb_check, 0); | |
| 3695 | + timer_setup(&bnad->bna.ioceth.ioc.iocpf_timer, bnad_iocpf_timeout, 0); | |
| 3696 | + timer_setup(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout, | |
| 3697 | + 0); | |
| 3703 | 3698 | |
| 3704 | 3699 | /* |
| 3705 | 3700 | * Start the chip |
| @@ -611,6 +611,9 @@ static int macb_mii_init(struct macb *bp) · 610 unmodified lines | ||
| 611 | 611 | err_out_unregister_bus: |
| 612 | 612 | mdiobus_unregister(bp->mii_bus); |
| 613 | 613 | err_out_free_mdiobus: |
| 614 | + of_node_put(bp->phy_node); | |
| 615 | + if (np && of_phy_is_fixed_link(np)) | |
| 616 | + of_phy_deregister_fixed_link(np); | |
| 614 | 617 | mdiobus_free(bp->mii_bus); |
| 615 | 618 | err_out: |
| 616 | 619 | return err; |
| @@ -1218,8 +1221,6 @@ static int macb_poll(struct napi_struct *napi, int budget) · 601 unmodified lines | ||
| 1218 | 1221 | status = macb_readl(bp, RSR); |
| 1219 | 1222 | macb_writel(bp, RSR, status); |
| 1220 | 1223 | |
| 1221 | − work_done = 0; | |
| 1222 | − | |
| 1223 | 1224 | netdev_vdbg(bp->dev, "poll: status = %08lx, budget = %d\n", |
| 1224 | 1225 | (unsigned long)status, budget); |
| 1225 | 1226 | |
| @@ -3552,6 +3553,9 @@ static int macb_probe(struct platform_device *pdev) · 2326 unmodified lines | ||
| 3552 | 3553 | err_out_unregister_mdio: |
| 3553 | 3554 | phy_disconnect(dev->phydev); |
| 3554 | 3555 | mdiobus_unregister(bp->mii_bus); |
| 3556 | + of_node_put(bp->phy_node); | |
| 3557 | + if (np && of_phy_is_fixed_link(np)) | |
| 3558 | + of_phy_deregister_fixed_link(np); | |
| 3555 | 3559 | mdiobus_free(bp->mii_bus); |
| 3556 | 3560 | |
| 3557 | 3561 | /* Shutdown the PHY if there is a GPIO reset */ |
| @@ -3574,6 +3578,7 @@ static int macb_remove(struct platform_device *pdev) · 16 unmodified lines | ||
| 3574 | 3578 | { |
| 3575 | 3579 | struct net_device *dev; |
| 3576 | 3580 | struct macb *bp; |
| 3581 | + struct device_node *np = pdev->dev.of_node; | |
| 3577 | 3582 | |
| 3578 | 3583 | dev = platform_get_drvdata(pdev); |
| 3579 | 3584 | |
| @@ -3582,6 +3587,8 @@ static int macb_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 3582 | 3587 | if (dev->phydev) |
| 3583 | 3588 | phy_disconnect(dev->phydev); |
| 3584 | 3589 | mdiobus_unregister(bp->mii_bus); |
| 3590 | + if (np && of_phy_is_fixed_link(np)) | |
| 3591 | + of_phy_deregister_fixed_link(np); | |
| 3585 | 3592 | dev->phydev = NULL; |
| 3586 | 3593 | mdiobus_free(bp->mii_bus); |
| 3587 | 3594 | |
| @@ -53,6 +53,7 @@ config THUNDER_NIC_RGX · 52 unmodified lines | ||
| 53 | 53 | config LIQUIDIO |
| 54 | 54 | tristate "Cavium LiquidIO support" |
| 55 | 55 | depends on 64BIT |
| 56 | + depends on MAY_USE_DEVLINK | |
| 56 | 57 | imply PTP_1588_CLOCK |
| 57 | 58 | select FW_LOADER |
| 58 | 59 | select LIBCRC32C |
| @@ -18,7 +18,7 @@ liquidio-$(CONFIG_LIQUIDIO) += lio_ethtool.o \ · 17 unmodified lines | ||
| 18 | 18 | octeon_droq.o \ |
| 19 | 19 | octeon_nic.o |
| 20 | 20 | |
| 21 | −liquidio-objs := lio_main.o octeon_console.o $(liquidio-y) | |
| 21 | +liquidio-objs := lio_main.o octeon_console.o lio_vf_rep.o $(liquidio-y) | |
| 22 | 22 | |
| 23 | 23 | obj-$(CONFIG_LIQUIDIO_VF) += liquidio_vf.o |
| 24 | 24 | |
| @@ -91,7 +91,7 @@ void octeon_update_tx_completion_counters(void *buf, int reqtype, · 90 unmodified lines | ||
| 91 | 91 | *bytes_compl += skb->len; |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | −void octeon_report_sent_bytes_to_bql(void *buf, int reqtype) | |
| 94 | +int octeon_report_sent_bytes_to_bql(void *buf, int reqtype) | |
| 95 | 95 | { |
| 96 | 96 | struct octnet_buf_free_info *finfo; |
| 97 | 97 | struct sk_buff *skb; |
| @@ -112,11 +112,13 @@ void octeon_report_sent_bytes_to_bql(void *buf, int reqtype) · 14 unmodified lines | ||
| 112 | 112 | break; |
| 113 | 113 | |
| 114 | 114 | default: |
| 115 | − return; | |
| 115 | + return 0; | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | txq = netdev_get_tx_queue(skb->dev, skb_get_queue_mapping(skb)); |
| 119 | 119 | netdev_tx_sent_queue(txq, skb->len); |
| 120 | + | |
| 121 | + return netif_xmit_stopped(txq); | |
| 120 | 122 | } |
| 121 | 123 | |
| 122 | 124 | void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr) |
| @@ -141,6 +143,7 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr) · 18 unmodified lines | ||
| 141 | 143 | switch (nctrl->ncmd.s.cmd) { |
| 142 | 144 | case OCTNET_CMD_CHANGE_DEVFLAGS: |
| 143 | 145 | case OCTNET_CMD_SET_MULTI_LIST: |
| 146 | + case OCTNET_CMD_SET_UC_LIST: | |
| 144 | 147 | break; |
| 145 | 148 | |
| 146 | 149 | case OCTNET_CMD_CHANGE_MACADDR: |
| @@ -464,7 +467,6 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), · 317 unmodified lines | ||
| 464 | 467 | if (netdev) { |
| 465 | 468 | struct lio *lio = GET_LIO(netdev); |
| 466 | 469 | struct octeon_device *oct = lio->oct_dev; |
| 467 | − int packet_was_received; | |
| 468 | 470 | |
| 469 | 471 | /* Do not proceed if the interface is not in RUNNING state. */ |
| 470 | 472 | if (!ifstate_check(lio, LIO_IFSTATE_RUNNING)) { |
| @@ -567,18 +569,10 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), · 96 unmodified lines | ||
| 567 | 569 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vtag); |
| 568 | 570 | } |
| 569 | 571 | |
| 570 | − packet_was_received = (napi_gro_receive(napi, skb) != GRO_DROP); | |
| 571 | − | |
| 572 | − if (packet_was_received) { | |
| 573 | − droq->stats.rx_bytes_received += len; | |
| 574 | − droq->stats.rx_pkts_received++; | |
| 575 | − } else { | |
| 576 | − droq->stats.rx_dropped++; | |
| 577 | − netif_info(lio, rx_err, lio->netdev, | |
| 578 | − "droq:%d error rx_dropped:%llu\n", | |
| 579 | − droq->q_no, droq->stats.rx_dropped); | |
| 580 | − } | |
| 572 | + napi_gro_receive(napi, skb); | |
| 581 | 573 | |
| 574 | + droq->stats.rx_bytes_received += len; | |
| 575 | + droq->stats.rx_pkts_received++; | |
| 582 | 576 | } else { |
| 583 | 577 | recv_buffer_free(skb); |
| 584 | 578 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/firmware.h> |
| 22 | 22 | #include <net/vxlan.h> |
| 23 | 23 | #include <linux/kthread.h> |
| 24 | +#include <net/switchdev.h> | |
| 24 | 25 | #include "liquidio_common.h" |
| 25 | 26 | #include "octeon_droq.h" |
| 26 | 27 | #include "octeon_iq.h" |
| @@ -34,6 +35,7 @@ · 7 unmodified lines | ||
| 34 | 35 | #include "cn68xx_device.h" |
| 35 | 36 | #include "cn23xx_pf_device.h" |
| 36 | 37 | #include "liquidio_image.h" |
| 38 | +#include "lio_vf_rep.h" | |
| 37 | 39 | |
| 38 | 40 | MODULE_AUTHOR("Cavium Networks, <support@cavium.com>"); |
| 39 | 41 | MODULE_DESCRIPTION("Cavium LiquidIO Intelligent Server Adapter Driver"); |
| @@ -59,9 +61,9 @@ static int debug = -1; · 19 unmodified lines | ||
| 59 | 61 | module_param(debug, int, 0644); |
| 60 | 62 | MODULE_PARM_DESC(debug, "NETIF_MSG debug bits"); |
| 61 | 63 | |
| 62 | −static char fw_type[LIO_MAX_FW_TYPE_LEN] = LIO_FW_NAME_TYPE_NIC; | |
| 64 | +static char fw_type[LIO_MAX_FW_TYPE_LEN] = LIO_FW_NAME_TYPE_AUTO; | |
| 63 | 65 | module_param_string(fw_type, fw_type, sizeof(fw_type), 0444); |
| 64 | −MODULE_PARM_DESC(fw_type, "Type of firmware to be loaded. Default \"nic\". Use \"none\" to load firmware from flash."); | |
| 66 | +MODULE_PARM_DESC(fw_type, "Type of firmware to be loaded (default is \"auto\"), which uses firmware in flash, if present, else loads \"nic\"."); | |
| 65 | 67 | |
| 66 | 68 | static u32 console_bitmask; |
| 67 | 69 | module_param(console_bitmask, int, 0644); |
| @@ -83,6 +85,11 @@ static int octeon_console_debug_enabled(u32 console) · 15 unmodified lines | ||
| 83 | 85 | |
| 84 | 86 | /* runtime link query interval */ |
| 85 | 87 | #define LIQUIDIO_LINK_QUERY_INTERVAL_MS 1000 |
| 88 | +/* update localtime to octeon firmware every 60 seconds. | |
| 89 | + * make firmware to use same time reference, so that it will be easy to | |
| 90 | + * correlate firmware logged events/errors with host events, for debugging. | |
| 91 | + */ | |
| 92 | +#define LIO_SYNC_OCTEON_TIME_INTERVAL_MS 60000 | |
| 86 | 93 | |
| 87 | 94 | struct liquidio_if_cfg_context { |
| 88 | 95 | int octeon_id; |
| @@ -901,6 +908,121 @@ static inline void update_link_status(struct net_device *netdev, · 812 unmodified lines | ||
| 901 | 908 | } |
| 902 | 909 | } |
| 903 | 910 | |
| 911 | +/** | |
| 912 | + * lio_sync_octeon_time_cb - callback that is invoked when soft command | |
| 913 | + * sent by lio_sync_octeon_time() has completed successfully or failed | |
| 914 | + * | |
| 915 | + * @oct - octeon device structure | |
| 916 | + * @status - indicates success or failure | |
| 917 | + * @buf - pointer to the command that was sent to firmware | |
| 918 | + **/ | |
| 919 | +static void lio_sync_octeon_time_cb(struct octeon_device *oct, | |
| 920 | + u32 status, void *buf) | |
| 921 | +{ | |
| 922 | + struct octeon_soft_command *sc = (struct octeon_soft_command *)buf; | |
| 923 | + | |
| 924 | + if (status) | |
| 925 | + dev_err(&oct->pci_dev->dev, | |
| 926 | + "Failed to sync time to octeon; error=%d\n", status); | |
| 927 | + | |
| 928 | + octeon_free_soft_command(oct, sc); | |
| 929 | +} | |
| 930 | + | |
| 931 | +/** | |
| 932 | + * lio_sync_octeon_time - send latest localtime to octeon firmware so that | |
| 933 | + * firmware will correct it's time, in case there is a time skew | |
| 934 | + * | |
| 935 | + * @work: work scheduled to send time update to octeon firmware | |
| 936 | + **/ | |
| 937 | +static void lio_sync_octeon_time(struct work_struct *work) | |
| 938 | +{ | |
| 939 | + struct cavium_wk *wk = (struct cavium_wk *)work; | |
| 940 | + struct lio *lio = (struct lio *)wk->ctxptr; | |
| 941 | + struct octeon_device *oct = lio->oct_dev; | |
| 942 | + struct octeon_soft_command *sc; | |
| 943 | + struct timespec64 ts; | |
| 944 | + struct lio_time *lt; | |
| 945 | + int ret; | |
| 946 | + | |
| 947 | + sc = octeon_alloc_soft_command(oct, sizeof(struct lio_time), 0, 0); | |
| 948 | + if (!sc) { | |
| 949 | + dev_err(&oct->pci_dev->dev, | |
| 950 | + "Failed to sync time to octeon: soft command allocation failed\n"); | |
| 951 | + return; | |
| 952 | + } | |
| 953 | + | |
| 954 | + lt = (struct lio_time *)sc->virtdptr; | |
| 955 | + | |
| 956 | + /* Get time of the day */ | |
| 957 | + getnstimeofday64(&ts); | |
| 958 | + lt->sec = ts.tv_sec; | |
| 959 | + lt->nsec = ts.tv_nsec; | |
| 960 | + octeon_swap_8B_data((u64 *)lt, (sizeof(struct lio_time)) / 8); | |
| 961 | + | |
| 962 | + sc->iq_no = lio->linfo.txpciq[0].s.q_no; | |
| 963 | + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, | |
| 964 | + OPCODE_NIC_SYNC_OCTEON_TIME, 0, 0, 0); | |
| 965 | + | |
| 966 | + sc->callback = lio_sync_octeon_time_cb; | |
| 967 | + sc->callback_arg = sc; | |
| 968 | + sc->wait_time = 1000; | |
| 969 | + | |
| 970 | + ret = octeon_send_soft_command(oct, sc); | |
| 971 | + if (ret == IQ_SEND_FAILED) { | |
| 972 | + dev_err(&oct->pci_dev->dev, | |
| 973 | + "Failed to sync time to octeon: failed to send soft command\n"); | |
| 974 | + octeon_free_soft_command(oct, sc); | |
| 975 | + } | |
| 976 | + | |
| 977 | + queue_delayed_work(lio->sync_octeon_time_wq.wq, | |
| 978 | + &lio->sync_octeon_time_wq.wk.work, | |
| 979 | + msecs_to_jiffies(LIO_SYNC_OCTEON_TIME_INTERVAL_MS)); | |
| 980 | +} | |
| 981 | + | |
| 982 | +/** | |
| 983 | + * setup_sync_octeon_time_wq - Sets up the work to periodically update | |
| 984 | + * local time to octeon firmware | |
| 985 | + * | |
| 986 | + * @netdev - network device which should send time update to firmware | |
| 987 | + **/ | |
| 988 | +static inline int setup_sync_octeon_time_wq(struct net_device *netdev) | |
| 989 | +{ | |
| 990 | + struct lio *lio = GET_LIO(netdev); | |
| 991 | + struct octeon_device *oct = lio->oct_dev; | |
| 992 | + | |
| 993 | + lio->sync_octeon_time_wq.wq = | |
| 994 | + alloc_workqueue("update-octeon-time", WQ_MEM_RECLAIM, 0); | |
| 995 | + if (!lio->sync_octeon_time_wq.wq) { | |
| 996 | + dev_err(&oct->pci_dev->dev, "Unable to create wq to update octeon time\n"); | |
| 997 | + return -1; | |
| 998 | + } | |
| 999 | + INIT_DELAYED_WORK(&lio->sync_octeon_time_wq.wk.work, | |
| 1000 | + lio_sync_octeon_time); | |
| 1001 | + lio->sync_octeon_time_wq.wk.ctxptr = lio; | |
| 1002 | + queue_delayed_work(lio->sync_octeon_time_wq.wq, | |
| 1003 | + &lio->sync_octeon_time_wq.wk.work, | |
| 1004 | + msecs_to_jiffies(LIO_SYNC_OCTEON_TIME_INTERVAL_MS)); | |
| 1005 | + | |
| 1006 | + return 0; | |
| 1007 | +} | |
| 1008 | + | |
| 1009 | +/** | |
| 1010 | + * cleanup_sync_octeon_time_wq - stop scheduling and destroy the work created | |
| 1011 | + * to periodically update local time to octeon firmware | |
| 1012 | + * | |
| 1013 | + * @netdev - network device which should send time update to firmware | |
| 1014 | + **/ | |
| 1015 | +static inline void cleanup_sync_octeon_time_wq(struct net_device *netdev) | |
| 1016 | +{ | |
| 1017 | + struct lio *lio = GET_LIO(netdev); | |
| 1018 | + struct cavium_wq *time_wq = &lio->sync_octeon_time_wq; | |
| 1019 | + | |
| 1020 | + if (time_wq->wq) { | |
| 1021 | + cancel_delayed_work_sync(&time_wq->wk.work); | |
| 1022 | + destroy_workqueue(time_wq->wq); | |
| 1023 | + } | |
| 1024 | +} | |
| 1025 | + | |
| 904 | 1026 | static struct octeon_device *get_other_octeon_device(struct octeon_device *oct) |
| 905 | 1027 | { |
| 906 | 1028 | struct octeon_device *other_oct; |
| @@ -1076,19 +1198,13 @@ liquidio_probe(struct pci_dev *pdev, · 169 unmodified lines | ||
| 1076 | 1198 | } |
| 1077 | 1199 | |
| 1078 | 1200 | if (OCTEON_CN23XX_PF(oct_dev)) { |
| 1079 | − u64 scratch1; | |
| 1080 | 1201 | u8 bus, device, function; |
| 1081 | 1202 | |
| 1082 | − scratch1 = octeon_read_csr64(oct_dev, CN23XX_SLI_SCRATCH1); | |
| 1083 | − if (!(scratch1 & 4ULL)) { | |
| 1084 | − /* Bit 2 of SLI_SCRATCH_1 is a flag that indicates that | |
| 1085 | − * the lio watchdog kernel thread is running for this | |
| 1086 | − * NIC. Each NIC gets one watchdog kernel thread. | |
| 1203 | + if (atomic_read(oct_dev->adapter_refcount) == 1) { | |
| 1204 | + /* Each NIC gets one watchdog kernel thread. The first | |
| 1205 | + * PF (of each NIC) that gets pci_driver->probe()'d | |
| 1206 | + * creates that thread. | |
| 1087 | 1207 | */ |
| 1088 | − scratch1 |= 4ULL; | |
| 1089 | − octeon_write_csr64(oct_dev, CN23XX_SLI_SCRATCH1, | |
| 1090 | − scratch1); | |
| 1091 | − | |
| 1092 | 1208 | bus = pdev->bus->number; |
| 1093 | 1209 | device = PCI_SLOT(pdev->devfn); |
| 1094 | 1210 | function = PCI_FUNC(pdev->devfn); |
| @@ -1115,10 +1231,10 @@ liquidio_probe(struct pci_dev *pdev, · 20 unmodified lines | ||
| 1115 | 1231 | return 0; |
| 1116 | 1232 | } |
| 1117 | 1233 | |
| 1118 | −static bool fw_type_is_none(void) | |
| 1234 | +static bool fw_type_is_auto(void) | |
| 1119 | 1235 | { |
| 1120 | − return strncmp(fw_type, LIO_FW_NAME_TYPE_NONE, | |
| 1121 | − sizeof(LIO_FW_NAME_TYPE_NONE)) == 0; | |
| 1236 | + return strncmp(fw_type, LIO_FW_NAME_TYPE_AUTO, | |
| 1237 | + sizeof(LIO_FW_NAME_TYPE_AUTO)) == 0; | |
| 1122 | 1238 | } |
| 1123 | 1239 | |
| 1124 | 1240 | /** |
| @@ -1302,7 +1418,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) · 177 unmodified lines | ||
| 1302 | 1418 | * Implementation note: only soft-reset the device |
| 1303 | 1419 | * if it is a CN6XXX OR the LAST CN23XX device. |
| 1304 | 1420 | */ |
| 1305 | − if (fw_type_is_none()) | |
| 1421 | + if (atomic_read(oct->adapter_fw_state) == FW_IS_PRELOADED) | |
| 1306 | 1422 | octeon_pci_flr(oct); |
| 1307 | 1423 | else if (OCTEON_CN6XXX(oct) || !refcount) |
| 1308 | 1424 | oct->fn_list.soft_reset(oct); |
| @@ -1455,6 +1571,7 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx) · 146 unmodified lines | ||
| 1455 | 1571 | if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED) |
| 1456 | 1572 | unregister_netdev(netdev); |
| 1457 | 1573 | |
| 1574 | + cleanup_sync_octeon_time_wq(netdev); | |
| 1458 | 1575 | cleanup_link_status_change_wq(netdev); |
| 1459 | 1576 | |
| 1460 | 1577 | cleanup_rx_oom_poll_fn(netdev); |
| @@ -1487,6 +1604,8 @@ static int liquidio_stop_nic_module(struct octeon_device *oct) · 26 unmodified lines | ||
| 1487 | 1604 | oct->cmd_resp_state = OCT_DRV_OFFLINE; |
| 1488 | 1605 | spin_unlock_bh(&oct->cmd_resp_wqlock); |
| 1489 | 1606 | |
| 1607 | + lio_vf_rep_destroy(oct); | |
| 1608 | + | |
| 1490 | 1609 | for (i = 0; i < oct->ifcount; i++) { |
| 1491 | 1610 | lio = GET_LIO(oct->props[i].netdev); |
| 1492 | 1611 | for (j = 0; j < oct->num_oqs; j++) |
| @@ -1497,6 +1616,12 @@ static int liquidio_stop_nic_module(struct octeon_device *oct) · 4 unmodified lines | ||
| 1497 | 1616 | for (i = 0; i < oct->ifcount; i++) |
| 1498 | 1617 | liquidio_destroy_nic_device(oct, i); |
| 1499 | 1618 | |
| 1619 | + if (oct->devlink) { | |
| 1620 | + devlink_unregister(oct->devlink); | |
| 1621 | + devlink_free(oct->devlink); | |
| 1622 | + oct->devlink = NULL; | |
| 1623 | + } | |
| 1624 | + | |
| 1500 | 1625 | dev_dbg(&oct->pci_dev->dev, "Network interfaces stopped\n"); |
| 1501 | 1626 | return 0; |
| 1502 | 1627 | } |
| @@ -1514,6 +1639,10 @@ static void liquidio_remove(struct pci_dev *pdev) · 11 unmodified lines | ||
| 1514 | 1639 | if (oct_dev->watchdog_task) |
| 1515 | 1640 | kthread_stop(oct_dev->watchdog_task); |
| 1516 | 1641 | |
| 1642 | + if (!oct_dev->octeon_id && | |
| 1643 | + oct_dev->fw_info.app_cap_flags & LIQUIDIO_SWITCHDEV_CAP) | |
| 1644 | + lio_vf_rep_modexit(); | |
| 1645 | + | |
| 1517 | 1646 | if (oct_dev->app_mode && (oct_dev->app_mode == CVM_DRV_NIC_APP)) |
| 1518 | 1647 | liquidio_stop_nic_module(oct_dev); |
| 1519 | 1648 | |
| @@ -1934,10 +2063,12 @@ static int load_firmware(struct octeon_device *oct) · 414 unmodified lines | ||
| 1934 | 2063 | char fw_name[LIO_MAX_FW_FILENAME_LEN]; |
| 1935 | 2064 | char *tmp_fw_type; |
| 1936 | 2065 | |
| 1937 | − if (fw_type[0] == '\0') | |
| 2066 | + if (fw_type_is_auto()) { | |
| 1938 | 2067 | tmp_fw_type = LIO_FW_NAME_TYPE_NIC; |
| 1939 | − else | |
| 2068 | + strncpy(fw_type, tmp_fw_type, sizeof(fw_type)); | |
| 2069 | + } else { | |
| 1940 | 2070 | tmp_fw_type = fw_type; |
| 2071 | + } | |
| 1941 | 2072 | |
| 1942 | 2073 | sprintf(fw_name, "%s%s%s_%s%s", LIO_FW_DIR, LIO_FW_BASE_NAME, |
| 1943 | 2074 | octeon_get_conf(oct)->card_name, tmp_fw_type, |
| @@ -2477,7 +2608,8 @@ static void handle_timestamp(struct octeon_device *oct, · 533 unmodified lines | ||
| 2477 | 2608 | */ |
| 2478 | 2609 | static inline int send_nic_timestamp_pkt(struct octeon_device *oct, |
| 2479 | 2610 | struct octnic_data_pkt *ndata, |
| 2480 | − struct octnet_buf_free_info *finfo) | |
| 2611 | + struct octnet_buf_free_info *finfo, | |
| 2612 | + int xmit_more) | |
| 2481 | 2613 | { |
| 2482 | 2614 | int retval; |
| 2483 | 2615 | struct octeon_soft_command *sc; |
| @@ -2512,7 +2644,7 @@ static inline int send_nic_timestamp_pkt(struct octeon_device *oct, · 28 unmodified lines | ||
| 2512 | 2644 | len = (u32)((struct octeon_instr_ih2 *) |
| 2513 | 2645 | (&sc->cmd.cmd2.ih2))->dlengsz; |
| 2514 | 2646 | |
| 2515 | − ring_doorbell = 1; | |
| 2647 | + ring_doorbell = !xmit_more; | |
| 2516 | 2648 | |
| 2517 | 2649 | retval = octeon_send_command(oct, sc->iq_no, ring_doorbell, &sc->cmd, |
| 2518 | 2650 | sc, len, ndata->reqtype); |
| @@ -2546,7 +2678,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) · 27 unmodified lines | ||
| 2546 | 2678 | union tx_info *tx_info; |
| 2547 | 2679 | int status = 0; |
| 2548 | 2680 | int q_idx = 0, iq_no = 0; |
| 2549 | − int j; | |
| 2681 | + int j, xmit_more = 0; | |
| 2550 | 2682 | u64 dptr = 0; |
| 2551 | 2683 | u32 tag = 0; |
| 2552 | 2684 | |
| @@ -2751,17 +2883,19 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) · 198 unmodified lines | ||
| 2751 | 2883 | irh->vlan = skb_vlan_tag_get(skb) & 0xfff; |
| 2752 | 2884 | } |
| 2753 | 2885 | |
| 2886 | + xmit_more = skb->xmit_more; | |
| 2887 | + | |
| 2754 | 2888 | if (unlikely(cmdsetup.s.timestamp)) |
| 2755 | − status = send_nic_timestamp_pkt(oct, &ndata, finfo); | |
| 2889 | + status = send_nic_timestamp_pkt(oct, &ndata, finfo, xmit_more); | |
| 2756 | 2890 | else |
| 2757 | − status = octnet_send_nic_data_pkt(oct, &ndata); | |
| 2891 | + status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more); | |
| 2758 | 2892 | if (status == IQ_SEND_FAILED) |
| 2759 | 2893 | goto lio_xmit_failed; |
| 2760 | 2894 | |
| 2761 | 2895 | netif_info(lio, tx_queued, lio->netdev, "Transmit queued successfully\n"); |
| 2762 | 2896 | |
| 2763 | 2897 | if (status == IQ_SEND_STOP) |
| 2764 | − stop_q(lio->netdev, q_idx); | |
| 2898 | + stop_q(netdev, q_idx); | |
| 2765 | 2899 | |
| 2766 | 2900 | netif_trans_update(netdev); |
| 2767 | 2901 | |
| @@ -2780,6 +2914,9 @@ lio_xmit_failed: · 12 unmodified lines | ||
| 2780 | 2914 | if (dptr) |
| 2781 | 2915 | dma_unmap_single(&oct->pci_dev->dev, dptr, |
| 2782 | 2916 | ndata.datasize, DMA_TO_DEVICE); |
| 2917 | + | |
| 2918 | + octeon_ring_doorbell_locked(oct, iq_no); | |
| 2919 | + | |
| 2783 | 2920 | tx_buffer_free(skb); |
| 2784 | 2921 | return NETDEV_TX_OK; |
| 2785 | 2922 | } |
| @@ -3186,6 +3323,86 @@ static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, · 400 unmodified lines | ||
| 3186 | 3323 | return 0; |
| 3187 | 3324 | } |
| 3188 | 3325 | |
| 3326 | +static int | |
| 3327 | +liquidio_eswitch_mode_get(struct devlink *devlink, u16 *mode) | |
| 3328 | +{ | |
| 3329 | + struct lio_devlink_priv *priv; | |
| 3330 | + struct octeon_device *oct; | |
| 3331 | + | |
| 3332 | + priv = devlink_priv(devlink); | |
| 3333 | + oct = priv->oct; | |
| 3334 | + | |
| 3335 | + *mode = oct->eswitch_mode; | |
| 3336 | + | |
| 3337 | + return 0; | |
| 3338 | +} | |
| 3339 | + | |
| 3340 | +static int | |
| 3341 | +liquidio_eswitch_mode_set(struct devlink *devlink, u16 mode) | |
| 3342 | +{ | |
| 3343 | + struct lio_devlink_priv *priv; | |
| 3344 | + struct octeon_device *oct; | |
| 3345 | + int ret = 0; | |
| 3346 | + | |
| 3347 | + priv = devlink_priv(devlink); | |
| 3348 | + oct = priv->oct; | |
| 3349 | + | |
| 3350 | + if (!(oct->fw_info.app_cap_flags & LIQUIDIO_SWITCHDEV_CAP)) | |
| 3351 | + return -EINVAL; | |
| 3352 | + | |
| 3353 | + if (oct->eswitch_mode == mode) | |
| 3354 | + return 0; | |
| 3355 | + | |
| 3356 | + switch (mode) { | |
| 3357 | + case DEVLINK_ESWITCH_MODE_SWITCHDEV: | |
| 3358 | + oct->eswitch_mode = mode; | |
| 3359 | + ret = lio_vf_rep_create(oct); | |
| 3360 | + break; | |
| 3361 | + | |
| 3362 | + case DEVLINK_ESWITCH_MODE_LEGACY: | |
| 3363 | + lio_vf_rep_destroy(oct); | |
| 3364 | + oct->eswitch_mode = mode; | |
| 3365 | + break; | |
| 3366 | + | |
| 3367 | + default: | |
| 3368 | + ret = -EINVAL; | |
| 3369 | + } | |
| 3370 | + | |
| 3371 | + return ret; | |
| 3372 | +} | |
| 3373 | + | |
| 3374 | +static const struct devlink_ops liquidio_devlink_ops = { | |
| 3375 | + .eswitch_mode_get = liquidio_eswitch_mode_get, | |
| 3376 | + .eswitch_mode_set = liquidio_eswitch_mode_set, | |
| 3377 | +}; | |
| 3378 | + | |
| 3379 | +static int | |
| 3380 | +lio_pf_switchdev_attr_get(struct net_device *dev, struct switchdev_attr *attr) | |
| 3381 | +{ | |
| 3382 | + struct lio *lio = GET_LIO(dev); | |
| 3383 | + struct octeon_device *oct = lio->oct_dev; | |
| 3384 | + | |
| 3385 | + if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV) | |
| 3386 | + return -EOPNOTSUPP; | |
| 3387 | + | |
| 3388 | + switch (attr->id) { | |
| 3389 | + case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: | |
| 3390 | + attr->u.ppid.id_len = ETH_ALEN; | |
| 3391 | + ether_addr_copy(attr->u.ppid.id, | |
| 3392 | + (void *)&lio->linfo.hw_addr + 2); | |
| 3393 | + break; | |
| 3394 | + | |
| 3395 | + default: | |
| 3396 | + return -EOPNOTSUPP; | |
| 3397 | + } | |
| 3398 | + | |
| 3399 | + return 0; | |
| 3400 | +} | |
| 3401 | + | |
| 3402 | +static const struct switchdev_ops lio_pf_switchdev_ops = { | |
| 3403 | + .switchdev_port_attr_get = lio_pf_switchdev_attr_get, | |
| 3404 | +}; | |
| 3405 | + | |
| 3189 | 3406 | static const struct net_device_ops lionetdevops = { |
| 3190 | 3407 | .ndo_open = liquidio_open, |
| 3191 | 3408 | .ndo_stop = liquidio_stop, |
| @@ -3303,7 +3520,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 111 unmodified lines | ||
| 3303 | 3520 | { |
| 3304 | 3521 | struct lio *lio = NULL; |
| 3305 | 3522 | struct net_device *netdev; |
| 3306 | − u8 mac[6], i, j; | |
| 3523 | + u8 mac[6], i, j, *fw_ver; | |
| 3307 | 3524 | struct octeon_soft_command *sc; |
| 3308 | 3525 | struct liquidio_if_cfg_context *ctx; |
| 3309 | 3526 | struct liquidio_if_cfg_resp *resp; |
| @@ -3315,6 +3532,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 5 unmodified lines | ||
| 3315 | 3532 | u32 resp_size, ctx_size, data_size; |
| 3316 | 3533 | u32 ifidx_or_pfnum; |
| 3317 | 3534 | struct lio_version *vdata; |
| 3535 | + struct devlink *devlink; | |
| 3536 | + struct lio_devlink_priv *lio_devlink; | |
| 3318 | 3537 | |
| 3319 | 3538 | /* This is to handle link status changes */ |
| 3320 | 3539 | octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC, |
| @@ -3414,6 +3633,22 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 93 unmodified lines | ||
| 3414 | 3633 | goto setup_nic_dev_fail; |
| 3415 | 3634 | } |
| 3416 | 3635 | |
| 3636 | + /* Verify f/w version (in case of 'auto' loading from flash) */ | |
| 3637 | + fw_ver = octeon_dev->fw_info.liquidio_firmware_version; | |
| 3638 | + if (memcmp(LIQUIDIO_BASE_VERSION, | |
| 3639 | + fw_ver, | |
| 3640 | + strlen(LIQUIDIO_BASE_VERSION))) { | |
| 3641 | + dev_err(&octeon_dev->pci_dev->dev, | |
| 3642 | + "Unmatched firmware version. Expected %s.x, got %s.\n", | |
| 3643 | + LIQUIDIO_BASE_VERSION, fw_ver); | |
| 3644 | + goto setup_nic_dev_fail; | |
| 3645 | + } else if (atomic_read(octeon_dev->adapter_fw_state) == | |
| 3646 | + FW_IS_PRELOADED) { | |
| 3647 | + dev_info(&octeon_dev->pci_dev->dev, | |
| 3648 | + "Using auto-loaded firmware version %s.\n", | |
| 3649 | + fw_ver); | |
| 3650 | + } | |
| 3651 | + | |
| 3417 | 3652 | octeon_swap_8B_data((u64 *)(&resp->cfg_info), |
| 3418 | 3653 | (sizeof(struct liquidio_if_cfg_info)) >> 3); |
| 3419 | 3654 | |
| @@ -3444,6 +3679,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 24 unmodified lines | ||
| 3444 | 3679 | * netdev tasks. |
| 3445 | 3680 | */ |
| 3446 | 3681 | netdev->netdev_ops = &lionetdevops; |
| 3682 | + SWITCHDEV_SET_OPS(netdev, &lio_pf_switchdev_ops); | |
| 3447 | 3683 | |
| 3448 | 3684 | lio = GET_LIO(netdev); |
| 3449 | 3685 | |
| @@ -3593,6 +3829,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 143 unmodified lines | ||
| 3593 | 3829 | if (setup_link_status_change_wq(netdev)) |
| 3594 | 3830 | goto setup_nic_dev_fail; |
| 3595 | 3831 | |
| 3832 | + if ((octeon_dev->fw_info.app_cap_flags & | |
| 3833 | + LIQUIDIO_TIME_SYNC_CAP) && | |
| 3834 | + setup_sync_octeon_time_wq(netdev)) | |
| 3835 | + goto setup_nic_dev_fail; | |
| 3836 | + | |
| 3596 | 3837 | if (setup_rx_oom_poll_fn(netdev)) |
| 3597 | 3838 | goto setup_nic_dev_fail; |
| 3598 | 3839 | |
| @@ -3625,6 +3866,26 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) · 26 unmodified lines | ||
| 3625 | 3866 | octeon_free_soft_command(octeon_dev, sc); |
| 3626 | 3867 | } |
| 3627 | 3868 | |
| 3869 | + devlink = devlink_alloc(&liquidio_devlink_ops, | |
| 3870 | + sizeof(struct lio_devlink_priv)); | |
| 3871 | + if (!devlink) { | |
| 3872 | + dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n"); | |
| 3873 | + goto setup_nic_wait_intr; | |
| 3874 | + } | |
| 3875 | + | |
| 3876 | + lio_devlink = devlink_priv(devlink); | |
| 3877 | + lio_devlink->oct = octeon_dev; | |
| 3878 | + | |
| 3879 | + if (devlink_register(devlink, &octeon_dev->pci_dev->dev)) { | |
| 3880 | + devlink_free(devlink); | |
| 3881 | + dev_err(&octeon_dev->pci_dev->dev, | |
| 3882 | + "devlink registration failed\n"); | |
| 3883 | + goto setup_nic_wait_intr; | |
| 3884 | + } | |
| 3885 | + | |
| 3886 | + octeon_dev->devlink = devlink; | |
| 3887 | + octeon_dev->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; | |
| 3888 | + | |
| 3628 | 3889 | return 0; |
| 3629 | 3890 | |
| 3630 | 3891 | setup_nic_dev_fail: |
| @@ -3719,6 +3980,7 @@ static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs) · 88 unmodified lines | ||
| 3719 | 3980 | } |
| 3720 | 3981 | |
| 3721 | 3982 | if (!num_vfs) { |
| 3983 | + lio_vf_rep_destroy(oct); | |
| 3722 | 3984 | ret = lio_pci_sriov_disable(oct); |
| 3723 | 3985 | } else if (num_vfs > oct->sriov_info.max_vfs) { |
| 3724 | 3986 | dev_err(&oct->pci_dev->dev, |
| @@ -3730,6 +3992,10 @@ static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs) · 5 unmodified lines | ||
| 3730 | 3992 | ret = octeon_enable_sriov(oct); |
| 3731 | 3993 | dev_info(&oct->pci_dev->dev, "oct->pf_num:%d num_vfs:%d\n", |
| 3732 | 3994 | oct->pf_num, num_vfs); |
| 3995 | + ret = lio_vf_rep_create(oct); | |
| 3996 | + if (ret) | |
| 3997 | + dev_info(&oct->pci_dev->dev, | |
| 3998 | + "vf representor create failed"); | |
| 3733 | 3999 | } |
| 3734 | 4000 | |
| 3735 | 4001 | return ret; |
| @@ -3767,6 +4033,18 @@ static int liquidio_init_nic_module(struct octeon_device *oct) · 31 unmodified lines | ||
| 3767 | 4033 | goto octnet_init_failure; |
| 3768 | 4034 | } |
| 3769 | 4035 | |
| 4036 | + /* Call vf_rep_modinit if the firmware is switchdev capable | |
| 4037 | + * and do it from the first liquidio function probed. | |
| 4038 | + */ | |
| 4039 | + if (!oct->octeon_id && | |
| 4040 | + oct->fw_info.app_cap_flags & LIQUIDIO_SWITCHDEV_CAP) { | |
| 4041 | + retval = lio_vf_rep_modinit(); | |
| 4042 | + if (retval) { | |
| 4043 | + liquidio_stop_nic_module(oct); | |
| 4044 | + goto octnet_init_failure; | |
| 4045 | + } | |
| 4046 | + } | |
| 4047 | + | |
| 3770 | 4048 | liquidio_ptp_init(oct); |
| 3771 | 4049 | |
| 3772 | 4050 | dev_dbg(&oct->pci_dev->dev, "Network interfaces ready\n"); |
| @@ -3882,9 +4160,9 @@ octeon_recv_vf_drv_notice(struct octeon_recv_info *recv_info, void *buf) · 109 unmodified lines | ||
| 3882 | 4160 | static int octeon_device_init(struct octeon_device *octeon_dev) |
| 3883 | 4161 | { |
| 3884 | 4162 | int j, ret; |
| 3885 | − int fw_loaded = 0; | |
| 3886 | 4163 | char bootcmd[] = "\n"; |
| 3887 | 4164 | char *dbg_enb = NULL; |
| 4165 | + enum lio_fw_state fw_state; | |
| 3888 | 4166 | struct octeon_device_priv *oct_priv = |
| 3889 | 4167 | (struct octeon_device_priv *)octeon_dev->priv; |
| 3890 | 4168 | atomic_set(&octeon_dev->status, OCT_DEV_BEGIN_STATE); |
| @@ -3916,24 +4194,40 @@ static int octeon_device_init(struct octeon_device *octeon_dev) · 25 unmodified lines | ||
| 3916 | 4194 | |
| 3917 | 4195 | octeon_dev->app_mode = CVM_DRV_INVALID_APP; |
| 3918 | 4196 | |
| 3919 | − if (OCTEON_CN23XX_PF(octeon_dev)) { | |
| 3920 | − if (!cn23xx_fw_loaded(octeon_dev) && !fw_type_is_none()) { | |
| 3921 | − fw_loaded = 0; | |
| 3922 | − /* Do a soft reset of the Octeon device. */ | |
| 3923 | − if (octeon_dev->fn_list.soft_reset(octeon_dev)) | |
| 3924 | − return 1; | |
| 3925 | − /* things might have changed */ | |
| 3926 | − if (!cn23xx_fw_loaded(octeon_dev)) | |
| 3927 | − fw_loaded = 0; | |
| 3928 | − else | |
| 3929 | − fw_loaded = 1; | |
| 3930 | − } else { | |
| 3931 | − fw_loaded = 1; | |
| 3932 | − } | |
| 3933 | − } else if (octeon_dev->fn_list.soft_reset(octeon_dev)) { | |
| 3934 | − return 1; | |
| 4197 | + /* CN23XX supports preloaded firmware if the following is true: | |
| 4198 | + * | |
| 4199 | + * The adapter indicates that firmware is currently running AND | |
| 4200 | + * 'fw_type' is 'auto'. | |
| 4201 | + * | |
| 4202 | + * (default state is NEEDS_TO_BE_LOADED, override it if appropriate). | |
| 4203 | + */ | |
| 4204 | + if (OCTEON_CN23XX_PF(octeon_dev) && | |
| 4205 | + cn23xx_fw_loaded(octeon_dev) && fw_type_is_auto()) { | |
| 4206 | + atomic_cmpxchg(octeon_dev->adapter_fw_state, | |
| 4207 | + FW_NEEDS_TO_BE_LOADED, FW_IS_PRELOADED); | |
| 3935 | 4208 | } |
| 3936 | 4209 | |
| 4210 | + /* If loading firmware, only first device of adapter needs to do so. */ | |
| 4211 | + fw_state = atomic_cmpxchg(octeon_dev->adapter_fw_state, | |
| 4212 | + FW_NEEDS_TO_BE_LOADED, | |
| 4213 | + FW_IS_BEING_LOADED); | |
| 4214 | + | |
| 4215 | + /* Here, [local variable] 'fw_state' is set to one of: | |
| 4216 | + * | |
| 4217 | + * FW_IS_PRELOADED: No firmware is to be loaded (see above) | |
| 4218 | + * FW_NEEDS_TO_BE_LOADED: The driver's first instance will load | |
| 4219 | + * firmware to the adapter. | |
| 4220 | + * FW_IS_BEING_LOADED: The driver's second instance will not load | |
| 4221 | + * firmware to the adapter. | |
| 4222 | + */ | |
| 4223 | + | |
| 4224 | + /* Prior to f/w load, perform a soft reset of the Octeon device; | |
| 4225 | + * if error resetting, return w/error. | |
| 4226 | + */ | |
| 4227 | + if (fw_state == FW_NEEDS_TO_BE_LOADED) | |
| 4228 | + if (octeon_dev->fn_list.soft_reset(octeon_dev)) | |
| 4229 | + return 1; | |
| 4230 | + | |
| 3937 | 4231 | /* Initialize the dispatch mechanism used to push packets arriving on |
| 3938 | 4232 | * Octeon Output queues. |
| 3939 | 4233 | */ |
| @@ -4063,7 +4357,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev) · 123 unmodified lines | ||
| 4063 | 4357 | |
| 4064 | 4358 | atomic_set(&octeon_dev->status, OCT_DEV_IO_QUEUES_DONE); |
| 4065 | 4359 | |
| 4066 | − if ((!OCTEON_CN23XX_PF(octeon_dev)) || !fw_loaded) { | |
| 4360 | + if (fw_state == FW_NEEDS_TO_BE_LOADED) { | |
| 4067 | 4361 | dev_dbg(&octeon_dev->pci_dev->dev, "Waiting for DDR initialization...\n"); |
| 4068 | 4362 | if (!ddr_timeout) { |
| 4069 | 4363 | dev_info(&octeon_dev->pci_dev->dev, |
| @@ -4125,6 +4419,8 @@ static int octeon_device_init(struct octeon_device *octeon_dev) · 55 unmodified lines | ||
| 4125 | 4419 | dev_err(&octeon_dev->pci_dev->dev, "Could not load firmware to board\n"); |
| 4126 | 4420 | return 1; |
| 4127 | 4421 | } |
| 4422 | + | |
| 4423 | + atomic_set(octeon_dev->adapter_fw_state, FW_HAS_BEEN_LOADED); | |
| 4128 | 4424 | } |
| 4129 | 4425 | |
| 4130 | 4426 | handshake[octeon_dev->octeon_id].init_ok = 1; |
| @@ -435,8 +435,7 @@ static void delete_glists(struct lio *lio) · 434 unmodified lines | ||
| 435 | 435 | do { |
| 436 | 436 | g = (struct octnic_gather *) |
| 437 | 437 | list_delete_head(&lio->glist[i]); |
| 438 | − if (g) | |
| 439 | − kfree(g); | |
| 438 | + kfree(g); | |
| 440 | 439 | } while (g); |
| 441 | 440 | |
| 442 | 441 | if (lio->glists_virt_base && lio->glists_virt_base[i] && |
| @@ -748,7 +747,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) · 305 unmodified lines | ||
| 748 | 747 | |
| 749 | 748 | if (lio_wait_for_oq_pkts(oct)) |
| 750 | 749 | dev_err(&oct->pci_dev->dev, "OQ had pending packets\n"); |
| 751 | − | |
| 750 | + /* fall through */ | |
| 752 | 751 | case OCT_DEV_INTR_SET_DONE: |
| 753 | 752 | /* Disable interrupts */ |
| 754 | 753 | oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR); |
| @@ -1289,6 +1288,9 @@ static int liquidio_stop(struct net_device *netdev) · 534 unmodified lines | ||
| 1289 | 1288 | struct octeon_device *oct = lio->oct_dev; |
| 1290 | 1289 | struct napi_struct *napi, *n; |
| 1291 | 1290 | |
| 1291 | + /* tell Octeon to stop forwarding packets to host */ | |
| 1292 | + send_rx_ctrl_cmd(lio, 0); | |
| 1293 | + | |
| 1292 | 1294 | if (oct->props[lio->ifidx].napi_enabled) { |
| 1293 | 1295 | list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) |
| 1294 | 1296 | napi_disable(napi); |
| @@ -1306,9 +1308,6 @@ static int liquidio_stop(struct net_device *netdev) · 11 unmodified lines | ||
| 1306 | 1308 | netif_carrier_off(netdev); |
| 1307 | 1309 | lio->link_changes++; |
| 1308 | 1310 | |
| 1309 | − /* tell Octeon to stop forwarding packets to host */ | |
| 1310 | − send_rx_ctrl_cmd(lio, 0); | |
| 1311 | − | |
| 1312 | 1311 | ifstate_reset(lio, LIO_IFSTATE_RUNNING); |
| 1313 | 1312 | |
| 1314 | 1313 | txqs_stop(netdev); |
| @@ -1691,7 +1690,8 @@ static void handle_timestamp(struct octeon_device *oct, u32 status, void *buf) · 376 unmodified lines | ||
| 1691 | 1690 | */ |
| 1692 | 1691 | static int send_nic_timestamp_pkt(struct octeon_device *oct, |
| 1693 | 1692 | struct octnic_data_pkt *ndata, |
| 1694 | − struct octnet_buf_free_info *finfo) | |
| 1693 | + struct octnet_buf_free_info *finfo, | |
| 1694 | + int xmit_more) | |
| 1695 | 1695 | { |
| 1696 | 1696 | struct octeon_soft_command *sc; |
| 1697 | 1697 | int ring_doorbell; |
| @@ -1721,7 +1721,7 @@ static int send_nic_timestamp_pkt(struct octeon_device *oct, · 23 unmodified lines | ||
| 1721 | 1721 | |
| 1722 | 1722 | len = (u32)((struct octeon_instr_ih3 *)(&sc->cmd.cmd3.ih3))->dlengsz; |
| 1723 | 1723 | |
| 1724 | − ring_doorbell = 1; | |
| 1724 | + ring_doorbell = !xmit_more; | |
| 1725 | 1725 | |
| 1726 | 1726 | retval = octeon_send_command(oct, sc->iq_no, ring_doorbell, &sc->cmd, |
| 1727 | 1727 | sc, len, ndata->reqtype); |
| @@ -1753,6 +1753,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) · 25 unmodified lines | ||
| 1753 | 1753 | struct octeon_device *oct; |
| 1754 | 1754 | int q_idx = 0, iq_no = 0; |
| 1755 | 1755 | union tx_info *tx_info; |
| 1756 | + int xmit_more = 0; | |
| 1756 | 1757 | struct lio *lio; |
| 1757 | 1758 | int status = 0; |
| 1758 | 1759 | u64 dptr = 0; |
| @@ -1941,10 +1942,12 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) · 182 unmodified lines | ||
| 1941 | 1942 | irh->vlan = skb_vlan_tag_get(skb) & VLAN_VID_MASK; |
| 1942 | 1943 | } |
| 1943 | 1944 | |
| 1945 | + xmit_more = skb->xmit_more; | |
| 1946 | + | |
| 1944 | 1947 | if (unlikely(cmdsetup.s.timestamp)) |
| 1945 | − status = send_nic_timestamp_pkt(oct, &ndata, finfo); | |
| 1948 | + status = send_nic_timestamp_pkt(oct, &ndata, finfo, xmit_more); | |
| 1946 | 1949 | else |
| 1947 | − status = octnet_send_nic_data_pkt(oct, &ndata); | |
| 1950 | + status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more); | |
| 1948 | 1951 | if (status == IQ_SEND_FAILED) |
| 1949 | 1952 | goto lio_xmit_failed; |
| 1950 | 1953 | |
| @@ -1953,7 +1956,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) · 2 unmodified lines | ||
| 1953 | 1956 | if (status == IQ_SEND_STOP) { |
| 1954 | 1957 | dev_err(&oct->pci_dev->dev, "Rcvd IQ_SEND_STOP signal; stopping IQ-%d\n", |
| 1955 | 1958 | iq_no); |
| 1956 | − stop_q(lio->netdev, q_idx); | |
| 1959 | + stop_q(netdev, q_idx); | |
| 1957 | 1960 | } |
| 1958 | 1961 | |
| 1959 | 1962 | netif_trans_update(netdev); |
| @@ -1973,6 +1976,9 @@ lio_xmit_failed: · 13 unmodified lines | ||
| 1973 | 1976 | if (dptr) |
| 1974 | 1977 | dma_unmap_single(&oct->pci_dev->dev, dptr, |
| 1975 | 1978 | ndata.datasize, DMA_TO_DEVICE); |
| 1979 | + | |
| 1980 | + octeon_ring_doorbell_locked(oct, iq_no); | |
| 1981 | + | |
| 1976 | 1982 | tx_buffer_free(skb); |
| 1977 | 1983 | return NETDEV_TX_OK; |
| 1978 | 1984 | } |
| @@ -0,0 +1,695 @@ | ||
| 1 | +/********************************************************************** | |
| 2 | + * Author: Cavium, Inc. | |
| 3 | + * | |
| 4 | + * Contact: support@cavium.com | |
| 5 | + * Please include "LiquidIO" in the subject. | |
| 6 | + * | |
| 7 | + * Copyright (c) 2003-2017 Cavium, Inc. | |
| 8 | + * | |
| 9 | + * This file is free software; you can redistribute it and/or modify | |
| 10 | + * it under the terms of the GNU General Public License, Version 2, as | |
| 11 | + * published by the Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This file is distributed in the hope that it will be useful, but | |
| 14 | + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | |
| 15 | + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | |
| 16 | + * NONINFRINGEMENT. See the GNU General Public License for more details. | |
| 17 | + ***********************************************************************/ | |
| 18 | +#include <linux/pci.h> | |
| 19 | +#include <linux/if_vlan.h> | |
| 20 | +#include "liquidio_common.h" | |
| 21 | +#include "octeon_droq.h" | |
| 22 | +#include "octeon_iq.h" | |
| 23 | +#include "response_manager.h" | |
| 24 | +#include "octeon_device.h" | |
| 25 | +#include "octeon_nic.h" | |
| 26 | +#include "octeon_main.h" | |
| 27 | +#include "octeon_network.h" | |
| 28 | +#include <net/switchdev.h> | |
| 29 | +#include "lio_vf_rep.h" | |
| 30 | +#include "octeon_network.h" | |
| 31 | + | |
| 32 | +static int lio_vf_rep_open(struct net_device *ndev); | |
| 33 | +static int lio_vf_rep_stop(struct net_device *ndev); | |
| 34 | +static int lio_vf_rep_pkt_xmit(struct sk_buff *skb, struct net_device *ndev); | |
| 35 | +static void lio_vf_rep_tx_timeout(struct net_device *netdev); | |
| 36 | +static int lio_vf_rep_phys_port_name(struct net_device *dev, | |
| 37 | + char *buf, size_t len); | |
| 38 | +static void lio_vf_rep_get_stats64(struct net_device *dev, | |
| 39 | + struct rtnl_link_stats64 *stats64); | |
| 40 | +static int lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu); | |
| 41 | + | |
| 42 | +static const struct net_device_ops lio_vf_rep_ndev_ops = { | |
| 43 | + .ndo_open = lio_vf_rep_open, | |
| 44 | + .ndo_stop = lio_vf_rep_stop, | |
| 45 | + .ndo_start_xmit = lio_vf_rep_pkt_xmit, | |
| 46 | + .ndo_tx_timeout = lio_vf_rep_tx_timeout, | |
| 47 | + .ndo_get_phys_port_name = lio_vf_rep_phys_port_name, | |
| 48 | + .ndo_get_stats64 = lio_vf_rep_get_stats64, | |
| 49 | + .ndo_change_mtu = lio_vf_rep_change_mtu, | |
| 50 | +}; | |
| 51 | + | |
| 52 | +static void | |
| 53 | +lio_vf_rep_send_sc_complete(struct octeon_device *oct, | |
| 54 | + u32 status, void *ptr) | |
| 55 | +{ | |
| 56 | + struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr; | |
| 57 | + struct lio_vf_rep_sc_ctx *ctx = | |
| 58 | + (struct lio_vf_rep_sc_ctx *)sc->ctxptr; | |
| 59 | + struct lio_vf_rep_resp *resp = | |
| 60 | + (struct lio_vf_rep_resp *)sc->virtrptr; | |
| 61 | + | |
| 62 | + if (status != OCTEON_REQUEST_TIMEOUT && READ_ONCE(resp->status)) | |
| 63 | + WRITE_ONCE(resp->status, 0); | |
| 64 | + | |
| 65 | + complete(&ctx->complete); | |
| 66 | +} | |
| 67 | + | |
| 68 | +static int | |
| 69 | +lio_vf_rep_send_soft_command(struct octeon_device *oct, | |
| 70 | + void *req, int req_size, | |
| 71 | + void *resp, int resp_size) | |
| 72 | +{ | |
| 73 | + int tot_resp_size = sizeof(struct lio_vf_rep_resp) + resp_size; | |
| 74 | + int ctx_size = sizeof(struct lio_vf_rep_sc_ctx); | |
| 75 | + struct octeon_soft_command *sc = NULL; | |
| 76 | + struct lio_vf_rep_resp *rep_resp; | |
| 77 | + struct lio_vf_rep_sc_ctx *ctx; | |
| 78 | + void *sc_req; | |
| 79 | + int err; | |
| 80 | + | |
| 81 | + sc = (struct octeon_soft_command *) | |
| 82 | + octeon_alloc_soft_command(oct, req_size, | |
| 83 | + tot_resp_size, ctx_size); | |
| 84 | + if (!sc) | |
| 85 | + return -ENOMEM; | |
| 86 | + | |
| 87 | + ctx = (struct lio_vf_rep_sc_ctx *)sc->ctxptr; | |
| 88 | + memset(ctx, 0, ctx_size); | |
| 89 | + init_completion(&ctx->complete); | |
| 90 | + | |
| 91 | + sc_req = (struct lio_vf_rep_req *)sc->virtdptr; | |
| 92 | + memcpy(sc_req, req, req_size); | |
| 93 | + | |
| 94 | + rep_resp = (struct lio_vf_rep_resp *)sc->virtrptr; | |
| 95 | + memset(rep_resp, 0, tot_resp_size); | |
| 96 | + WRITE_ONCE(rep_resp->status, 1); | |
| 97 | + | |
| 98 | + sc->iq_no = 0; | |
| 99 | + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, | |
| 100 | + OPCODE_NIC_VF_REP_CMD, 0, 0, 0); | |
| 101 | + sc->callback = lio_vf_rep_send_sc_complete; | |
| 102 | + sc->callback_arg = sc; | |
| 103 | + sc->wait_time = LIO_VF_REP_REQ_TMO_MS; | |
| 104 | + | |
| 105 | + err = octeon_send_soft_command(oct, sc); | |
| 106 | + if (err == IQ_SEND_FAILED) | |
| 107 | + goto free_buff; | |
| 108 | + | |
| 109 | + wait_for_completion_timeout(&ctx->complete, | |
| 110 | + msecs_to_jiffies | |
| 111 | + (2 * LIO_VF_REP_REQ_TMO_MS)); | |
| 112 | + err = READ_ONCE(rep_resp->status) ? -EBUSY : 0; | |
| 113 | + if (err) | |
| 114 | + dev_err(&oct->pci_dev->dev, "VF rep send config failed\n"); | |
| 115 | + | |
| 116 | + if (resp) | |
| 117 | + memcpy(resp, (rep_resp + 1), resp_size); | |
| 118 | +free_buff: | |
| 119 | + octeon_free_soft_command(oct, sc); | |
| 120 | + | |
| 121 | + return err; | |
| 122 | +} | |
| 123 | + | |
| 124 | +static int | |
| 125 | +lio_vf_rep_open(struct net_device *ndev) | |
| 126 | +{ | |
| 127 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev); | |
| 128 | + struct lio_vf_rep_req rep_cfg; | |
| 129 | + struct octeon_device *oct; | |
| 130 | + int ret; | |
| 131 | + | |
| 132 | + oct = vf_rep->oct; | |
| 133 | + | |
| 134 | + memset(&rep_cfg, 0, sizeof(rep_cfg)); | |
| 135 | + rep_cfg.req_type = LIO_VF_REP_REQ_STATE; | |
| 136 | + rep_cfg.ifidx = vf_rep->ifidx; | |
| 137 | + rep_cfg.rep_state.state = LIO_VF_REP_STATE_UP; | |
| 138 | + | |
| 139 | + ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, | |
| 140 | + sizeof(rep_cfg), NULL, 0); | |
| 141 | + | |
| 142 | + if (ret) { | |
| 143 | + dev_err(&oct->pci_dev->dev, | |
| 144 | + "VF_REP open failed with err %d\n", ret); | |
| 145 | + return -EIO; | |
| 146 | + } | |
| 147 | + | |
| 148 | + atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) | | |
| 149 | + LIO_IFSTATE_RUNNING)); | |
| 150 | + | |
| 151 | + netif_carrier_on(ndev); | |
| 152 | + netif_start_queue(ndev); | |
| 153 | + | |
| 154 | + return 0; | |
| 155 | +} | |
| 156 | + | |
| 157 | +static int | |
| 158 | +lio_vf_rep_stop(struct net_device *ndev) | |
| 159 | +{ | |
| 160 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev); | |
| 161 | + struct lio_vf_rep_req rep_cfg; | |
| 162 | + struct octeon_device *oct; | |
| 163 | + int ret; | |
| 164 | + | |
| 165 | + oct = vf_rep->oct; | |
| 166 | + | |
| 167 | + memset(&rep_cfg, 0, sizeof(rep_cfg)); | |
| 168 | + rep_cfg.req_type = LIO_VF_REP_REQ_STATE; | |
| 169 | + rep_cfg.ifidx = vf_rep->ifidx; | |
| 170 | + rep_cfg.rep_state.state = LIO_VF_REP_STATE_DOWN; | |
| 171 | + | |
| 172 | + ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, | |
| 173 | + sizeof(rep_cfg), NULL, 0); | |
| 174 | + | |
| 175 | + if (ret) { | |
| 176 | + dev_err(&oct->pci_dev->dev, | |
| 177 | + "VF_REP dev stop failed with err %d\n", ret); | |
| 178 | + return -EIO; | |
| 179 | + } | |
| 180 | + | |
| 181 | + atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) & | |
| 182 | + ~LIO_IFSTATE_RUNNING)); | |
| 183 | + | |
| 184 | + netif_tx_disable(ndev); | |
| 185 | + netif_carrier_off(ndev); | |
| 186 | + | |
| 187 | + return 0; | |
| 188 | +} | |
| 189 | + | |
| 190 | +static void | |
| 191 | +lio_vf_rep_tx_timeout(struct net_device *ndev) | |
| 192 | +{ | |
| 193 | + netif_trans_update(ndev); | |
| 194 | + | |
| 195 | + netif_wake_queue(ndev); | |
| 196 | +} | |
| 197 | + | |
| 198 | +static void | |
| 199 | +lio_vf_rep_get_stats64(struct net_device *dev, | |
| 200 | + struct rtnl_link_stats64 *stats64) | |
| 201 | +{ | |
| 202 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(dev); | |
| 203 | + | |
| 204 | + stats64->tx_packets = vf_rep->stats.tx_packets; | |
| 205 | + stats64->tx_bytes = vf_rep->stats.tx_bytes; | |
| 206 | + stats64->tx_dropped = vf_rep->stats.tx_dropped; | |
| 207 | + | |
| 208 | + stats64->rx_packets = vf_rep->stats.rx_packets; | |
| 209 | + stats64->rx_bytes = vf_rep->stats.rx_bytes; | |
| 210 | + stats64->rx_dropped = vf_rep->stats.rx_dropped; | |
| 211 | +} | |
| 212 | + | |
| 213 | +static int | |
| 214 | +lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu) | |
| 215 | +{ | |
| 216 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev); | |
| 217 | + struct lio_vf_rep_req rep_cfg; | |
| 218 | + struct octeon_device *oct; | |
| 219 | + int ret; | |
| 220 | + | |
| 221 | + oct = vf_rep->oct; | |
| 222 | + | |
| 223 | + memset(&rep_cfg, 0, sizeof(rep_cfg)); | |
| 224 | + rep_cfg.req_type = LIO_VF_REP_REQ_MTU; | |
| 225 | + rep_cfg.ifidx = vf_rep->ifidx; | |
| 226 | + rep_cfg.rep_mtu.mtu = cpu_to_be32(new_mtu); | |
| 227 | + | |
| 228 | + ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, | |
| 229 | + sizeof(rep_cfg), NULL, 0); | |
| 230 | + if (ret) { | |
| 231 | + dev_err(&oct->pci_dev->dev, | |
| 232 | + "Change MTU failed with err %d\n", ret); | |
| 233 | + return -EIO; | |
| 234 | + } | |
| 235 | + | |
| 236 | + ndev->mtu = new_mtu; | |
| 237 | + | |
| 238 | + return 0; | |
| 239 | +} | |
| 240 | + | |
| 241 | +static int | |
| 242 | +lio_vf_rep_phys_port_name(struct net_device *dev, | |
| 243 | + char *buf, size_t len) | |
| 244 | +{ | |
| 245 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(dev); | |
| 246 | + struct octeon_device *oct = vf_rep->oct; | |
| 247 | + int ret; | |
| 248 | + | |
| 249 | + ret = snprintf(buf, len, "pf%dvf%d", oct->pf_num, | |
| 250 | + vf_rep->ifidx - oct->pf_num * 64 - 1); | |
| 251 | + if (ret >= len) | |
| 252 | + return -EOPNOTSUPP; | |
| 253 | + | |
| 254 | + return 0; | |
| 255 | +} | |
| 256 | + | |
| 257 | +static struct net_device * | |
| 258 | +lio_vf_rep_get_ndev(struct octeon_device *oct, int ifidx) | |
| 259 | +{ | |
| 260 | + int vf_id, max_vfs = CN23XX_MAX_VFS_PER_PF + 1; | |
| 261 | + int vfid_mask = max_vfs - 1; | |
| 262 | + | |
| 263 | + if (ifidx <= oct->pf_num * max_vfs || | |
| 264 | + ifidx >= oct->pf_num * max_vfs + max_vfs) | |
| 265 | + return NULL; | |
| 266 | + | |
| 267 | + /* ifidx 1-63 for PF0 VFs | |
| 268 | + * ifidx 65-127 for PF1 VFs | |
| 269 | + */ | |
| 270 | + vf_id = (ifidx & vfid_mask) - 1; | |
| 271 | + | |
| 272 | + return oct->vf_rep_list.ndev[vf_id]; | |
| 273 | +} | |
| 274 | + | |
| 275 | +static void | |
| 276 | +lio_vf_rep_copy_packet(struct octeon_device *oct, | |
| 277 | + struct sk_buff *skb, | |
| 278 | + int len) | |
| 279 | +{ | |
| 280 | + if (likely(len > MIN_SKB_SIZE)) { | |
| 281 | + struct octeon_skb_page_info *pg_info; | |
| 282 | + unsigned char *va; | |
| 283 | + | |
| 284 | + pg_info = ((struct octeon_skb_page_info *)(skb->cb)); | |
| 285 | + if (pg_info->page) { | |
| 286 | + va = page_address(pg_info->page) + | |
| 287 | + pg_info->page_offset; | |
| 288 | + memcpy(skb->data, va, MIN_SKB_SIZE); | |
| 289 | + skb_put(skb, MIN_SKB_SIZE); | |
| 290 | + } | |
| 291 | + | |
| 292 | + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | |
| 293 | + pg_info->page, | |
| 294 | + pg_info->page_offset + MIN_SKB_SIZE, | |
| 295 | + len - MIN_SKB_SIZE, | |
| 296 | + LIO_RXBUFFER_SZ); | |
| 297 | + } else { | |
| 298 | + struct octeon_skb_page_info *pg_info = | |
| 299 | + ((struct octeon_skb_page_info *)(skb->cb)); | |
| 300 | + | |
| 301 | + skb_copy_to_linear_data(skb, page_address(pg_info->page) + | |
| 302 | + pg_info->page_offset, len); | |
| 303 | + skb_put(skb, len); | |
| 304 | + put_page(pg_info->page); | |
| 305 | + } | |
| 306 | +} | |
| 307 | + | |
| 308 | +static int | |
| 309 | +lio_vf_rep_pkt_recv(struct octeon_recv_info *recv_info, void *buf) | |
| 310 | +{ | |
| 311 | + struct octeon_recv_pkt *recv_pkt = recv_info->recv_pkt; | |
| 312 | + struct lio_vf_rep_desc *vf_rep; | |
| 313 | + struct net_device *vf_ndev; | |
| 314 | + struct octeon_device *oct; | |
| 315 | + union octeon_rh *rh; | |
| 316 | + struct sk_buff *skb; | |
| 317 | + int i, ifidx; | |
| 318 | + | |
| 319 | + oct = lio_get_device(recv_pkt->octeon_id); | |
| 320 | + if (!oct) | |
| 321 | + goto free_buffers; | |
| 322 | + | |
| 323 | + skb = recv_pkt->buffer_ptr[0]; | |
| 324 | + rh = &recv_pkt->rh; | |
| 325 | + ifidx = rh->r.ossp; | |
| 326 | + | |
| 327 | + vf_ndev = lio_vf_rep_get_ndev(oct, ifidx); | |
| 328 | + if (!vf_ndev) | |
| 329 | + goto free_buffers; | |
| 330 | + | |
| 331 | + vf_rep = netdev_priv(vf_ndev); | |
| 332 | + if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) || | |
| 333 | + recv_pkt->buffer_count > 1) | |
| 334 | + goto free_buffers; | |
| 335 | + | |
| 336 | + skb->dev = vf_ndev; | |
| 337 | + | |
| 338 | + /* Multiple buffers are not used for vf_rep packets. | |
| 339 | + * So just buffer_size[0] is valid. | |
| 340 | + */ | |
| 341 | + lio_vf_rep_copy_packet(oct, skb, recv_pkt->buffer_size[0]); | |
| 342 | + | |
| 343 | + skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT); | |
| 344 | + skb->protocol = eth_type_trans(skb, skb->dev); | |
| 345 | + skb->ip_summed = CHECKSUM_NONE; | |
| 346 | + | |
| 347 | + netif_rx(skb); | |
| 348 | + | |
| 349 | + octeon_free_recv_info(recv_info); | |
| 350 | + | |
| 351 | + return 0; | |
| 352 | + | |
| 353 | +free_buffers: | |
| 354 | + for (i = 0; i < recv_pkt->buffer_count; i++) | |
| 355 | + recv_buffer_free(recv_pkt->buffer_ptr[i]); | |
| 356 | + | |
| 357 | + octeon_free_recv_info(recv_info); | |
| 358 | + | |
| 359 | + return 0; | |
| 360 | +} | |
| 361 | + | |
| 362 | +static void | |
| 363 | +lio_vf_rep_packet_sent_callback(struct octeon_device *oct, | |
| 364 | + u32 status, void *buf) | |
| 365 | +{ | |
| 366 | + struct octeon_soft_command *sc = (struct octeon_soft_command *)buf; | |
| 367 | + struct sk_buff *skb = sc->ctxptr; | |
| 368 | + struct net_device *ndev = skb->dev; | |
| 369 | + | |
| 370 | + dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr, | |
| 371 | + sc->datasize, DMA_TO_DEVICE); | |
| 372 | + dev_kfree_skb_any(skb); | |
| 373 | + octeon_free_soft_command(oct, sc); | |
| 374 | + | |
| 375 | + if (octnet_iq_is_full(oct, sc->iq_no)) | |
| 376 | + return; | |
| 377 | + | |
| 378 | + if (netif_queue_stopped(ndev)) | |
| 379 | + netif_wake_queue(ndev); | |
| 380 | +} | |
| 381 | + | |
| 382 | +static int | |
| 383 | +lio_vf_rep_pkt_xmit(struct sk_buff *skb, struct net_device *ndev) | |
| 384 | +{ | |
| 385 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev); | |
| 386 | + struct net_device *parent_ndev = vf_rep->parent_ndev; | |
| 387 | + struct octeon_device *oct = vf_rep->oct; | |
| 388 | + struct octeon_instr_pki_ih3 *pki_ih3; | |
| 389 | + struct octeon_soft_command *sc; | |
| 390 | + struct lio *parent_lio; | |
| 391 | + int status; | |
| 392 | + | |
| 393 | + parent_lio = GET_LIO(parent_ndev); | |
| 394 | + | |
| 395 | + if (!(atomic_read(&vf_rep->ifstate) & LIO_IFSTATE_RUNNING) || | |
| 396 | + skb->len <= 0) | |
| 397 | + goto xmit_failed; | |
| 398 | + | |
| 399 | + if (octnet_iq_is_full(vf_rep->oct, parent_lio->txq)) { | |
| 400 | + dev_err(&oct->pci_dev->dev, "VF rep: Device IQ full\n"); | |
| 401 | + netif_stop_queue(ndev); | |
| 402 | + return NETDEV_TX_BUSY; | |
| 403 | + } | |
| 404 | + | |
| 405 | + sc = (struct octeon_soft_command *) | |
| 406 | + octeon_alloc_soft_command(oct, 0, 0, 0); | |
| 407 | + if (!sc) { | |
| 408 | + dev_err(&oct->pci_dev->dev, "VF rep: Soft command alloc failed\n"); | |
| 409 | + goto xmit_failed; | |
| 410 | + } | |
| 411 | + | |
| 412 | + /* Multiple buffers are not used for vf_rep packets. */ | |
| 413 | + if (skb_shinfo(skb)->nr_frags != 0) { | |
| 414 | + dev_err(&oct->pci_dev->dev, "VF rep: nr_frags != 0. Dropping packet\n"); | |
| 415 | + goto xmit_failed; | |
| 416 | + } | |
| 417 | + | |
| 418 | + sc->dmadptr = dma_map_single(&oct->pci_dev->dev, | |
| 419 | + skb->data, skb->len, DMA_TO_DEVICE); | |
| 420 | + if (dma_mapping_error(&oct->pci_dev->dev, sc->dmadptr)) { | |
| 421 | + dev_err(&oct->pci_dev->dev, "VF rep: DMA mapping failed\n"); | |
| 422 | + goto xmit_failed; | |
| 423 | + } | |
| 424 | + | |
| 425 | + sc->virtdptr = skb->data; | |
| 426 | + sc->datasize = skb->len; | |
| 427 | + sc->ctxptr = skb; | |
| 428 | + sc->iq_no = parent_lio->txq; | |
| 429 | + | |
| 430 | + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_VF_REP_PKT, | |
| 431 | + vf_rep->ifidx, 0, 0); | |
| 432 | + pki_ih3 = (struct octeon_instr_pki_ih3 *)&sc->cmd.cmd3.pki_ih3; | |
| 433 | + pki_ih3->tagtype = ORDERED_TAG; | |
| 434 | + | |
| 435 | + sc->callback = lio_vf_rep_packet_sent_callback; | |
| 436 | + sc->callback_arg = sc; | |
| 437 | + | |
| 438 | + status = octeon_send_soft_command(oct, sc); | |
| 439 | + if (status == IQ_SEND_FAILED) { | |
| 440 | + dma_unmap_single(&oct->pci_dev->dev, sc->dmadptr, | |
| 441 | + sc->datasize, DMA_TO_DEVICE); | |
| 442 | + goto xmit_failed; | |
| 443 | + } | |
| 444 | + | |
| 445 | + if (status == IQ_SEND_STOP) | |
| 446 | + netif_stop_queue(ndev); | |
| 447 | + | |
| 448 | + netif_trans_update(ndev); | |
| 449 | + | |
| 450 | + return NETDEV_TX_OK; | |
| 451 | + | |
| 452 | +xmit_failed: | |
| 453 | + dev_kfree_skb_any(skb); | |
| 454 | + | |
| 455 | + return NETDEV_TX_OK; | |
| 456 | +} | |
| 457 | + | |
| 458 | +static int | |
| 459 | +lio_vf_rep_attr_get(struct net_device *dev, struct switchdev_attr *attr) | |
| 460 | +{ | |
| 461 | + struct lio_vf_rep_desc *vf_rep = netdev_priv(dev); | |
| 462 | + struct net_device *parent_ndev = vf_rep->parent_ndev; | |
| 463 | + struct lio *lio = GET_LIO(parent_ndev); | |
| 464 | + | |
| 465 | + switch (attr->id) { | |
| 466 | + case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: | |
| 467 | + attr->u.ppid.id_len = ETH_ALEN; | |
| 468 | + ether_addr_copy(attr->u.ppid.id, | |
| 469 | + (void *)&lio->linfo.hw_addr + 2); | |
| 470 | + break; | |
| 471 | + | |
| 472 | + default: | |
| 473 | + return -EOPNOTSUPP; | |
| 474 | + } | |
| 475 | + | |
| 476 | + return 0; | |
| 477 | +} | |
| 478 | + | |
| 479 | +static const struct switchdev_ops lio_vf_rep_switchdev_ops = { | |
| 480 | + .switchdev_port_attr_get = lio_vf_rep_attr_get, | |
| 481 | +}; | |
| 482 | + | |
| 483 | +static void | |
| 484 | +lio_vf_rep_fetch_stats(struct work_struct *work) | |
| 485 | +{ | |
| 486 | + struct cavium_wk *wk = (struct cavium_wk *)work; | |
| 487 | + struct lio_vf_rep_desc *vf_rep = wk->ctxptr; | |
| 488 | + struct lio_vf_rep_stats stats; | |
| 489 | + struct lio_vf_rep_req rep_cfg; | |
| 490 | + struct octeon_device *oct; | |
| 491 | + int ret; | |
| 492 | + | |
| 493 | + oct = vf_rep->oct; | |
| 494 | + | |
| 495 | + memset(&rep_cfg, 0, sizeof(rep_cfg)); | |
| 496 | + rep_cfg.req_type = LIO_VF_REP_REQ_STATS; | |
| 497 | + rep_cfg.ifidx = vf_rep->ifidx; | |
| 498 | + | |
| 499 | + ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, sizeof(rep_cfg), | |
| 500 | + &stats, sizeof(stats)); | |
| 501 | + | |
| 502 | + if (!ret) { | |
| 503 | + octeon_swap_8B_data((u64 *)&stats, (sizeof(stats) >> 3)); | |
| 504 | + memcpy(&vf_rep->stats, &stats, sizeof(stats)); | |
| 505 | + } | |
| 506 | + | |
| 507 | + schedule_delayed_work(&vf_rep->stats_wk.work, | |
| 508 | + msecs_to_jiffies(LIO_VF_REP_STATS_POLL_TIME_MS)); | |
| 509 | +} | |
| 510 | + | |
| 511 | +int | |
| 512 | +lio_vf_rep_create(struct octeon_device *oct) | |
| 513 | +{ | |
| 514 | + struct lio_vf_rep_desc *vf_rep; | |
| 515 | + struct net_device *ndev; | |
| 516 | + int i, num_vfs; | |
| 517 | + | |
| 518 | + if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV) | |
| 519 | + return 0; | |
| 520 | + | |
| 521 | + if (!oct->sriov_info.sriov_enabled) | |
| 522 | + return 0; | |
| 523 | + | |
| 524 | + num_vfs = oct->sriov_info.num_vfs_alloced; | |
| 525 | + | |
| 526 | + oct->vf_rep_list.num_vfs = 0; | |
| 527 | + for (i = 0; i < num_vfs; i++) { | |
| 528 | + ndev = alloc_etherdev(sizeof(struct lio_vf_rep_desc)); | |
| 529 | + | |
| 530 | + if (!ndev) { | |
| 531 | + dev_err(&oct->pci_dev->dev, | |
| 532 | + "VF rep device %d creation failed\n", i); | |
| 533 | + goto cleanup; | |
| 534 | + } | |
| 535 | + | |
| 536 | + ndev->min_mtu = LIO_MIN_MTU_SIZE; | |
| 537 | + ndev->max_mtu = LIO_MAX_MTU_SIZE; | |
| 538 | + ndev->netdev_ops = &lio_vf_rep_ndev_ops; | |
| 539 | + SWITCHDEV_SET_OPS(ndev, &lio_vf_rep_switchdev_ops); | |
| 540 | + | |
| 541 | + vf_rep = netdev_priv(ndev); | |
| 542 | + memset(vf_rep, 0, sizeof(*vf_rep)); | |
| 543 | + | |
| 544 | + vf_rep->ndev = ndev; | |
| 545 | + vf_rep->oct = oct; | |
| 546 | + vf_rep->parent_ndev = oct->props[0].netdev; | |
| 547 | + vf_rep->ifidx = (oct->pf_num * 64) + i + 1; | |
| 548 | + | |
| 549 | + eth_hw_addr_random(ndev); | |
| 550 | + | |
| 551 | + if (register_netdev(ndev)) { | |
| 552 | + dev_err(&oct->pci_dev->dev, "VF rep nerdev registration failed\n"); | |
| 553 | + | |
| 554 | + free_netdev(ndev); | |
| 555 | + goto cleanup; | |
| 556 | + } | |
| 557 | + | |
| 558 | + netif_carrier_off(ndev); | |
| 559 | + | |
| 560 | + INIT_DELAYED_WORK(&vf_rep->stats_wk.work, | |
| 561 | + lio_vf_rep_fetch_stats); | |
| 562 | + vf_rep->stats_wk.ctxptr = (void *)vf_rep; | |
| 563 | + schedule_delayed_work(&vf_rep->stats_wk.work, | |
| 564 | + msecs_to_jiffies | |
| 565 | + (LIO_VF_REP_STATS_POLL_TIME_MS)); | |
| 566 | + oct->vf_rep_list.num_vfs++; | |
| 567 | + oct->vf_rep_list.ndev[i] = ndev; | |
| 568 | + } | |
| 569 | + | |
| 570 | + if (octeon_register_dispatch_fn(oct, OPCODE_NIC, | |
| 571 | + OPCODE_NIC_VF_REP_PKT, | |
| 572 | + lio_vf_rep_pkt_recv, oct)) { | |
| 573 | + dev_err(&oct->pci_dev->dev, "VF rep Dispatch func registration failed\n"); | |
| 574 | + | |
| 575 | + goto cleanup; | |
| 576 | + } | |
| 577 | + | |
| 578 | + return 0; | |
| 579 | + | |
| 580 | +cleanup: | |
| 581 | + for (i = 0; i < oct->vf_rep_list.num_vfs; i++) { | |
| 582 | + ndev = oct->vf_rep_list.ndev[i]; | |
| 583 | + oct->vf_rep_list.ndev[i] = NULL; | |
| 584 | + if (ndev) { | |
| 585 | + vf_rep = netdev_priv(ndev); | |
| 586 | + cancel_delayed_work_sync | |
| 587 | + (&vf_rep->stats_wk.work); | |
| 588 | + unregister_netdev(ndev); | |
| 589 | + free_netdev(ndev); | |
| 590 | + } | |
| 591 | + } | |
| 592 | + | |
| 593 | + oct->vf_rep_list.num_vfs = 0; | |
| 594 | + | |
| 595 | + return -1; | |
| 596 | +} | |
| 597 | + | |
| 598 | +void | |
| 599 | +lio_vf_rep_destroy(struct octeon_device *oct) | |
| 600 | +{ | |
| 601 | + struct lio_vf_rep_desc *vf_rep; | |
| 602 | + struct net_device *ndev; | |
| 603 | + int i; | |
| 604 | + | |
| 605 | + if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV) | |
| 606 | + return; | |
| 607 | + | |
| 608 | + if (!oct->sriov_info.sriov_enabled) | |
| 609 | + return; | |
| 610 | + | |
| 611 | + for (i = 0; i < oct->vf_rep_list.num_vfs; i++) { | |
| 612 | + ndev = oct->vf_rep_list.ndev[i]; | |
| 613 | + oct->vf_rep_list.ndev[i] = NULL; | |
| 614 | + if (ndev) { | |
| 615 | + vf_rep = netdev_priv(ndev); | |
| 616 | + cancel_delayed_work_sync | |
| 617 | + (&vf_rep->stats_wk.work); | |
| 618 | + netif_tx_disable(ndev); | |
| 619 | + netif_carrier_off(ndev); | |
| 620 | + | |
| 621 | + unregister_netdev(ndev); | |
| 622 | + free_netdev(ndev); | |
| 623 | + } | |
| 624 | + } | |
| 625 | + | |
| 626 | + oct->vf_rep_list.num_vfs = 0; | |
| 627 | +} | |
| 628 | + | |
| 629 | +static int | |
| 630 | +lio_vf_rep_netdev_event(struct notifier_block *nb, | |
| 631 | + unsigned long event, void *ptr) | |
| 632 | +{ | |
| 633 | + struct net_device *ndev = netdev_notifier_info_to_dev(ptr); | |
| 634 | + struct lio_vf_rep_desc *vf_rep; | |
| 635 | + struct lio_vf_rep_req rep_cfg; | |
| 636 | + struct octeon_device *oct; | |
| 637 | + int ret; | |
| 638 | + | |
| 639 | + switch (event) { | |
| 640 | + case NETDEV_REGISTER: | |
| 641 | + case NETDEV_CHANGENAME: | |
| 642 | + break; | |
| 643 | + | |
| 644 | + default: | |
| 645 | + return NOTIFY_DONE; | |
| 646 | + } | |
| 647 | + | |
| 648 | + if (ndev->netdev_ops != &lio_vf_rep_ndev_ops) | |
| 649 | + return NOTIFY_DONE; | |
| 650 | + | |
| 651 | + vf_rep = netdev_priv(ndev); | |
| 652 | + oct = vf_rep->oct; | |
| 653 | + | |
| 654 | + if (strlen(ndev->name) > LIO_IF_NAME_SIZE) { | |
| 655 | + dev_err(&oct->pci_dev->dev, | |
| 656 | + "Device name change sync failed as the size is > %d\n", | |
| 657 | + LIO_IF_NAME_SIZE); | |
| 658 | + return NOTIFY_DONE; | |
| 659 | + } | |
| 660 | + | |
| 661 | + memset(&rep_cfg, 0, sizeof(rep_cfg)); | |
| 662 | + rep_cfg.req_type = LIO_VF_REP_REQ_DEVNAME; | |
| 663 | + rep_cfg.ifidx = vf_rep->ifidx; | |
| 664 | + strncpy(rep_cfg.rep_name.name, ndev->name, LIO_IF_NAME_SIZE); | |
| 665 | + | |
| 666 | + ret = lio_vf_rep_send_soft_command(oct, &rep_cfg, | |
| 667 | + sizeof(rep_cfg), NULL, 0); | |
| 668 | + if (ret) | |
| 669 | + dev_err(&oct->pci_dev->dev, | |
| 670 | + "vf_rep netdev name change failed with err %d\n", ret); | |
| 671 | + | |
| 672 | + return NOTIFY_DONE; | |
| 673 | +} | |
| 674 | + | |
| 675 | +static struct notifier_block lio_vf_rep_netdev_notifier = { | |
| 676 | + .notifier_call = lio_vf_rep_netdev_event, | |
| 677 | +}; | |
| 678 | + | |
| 679 | +int | |
| 680 | +lio_vf_rep_modinit(void) | |
| 681 | +{ | |
| 682 | + if (register_netdevice_notifier(&lio_vf_rep_netdev_notifier)) { | |
| 683 | + pr_err("netdev notifier registration failed\n"); | |
| 684 | + return -EFAULT; | |
| 685 | + } | |
| 686 | + | |
| 687 | + return 0; | |
| 688 | +} | |
| 689 | + | |
| 690 | +void | |
| 691 | +lio_vf_rep_modexit(void) | |
| 692 | +{ | |
| 693 | + if (unregister_netdevice_notifier(&lio_vf_rep_netdev_notifier)) | |
| 694 | + pr_err("netdev notifier unregister failed\n"); | |
| 695 | +} | |
| @@ -0,0 +1,49 @@ | ||
| 1 | +/********************************************************************** | |
| 2 | + * Author: Cavium, Inc. | |
| 3 | + * | |
| 4 | + * Contact: support@cavium.com | |
| 5 | + * Please include "LiquidIO" in the subject. | |
| 6 | + * | |
| 7 | + * Copyright (c) 2003-2017 Cavium, Inc. | |
| 8 | + * | |
| 9 | + * This file is free software; you can redistribute it and/or modify | |
| 10 | + * it under the terms of the GNU General Public License, Version 2, as | |
| 11 | + * published by the Free Software Foundation. | |
| 12 | + * | |
| 13 | + * This file is distributed in the hope that it will be useful, but | |
| 14 | + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | |
| 15 | + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | |
| 16 | + * NONINFRINGEMENT. See the GNU General Public License for more | |
| 17 | + * details. | |
| 18 | + * | |
| 19 | + * This file may also be available under a different license from Cavium. | |
| 20 | + * Contact Cavium, Inc. for more information | |
| 21 | + **********************************************************************/ | |
| 22 | + | |
| 23 | +/*! \file octeon_vf_main.h | |
| 24 | + * \brief Host Driver: This file defines vf_rep related macros and structures | |
| 25 | + */ | |
| 26 | +#ifndef __LIO_VF_REP_H__ | |
| 27 | +#define __LIO_VF_REP_H__ | |
| 28 | +#define LIO_VF_REP_REQ_TMO_MS 5000 | |
| 29 | +#define LIO_VF_REP_STATS_POLL_TIME_MS 200 | |
| 30 | + | |
| 31 | +struct lio_vf_rep_desc { | |
| 32 | + struct net_device *parent_ndev; | |
| 33 | + struct net_device *ndev; | |
| 34 | + struct octeon_device *oct; | |
| 35 | + struct lio_vf_rep_stats stats; | |
| 36 | + struct cavium_wk stats_wk; | |
| 37 | + atomic_t ifstate; | |
| 38 | + int ifidx; | |
| 39 | +}; | |
| 40 | + | |
| 41 | +struct lio_vf_rep_sc_ctx { | |
| 42 | + struct completion complete; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +int lio_vf_rep_create(struct octeon_device *oct); | |
| 46 | +void lio_vf_rep_destroy(struct octeon_device *oct); | |
| 47 | +int lio_vf_rep_modinit(void); | |
| 48 | +void lio_vf_rep_modexit(void); | |
| 49 | +#endif | |
| @@ -27,8 +27,8 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #define LIQUIDIO_PACKAGE "" |
| 29 | 29 | #define LIQUIDIO_BASE_MAJOR_VERSION 1 |
| 30 | −#define LIQUIDIO_BASE_MINOR_VERSION 6 | |
| 31 | −#define LIQUIDIO_BASE_MICRO_VERSION 1 | |
| 30 | +#define LIQUIDIO_BASE_MINOR_VERSION 7 | |
| 31 | +#define LIQUIDIO_BASE_MICRO_VERSION 0 | |
| 32 | 32 | #define LIQUIDIO_BASE_VERSION __stringify(LIQUIDIO_BASE_MAJOR_VERSION) "." \ |
| 33 | 33 | __stringify(LIQUIDIO_BASE_MINOR_VERSION) |
| 34 | 34 | #define LIQUIDIO_MICRO_VERSION "." __stringify(LIQUIDIO_BASE_MICRO_VERSION) |
| @@ -84,10 +84,14 @@ enum octeon_tag_type { · 49 unmodified lines | ||
| 84 | 84 | #define OPCODE_NIC_IF_CFG 0x09 |
| 85 | 85 | #define OPCODE_NIC_VF_DRV_NOTICE 0x0A |
| 86 | 86 | #define OPCODE_NIC_INTRMOD_PARAMS 0x0B |
| 87 | +#define OPCODE_NIC_SYNC_OCTEON_TIME 0x14 | |
| 87 | 88 | #define VF_DRV_LOADED 1 |
| 88 | 89 | #define VF_DRV_REMOVED -1 |
| 89 | 90 | #define VF_DRV_MACADDR_CHANGED 2 |
| 90 | 91 | |
| 92 | +#define OPCODE_NIC_VF_REP_PKT 0x15 | |
| 93 | +#define OPCODE_NIC_VF_REP_CMD 0x16 | |
| 94 | + | |
| 91 | 95 | #define CORE_DRV_TEST_SCATTER_OP 0xFFF5 |
| 92 | 96 | |
| 93 | 97 | /* Application codes advertised by the core driver initialization packet. */ |
| @@ -108,6 +112,10 @@ enum octeon_tag_type { · 14 unmodified lines | ||
| 108 | 112 | |
| 109 | 113 | #define SCR2_BIT_FW_LOADED 63 |
| 110 | 114 | |
| 115 | +/* App specific capabilities from firmware to pf driver */ | |
| 116 | +#define LIQUIDIO_TIME_SYNC_CAP 0x1 | |
| 117 | +#define LIQUIDIO_SWITCHDEV_CAP 0x2 | |
| 118 | + | |
| 111 | 119 | static inline u32 incr_index(u32 index, u32 count, u32 max) |
| 112 | 120 | { |
| 113 | 121 | if ((index + count) >= max) |
| @@ -901,4 +909,60 @@ union oct_nic_if_cfg { · 787 unmodified lines | ||
| 901 | 909 | } s; |
| 902 | 910 | }; |
| 903 | 911 | |
| 912 | +struct lio_time { | |
| 913 | + s64 sec; /* seconds */ | |
| 914 | + s64 nsec; /* nanoseconds */ | |
| 915 | +}; | |
| 916 | + | |
| 917 | +struct lio_vf_rep_stats { | |
| 918 | + u64 tx_packets; | |
| 919 | + u64 tx_bytes; | |
| 920 | + u64 tx_dropped; | |
| 921 | + | |
| 922 | + u64 rx_packets; | |
| 923 | + u64 rx_bytes; | |
| 924 | + u64 rx_dropped; | |
| 925 | +}; | |
| 926 | + | |
| 927 | +enum lio_vf_rep_req_type { | |
| 928 | + LIO_VF_REP_REQ_NONE, | |
| 929 | + LIO_VF_REP_REQ_STATE, | |
| 930 | + LIO_VF_REP_REQ_MTU, | |
| 931 | + LIO_VF_REP_REQ_STATS, | |
| 932 | + LIO_VF_REP_REQ_DEVNAME | |
| 933 | +}; | |
| 934 | + | |
| 935 | +enum { | |
| 936 | + LIO_VF_REP_STATE_DOWN, | |
| 937 | + LIO_VF_REP_STATE_UP | |
| 938 | +}; | |
| 939 | + | |
| 940 | +#define LIO_IF_NAME_SIZE 16 | |
| 941 | +struct lio_vf_rep_req { | |
| 942 | + u8 req_type; | |
| 943 | + u8 ifidx; | |
| 944 | + u8 rsvd[6]; | |
| 945 | + | |
| 946 | + union { | |
| 947 | + struct lio_vf_rep_name { | |
| 948 | + char name[LIO_IF_NAME_SIZE]; | |
| 949 | + } rep_name; | |
| 950 | + | |
| 951 | + struct lio_vf_rep_mtu { | |
| 952 | + u32 mtu; | |
| 953 | + u32 rsvd; | |
| 954 | + } rep_mtu; | |
| 955 | + | |
| 956 | + struct lio_vf_rep_state { | |
| 957 | + u8 state; | |
| 958 | + u8 rsvd[7]; | |
| 959 | + } rep_state; | |
| 960 | + }; | |
| 961 | +}; | |
| 962 | + | |
| 963 | +struct lio_vf_rep_resp { | |
| 964 | + u64 rh; | |
| 965 | + u8 status; | |
| 966 | + u8 rsvd[7]; | |
| 967 | +}; | |
| 904 | 968 | #endif |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #define LIO_FW_BASE_NAME "lio_" |
| 25 | 25 | #define LIO_FW_NAME_SUFFIX ".bin" |
| 26 | 26 | #define LIO_FW_NAME_TYPE_NIC "nic" |
| 27 | +#define LIO_FW_NAME_TYPE_AUTO "auto" | |
| 27 | 28 | #define LIO_FW_NAME_TYPE_NONE "none" |
| 28 | 29 | #define LIO_MAX_FIRMWARE_VERSION_LEN 16 |
| 29 | 30 | |
| @@ -37,6 +37,8 @@ · 36 unmodified lines | ||
| 37 | 37 | #define MAX_OCTEON_LINKS MAX_OCTEON_NICIF |
| 38 | 38 | #define MAX_OCTEON_MULTICAST_ADDR 32 |
| 39 | 39 | |
| 40 | +#define MAX_OCTEON_FILL_COUNT 8 | |
| 41 | + | |
| 40 | 42 | /* CN6xxx IQ configuration macros */ |
| 41 | 43 | #define CN6XXX_MAX_INPUT_QUEUES 32 |
| 42 | 44 | #define CN6XXX_MAX_IQ_DESCRIPTORS 2048 |
| @@ -803,15 +803,18 @@ static int octeon_console_read(struct octeon_device *oct, u32 console_num, · 802 unmodified lines | ||
| 803 | 803 | } |
| 804 | 804 | |
| 805 | 805 | #define FBUF_SIZE (4 * 1024 * 1024) |
| 806 | +#define MAX_BOOTTIME_SIZE 80 | |
| 806 | 807 | |
| 807 | 808 | int octeon_download_firmware(struct octeon_device *oct, const u8 *data, |
| 808 | 809 | size_t size) |
| 809 | 810 | { |
| 810 | − int ret = 0; | |
| 811 | + struct octeon_firmware_file_header *h; | |
| 812 | + char boottime[MAX_BOOTTIME_SIZE]; | |
| 813 | + struct timespec64 ts; | |
| 811 | 814 | u32 crc32_result; |
| 812 | 815 | u64 load_addr; |
| 813 | 816 | u32 image_len; |
| 814 | − struct octeon_firmware_file_header *h; | |
| 817 | + int ret = 0; | |
| 815 | 818 | u32 i, rem; |
| 816 | 819 | |
| 817 | 820 | if (size < sizeof(struct octeon_firmware_file_header)) { |
| @@ -890,11 +893,34 @@ int octeon_download_firmware(struct octeon_device *oct, const u8 *data, · 72 unmodified lines | ||
| 890 | 893 | load_addr += size; |
| 891 | 894 | } |
| 892 | 895 | } |
| 896 | + | |
| 897 | + /* Pass date and time information to NIC at the time of loading | |
| 898 | + * firmware and periodically update the host time to NIC firmware. | |
| 899 | + * This is to make NIC firmware use the same time reference as Host, | |
| 900 | + * so that it is easy to correlate logs from firmware and host for | |
| 901 | + * debugging. | |
| 902 | + * | |
| 903 | + * Octeon always uses UTC time. so timezone information is not sent. | |
| 904 | + */ | |
| 905 | + getnstimeofday64(&ts); | |
| 906 | + ret = snprintf(boottime, MAX_BOOTTIME_SIZE, | |
| 907 | + " time_sec=%lld time_nsec=%ld", | |
| 908 | + (s64)ts.tv_sec, ts.tv_nsec); | |
| 909 | + if ((sizeof(h->bootcmd) - strnlen(h->bootcmd, sizeof(h->bootcmd))) < | |
| 910 | + ret) { | |
| 911 | + dev_err(&oct->pci_dev->dev, "Boot command buffer too small\n"); | |
| 912 | + return -EINVAL; | |
| 913 | + } | |
| 914 | + strncat(h->bootcmd, boottime, | |
| 915 | + sizeof(h->bootcmd) - strnlen(h->bootcmd, sizeof(h->bootcmd))); | |
| 916 | + | |
| 893 | 917 | dev_info(&oct->pci_dev->dev, "Writing boot command: %s\n", |
| 894 | 918 | h->bootcmd); |
| 895 | 919 | |
| 896 | 920 | /* Invoke the bootcmd */ |
| 897 | 921 | ret = octeon_console_send_cmd(oct, h->bootcmd, 50); |
| 922 | + if (ret) | |
| 923 | + dev_info(&oct->pci_dev->dev, "Boot command send failed\n"); | |
| 898 | 924 | |
| 899 | − return 0; | |
| 925 | + return ret; | |
| 900 | 926 | } |
| @@ -541,6 +541,7 @@ static char oct_dev_app_str[CVM_DRV_APP_COUNT + 1][32] = { · 540 unmodified lines | ||
| 541 | 541 | |
| 542 | 542 | static struct octeon_device *octeon_device[MAX_OCTEON_DEVICES]; |
| 543 | 543 | static atomic_t adapter_refcounts[MAX_OCTEON_DEVICES]; |
| 544 | +static atomic_t adapter_fw_states[MAX_OCTEON_DEVICES]; | |
| 544 | 545 | |
| 545 | 546 | static u32 octeon_device_count; |
| 546 | 547 | /* locks device array (i.e. octeon_device[]) */ |
| @@ -770,6 +771,10 @@ int octeon_register_device(struct octeon_device *oct, · 223 unmodified lines | ||
| 770 | 771 | oct->adapter_refcount = &adapter_refcounts[oct->octeon_id]; |
| 771 | 772 | atomic_set(oct->adapter_refcount, 0); |
| 772 | 773 | |
| 774 | + /* Like the reference count, the f/w state is shared 'per-adapter' */ | |
| 775 | + oct->adapter_fw_state = &adapter_fw_states[oct->octeon_id]; | |
| 776 | + atomic_set(oct->adapter_fw_state, FW_NEEDS_TO_BE_LOADED); | |
| 777 | + | |
| 773 | 778 | spin_lock(&octeon_devices_lock); |
| 774 | 779 | for (idx = (int)oct->octeon_id - 1; idx >= 0; idx--) { |
| 775 | 780 | if (!octeon_device[idx]) { |
| @@ -780,11 +785,15 @@ int octeon_register_device(struct octeon_device *oct, · 4 unmodified lines | ||
| 780 | 785 | atomic_inc(oct->adapter_refcount); |
| 781 | 786 | return 1; /* here, refcount is guaranteed to be 1 */ |
| 782 | 787 | } |
| 783 | − /* if another device is at same bus/dev, use its refcounter */ | |
| 788 | + /* If another device is at same bus/dev, use its refcounter | |
| 789 | + * (and f/w state variable). | |
| 790 | + */ | |
| 784 | 791 | if ((octeon_device[idx]->loc.bus == bus) && |
| 785 | 792 | (octeon_device[idx]->loc.dev == dev)) { |
| 786 | 793 | oct->adapter_refcount = |
| 787 | 794 | octeon_device[idx]->adapter_refcount; |
| 795 | + oct->adapter_fw_state = | |
| 796 | + octeon_device[idx]->adapter_fw_state; | |
| 788 | 797 | break; |
| 789 | 798 | } |
| 790 | 799 | } |
| @@ -1171,6 +1180,10 @@ octeon_register_dispatch_fn(struct octeon_device *oct, · 380 unmodified lines | ||
| 1171 | 1180 | spin_unlock_bh(&oct->dispatch.lock); |
| 1172 | 1181 | |
| 1173 | 1182 | } else { |
| 1183 | + if (pfn == fn && | |
| 1184 | + octeon_get_dispatch_arg(oct, opcode, subcode) == fn_arg) | |
| 1185 | + return 0; | |
| 1186 | + | |
| 1174 | 1187 | dev_err(&oct->pci_dev->dev, |
| 1175 | 1188 | "Found previously registered dispatch fn for opcode/subcode: %x/%x\n", |
| 1176 | 1189 | opcode, subcode); |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #define _OCTEON_DEVICE_H_ |
| 24 | 24 | |
| 25 | 25 | #include <linux/interrupt.h> |
| 26 | +#include <net/devlink.h> | |
| 26 | 27 | |
| 27 | 28 | /** PCI VendorId Device Id */ |
| 28 | 29 | #define OCTEON_CN68XX_PCIID 0x91177d |
| @@ -50,6 +51,13 @@ enum octeon_pci_swap_mode { · 21 unmodified lines | ||
| 50 | 51 | OCTEON_PCI_32BIT_LW_SWAP = 3 |
| 51 | 52 | }; |
| 52 | 53 | |
| 54 | +enum lio_fw_state { | |
| 55 | + FW_IS_PRELOADED = 0, | |
| 56 | + FW_NEEDS_TO_BE_LOADED = 1, | |
| 57 | + FW_IS_BEING_LOADED = 2, | |
| 58 | + FW_HAS_BEEN_LOADED = 3, | |
| 59 | +}; | |
| 60 | + | |
| 53 | 61 | enum { |
| 54 | 62 | OCTEON_CONFIG_TYPE_DEFAULT = 0, |
| 55 | 63 | NUM_OCTEON_CONFS, |
| @@ -384,6 +392,15 @@ struct octeon_ioq_vector { · 328 unmodified lines | ||
| 384 | 392 | u32 ioq_num; |
| 385 | 393 | }; |
| 386 | 394 | |
| 395 | +struct lio_vf_rep_list { | |
| 396 | + int num_vfs; | |
| 397 | + struct net_device *ndev[CN23XX_MAX_VFS_PER_PF]; | |
| 398 | +}; | |
| 399 | + | |
| 400 | +struct lio_devlink_priv { | |
| 401 | + struct octeon_device *oct; | |
| 402 | +}; | |
| 403 | + | |
| 387 | 404 | /** The Octeon device. |
| 388 | 405 | * Each Octeon device has this structure to represent all its |
| 389 | 406 | * components. |
| @@ -557,7 +574,14 @@ struct octeon_device { · 167 unmodified lines | ||
| 557 | 574 | } loc; |
| 558 | 575 | |
| 559 | 576 | atomic_t *adapter_refcount; /* reference count of adapter */ |
| 577 | + | |
| 578 | + atomic_t *adapter_fw_state; /* per-adapter, lio_fw_state */ | |
| 579 | + | |
| 560 | 580 | bool ptp_enable; |
| 581 | + | |
| 582 | + struct lio_vf_rep_list vf_rep_list; | |
| 583 | + struct devlink *devlink; | |
| 584 | + enum devlink_eswitch_mode eswitch_mode; | |
| 561 | 585 | }; |
| 562 | 586 | |
| 563 | 587 | #define OCT_DRV_ONLINE 1 |
| @@ -52,8 +52,8 @@ struct __dispatch { · 51 unmodified lines | ||
| 52 | 52 | * @return Failure: NULL |
| 53 | 53 | * |
| 54 | 54 | */ |
| 55 | −static inline void *octeon_get_dispatch_arg(struct octeon_device *octeon_dev, | |
| 56 | − u16 opcode, u16 subcode) | |
| 55 | +void *octeon_get_dispatch_arg(struct octeon_device *octeon_dev, | |
| 56 | + u16 opcode, u16 subcode) | |
| 57 | 57 | { |
| 58 | 58 | int idx; |
| 59 | 59 | struct list_head *dispatch; |
| @@ -400,6 +400,9 @@ int octeon_register_dispatch_fn(struct octeon_device *oct, · 399 unmodified lines | ||
| 400 | 400 | u16 subcode, |
| 401 | 401 | octeon_dispatch_fn_t fn, void *fn_arg); |
| 402 | 402 | |
| 403 | +void *octeon_get_dispatch_arg(struct octeon_device *oct, | |
| 404 | + u16 opcode, u16 subcode); | |
| 405 | + | |
| 403 | 406 | void octeon_droq_print_stats(void); |
| 404 | 407 | |
| 405 | 408 | u32 octeon_droq_check_hw_for_pkts(struct octeon_droq *droq); |
| @@ -343,6 +343,9 @@ int octeon_delete_instr_queue(struct octeon_device *octeon_dev, u32 iq_no); · 342 unmodified lines | ||
| 343 | 343 | |
| 344 | 344 | int lio_wait_for_instr_fetch(struct octeon_device *oct); |
| 345 | 345 | |
| 346 | +void | |
| 347 | +octeon_ring_doorbell_locked(struct octeon_device *oct, u32 iq_no); | |
| 348 | + | |
| 346 | 349 | int |
| 347 | 350 | octeon_register_reqtype_free_fn(struct octeon_device *oct, int reqtype, |
| 348 | 351 | void (*fn)(void *)); |
| @@ -63,7 +63,7 @@ struct octnet_buf_free_info { · 62 unmodified lines | ||
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | 65 | /* BQL-related functions */ |
| 66 | −void octeon_report_sent_bytes_to_bql(void *buf, int reqtype); | |
| 66 | +int octeon_report_sent_bytes_to_bql(void *buf, int reqtype); | |
| 67 | 67 | void octeon_update_tx_completion_counters(void *buf, int reqtype, |
| 68 | 68 | unsigned int *pkts_compl, |
| 69 | 69 | unsigned int *bytes_compl); |
| @@ -136,6 +136,9 @@ struct lio { · 135 unmodified lines | ||
| 136 | 136 | /* work queue for link status */ |
| 137 | 137 | struct cavium_wq link_status_wq; |
| 138 | 138 | |
| 139 | + /* work queue to regularly send local time to octeon firmware */ | |
| 140 | + struct cavium_wq sync_octeon_time_wq; | |
| 141 | + | |
| 139 | 142 | int netdev_uc_count; |
| 140 | 143 | }; |
| 141 | 144 | |
| @@ -82,9 +82,10 @@ octeon_alloc_soft_command_resp(struct octeon_device *oct, · 81 unmodified lines | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | int octnet_send_nic_data_pkt(struct octeon_device *oct, |
| 85 | − struct octnic_data_pkt *ndata) | |
| 85 | + struct octnic_data_pkt *ndata, | |
| 86 | + int xmit_more) | |
| 86 | 87 | { |
| 87 | − int ring_doorbell = 1; | |
| 88 | + int ring_doorbell = !xmit_more; | |
| 88 | 89 | |
| 89 | 90 | return octeon_send_command(oct, ndata->q_no, ring_doorbell, &ndata->cmd, |
| 90 | 91 | ndata->buf, ndata->datasize, |
| @@ -279,7 +279,8 @@ octeon_alloc_soft_command_resp(struct octeon_device *oct, · 278 unmodified lines | ||
| 279 | 279 | * queue should be stopped, and IQ_SEND_OK if it sent okay. |
| 280 | 280 | */ |
| 281 | 281 | int octnet_send_nic_data_pkt(struct octeon_device *oct, |
| 282 | − struct octnic_data_pkt *ndata); | |
| 282 | + struct octnic_data_pkt *ndata, | |
| 283 | + int xmit_more); | |
| 283 | 284 | |
| 284 | 285 | /** Send a NIC control packet to the device |
| 285 | 286 | * @param oct - octeon device pointer |
| @@ -278,6 +278,18 @@ ring_doorbell(struct octeon_device *oct, struct octeon_instr_queue *iq) · 277 unmodified lines | ||
| 278 | 278 | } |
| 279 | 279 | } |
| 280 | 280 | |
| 281 | +void | |
| 282 | +octeon_ring_doorbell_locked(struct octeon_device *oct, u32 iq_no) | |
| 283 | +{ | |
| 284 | + struct octeon_instr_queue *iq; | |
| 285 | + | |
| 286 | + iq = oct->instr_queue[iq_no]; | |
| 287 | + spin_lock(&iq->post_lock); | |
| 288 | + if (iq->fill_cnt) | |
| 289 | + ring_doorbell(oct, iq); | |
| 290 | + spin_unlock(&iq->post_lock); | |
| 291 | +} | |
| 292 | + | |
| 281 | 293 | static inline void __copy_cmd_into_iq(struct octeon_instr_queue *iq, |
| 282 | 294 | u8 *cmd) |
| 283 | 295 | { |
| @@ -477,8 +489,6 @@ octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq, · 193 unmodified lines | ||
| 477 | 489 | } |
| 478 | 490 | |
| 479 | 491 | tot_inst_processed += inst_processed; |
| 480 | − inst_processed = 0; | |
| 481 | − | |
| 482 | 492 | } while (tot_inst_processed < napi_budget); |
| 483 | 493 | |
| 484 | 494 | if (napi_budget && (tot_inst_processed >= napi_budget)) |
| @@ -543,6 +553,7 @@ octeon_send_command(struct octeon_device *oct, u32 iq_no, · 58 unmodified lines | ||
| 543 | 553 | u32 force_db, void *cmd, void *buf, |
| 544 | 554 | u32 datasize, u32 reqtype) |
| 545 | 555 | { |
| 556 | + int xmit_stopped; | |
| 546 | 557 | struct iq_post_status st; |
| 547 | 558 | struct octeon_instr_queue *iq = oct->instr_queue[iq_no]; |
| 548 | 559 | |
| @@ -554,12 +565,13 @@ octeon_send_command(struct octeon_device *oct, u32 iq_no, · 5 unmodified lines | ||
| 554 | 565 | st = __post_command2(iq, cmd); |
| 555 | 566 | |
| 556 | 567 | if (st.status != IQ_SEND_FAILED) { |
| 557 | − octeon_report_sent_bytes_to_bql(buf, reqtype); | |
| 568 | + xmit_stopped = octeon_report_sent_bytes_to_bql(buf, reqtype); | |
| 558 | 569 | __add_to_request_list(iq, st.index, buf, reqtype); |
| 559 | 570 | INCR_INSTRQUEUE_PKT_COUNT(oct, iq_no, bytes_sent, datasize); |
| 560 | 571 | INCR_INSTRQUEUE_PKT_COUNT(oct, iq_no, instr_posted, 1); |
| 561 | 572 | |
| 562 | − if (force_db) | |
| 573 | + if (iq->fill_cnt >= MAX_OCTEON_FILL_COUNT || force_db || | |
| 574 | + xmit_stopped || st.status == IQ_SEND_STOP) | |
| 563 | 575 | ring_doorbell(oct, iq); |
| 564 | 576 | } else { |
| 565 | 577 | INCR_INSTRQUEUE_PKT_COUNT(oct, iq_no, instr_dropped, 1); |
| @@ -705,14 +705,15 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev, · 704 unmodified lines | ||
| 705 | 705 | u64 clock_comp = (NSEC_PER_SEC << 32) / octeon_get_io_clock_rate(); |
| 706 | 706 | if (!ptp.s.ptp_en) |
| 707 | 707 | cvmx_write_csr(CVMX_MIO_PTP_CLOCK_COMP, clock_comp); |
| 708 | − pr_info("PTP Clock: Using sclk reference at %lld Hz\n", | |
| 709 | − (NSEC_PER_SEC << 32) / clock_comp); | |
| 708 | + netdev_info(netdev, | |
| 709 | + "PTP Clock using sclk reference @ %lldHz\n", | |
| 710 | + (NSEC_PER_SEC << 32) / clock_comp); | |
| 710 | 711 | } else { |
| 711 | 712 | /* The clock is already programmed to use a GPIO */ |
| 712 | 713 | u64 clock_comp = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_COMP); |
| 713 | − pr_info("PTP Clock: Using GPIO %d at %lld Hz\n", | |
| 714 | − ptp.s.ext_clk_in, | |
| 715 | − (NSEC_PER_SEC << 32) / clock_comp); | |
| 714 | + netdev_info(netdev, | |
| 715 | + "PTP Clock using GPIO%d @ %lld Hz\n", | |
| 716 | + ptp.s.ext_clk_in, (NSEC_PER_SEC << 32) / clock_comp); | |
| 716 | 717 | } |
| 717 | 718 | |
| 718 | 719 | /* Enable the clock if it wasn't done already */ |
| @@ -926,14 +927,11 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev) · 207 unmodified lines | ||
| 926 | 927 | spin_unlock_irqrestore(&p->lock, flags); |
| 927 | 928 | |
| 928 | 929 | if (link_changed != 0) { |
| 929 | − if (link_changed > 0) { | |
| 930 | − pr_info("%s: Link is up - %d/%s\n", netdev->name, | |
| 931 | − phydev->speed, | |
| 932 | − phydev->duplex == DUPLEX_FULL ? | |
| 933 | − "Full" : "Half"); | |
| 934 | − } else { | |
| 935 | − pr_info("%s: Link is down\n", netdev->name); | |
| 936 | − } | |
| 930 | + if (link_changed > 0) | |
| 931 | + netdev_info(netdev, "Link is up - %d/%s\n", | |
| 932 | + phydev->speed, phydev->duplex == DUPLEX_FULL ? "Full" : "Half"); | |
| 933 | + else | |
| 934 | + netdev_info(netdev, "Link is down\n"); | |
| 937 | 935 | } |
| 938 | 936 | } |
| 939 | 937 | |
| @@ -361,17 +361,8 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic) · 360 unmodified lines | ||
| 361 | 361 | } |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | −static void nic_free_lmacmem(struct nicpf *nic) | |
| 364 | +static void nic_get_hw_info(struct nicpf *nic) | |
| 365 | 365 | { |
| 366 | − kfree(nic->vf_lmac_map); | |
| 367 | − kfree(nic->link); | |
| 368 | − kfree(nic->duplex); | |
| 369 | − kfree(nic->speed); | |
| 370 | −} | |
| 371 | − | |
| 372 | −static int nic_get_hw_info(struct nicpf *nic) | |
| 373 | −{ | |
| 374 | − u8 max_lmac; | |
| 375 | 366 | u16 sdevid; |
| 376 | 367 | struct hw_info *hw = nic->hw; |
| 377 | 368 | |
| @@ -419,41 +410,16 @@ static int nic_get_hw_info(struct nicpf *nic) · 41 unmodified lines | ||
| 419 | 410 | break; |
| 420 | 411 | } |
| 421 | 412 | hw->tl4_cnt = MAX_QUEUES_PER_QSET * pci_sriov_get_totalvfs(nic->pdev); |
| 422 | − | |
| 423 | − /* Allocate memory for LMAC tracking elements */ | |
| 424 | − max_lmac = hw->bgx_cnt * MAX_LMAC_PER_BGX; | |
| 425 | − nic->vf_lmac_map = kmalloc_array(max_lmac, sizeof(u8), GFP_KERNEL); | |
| 426 | − if (!nic->vf_lmac_map) | |
| 427 | − goto error; | |
| 428 | − nic->link = kmalloc_array(max_lmac, sizeof(u8), GFP_KERNEL); | |
| 429 | − if (!nic->link) | |
| 430 | − goto error; | |
| 431 | − nic->duplex = kmalloc_array(max_lmac, sizeof(u8), GFP_KERNEL); | |
| 432 | − if (!nic->duplex) | |
| 433 | − goto error; | |
| 434 | − nic->speed = kmalloc_array(max_lmac, sizeof(u32), GFP_KERNEL); | |
| 435 | − if (!nic->speed) | |
| 436 | − goto error; | |
| 437 | − return 0; | |
| 438 | − | |
| 439 | −error: | |
| 440 | − nic_free_lmacmem(nic); | |
| 441 | − return -ENOMEM; | |
| 442 | 413 | } |
| 443 | 414 | |
| 444 | 415 | #define BGX0_BLOCK 8 |
| 445 | 416 | #define BGX1_BLOCK 9 |
| 446 | 417 | |
| 447 | −static int nic_init_hw(struct nicpf *nic) | |
| 418 | +static void nic_init_hw(struct nicpf *nic) | |
| 448 | 419 | { |
| 449 | − int i, err; | |
| 420 | + int i; | |
| 450 | 421 | u64 cqm_cfg; |
| 451 | 422 | |
| 452 | − /* Get HW capability info */ | |
| 453 | − err = nic_get_hw_info(nic); | |
| 454 | − if (err) | |
| 455 | − return err; | |
| 456 | − | |
| 457 | 423 | /* Enable NIC HW block */ |
| 458 | 424 | nic_reg_write(nic, NIC_PF_CFG, 0x3); |
| 459 | 425 | |
| @@ -498,8 +464,6 @@ static int nic_init_hw(struct nicpf *nic) · 38 unmodified lines | ||
| 498 | 464 | cqm_cfg = nic_reg_read(nic, NIC_PF_CQM_CFG); |
| 499 | 465 | if (cqm_cfg < NICPF_CQM_MIN_DROP_LEVEL) |
| 500 | 466 | nic_reg_write(nic, NIC_PF_CQM_CFG, NICPF_CQM_MIN_DROP_LEVEL); |
| 501 | − | |
| 502 | − return 0; | |
| 503 | 467 | } |
| 504 | 468 | |
| 505 | 469 | /* Channel parse index configuration */ |
| @@ -584,9 +548,6 @@ static void nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg) · 78 unmodified lines | ||
| 584 | 548 | static void nic_send_rss_size(struct nicpf *nic, int vf) |
| 585 | 549 | { |
| 586 | 550 | union nic_mbx mbx = {}; |
| 587 | − u64 *msg; | |
| 588 | − | |
| 589 | − msg = (u64 *)&mbx; | |
| 590 | 551 | |
| 591 | 552 | mbx.rss_size.msg = NIC_MBOX_MSG_RSS_SIZE; |
| 592 | 553 | mbx.rss_size.ind_tbl_size = nic->hw->rss_ind_tbl_size; |
| @@ -608,7 +569,6 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg) · 15 unmodified lines | ||
| 608 | 569 | rssi_base = nic->rssi_base[cfg->vf_id] + cfg->tbl_offset; |
| 609 | 570 | |
| 610 | 571 | rssi = rssi_base; |
| 611 | − qset = cfg->vf_id; | |
| 612 | 572 | |
| 613 | 573 | for (; rssi < (rssi_base + cfg->tbl_len); rssi++) { |
| 614 | 574 | u8 svf = cfg->ind_tbl[idx] >> 3; |
| @@ -1273,6 +1233,7 @@ static int nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 658 unmodified lines | ||
| 1273 | 1233 | { |
| 1274 | 1234 | struct device *dev = &pdev->dev; |
| 1275 | 1235 | struct nicpf *nic; |
| 1236 | + u8 max_lmac; | |
| 1276 | 1237 | int err; |
| 1277 | 1238 | |
| 1278 | 1239 | BUILD_BUG_ON(sizeof(union nic_mbx) > 16); |
| @@ -1282,10 +1243,8 @@ static int nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 3 unmodified lines | ||
| 1282 | 1243 | return -ENOMEM; |
| 1283 | 1244 | |
| 1284 | 1245 | nic->hw = devm_kzalloc(dev, sizeof(struct hw_info), GFP_KERNEL); |
| 1285 | − if (!nic->hw) { | |
| 1286 | − devm_kfree(dev, nic); | |
| 1246 | + if (!nic->hw) | |
| 1287 | 1247 | return -ENOMEM; |
| 1288 | − } | |
| 1289 | 1248 | |
| 1290 | 1249 | pci_set_drvdata(pdev, nic); |
| 1291 | 1250 | |
| @@ -1326,11 +1285,33 @@ static int nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 34 unmodified lines | ||
| 1326 | 1285 | |
| 1327 | 1286 | nic->node = nic_get_node_id(pdev); |
| 1328 | 1287 | |
| 1329 | − /* Initialize hardware */ | |
| 1330 | − err = nic_init_hw(nic); | |
| 1331 | − if (err) | |
| 1288 | + /* Get HW capability info */ | |
| 1289 | + nic_get_hw_info(nic); | |
| 1290 | + | |
| 1291 | + /* Allocate memory for LMAC tracking elements */ | |
| 1292 | + err = -ENOMEM; | |
| 1293 | + max_lmac = nic->hw->bgx_cnt * MAX_LMAC_PER_BGX; | |
| 1294 | + | |
| 1295 | + nic->vf_lmac_map = devm_kmalloc_array(dev, max_lmac, sizeof(u8), | |
| 1296 | + GFP_KERNEL); | |
| 1297 | + if (!nic->vf_lmac_map) | |
| 1298 | + goto err_release_regions; | |
| 1299 | + | |
| 1300 | + nic->link = devm_kmalloc_array(dev, max_lmac, sizeof(u8), GFP_KERNEL); | |
| 1301 | + if (!nic->link) | |
| 1302 | + goto err_release_regions; | |
| 1303 | + | |
| 1304 | + nic->duplex = devm_kmalloc_array(dev, max_lmac, sizeof(u8), GFP_KERNEL); | |
| 1305 | + if (!nic->duplex) | |
| 1306 | + goto err_release_regions; | |
| 1307 | + | |
| 1308 | + nic->speed = devm_kmalloc_array(dev, max_lmac, sizeof(u32), GFP_KERNEL); | |
| 1309 | + if (!nic->speed) | |
| 1332 | 1310 | goto err_release_regions; |
| 1333 | 1311 | |
| 1312 | + /* Initialize hardware */ | |
| 1313 | + nic_init_hw(nic); | |
| 1314 | + | |
| 1334 | 1315 | nic_set_lmac_vf_mapping(nic); |
| 1335 | 1316 | |
| 1336 | 1317 | /* Register interrupts */ |
| @@ -1364,9 +1345,6 @@ err_unregister_interrupts: · 27 unmodified lines | ||
| 1364 | 1345 | err_release_regions: |
| 1365 | 1346 | pci_release_regions(pdev); |
| 1366 | 1347 | err_disable_device: |
| 1367 | − nic_free_lmacmem(nic); | |
| 1368 | − devm_kfree(dev, nic->hw); | |
| 1369 | − devm_kfree(dev, nic); | |
| 1370 | 1348 | pci_disable_device(pdev); |
| 1371 | 1349 | pci_set_drvdata(pdev, NULL); |
| 1372 | 1350 | return err; |
| @@ -1388,10 +1366,6 @@ static void nic_remove(struct pci_dev *pdev) · 15 unmodified lines | ||
| 1388 | 1366 | nic_unregister_interrupts(nic); |
| 1389 | 1367 | pci_release_regions(pdev); |
| 1390 | 1368 | |
| 1391 | − nic_free_lmacmem(nic); | |
| 1392 | − devm_kfree(&pdev->dev, nic->hw); | |
| 1393 | − devm_kfree(&pdev->dev, nic); | |
| 1394 | − | |
| 1395 | 1369 | pci_disable_device(pdev); |
| 1396 | 1370 | pci_set_drvdata(pdev, NULL); |
| 1397 | 1371 | } |
| @@ -523,6 +523,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, · 522 unmodified lines | ||
| 523 | 523 | |
| 524 | 524 | xdp.data_hard_start = page_address(page); |
| 525 | 525 | xdp.data = (void *)cpu_addr; |
| 526 | + xdp_set_data_meta_invalid(&xdp); | |
| 526 | 527 | xdp.data_end = xdp.data + len; |
| 527 | 528 | orig_data = xdp.data; |
| 528 | 529 | |
| @@ -1740,7 +1741,7 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) · 1211 unmodified lines | ||
| 1740 | 1741 | return 0; |
| 1741 | 1742 | } |
| 1742 | 1743 | |
| 1743 | −static int nicvf_xdp(struct net_device *netdev, struct netdev_xdp *xdp) | |
| 1744 | +static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) | |
| 1744 | 1745 | { |
| 1745 | 1746 | struct nicvf *nic = netdev_priv(netdev); |
| 1746 | 1747 | |
| @@ -1773,7 +1774,7 @@ static const struct net_device_ops nicvf_netdev_ops = { · 26 unmodified lines | ||
| 1773 | 1774 | .ndo_tx_timeout = nicvf_tx_timeout, |
| 1774 | 1775 | .ndo_fix_features = nicvf_fix_features, |
| 1775 | 1776 | .ndo_set_features = nicvf_set_features, |
| 1776 | − .ndo_xdp = nicvf_xdp, | |
| 1777 | + .ndo_bpf = nicvf_xdp, | |
| 1777 | 1778 | }; |
| 1778 | 1779 | |
| 1779 | 1780 | static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
| @@ -1882,10 +1882,10 @@ send: · 1881 unmodified lines | ||
| 1882 | 1882 | /* |
| 1883 | 1883 | * Callback for the Tx buffer reclaim timer. Runs with softirqs disabled. |
| 1884 | 1884 | */ |
| 1885 | −static void sge_tx_reclaim_cb(unsigned long data) | |
| 1885 | +static void sge_tx_reclaim_cb(struct timer_list *t) | |
| 1886 | 1886 | { |
| 1887 | 1887 | int i; |
| 1888 | − struct sge *sge = (struct sge *)data; | |
| 1888 | + struct sge *sge = from_timer(sge, t, tx_reclaim_timer); | |
| 1889 | 1889 | |
| 1890 | 1890 | for (i = 0; i < SGE_CMDQ_N; ++i) { |
| 1891 | 1891 | struct cmdQ *q = &sge->cmdQ[i]; |
| @@ -1978,10 +1978,10 @@ void t1_sge_start(struct sge *sge) · 86 unmodified lines | ||
| 1978 | 1978 | /* |
| 1979 | 1979 | * Callback for the T2 ESPI 'stuck packet feature' workaorund |
| 1980 | 1980 | */ |
| 1981 | −static void espibug_workaround_t204(unsigned long data) | |
| 1981 | +static void espibug_workaround_t204(struct timer_list *t) | |
| 1982 | 1982 | { |
| 1983 | − struct adapter *adapter = (struct adapter *)data; | |
| 1984 | − struct sge *sge = adapter->sge; | |
| 1983 | + struct sge *sge = from_timer(sge, t, espibug_timer); | |
| 1984 | + struct adapter *adapter = sge->adapter; | |
| 1985 | 1985 | unsigned int nports = adapter->params.nports; |
| 1986 | 1986 | u32 seop[MAX_NPORTS]; |
| 1987 | 1987 | |
| @@ -2021,10 +2021,10 @@ static void espibug_workaround_t204(unsigned long data) · 33 unmodified lines | ||
| 2021 | 2021 | mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout); |
| 2022 | 2022 | } |
| 2023 | 2023 | |
| 2024 | −static void espibug_workaround(unsigned long data) | |
| 2024 | +static void espibug_workaround(struct timer_list *t) | |
| 2025 | 2025 | { |
| 2026 | − struct adapter *adapter = (struct adapter *)data; | |
| 2027 | − struct sge *sge = adapter->sge; | |
| 2026 | + struct sge *sge = from_timer(sge, t, espibug_timer); | |
| 2027 | + struct adapter *adapter = sge->adapter; | |
| 2028 | 2028 | |
| 2029 | 2029 | if (netif_running(adapter->port[0].dev)) { |
| 2030 | 2030 | struct sk_buff *skb = sge->espibug_skb[0]; |
| @@ -2075,19 +2075,15 @@ struct sge *t1_sge_create(struct adapter *adapter, struct sge_params *p) · 44 unmodified lines | ||
| 2075 | 2075 | goto nomem_port; |
| 2076 | 2076 | } |
| 2077 | 2077 | |
| 2078 | − init_timer(&sge->tx_reclaim_timer); | |
| 2079 | − sge->tx_reclaim_timer.data = (unsigned long)sge; | |
| 2080 | − sge->tx_reclaim_timer.function = sge_tx_reclaim_cb; | |
| 2078 | + timer_setup(&sge->tx_reclaim_timer, sge_tx_reclaim_cb, 0); | |
| 2081 | 2079 | |
| 2082 | 2080 | if (is_T2(sge->adapter)) { |
| 2083 | − init_timer(&sge->espibug_timer); | |
| 2081 | + timer_setup(&sge->espibug_timer, | |
| 2082 | + adapter->params.nports > 1 ? espibug_workaround_t204 : espibug_workaround, | |
| 2083 | + 0); | |
| 2084 | 2084 | |
| 2085 | − if (adapter->params.nports > 1) { | |
| 2085 | + if (adapter->params.nports > 1) | |
| 2086 | 2086 | tx_sched_init(sge); |
| 2087 | − sge->espibug_timer.function = espibug_workaround_t204; | |
| 2088 | − } else | |
| 2089 | − sge->espibug_timer.function = espibug_workaround; | |
| 2090 | − sge->espibug_timer.data = (unsigned long)sge->adapter; | |
| 2091 | 2087 | |
| 2092 | 2088 | sge->espibug_timeout = 1; |
| 2093 | 2089 | /* for T204, every 10ms */ |
| @@ -455,6 +455,11 @@ static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q, · 454 unmodified lines | ||
| 455 | 455 | q->pg_chunk.offset = 0; |
| 456 | 456 | mapping = pci_map_page(adapter->pdev, q->pg_chunk.page, |
| 457 | 457 | 0, q->alloc_size, PCI_DMA_FROMDEVICE); |
| 458 | + if (unlikely(pci_dma_mapping_error(adapter->pdev, mapping))) { | |
| 459 | + __free_pages(q->pg_chunk.page, order); | |
| 460 | + q->pg_chunk.page = NULL; | |
| 461 | + return -EIO; | |
| 462 | + } | |
| 458 | 463 | q->pg_chunk.mapping = mapping; |
| 459 | 464 | } |
| 460 | 465 | sd->pg_chunk = q->pg_chunk; |
| @@ -949,40 +954,78 @@ static inline unsigned int calc_tx_descs(const struct sk_buff *skb) · 488 unmodified lines | ||
| 949 | 954 | return flits_to_desc(flits); |
| 950 | 955 | } |
| 951 | 956 | |
| 957 | +/* map_skb - map a packet main body and its page fragments | |
| 958 | + * @pdev: the PCI device | |
| 959 | + * @skb: the packet | |
| 960 | + * @addr: placeholder to save the mapped addresses | |
| 961 | + * | |
| 962 | + * map the main body of an sk_buff and its page fragments, if any. | |
| 963 | + */ | |
| 964 | +static int map_skb(struct pci_dev *pdev, const struct sk_buff *skb, | |
| 965 | + dma_addr_t *addr) | |
| 966 | +{ | |
| 967 | + const skb_frag_t *fp, *end; | |
| 968 | + const struct skb_shared_info *si; | |
| 969 | + | |
| 970 | + if (skb_headlen(skb)) { | |
| 971 | + *addr = pci_map_single(pdev, skb->data, skb_headlen(skb), | |
| 972 | + PCI_DMA_TODEVICE); | |
| 973 | + if (pci_dma_mapping_error(pdev, *addr)) | |
| 974 | + goto out_err; | |
| 975 | + addr++; | |
| 976 | + } | |
| 977 | + | |
| 978 | + si = skb_shinfo(skb); | |
| 979 | + end = &si->frags[si->nr_frags]; | |
| 980 | + | |
| 981 | + for (fp = si->frags; fp < end; fp++) { | |
| 982 | + *addr = skb_frag_dma_map(&pdev->dev, fp, 0, skb_frag_size(fp), | |
| 983 | + DMA_TO_DEVICE); | |
| 984 | + if (pci_dma_mapping_error(pdev, *addr)) | |
| 985 | + goto unwind; | |
| 986 | + addr++; | |
| 987 | + } | |
| 988 | + return 0; | |
| 989 | + | |
| 990 | +unwind: | |
| 991 | + while (fp-- > si->frags) | |
| 992 | + dma_unmap_page(&pdev->dev, *--addr, skb_frag_size(fp), | |
| 993 | + DMA_TO_DEVICE); | |
| 994 | + | |
| 995 | + pci_unmap_single(pdev, addr[-1], skb_headlen(skb), PCI_DMA_TODEVICE); | |
| 996 | +out_err: | |
| 997 | + return -ENOMEM; | |
| 998 | +} | |
| 999 | + | |
| 952 | 1000 | /** |
| 953 | − * make_sgl - populate a scatter/gather list for a packet | |
| 1001 | + * write_sgl - populate a scatter/gather list for a packet | |
| 954 | 1002 | * @skb: the packet |
| 955 | 1003 | * @sgp: the SGL to populate |
| 956 | 1004 | * @start: start address of skb main body data to include in the SGL |
| 957 | 1005 | * @len: length of skb main body data to include in the SGL |
| 958 | − * @pdev: the PCI device | |
| 1006 | + * @addr: the list of the mapped addresses | |
| 959 | 1007 | * |
| 960 | − * Generates a scatter/gather list for the buffers that make up a packet | |
| 1008 | + * Copies the scatter/gather list for the buffers that make up a packet | |
| 961 | 1009 | * and returns the SGL size in 8-byte words. The caller must size the SGL |
| 962 | 1010 | * appropriately. |
| 963 | 1011 | */ |
| 964 | −static inline unsigned int make_sgl(const struct sk_buff *skb, | |
| 965 | − struct sg_ent *sgp, unsigned char *start, | |
| 966 | − unsigned int len, struct pci_dev *pdev) | |
| 1012 | +static inline unsigned int write_sgl(const struct sk_buff *skb, | |
| 1013 | + struct sg_ent *sgp, unsigned char *start, | |
| 1014 | + unsigned int len, const dma_addr_t *addr) | |
| 967 | 1015 | { |
| 968 | − dma_addr_t mapping; | |
| 969 | − unsigned int i, j = 0, nfrags; | |
| 1016 | + unsigned int i, j = 0, k = 0, nfrags; | |
| 970 | 1017 | |
| 971 | 1018 | if (len) { |
| 972 | − mapping = pci_map_single(pdev, start, len, PCI_DMA_TODEVICE); | |
| 973 | 1019 | sgp->len[0] = cpu_to_be32(len); |
| 974 | − sgp->addr[0] = cpu_to_be64(mapping); | |
| 975 | − j = 1; | |
| 1020 | + sgp->addr[j++] = cpu_to_be64(addr[k++]); | |
| 976 | 1021 | } |
| 977 | 1022 | |
| 978 | 1023 | nfrags = skb_shinfo(skb)->nr_frags; |
| 979 | 1024 | for (i = 0; i < nfrags; i++) { |
| 980 | 1025 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
| 981 | 1026 | |
| 982 | − mapping = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag), | |
| 983 | − DMA_TO_DEVICE); | |
| 984 | 1027 | sgp->len[j] = cpu_to_be32(skb_frag_size(frag)); |
| 985 | − sgp->addr[j] = cpu_to_be64(mapping); | |
| 1028 | + sgp->addr[j] = cpu_to_be64(addr[k++]); | |
| 986 | 1029 | j ^= 1; |
| 987 | 1030 | if (j == 0) |
| 988 | 1031 | ++sgp; |
| @@ -1138,7 +1181,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, · 149 unmodified lines | ||
| 1138 | 1181 | const struct port_info *pi, |
| 1139 | 1182 | unsigned int pidx, unsigned int gen, |
| 1140 | 1183 | struct sge_txq *q, unsigned int ndesc, |
| 1141 | − unsigned int compl) | |
| 1184 | + unsigned int compl, const dma_addr_t *addr) | |
| 1142 | 1185 | { |
| 1143 | 1186 | unsigned int flits, sgl_flits, cntrl, tso_info; |
| 1144 | 1187 | struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1]; |
| @@ -1196,7 +1239,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, · 51 unmodified lines | ||
| 1196 | 1239 | } |
| 1197 | 1240 | |
| 1198 | 1241 | sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; |
| 1199 | − sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev); | |
| 1242 | + sgl_flits = write_sgl(skb, sgp, skb->data, skb_headlen(skb), addr); | |
| 1200 | 1243 | |
| 1201 | 1244 | write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen, |
| 1202 | 1245 | htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl), |
| @@ -1227,6 +1270,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 24 unmodified lines | ||
| 1227 | 1270 | struct netdev_queue *txq; |
| 1228 | 1271 | struct sge_qset *qs; |
| 1229 | 1272 | struct sge_txq *q; |
| 1273 | + dma_addr_t addr[MAX_SKB_FRAGS + 1]; | |
| 1230 | 1274 | |
| 1231 | 1275 | /* |
| 1232 | 1276 | * The chip min packet length is 9 octets but play safe and reject |
| @@ -1255,6 +1299,14 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 22 unmodified lines | ||
| 1255 | 1299 | return NETDEV_TX_BUSY; |
| 1256 | 1300 | } |
| 1257 | 1301 | |
| 1302 | + /* Check if ethernet packet can't be sent as immediate data */ | |
| 1303 | + if (skb->len > (WR_LEN - sizeof(struct cpl_tx_pkt))) { | |
| 1304 | + if (unlikely(map_skb(adap->pdev, skb, addr) < 0)) { | |
| 1305 | + dev_kfree_skb(skb); | |
| 1306 | + return NETDEV_TX_OK; | |
| 1307 | + } | |
| 1308 | + } | |
| 1309 | + | |
| 1258 | 1310 | q->in_use += ndesc; |
| 1259 | 1311 | if (unlikely(credits - ndesc < q->stop_thres)) { |
| 1260 | 1312 | t3_stop_tx_queue(txq, qs, q); |
| @@ -1312,7 +1364,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) · 51 unmodified lines | ||
| 1312 | 1364 | if (likely(!skb_shared(skb))) |
| 1313 | 1365 | skb_orphan(skb); |
| 1314 | 1366 | |
| 1315 | − write_tx_pkt_wr(adap, skb, pi, pidx, gen, q, ndesc, compl); | |
| 1367 | + write_tx_pkt_wr(adap, skb, pi, pidx, gen, q, ndesc, compl, addr); | |
| 1316 | 1368 | check_ring_tx_db(adap, q); |
| 1317 | 1369 | return NETDEV_TX_OK; |
| 1318 | 1370 | } |
| @@ -1577,7 +1629,8 @@ static void setup_deferred_unmapping(struct sk_buff *skb, struct pci_dev *pdev, · 258 unmodified lines | ||
| 1577 | 1629 | */ |
| 1578 | 1630 | static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb, |
| 1579 | 1631 | struct sge_txq *q, unsigned int pidx, |
| 1580 | − unsigned int gen, unsigned int ndesc) | |
| 1632 | + unsigned int gen, unsigned int ndesc, | |
| 1633 | + const dma_addr_t *addr) | |
| 1581 | 1634 | { |
| 1582 | 1635 | unsigned int sgl_flits, flits; |
| 1583 | 1636 | struct work_request_hdr *from; |
| @@ -1598,10 +1651,9 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb, · 14 unmodified lines | ||
| 1598 | 1651 | |
| 1599 | 1652 | flits = skb_transport_offset(skb) / 8; |
| 1600 | 1653 | sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; |
| 1601 | − sgl_flits = make_sgl(skb, sgp, skb_transport_header(skb), | |
| 1602 | − skb_tail_pointer(skb) - | |
| 1603 | − skb_transport_header(skb), | |
| 1604 | − adap->pdev); | |
| 1654 | + sgl_flits = write_sgl(skb, sgp, skb_transport_header(skb), | |
| 1655 | + skb_tail_pointer(skb) - skb_transport_header(skb), | |
| 1656 | + addr); | |
| 1605 | 1657 | if (need_skb_unmap()) { |
| 1606 | 1658 | setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits); |
| 1607 | 1659 | skb->destructor = deferred_unmap_destructor; |
| @@ -1659,6 +1711,12 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); · 51 unmodified lines | ||
| 1659 | 1711 | goto again; |
| 1660 | 1712 | } |
| 1661 | 1713 | |
| 1714 | + if (!immediate(skb) && | |
| 1715 | + map_skb(adap->pdev, skb, (dma_addr_t *)skb->head)) { | |
| 1716 | + spin_unlock(&q->lock); | |
| 1717 | + return NET_XMIT_SUCCESS; | |
| 1718 | + } | |
| 1719 | + | |
| 1662 | 1720 | gen = q->gen; |
| 1663 | 1721 | q->in_use += ndesc; |
| 1664 | 1722 | pidx = q->pidx; |
| @@ -1669,7 +1727,7 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); · 4 unmodified lines | ||
| 1669 | 1727 | } |
| 1670 | 1728 | spin_unlock(&q->lock); |
| 1671 | 1729 | |
| 1672 | − write_ofld_wr(adap, skb, q, pidx, gen, ndesc); | |
| 1730 | + write_ofld_wr(adap, skb, q, pidx, gen, ndesc, (dma_addr_t *)skb->head); | |
| 1673 | 1731 | check_ring_tx_db(adap, q); |
| 1674 | 1732 | return NET_XMIT_SUCCESS; |
| 1675 | 1733 | } |
| @@ -1687,6 +1745,7 @@ static void restart_offloadq(unsigned long data) · 11 unmodified lines | ||
| 1687 | 1745 | struct sge_txq *q = &qs->txq[TXQ_OFLD]; |
| 1688 | 1746 | const struct port_info *pi = netdev_priv(qs->netdev); |
| 1689 | 1747 | struct adapter *adap = pi->adapter; |
| 1748 | + unsigned int written = 0; | |
| 1690 | 1749 | |
| 1691 | 1750 | spin_lock(&q->lock); |
| 1692 | 1751 | again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); |
| @@ -1706,10 +1765,15 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); · 13 unmodified lines | ||
| 1706 | 1765 | break; |
| 1707 | 1766 | } |
| 1708 | 1767 | |
| 1768 | + if (!immediate(skb) && | |
| 1769 | + map_skb(adap->pdev, skb, (dma_addr_t *)skb->head)) | |
| 1770 | + break; | |
| 1771 | + | |
| 1709 | 1772 | gen = q->gen; |
| 1710 | 1773 | q->in_use += ndesc; |
| 1711 | 1774 | pidx = q->pidx; |
| 1712 | 1775 | q->pidx += ndesc; |
| 1776 | + written += ndesc; | |
| 1713 | 1777 | if (q->pidx >= q->size) { |
| 1714 | 1778 | q->pidx -= q->size; |
| 1715 | 1779 | q->gen ^= 1; |
| @@ -1717,7 +1781,8 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); · 1 unmodified line | ||
| 1717 | 1781 | __skb_unlink(skb, &q->sendq); |
| 1718 | 1782 | spin_unlock(&q->lock); |
| 1719 | 1783 | |
| 1720 | − write_ofld_wr(adap, skb, q, pidx, gen, ndesc); | |
| 1784 | + write_ofld_wr(adap, skb, q, pidx, gen, ndesc, | |
| 1785 | + (dma_addr_t *)skb->head); | |
| 1721 | 1786 | spin_lock(&q->lock); |
| 1722 | 1787 | } |
| 1723 | 1788 | spin_unlock(&q->lock); |
| @@ -1727,8 +1792,9 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); · 3 unmodified lines | ||
| 1727 | 1792 | set_bit(TXQ_LAST_PKT_DB, &q->flags); |
| 1728 | 1793 | #endif |
| 1729 | 1794 | wmb(); |
| 1730 | − t3_write_reg(adap, A_SG_KDOORBELL, | |
| 1731 | − F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); | |
| 1795 | + if (likely(written)) | |
| 1796 | + t3_write_reg(adap, A_SG_KDOORBELL, | |
| 1797 | + F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); | |
| 1732 | 1798 | } |
| 1733 | 1799 | |
| 1734 | 1800 | /** |
| @@ -2853,9 +2919,9 @@ void t3_sge_err_intr_handler(struct adapter *adapter) · 1118 unmodified lines | ||
| 2853 | 2919 | * bother cleaning them up here. |
| 2854 | 2920 | * |
| 2855 | 2921 | */ |
| 2856 | −static void sge_timer_tx(unsigned long data) | |
| 2922 | +static void sge_timer_tx(struct timer_list *t) | |
| 2857 | 2923 | { |
| 2858 | − struct sge_qset *qs = (struct sge_qset *)data; | |
| 2924 | + struct sge_qset *qs = from_timer(qs, t, tx_reclaim_timer); | |
| 2859 | 2925 | struct port_info *pi = netdev_priv(qs->netdev); |
| 2860 | 2926 | struct adapter *adap = pi->adapter; |
| 2861 | 2927 | unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0}; |
| @@ -2893,10 +2959,10 @@ static void sge_timer_tx(unsigned long data) · 31 unmodified lines | ||
| 2893 | 2959 | * starved. |
| 2894 | 2960 | * |
| 2895 | 2961 | */ |
| 2896 | −static void sge_timer_rx(unsigned long data) | |
| 2962 | +static void sge_timer_rx(struct timer_list *t) | |
| 2897 | 2963 | { |
| 2898 | 2964 | spinlock_t *lock; |
| 2899 | − struct sge_qset *qs = (struct sge_qset *)data; | |
| 2965 | + struct sge_qset *qs = from_timer(qs, t, rx_reclaim_timer); | |
| 2900 | 2966 | struct port_info *pi = netdev_priv(qs->netdev); |
| 2901 | 2967 | struct adapter *adap = pi->adapter; |
| 2902 | 2968 | u32 status; |
| @@ -2976,8 +3042,8 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, · 73 unmodified lines | ||
| 2976 | 3042 | struct sge_qset *q = &adapter->sge.qs[id]; |
| 2977 | 3043 | |
| 2978 | 3044 | init_qset_cntxt(q, id); |
| 2979 | − setup_timer(&q->tx_reclaim_timer, sge_timer_tx, (unsigned long)q); | |
| 2980 | − setup_timer(&q->rx_reclaim_timer, sge_timer_rx, (unsigned long)q); | |
| 3045 | + timer_setup(&q->tx_reclaim_timer, sge_timer_tx, 0); | |
| 3046 | + timer_setup(&q->rx_reclaim_timer, sge_timer_rx, 0); | |
| 2981 | 3047 | |
| 2982 | 3048 | q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size, |
| 2983 | 3049 | sizeof(struct rx_desc), |
| @@ -5,7 +5,10 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | obj-$(CONFIG_CHELSIO_T4) += cxgb4.o |
| 7 | 7 | |
| 8 | −cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o cxgb4_uld.o sched.o cxgb4_filter.o cxgb4_tc_u32.o cxgb4_ptp.o | |
| 8 | +cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o \ | |
| 9 | + cxgb4_uld.o sched.o cxgb4_filter.o cxgb4_tc_u32.o \ | |
| 10 | + cxgb4_ptp.o cxgb4_tc_flower.o cxgb4_cudbg.o \ | |
| 11 | + cudbg_common.o cudbg_lib.o | |
| 9 | 12 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o |
| 10 | 13 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o |
| 11 | 14 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o |
| @@ -96,7 +96,8 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6) · 95 unmodified lines | ||
| 96 | 96 | if (!ret) { |
| 97 | 97 | ce = cte; |
| 98 | 98 | read_unlock_bh(&ctbl->lock); |
| 99 | − goto found; | |
| 99 | + refcount_inc(&ce->refcnt); | |
| 100 | + return 0; | |
| 100 | 101 | } |
| 101 | 102 | } |
| 102 | 103 | read_unlock_bh(&ctbl->lock); |
| @@ -108,7 +109,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6) · 5 unmodified lines | ||
| 108 | 109 | list_del(&ce->list); |
| 109 | 110 | INIT_LIST_HEAD(&ce->list); |
| 110 | 111 | spin_lock_init(&ce->lock); |
| 111 | − atomic_set(&ce->refcnt, 0); | |
| 112 | + refcount_set(&ce->refcnt, 0); | |
| 112 | 113 | atomic_dec(&ctbl->nfree); |
| 113 | 114 | list_add_tail(&ce->list, &ctbl->hash_list[hash]); |
| 114 | 115 | if (v6) { |
| @@ -138,9 +139,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6) · 23 unmodified lines | ||
| 138 | 139 | return -ENOMEM; |
| 139 | 140 | } |
| 140 | 141 | write_unlock_bh(&ctbl->lock); |
| 141 | −found: | |
| 142 | − atomic_inc(&ce->refcnt); | |
| 143 | − | |
| 142 | + refcount_set(&ce->refcnt, 1); | |
| 144 | 143 | return 0; |
| 145 | 144 | } |
| 146 | 145 | EXPORT_SYMBOL(cxgb4_clip_get); |
| @@ -179,7 +178,7 @@ void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6) · 32 unmodified lines | ||
| 179 | 178 | found: |
| 180 | 179 | write_lock_bh(&ctbl->lock); |
| 181 | 180 | spin_lock_bh(&ce->lock); |
| 182 | − if (atomic_dec_and_test(&ce->refcnt)) { | |
| 181 | + if (refcount_dec_and_test(&ce->refcnt)) { | |
| 183 | 182 | list_del(&ce->list); |
| 184 | 183 | INIT_LIST_HEAD(&ce->list); |
| 185 | 184 | list_add_tail(&ce->list, &ctbl->ce_free_head); |
| @@ -266,7 +265,7 @@ int clip_tbl_show(struct seq_file *seq, void *v) · 80 unmodified lines | ||
| 266 | 265 | ip[0] = '\0'; |
| 267 | 266 | sprintf(ip, "%pISc", &ce->addr); |
| 268 | 267 | seq_printf(seq, "%-25s %u\n", ip, |
| 269 | − atomic_read(&ce->refcnt)); | |
| 268 | + refcount_read(&ce->refcnt)); | |
| 270 | 269 | } |
| 271 | 270 | } |
| 272 | 271 | seq_printf(seq, "Free clip entries : %d\n", atomic_read(&ctbl->nfree)); |
| @@ -10,9 +10,11 @@ · 9 unmodified lines | ||
| 10 | 10 | * release for licensing terms and conditions. |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | +#include <linux/refcount.h> | |
| 14 | + | |
| 13 | 15 | struct clip_entry { |
| 14 | 16 | spinlock_t lock; /* Hold while modifying clip reference */ |
| 15 | − atomic_t refcnt; | |
| 17 | + refcount_t refcnt; | |
| 16 | 18 | struct list_head list; |
| 17 | 19 | union { |
| 18 | 20 | struct sockaddr_in addr; |
| @@ -0,0 +1,54 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2017 Chelsio Communications. All rights reserved. | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify it | |
| 5 | + * under the terms and conditions of the GNU General Public License, | |
| 6 | + * version 2, as published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 9 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 10 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 11 | + * more details. | |
| 12 | + * | |
| 13 | + * The full GNU General Public License is included in this distribution in | |
| 14 | + * the file called "COPYING". | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include "cxgb4.h" | |
| 19 | +#include "cudbg_if.h" | |
| 20 | +#include "cudbg_lib_common.h" | |
| 21 | + | |
| 22 | +int cudbg_get_buff(struct cudbg_buffer *pdbg_buff, u32 size, | |
| 23 | + struct cudbg_buffer *pin_buff) | |
| 24 | +{ | |
| 25 | + u32 offset; | |
| 26 | + | |
| 27 | + offset = pdbg_buff->offset; | |
| 28 | + if (offset + size > pdbg_buff->size) | |
| 29 | + return CUDBG_STATUS_NO_MEM; | |
| 30 | + | |
| 31 | + pin_buff->data = (char *)pdbg_buff->data + offset; | |
| 32 | + pin_buff->offset = offset; | |
| 33 | + pin_buff->size = size; | |
| 34 | + pdbg_buff->size -= size; | |
| 35 | + return 0; | |
| 36 | +} | |
| 37 | + | |
| 38 | +void cudbg_put_buff(struct cudbg_buffer *pin_buff, | |
| 39 | + struct cudbg_buffer *pdbg_buff) | |
| 40 | +{ | |
| 41 | + pdbg_buff->size += pin_buff->size; | |
| 42 | + pin_buff->data = NULL; | |
| 43 | + pin_buff->offset = 0; | |
| 44 | + pin_buff->size = 0; | |
| 45 | +} | |
| 46 | + | |
| 47 | +void cudbg_update_buff(struct cudbg_buffer *pin_buff, | |
| 48 | + struct cudbg_buffer *pout_buff) | |
| 49 | +{ | |
| 50 | + /* We already write to buffer provided by ethool, so just | |
| 51 | + * increment offset to next free space. | |
| 52 | + */ | |
| 53 | + pout_buff->offset += pin_buff->size; | |
| 54 | +} | |
| @@ -0,0 +1,384 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2017 Chelsio Communications. All rights reserved. | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify it | |
| 5 | + * under the terms and conditions of the GNU General Public License, | |
| 6 | + * version 2, as published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 9 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 10 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 11 | + * more details. | |
| 12 | + * | |
| 13 | + * The full GNU General Public License is included in this distribution in | |
| 14 | + * the file called "COPYING". | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#ifndef __CUDBG_ENTITY_H__ | |
| 19 | +#define __CUDBG_ENTITY_H__ | |
| 20 | + | |
| 21 | +#define EDC0_FLAG 3 | |
| 22 | +#define EDC1_FLAG 4 | |
| 23 | + | |
| 24 | +#define CUDBG_ENTITY_SIGNATURE 0xCCEDB001 | |
| 25 | + | |
| 26 | +struct card_mem { | |
| 27 | + u16 size_edc0; | |
| 28 | + u16 size_edc1; | |
| 29 | + u16 mem_flag; | |
| 30 | +}; | |
| 31 | + | |
| 32 | +struct cudbg_mbox_log { | |
| 33 | + struct mbox_cmd entry; | |
| 34 | + u32 hi[MBOX_LEN / 8]; | |
| 35 | + u32 lo[MBOX_LEN / 8]; | |
| 36 | +}; | |
| 37 | + | |
| 38 | +struct cudbg_cim_qcfg { | |
| 39 | + u8 chip; | |
| 40 | + u16 base[CIM_NUM_IBQ + CIM_NUM_OBQ_T5]; | |
| 41 | + u16 size[CIM_NUM_IBQ + CIM_NUM_OBQ_T5]; | |
| 42 | + u16 thres[CIM_NUM_IBQ]; | |
| 43 | + u32 obq_wr[2 * CIM_NUM_OBQ_T5]; | |
| 44 | + u32 stat[4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5)]; | |
| 45 | +}; | |
| 46 | + | |
| 47 | +struct cudbg_rss_vf_conf { | |
| 48 | + u32 rss_vf_vfl; | |
| 49 | + u32 rss_vf_vfh; | |
| 50 | +}; | |
| 51 | + | |
| 52 | +struct cudbg_pm_stats { | |
| 53 | + u32 tx_cnt[T6_PM_NSTATS]; | |
| 54 | + u32 rx_cnt[T6_PM_NSTATS]; | |
| 55 | + u64 tx_cyc[T6_PM_NSTATS]; | |
| 56 | + u64 rx_cyc[T6_PM_NSTATS]; | |
| 57 | +}; | |
| 58 | + | |
| 59 | +struct cudbg_hw_sched { | |
| 60 | + u32 kbps[NTX_SCHED]; | |
| 61 | + u32 ipg[NTX_SCHED]; | |
| 62 | + u32 pace_tab[NTX_SCHED]; | |
| 63 | + u32 mode; | |
| 64 | + u32 map; | |
| 65 | +}; | |
| 66 | + | |
| 67 | +struct ireg_field { | |
| 68 | + u32 ireg_addr; | |
| 69 | + u32 ireg_data; | |
| 70 | + u32 ireg_local_offset; | |
| 71 | + u32 ireg_offset_range; | |
| 72 | +}; | |
| 73 | + | |
| 74 | +struct ireg_buf { | |
| 75 | + struct ireg_field tp_pio; | |
| 76 | + u32 outbuf[32]; | |
| 77 | +}; | |
| 78 | + | |
| 79 | +struct cudbg_ulprx_la { | |
| 80 | + u32 data[ULPRX_LA_SIZE * 8]; | |
| 81 | + u32 size; | |
| 82 | +}; | |
| 83 | + | |
| 84 | +struct cudbg_tp_la { | |
| 85 | + u32 size; | |
| 86 | + u32 mode; | |
| 87 | + u8 data[0]; | |
| 88 | +}; | |
| 89 | + | |
| 90 | +struct cudbg_cim_pif_la { | |
| 91 | + int size; | |
| 92 | + u8 data[0]; | |
| 93 | +}; | |
| 94 | + | |
| 95 | +struct cudbg_clk_info { | |
| 96 | + u64 retransmit_min; | |
| 97 | + u64 retransmit_max; | |
| 98 | + u64 persist_timer_min; | |
| 99 | + u64 persist_timer_max; | |
| 100 | + u64 keepalive_idle_timer; | |
| 101 | + u64 keepalive_interval; | |
| 102 | + u64 initial_srtt; | |
| 103 | + u64 finwait2_timer; | |
| 104 | + u32 dack_timer; | |
| 105 | + u32 res; | |
| 106 | + u32 cclk_ps; | |
| 107 | + u32 tre; | |
| 108 | + u32 dack_re; | |
| 109 | +}; | |
| 110 | + | |
| 111 | +struct cudbg_tid_info_region { | |
| 112 | + u32 ntids; | |
| 113 | + u32 nstids; | |
| 114 | + u32 stid_base; | |
| 115 | + u32 hash_base; | |
| 116 | + | |
| 117 | + u32 natids; | |
| 118 | + u32 nftids; | |
| 119 | + u32 ftid_base; | |
| 120 | + u32 aftid_base; | |
| 121 | + u32 aftid_end; | |
| 122 | + | |
| 123 | + u32 sftid_base; | |
| 124 | + u32 nsftids; | |
| 125 | + | |
| 126 | + u32 uotid_base; | |
| 127 | + u32 nuotids; | |
| 128 | + | |
| 129 | + u32 sb; | |
| 130 | + u32 flags; | |
| 131 | + u32 le_db_conf; | |
| 132 | + u32 ip_users; | |
| 133 | + u32 ipv6_users; | |
| 134 | + | |
| 135 | + u32 hpftid_base; | |
| 136 | + u32 nhpftids; | |
| 137 | +}; | |
| 138 | + | |
| 139 | +#define CUDBG_TID_INFO_REV 1 | |
| 140 | + | |
| 141 | +struct cudbg_tid_info_region_rev1 { | |
| 142 | + struct cudbg_ver_hdr ver_hdr; | |
| 143 | + struct cudbg_tid_info_region tid; | |
| 144 | + u32 tid_start; | |
| 145 | + u32 reserved[16]; | |
| 146 | +}; | |
| 147 | + | |
| 148 | +#define CUDBG_MAX_FL_QIDS 1024 | |
| 149 | + | |
| 150 | +struct cudbg_ch_cntxt { | |
| 151 | + u32 cntxt_type; | |
| 152 | + u32 cntxt_id; | |
| 153 | + u32 data[SGE_CTXT_SIZE / 4]; | |
| 154 | +}; | |
| 155 | + | |
| 156 | +#define CUDBG_MAX_RPLC_SIZE 128 | |
| 157 | + | |
| 158 | +struct cudbg_mps_tcam { | |
| 159 | + u64 mask; | |
| 160 | + u32 rplc[8]; | |
| 161 | + u32 idx; | |
| 162 | + u32 cls_lo; | |
| 163 | + u32 cls_hi; | |
| 164 | + u32 rplc_size; | |
| 165 | + u32 vniy; | |
| 166 | + u32 vnix; | |
| 167 | + u32 dip_hit; | |
| 168 | + u32 vlan_vld; | |
| 169 | + u32 repli; | |
| 170 | + u16 ivlan; | |
| 171 | + u8 addr[ETH_ALEN]; | |
| 172 | + u8 lookup_type; | |
| 173 | + u8 port_num; | |
| 174 | + u8 reserved[2]; | |
| 175 | +}; | |
| 176 | + | |
| 177 | +#define CUDBG_VPD_PF_SIZE 0x800 | |
| 178 | +#define CUDBG_SCFG_VER_ADDR 0x06 | |
| 179 | +#define CUDBG_SCFG_VER_LEN 4 | |
| 180 | +#define CUDBG_VPD_VER_ADDR 0x18c7 | |
| 181 | +#define CUDBG_VPD_VER_LEN 2 | |
| 182 | + | |
| 183 | +struct cudbg_vpd_data { | |
| 184 | + u8 sn[SERNUM_LEN + 1]; | |
| 185 | + u8 bn[PN_LEN + 1]; | |
| 186 | + u8 na[MACADDR_LEN + 1]; | |
| 187 | + u8 mn[ID_LEN + 1]; | |
| 188 | + u16 fw_major; | |
| 189 | + u16 fw_minor; | |
| 190 | + u16 fw_micro; | |
| 191 | + u16 fw_build; | |
| 192 | + u32 scfg_vers; | |
| 193 | + u32 vpd_vers; | |
| 194 | +}; | |
| 195 | + | |
| 196 | +#define CUDBG_MAX_TCAM_TID 0x800 | |
| 197 | + | |
| 198 | +enum cudbg_le_entry_types { | |
| 199 | + LE_ET_UNKNOWN = 0, | |
| 200 | + LE_ET_TCAM_CON = 1, | |
| 201 | + LE_ET_TCAM_SERVER = 2, | |
| 202 | + LE_ET_TCAM_FILTER = 3, | |
| 203 | + LE_ET_TCAM_CLIP = 4, | |
| 204 | + LE_ET_TCAM_ROUTING = 5, | |
| 205 | + LE_ET_HASH_CON = 6, | |
| 206 | + LE_ET_INVALID_TID = 8, | |
| 207 | +}; | |
| 208 | + | |
| 209 | +struct cudbg_tcam { | |
| 210 | + u32 filter_start; | |
| 211 | + u32 server_start; | |
| 212 | + u32 clip_start; | |
| 213 | + u32 routing_start; | |
| 214 | + u32 tid_hash_base; | |
| 215 | + u32 max_tid; | |
| 216 | +}; | |
| 217 | + | |
| 218 | +struct cudbg_tid_data { | |
| 219 | + u32 tid; | |
| 220 | + u32 dbig_cmd; | |
| 221 | + u32 dbig_conf; | |
| 222 | + u32 dbig_rsp_stat; | |
| 223 | + u32 data[NUM_LE_DB_DBGI_RSP_DATA_INSTANCES]; | |
| 224 | +}; | |
| 225 | + | |
| 226 | +#define CUDBG_NUM_ULPTX 11 | |
| 227 | +#define CUDBG_NUM_ULPTX_READ 512 | |
| 228 | + | |
| 229 | +struct cudbg_ulptx_la { | |
| 230 | + u32 rdptr[CUDBG_NUM_ULPTX]; | |
| 231 | + u32 wrptr[CUDBG_NUM_ULPTX]; | |
| 232 | + u32 rddata[CUDBG_NUM_ULPTX]; | |
| 233 | + u32 rd_data[CUDBG_NUM_ULPTX][CUDBG_NUM_ULPTX_READ]; | |
| 234 | +}; | |
| 235 | + | |
| 236 | +#define CUDBG_CHAC_PBT_ADDR 0x2800 | |
| 237 | +#define CUDBG_CHAC_PBT_LRF 0x3000 | |
| 238 | +#define CUDBG_CHAC_PBT_DATA 0x3800 | |
| 239 | +#define CUDBG_PBT_DYNAMIC_ENTRIES 8 | |
| 240 | +#define CUDBG_PBT_STATIC_ENTRIES 16 | |
| 241 | +#define CUDBG_LRF_ENTRIES 8 | |
| 242 | +#define CUDBG_PBT_DATA_ENTRIES 512 | |
| 243 | + | |
| 244 | +struct cudbg_pbt_tables { | |
| 245 | + u32 pbt_dynamic[CUDBG_PBT_DYNAMIC_ENTRIES]; | |
| 246 | + u32 pbt_static[CUDBG_PBT_STATIC_ENTRIES]; | |
| 247 | + u32 lrf_table[CUDBG_LRF_ENTRIES]; | |
| 248 | + u32 pbt_data[CUDBG_PBT_DATA_ENTRIES]; | |
| 249 | +}; | |
| 250 | + | |
| 251 | +#define IREG_NUM_ELEM 4 | |
| 252 | + | |
| 253 | +static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = { | |
| 254 | + {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */ | |
| 255 | + {0x7e40, 0x7e44, 0x040, 10}, /* t6_tp_pio_regs_40_to_49 */ | |
| 256 | + {0x7e40, 0x7e44, 0x050, 10}, /* t6_tp_pio_regs_50_to_59 */ | |
| 257 | + {0x7e40, 0x7e44, 0x060, 14}, /* t6_tp_pio_regs_60_to_6d */ | |
| 258 | + {0x7e40, 0x7e44, 0x06F, 1}, /* t6_tp_pio_regs_6f */ | |
| 259 | + {0x7e40, 0x7e44, 0x070, 6}, /* t6_tp_pio_regs_70_to_75 */ | |
| 260 | + {0x7e40, 0x7e44, 0x130, 18}, /* t6_tp_pio_regs_130_to_141 */ | |
| 261 | + {0x7e40, 0x7e44, 0x145, 19}, /* t6_tp_pio_regs_145_to_157 */ | |
| 262 | + {0x7e40, 0x7e44, 0x160, 1}, /* t6_tp_pio_regs_160 */ | |
| 263 | + {0x7e40, 0x7e44, 0x230, 25}, /* t6_tp_pio_regs_230_to_248 */ | |
| 264 | + {0x7e40, 0x7e44, 0x24a, 3}, /* t6_tp_pio_regs_24c */ | |
| 265 | + {0x7e40, 0x7e44, 0x8C0, 1} /* t6_tp_pio_regs_8c0 */ | |
| 266 | +}; | |
| 267 | + | |
| 268 | +static const u32 t5_tp_pio_array[][IREG_NUM_ELEM] = { | |
| 269 | + {0x7e40, 0x7e44, 0x020, 28}, /* t5_tp_pio_regs_20_to_3b */ | |
| 270 | + {0x7e40, 0x7e44, 0x040, 19}, /* t5_tp_pio_regs_40_to_52 */ | |
| 271 | + {0x7e40, 0x7e44, 0x054, 2}, /* t5_tp_pio_regs_54_to_55 */ | |
| 272 | + {0x7e40, 0x7e44, 0x060, 13}, /* t5_tp_pio_regs_60_to_6c */ | |
| 273 | + {0x7e40, 0x7e44, 0x06F, 1}, /* t5_tp_pio_regs_6f */ | |
| 274 | + {0x7e40, 0x7e44, 0x120, 4}, /* t5_tp_pio_regs_120_to_123 */ | |
| 275 | + {0x7e40, 0x7e44, 0x12b, 2}, /* t5_tp_pio_regs_12b_to_12c */ | |
| 276 | + {0x7e40, 0x7e44, 0x12f, 21}, /* t5_tp_pio_regs_12f_to_143 */ | |
| 277 | + {0x7e40, 0x7e44, 0x145, 19}, /* t5_tp_pio_regs_145_to_157 */ | |
| 278 | + {0x7e40, 0x7e44, 0x230, 25}, /* t5_tp_pio_regs_230_to_248 */ | |
| 279 | + {0x7e40, 0x7e44, 0x8C0, 1} /* t5_tp_pio_regs_8c0 */ | |
| 280 | +}; | |
| 281 | + | |
| 282 | +static const u32 t6_tp_tm_pio_array[][IREG_NUM_ELEM] = { | |
| 283 | + {0x7e18, 0x7e1c, 0x0, 12} | |
| 284 | +}; | |
| 285 | + | |
| 286 | +static const u32 t5_tp_tm_pio_array[][IREG_NUM_ELEM] = { | |
| 287 | + {0x7e18, 0x7e1c, 0x0, 12} | |
| 288 | +}; | |
| 289 | + | |
| 290 | +static const u32 t6_tp_mib_index_array[6][IREG_NUM_ELEM] = { | |
| 291 | + {0x7e50, 0x7e54, 0x0, 13}, | |
| 292 | + {0x7e50, 0x7e54, 0x10, 6}, | |
| 293 | + {0x7e50, 0x7e54, 0x18, 21}, | |
| 294 | + {0x7e50, 0x7e54, 0x30, 32}, | |
| 295 | + {0x7e50, 0x7e54, 0x50, 22}, | |
| 296 | + {0x7e50, 0x7e54, 0x68, 12} | |
| 297 | +}; | |
| 298 | + | |
| 299 | +static const u32 t5_tp_mib_index_array[9][IREG_NUM_ELEM] = { | |
| 300 | + {0x7e50, 0x7e54, 0x0, 13}, | |
| 301 | + {0x7e50, 0x7e54, 0x10, 6}, | |
| 302 | + {0x7e50, 0x7e54, 0x18, 8}, | |
| 303 | + {0x7e50, 0x7e54, 0x20, 13}, | |
| 304 | + {0x7e50, 0x7e54, 0x30, 16}, | |
| 305 | + {0x7e50, 0x7e54, 0x40, 16}, | |
| 306 | + {0x7e50, 0x7e54, 0x50, 16}, | |
| 307 | + {0x7e50, 0x7e54, 0x60, 6}, | |
| 308 | + {0x7e50, 0x7e54, 0x68, 4} | |
| 309 | +}; | |
| 310 | + | |
| 311 | +static const u32 t5_sge_dbg_index_array[2][IREG_NUM_ELEM] = { | |
| 312 | + {0x10cc, 0x10d0, 0x0, 16}, | |
| 313 | + {0x10cc, 0x10d4, 0x0, 16}, | |
| 314 | +}; | |
| 315 | + | |
| 316 | +static const u32 t5_pcie_pdbg_array[][IREG_NUM_ELEM] = { | |
| 317 | + {0x5a04, 0x5a0c, 0x00, 0x20}, /* t5_pcie_pdbg_regs_00_to_20 */ | |
| 318 | + {0x5a04, 0x5a0c, 0x21, 0x20}, /* t5_pcie_pdbg_regs_21_to_40 */ | |
| 319 | + {0x5a04, 0x5a0c, 0x41, 0x10}, /* t5_pcie_pdbg_regs_41_to_50 */ | |
| 320 | +}; | |
| 321 | + | |
| 322 | +static const u32 t5_pcie_cdbg_array[][IREG_NUM_ELEM] = { | |
| 323 | + {0x5a10, 0x5a18, 0x00, 0x20}, /* t5_pcie_cdbg_regs_00_to_20 */ | |
| 324 | + {0x5a10, 0x5a18, 0x21, 0x18}, /* t5_pcie_cdbg_regs_21_to_37 */ | |
| 325 | +}; | |
| 326 | + | |
| 327 | +static const u32 t5_pm_rx_array[][IREG_NUM_ELEM] = { | |
| 328 | + {0x8FD0, 0x8FD4, 0x10000, 0x20}, /* t5_pm_rx_regs_10000_to_10020 */ | |
| 329 | + {0x8FD0, 0x8FD4, 0x10021, 0x0D}, /* t5_pm_rx_regs_10021_to_1002c */ | |
| 330 | +}; | |
| 331 | + | |
| 332 | +static const u32 t5_pm_tx_array[][IREG_NUM_ELEM] = { | |
| 333 | + {0x8FF0, 0x8FF4, 0x10000, 0x20}, /* t5_pm_tx_regs_10000_to_10020 */ | |
| 334 | + {0x8FF0, 0x8FF4, 0x10021, 0x1D}, /* t5_pm_tx_regs_10021_to_1003c */ | |
| 335 | +}; | |
| 336 | + | |
| 337 | +static const u32 t6_ma_ireg_array[][IREG_NUM_ELEM] = { | |
| 338 | + {0x78f8, 0x78fc, 0xa000, 23}, /* t6_ma_regs_a000_to_a016 */ | |
| 339 | + {0x78f8, 0x78fc, 0xa400, 30}, /* t6_ma_regs_a400_to_a41e */ | |
| 340 | + {0x78f8, 0x78fc, 0xa800, 20} /* t6_ma_regs_a800_to_a813 */ | |
| 341 | +}; | |
| 342 | + | |
| 343 | +static const u32 t6_ma_ireg_array2[][IREG_NUM_ELEM] = { | |
| 344 | + {0x78f8, 0x78fc, 0xe400, 17}, /* t6_ma_regs_e400_to_e600 */ | |
| 345 | + {0x78f8, 0x78fc, 0xe640, 13} /* t6_ma_regs_e640_to_e7c0 */ | |
| 346 | +}; | |
| 347 | + | |
| 348 | +static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM] = { | |
| 349 | + {0x7b50, 0x7b54, 0x2000, 0x20}, /* up_cim_2000_to_207c */ | |
| 350 | + {0x7b50, 0x7b54, 0x2080, 0x1d}, /* up_cim_2080_to_20fc */ | |
| 351 | + {0x7b50, 0x7b54, 0x00, 0x20}, /* up_cim_00_to_7c */ | |
| 352 | + {0x7b50, 0x7b54, 0x80, 0x20}, /* up_cim_80_to_fc */ | |
| 353 | + {0x7b50, 0x7b54, 0x100, 0x11}, /* up_cim_100_to_14c */ | |
| 354 | + {0x7b50, 0x7b54, 0x200, 0x10}, /* up_cim_200_to_23c */ | |
| 355 | + {0x7b50, 0x7b54, 0x240, 0x2}, /* up_cim_240_to_244 */ | |
| 356 | + {0x7b50, 0x7b54, 0x250, 0x2}, /* up_cim_250_to_254 */ | |
| 357 | + {0x7b50, 0x7b54, 0x260, 0x2}, /* up_cim_260_to_264 */ | |
| 358 | + {0x7b50, 0x7b54, 0x270, 0x2}, /* up_cim_270_to_274 */ | |
| 359 | + {0x7b50, 0x7b54, 0x280, 0x20}, /* up_cim_280_to_2fc */ | |
| 360 | + {0x7b50, 0x7b54, 0x300, 0x20}, /* up_cim_300_to_37c */ | |
| 361 | + {0x7b50, 0x7b54, 0x380, 0x14}, /* up_cim_380_to_3cc */ | |
| 362 | + | |
| 363 | +}; | |
| 364 | + | |
| 365 | +static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM] = { | |
| 366 | + {0x7b50, 0x7b54, 0x2000, 0x20}, /* up_cim_2000_to_207c */ | |
| 367 | + {0x7b50, 0x7b54, 0x2080, 0x19}, /* up_cim_2080_to_20ec */ | |
| 368 | + {0x7b50, 0x7b54, 0x00, 0x20}, /* up_cim_00_to_7c */ | |
| 369 | + {0x7b50, 0x7b54, 0x80, 0x20}, /* up_cim_80_to_fc */ | |
| 370 | + {0x7b50, 0x7b54, 0x100, 0x11}, /* up_cim_100_to_14c */ | |
| 371 | + {0x7b50, 0x7b54, 0x200, 0x10}, /* up_cim_200_to_23c */ | |
| 372 | + {0x7b50, 0x7b54, 0x240, 0x2}, /* up_cim_240_to_244 */ | |
| 373 | + {0x7b50, 0x7b54, 0x250, 0x2}, /* up_cim_250_to_254 */ | |
| 374 | + {0x7b50, 0x7b54, 0x260, 0x2}, /* up_cim_260_to_264 */ | |
| 375 | + {0x7b50, 0x7b54, 0x270, 0x2}, /* up_cim_270_to_274 */ | |
| 376 | + {0x7b50, 0x7b54, 0x280, 0x20}, /* up_cim_280_to_2fc */ | |
| 377 | + {0x7b50, 0x7b54, 0x300, 0x20}, /* up_cim_300_to_37c */ | |
| 378 | + {0x7b50, 0x7b54, 0x380, 0x14}, /* up_cim_380_to_3cc */ | |
| 379 | +}; | |
| 380 | + | |
| 381 | +static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = { | |
| 382 | + {0x51320, 0x51324, 0xa000, 32} /* t6_hma_regs_a000_to_a01f */ | |
| 383 | +}; | |
| 384 | +#endif /* __CUDBG_ENTITY_H__ */ | |
| @@ -0,0 +1,90 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2017 Chelsio Communications. All rights reserved. | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify it | |
| 5 | + * under the terms and conditions of the GNU General Public License, | |
| 6 | + * version 2, as published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 9 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 10 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 11 | + * more details. | |
| 12 | + * | |
| 13 | + * The full GNU General Public License is included in this distribution in | |
| 14 | + * the file called "COPYING". | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#ifndef __CUDBG_IF_H__ | |
| 19 | +#define __CUDBG_IF_H__ | |
| 20 | + | |
| 21 | +/* Error codes */ | |
| 22 | +#define CUDBG_STATUS_NO_MEM -19 | |
| 23 | +#define CUDBG_STATUS_ENTITY_NOT_FOUND -24 | |
| 24 | +#define CUDBG_SYSTEM_ERROR -29 | |
| 25 | +#define CUDBG_STATUS_CCLK_NOT_DEFINED -32 | |
| 26 | + | |
| 27 | +#define CUDBG_MAJOR_VERSION 1 | |
| 28 | +#define CUDBG_MINOR_VERSION 14 | |
| 29 | + | |
| 30 | +enum cudbg_dbg_entity_type { | |
| 31 | + CUDBG_REG_DUMP = 1, | |
| 32 | + CUDBG_DEV_LOG = 2, | |
| 33 | + CUDBG_CIM_LA = 3, | |
| 34 | + CUDBG_CIM_MA_LA = 4, | |
| 35 | + CUDBG_CIM_QCFG = 5, | |
| 36 | + CUDBG_CIM_IBQ_TP0 = 6, | |
| 37 | + CUDBG_CIM_IBQ_TP1 = 7, | |
| 38 | + CUDBG_CIM_IBQ_ULP = 8, | |
| 39 | + CUDBG_CIM_IBQ_SGE0 = 9, | |
| 40 | + CUDBG_CIM_IBQ_SGE1 = 10, | |
| 41 | + CUDBG_CIM_IBQ_NCSI = 11, | |
| 42 | + CUDBG_CIM_OBQ_ULP0 = 12, | |
| 43 | + CUDBG_CIM_OBQ_ULP1 = 13, | |
| 44 | + CUDBG_CIM_OBQ_ULP2 = 14, | |
| 45 | + CUDBG_CIM_OBQ_ULP3 = 15, | |
| 46 | + CUDBG_CIM_OBQ_SGE = 16, | |
| 47 | + CUDBG_CIM_OBQ_NCSI = 17, | |
| 48 | + CUDBG_EDC0 = 18, | |
| 49 | + CUDBG_EDC1 = 19, | |
| 50 | + CUDBG_RSS = 22, | |
| 51 | + CUDBG_RSS_VF_CONF = 25, | |
| 52 | + CUDBG_PATH_MTU = 27, | |
| 53 | + CUDBG_PM_STATS = 30, | |
| 54 | + CUDBG_HW_SCHED = 31, | |
| 55 | + CUDBG_TP_INDIRECT = 36, | |
| 56 | + CUDBG_SGE_INDIRECT = 37, | |
| 57 | + CUDBG_ULPRX_LA = 41, | |
| 58 | + CUDBG_TP_LA = 43, | |
| 59 | + CUDBG_CIM_PIF_LA = 45, | |
| 60 | + CUDBG_CLK = 46, | |
| 61 | + CUDBG_CIM_OBQ_RXQ0 = 47, | |
| 62 | + CUDBG_CIM_OBQ_RXQ1 = 48, | |
| 63 | + CUDBG_PCIE_INDIRECT = 50, | |
| 64 | + CUDBG_PM_INDIRECT = 51, | |
| 65 | + CUDBG_TID_INFO = 54, | |
| 66 | + CUDBG_DUMP_CONTEXT = 56, | |
| 67 | + CUDBG_MPS_TCAM = 57, | |
| 68 | + CUDBG_VPD_DATA = 58, | |
| 69 | + CUDBG_LE_TCAM = 59, | |
| 70 | + CUDBG_CCTRL = 60, | |
| 71 | + CUDBG_MA_INDIRECT = 61, | |
| 72 | + CUDBG_ULPTX_LA = 62, | |
| 73 | + CUDBG_UP_CIM_INDIRECT = 64, | |
| 74 | + CUDBG_PBT_TABLE = 65, | |
| 75 | + CUDBG_MBOX_LOG = 66, | |
| 76 | + CUDBG_HMA_INDIRECT = 67, | |
| 77 | + CUDBG_MAX_ENTITY = 70, | |
| 78 | +}; | |
| 79 | + | |
| 80 | +struct cudbg_init { | |
| 81 | + struct adapter *adap; /* Pointer to adapter structure */ | |
| 82 | + void *outbuf; /* Output buffer */ | |
| 83 | + u32 outbuf_size; /* Output buffer size */ | |
| 84 | +}; | |
| 85 | + | |
| 86 | +static inline unsigned int cudbg_mbytes_to_bytes(unsigned int size) | |
| 87 | +{ | |
| 88 | + return size * 1024 * 1024; | |
| 89 | +} | |
| 90 | +#endif /* __CUDBG_IF_H__ */ | |
| @@ -0,0 +1,1929 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2017 Chelsio Communications. All rights reserved. | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify it | |
| 5 | + * under the terms and conditions of the GNU General Public License, | |
| 6 | + * version 2, as published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * This program is distributed in the hope it will be useful, but WITHOUT | |
| 9 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 10 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 11 | + * more details. | |
| 12 | + * | |
| 13 | + * The full GNU General Public License is included in this distribution in | |
| 14 | + * the file called "COPYING". | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include "t4_regs.h" | |
| 19 | +#include "cxgb4.h" | |
| 20 | +#include "cudbg_if.h" | |
| 21 | +#include "cudbg_lib_common.h" | |
| 22 | +#include "cudbg_lib.h" | |
| 23 | +#include "cudbg_entity.h" | |
| 24 | + | |
| 25 | +static void cudbg_write_and_release_buff(struct cudbg_buffer *pin_buff, | |
| 26 | + struct cudbg_buffer *dbg_buff) | |
| 27 | +{ | |
| 28 | + cudbg_update_buff(pin_buff, dbg_buff); | |
| 29 | + cudbg_put_buff(pin_buff, dbg_buff); | |
| 30 | +} | |
| 31 | + | |
| 32 | +static int is_fw_attached(struct cudbg_init *pdbg_init) | |
| 33 | +{ | |
| 34 | + struct adapter *padap = pdbg_init->adap; | |
| 35 | + | |
| 36 | + if (!(padap->flags & FW_OK) || padap->use_bd) | |
| 37 | + return 0; | |
| 38 | + | |
| 39 | + return 1; | |
| 40 | +} | |
| 41 | + | |
| 42 | +/* This function will add additional padding bytes into debug_buffer to make it | |
| 43 | + * 4 byte aligned. | |
| 44 | + */ | |
| 45 | +void cudbg_align_debug_buffer(struct cudbg_buffer *dbg_buff, | |
| 46 | + struct cudbg_entity_hdr *entity_hdr) | |
| 47 | +{ | |
| 48 | + u8 zero_buf[4] = {0}; | |
| 49 | + u8 padding, remain; | |
| 50 | + | |
| 51 | + remain = (dbg_buff->offset - entity_hdr->start_offset) % 4; | |
| 52 | + padding = 4 - remain; | |
| 53 | + if (remain) { | |
| 54 | + memcpy(((u8 *)dbg_buff->data) + dbg_buff->offset, &zero_buf, | |
| 55 | + padding); | |
| 56 | + dbg_buff->offset += padding; | |
| 57 | + entity_hdr->num_pad = padding; | |
| 58 | + } | |
| 59 | + entity_hdr->size = dbg_buff->offset - entity_hdr->start_offset; | |
| 60 | +} | |
| 61 | + | |
| 62 | +struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i) | |
| 63 | +{ | |
| 64 | + struct cudbg_hdr *cudbg_hdr = (struct cudbg_hdr *)outbuf; | |
| 65 | + | |
| 66 | + return (struct cudbg_entity_hdr *) | |
| 67 | + ((char *)outbuf + cudbg_hdr->hdr_len + | |
| 68 | + (sizeof(struct cudbg_entity_hdr) * (i - 1))); | |
| 69 | +} | |
| 70 | + | |
| 71 | +static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len, | |
| 72 | + void *dest) | |
| 73 | +{ | |
| 74 | + int vaddr, rc; | |
| 75 | + | |
| 76 | + vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE); | |
| 77 | + if (vaddr < 0) | |
| 78 | + return vaddr; | |
| 79 | + | |
| 80 | + rc = pci_read_vpd(padap->pdev, vaddr, len, dest); | |
| 81 | + if (rc < 0) | |
| 82 | + return rc; | |
| 83 | + | |
| 84 | + return 0; | |
| 85 | +} | |
| 86 | + | |
| 87 | +int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init, | |
| 88 | + struct cudbg_buffer *dbg_buff, | |
| 89 | + struct cudbg_error *cudbg_err) | |
| 90 | +{ | |
| 91 | + struct adapter *padap = pdbg_init->adap; | |
| 92 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 93 | + u32 buf_size = 0; | |
| 94 | + int rc = 0; | |
| 95 | + | |
| 96 | + if (is_t4(padap->params.chip)) | |
| 97 | + buf_size = T4_REGMAP_SIZE; | |
| 98 | + else if (is_t5(padap->params.chip) || is_t6(padap->params.chip)) | |
| 99 | + buf_size = T5_REGMAP_SIZE; | |
| 100 | + | |
| 101 | + rc = cudbg_get_buff(dbg_buff, buf_size, &temp_buff); | |
| 102 | + if (rc) | |
| 103 | + return rc; | |
| 104 | + t4_get_regs(padap, (void *)temp_buff.data, temp_buff.size); | |
| 105 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 106 | + return rc; | |
| 107 | +} | |
| 108 | + | |
| 109 | +int cudbg_collect_fw_devlog(struct cudbg_init *pdbg_init, | |
| 110 | + struct cudbg_buffer *dbg_buff, | |
| 111 | + struct cudbg_error *cudbg_err) | |
| 112 | +{ | |
| 113 | + struct adapter *padap = pdbg_init->adap; | |
| 114 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 115 | + struct devlog_params *dparams; | |
| 116 | + int rc = 0; | |
| 117 | + | |
| 118 | + rc = t4_init_devlog_params(padap); | |
| 119 | + if (rc < 0) { | |
| 120 | + cudbg_err->sys_err = rc; | |
| 121 | + return rc; | |
| 122 | + } | |
| 123 | + | |
| 124 | + dparams = &padap->params.devlog; | |
| 125 | + rc = cudbg_get_buff(dbg_buff, dparams->size, &temp_buff); | |
| 126 | + if (rc) | |
| 127 | + return rc; | |
| 128 | + | |
| 129 | + /* Collect FW devlog */ | |
| 130 | + if (dparams->start != 0) { | |
| 131 | + spin_lock(&padap->win0_lock); | |
| 132 | + rc = t4_memory_rw(padap, padap->params.drv_memwin, | |
| 133 | + dparams->memtype, dparams->start, | |
| 134 | + dparams->size, | |
| 135 | + (__be32 *)(char *)temp_buff.data, | |
| 136 | + 1); | |
| 137 | + spin_unlock(&padap->win0_lock); | |
| 138 | + if (rc) { | |
| 139 | + cudbg_err->sys_err = rc; | |
| 140 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 141 | + return rc; | |
| 142 | + } | |
| 143 | + } | |
| 144 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 145 | + return rc; | |
| 146 | +} | |
| 147 | + | |
| 148 | +int cudbg_collect_cim_la(struct cudbg_init *pdbg_init, | |
| 149 | + struct cudbg_buffer *dbg_buff, | |
| 150 | + struct cudbg_error *cudbg_err) | |
| 151 | +{ | |
| 152 | + struct adapter *padap = pdbg_init->adap; | |
| 153 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 154 | + int size, rc; | |
| 155 | + u32 cfg = 0; | |
| 156 | + | |
| 157 | + if (is_t6(padap->params.chip)) { | |
| 158 | + size = padap->params.cim_la_size / 10 + 1; | |
| 159 | + size *= 11 * sizeof(u32); | |
| 160 | + } else { | |
| 161 | + size = padap->params.cim_la_size / 8; | |
| 162 | + size *= 8 * sizeof(u32); | |
| 163 | + } | |
| 164 | + | |
| 165 | + size += sizeof(cfg); | |
| 166 | + rc = cudbg_get_buff(dbg_buff, size, &temp_buff); | |
| 167 | + if (rc) | |
| 168 | + return rc; | |
| 169 | + | |
| 170 | + rc = t4_cim_read(padap, UP_UP_DBG_LA_CFG_A, 1, &cfg); | |
| 171 | + if (rc) { | |
| 172 | + cudbg_err->sys_err = rc; | |
| 173 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 174 | + return rc; | |
| 175 | + } | |
| 176 | + | |
| 177 | + memcpy((char *)temp_buff.data, &cfg, sizeof(cfg)); | |
| 178 | + rc = t4_cim_read_la(padap, | |
| 179 | + (u32 *)((char *)temp_buff.data + sizeof(cfg)), | |
| 180 | + NULL); | |
| 181 | + if (rc < 0) { | |
| 182 | + cudbg_err->sys_err = rc; | |
| 183 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 184 | + return rc; | |
| 185 | + } | |
| 186 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 187 | + return rc; | |
| 188 | +} | |
| 189 | + | |
| 190 | +int cudbg_collect_cim_ma_la(struct cudbg_init *pdbg_init, | |
| 191 | + struct cudbg_buffer *dbg_buff, | |
| 192 | + struct cudbg_error *cudbg_err) | |
| 193 | +{ | |
| 194 | + struct adapter *padap = pdbg_init->adap; | |
| 195 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 196 | + int size, rc; | |
| 197 | + | |
| 198 | + size = 2 * CIM_MALA_SIZE * 5 * sizeof(u32); | |
| 199 | + rc = cudbg_get_buff(dbg_buff, size, &temp_buff); | |
| 200 | + if (rc) | |
| 201 | + return rc; | |
| 202 | + | |
| 203 | + t4_cim_read_ma_la(padap, | |
| 204 | + (u32 *)temp_buff.data, | |
| 205 | + (u32 *)((char *)temp_buff.data + | |
| 206 | + 5 * CIM_MALA_SIZE)); | |
| 207 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 208 | + return rc; | |
| 209 | +} | |
| 210 | + | |
| 211 | +int cudbg_collect_cim_qcfg(struct cudbg_init *pdbg_init, | |
| 212 | + struct cudbg_buffer *dbg_buff, | |
| 213 | + struct cudbg_error *cudbg_err) | |
| 214 | +{ | |
| 215 | + struct adapter *padap = pdbg_init->adap; | |
| 216 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 217 | + struct cudbg_cim_qcfg *cim_qcfg_data; | |
| 218 | + int rc; | |
| 219 | + | |
| 220 | + rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_cim_qcfg), | |
| 221 | + &temp_buff); | |
| 222 | + if (rc) | |
| 223 | + return rc; | |
| 224 | + | |
| 225 | + cim_qcfg_data = (struct cudbg_cim_qcfg *)temp_buff.data; | |
| 226 | + cim_qcfg_data->chip = padap->params.chip; | |
| 227 | + rc = t4_cim_read(padap, UP_IBQ_0_RDADDR_A, | |
| 228 | + ARRAY_SIZE(cim_qcfg_data->stat), cim_qcfg_data->stat); | |
| 229 | + if (rc) { | |
| 230 | + cudbg_err->sys_err = rc; | |
| 231 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 232 | + return rc; | |
| 233 | + } | |
| 234 | + | |
| 235 | + rc = t4_cim_read(padap, UP_OBQ_0_REALADDR_A, | |
| 236 | + ARRAY_SIZE(cim_qcfg_data->obq_wr), | |
| 237 | + cim_qcfg_data->obq_wr); | |
| 238 | + if (rc) { | |
| 239 | + cudbg_err->sys_err = rc; | |
| 240 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 241 | + return rc; | |
| 242 | + } | |
| 243 | + | |
| 244 | + t4_read_cimq_cfg(padap, cim_qcfg_data->base, cim_qcfg_data->size, | |
| 245 | + cim_qcfg_data->thres); | |
| 246 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 247 | + return rc; | |
| 248 | +} | |
| 249 | + | |
| 250 | +static int cudbg_read_cim_ibq(struct cudbg_init *pdbg_init, | |
| 251 | + struct cudbg_buffer *dbg_buff, | |
| 252 | + struct cudbg_error *cudbg_err, int qid) | |
| 253 | +{ | |
| 254 | + struct adapter *padap = pdbg_init->adap; | |
| 255 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 256 | + int no_of_read_words, rc = 0; | |
| 257 | + u32 qsize; | |
| 258 | + | |
| 259 | + /* collect CIM IBQ */ | |
| 260 | + qsize = CIM_IBQ_SIZE * 4 * sizeof(u32); | |
| 261 | + rc = cudbg_get_buff(dbg_buff, qsize, &temp_buff); | |
| 262 | + if (rc) | |
| 263 | + return rc; | |
| 264 | + | |
| 265 | + /* t4_read_cim_ibq will return no. of read words or error */ | |
| 266 | + no_of_read_words = t4_read_cim_ibq(padap, qid, | |
| 267 | + (u32 *)temp_buff.data, qsize); | |
| 268 | + /* no_of_read_words is less than or equal to 0 means error */ | |
| 269 | + if (no_of_read_words <= 0) { | |
| 270 | + if (!no_of_read_words) | |
| 271 | + rc = CUDBG_SYSTEM_ERROR; | |
| 272 | + else | |
| 273 | + rc = no_of_read_words; | |
| 274 | + cudbg_err->sys_err = rc; | |
| 275 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 276 | + return rc; | |
| 277 | + } | |
| 278 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 279 | + return rc; | |
| 280 | +} | |
| 281 | + | |
| 282 | +int cudbg_collect_cim_ibq_tp0(struct cudbg_init *pdbg_init, | |
| 283 | + struct cudbg_buffer *dbg_buff, | |
| 284 | + struct cudbg_error *cudbg_err) | |
| 285 | +{ | |
| 286 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 0); | |
| 287 | +} | |
| 288 | + | |
| 289 | +int cudbg_collect_cim_ibq_tp1(struct cudbg_init *pdbg_init, | |
| 290 | + struct cudbg_buffer *dbg_buff, | |
| 291 | + struct cudbg_error *cudbg_err) | |
| 292 | +{ | |
| 293 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 1); | |
| 294 | +} | |
| 295 | + | |
| 296 | +int cudbg_collect_cim_ibq_ulp(struct cudbg_init *pdbg_init, | |
| 297 | + struct cudbg_buffer *dbg_buff, | |
| 298 | + struct cudbg_error *cudbg_err) | |
| 299 | +{ | |
| 300 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 2); | |
| 301 | +} | |
| 302 | + | |
| 303 | +int cudbg_collect_cim_ibq_sge0(struct cudbg_init *pdbg_init, | |
| 304 | + struct cudbg_buffer *dbg_buff, | |
| 305 | + struct cudbg_error *cudbg_err) | |
| 306 | +{ | |
| 307 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 3); | |
| 308 | +} | |
| 309 | + | |
| 310 | +int cudbg_collect_cim_ibq_sge1(struct cudbg_init *pdbg_init, | |
| 311 | + struct cudbg_buffer *dbg_buff, | |
| 312 | + struct cudbg_error *cudbg_err) | |
| 313 | +{ | |
| 314 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 4); | |
| 315 | +} | |
| 316 | + | |
| 317 | +int cudbg_collect_cim_ibq_ncsi(struct cudbg_init *pdbg_init, | |
| 318 | + struct cudbg_buffer *dbg_buff, | |
| 319 | + struct cudbg_error *cudbg_err) | |
| 320 | +{ | |
| 321 | + return cudbg_read_cim_ibq(pdbg_init, dbg_buff, cudbg_err, 5); | |
| 322 | +} | |
| 323 | + | |
| 324 | +u32 cudbg_cim_obq_size(struct adapter *padap, int qid) | |
| 325 | +{ | |
| 326 | + u32 value; | |
| 327 | + | |
| 328 | + t4_write_reg(padap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F | | |
| 329 | + QUENUMSELECT_V(qid)); | |
| 330 | + value = t4_read_reg(padap, CIM_QUEUE_CONFIG_CTRL_A); | |
| 331 | + value = CIMQSIZE_G(value) * 64; /* size in number of words */ | |
| 332 | + return value * sizeof(u32); | |
| 333 | +} | |
| 334 | + | |
| 335 | +static int cudbg_read_cim_obq(struct cudbg_init *pdbg_init, | |
| 336 | + struct cudbg_buffer *dbg_buff, | |
| 337 | + struct cudbg_error *cudbg_err, int qid) | |
| 338 | +{ | |
| 339 | + struct adapter *padap = pdbg_init->adap; | |
| 340 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 341 | + int no_of_read_words, rc = 0; | |
| 342 | + u32 qsize; | |
| 343 | + | |
| 344 | + /* collect CIM OBQ */ | |
| 345 | + qsize = cudbg_cim_obq_size(padap, qid); | |
| 346 | + rc = cudbg_get_buff(dbg_buff, qsize, &temp_buff); | |
| 347 | + if (rc) | |
| 348 | + return rc; | |
| 349 | + | |
| 350 | + /* t4_read_cim_obq will return no. of read words or error */ | |
| 351 | + no_of_read_words = t4_read_cim_obq(padap, qid, | |
| 352 | + (u32 *)temp_buff.data, qsize); | |
| 353 | + /* no_of_read_words is less than or equal to 0 means error */ | |
| 354 | + if (no_of_read_words <= 0) { | |
| 355 | + if (!no_of_read_words) | |
| 356 | + rc = CUDBG_SYSTEM_ERROR; | |
| 357 | + else | |
| 358 | + rc = no_of_read_words; | |
| 359 | + cudbg_err->sys_err = rc; | |
| 360 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 361 | + return rc; | |
| 362 | + } | |
| 363 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 364 | + return rc; | |
| 365 | +} | |
| 366 | + | |
| 367 | +int cudbg_collect_cim_obq_ulp0(struct cudbg_init *pdbg_init, | |
| 368 | + struct cudbg_buffer *dbg_buff, | |
| 369 | + struct cudbg_error *cudbg_err) | |
| 370 | +{ | |
| 371 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 0); | |
| 372 | +} | |
| 373 | + | |
| 374 | +int cudbg_collect_cim_obq_ulp1(struct cudbg_init *pdbg_init, | |
| 375 | + struct cudbg_buffer *dbg_buff, | |
| 376 | + struct cudbg_error *cudbg_err) | |
| 377 | +{ | |
| 378 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 1); | |
| 379 | +} | |
| 380 | + | |
| 381 | +int cudbg_collect_cim_obq_ulp2(struct cudbg_init *pdbg_init, | |
| 382 | + struct cudbg_buffer *dbg_buff, | |
| 383 | + struct cudbg_error *cudbg_err) | |
| 384 | +{ | |
| 385 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 2); | |
| 386 | +} | |
| 387 | + | |
| 388 | +int cudbg_collect_cim_obq_ulp3(struct cudbg_init *pdbg_init, | |
| 389 | + struct cudbg_buffer *dbg_buff, | |
| 390 | + struct cudbg_error *cudbg_err) | |
| 391 | +{ | |
| 392 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 3); | |
| 393 | +} | |
| 394 | + | |
| 395 | +int cudbg_collect_cim_obq_sge(struct cudbg_init *pdbg_init, | |
| 396 | + struct cudbg_buffer *dbg_buff, | |
| 397 | + struct cudbg_error *cudbg_err) | |
| 398 | +{ | |
| 399 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 4); | |
| 400 | +} | |
| 401 | + | |
| 402 | +int cudbg_collect_cim_obq_ncsi(struct cudbg_init *pdbg_init, | |
| 403 | + struct cudbg_buffer *dbg_buff, | |
| 404 | + struct cudbg_error *cudbg_err) | |
| 405 | +{ | |
| 406 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 5); | |
| 407 | +} | |
| 408 | + | |
| 409 | +int cudbg_collect_obq_sge_rx_q0(struct cudbg_init *pdbg_init, | |
| 410 | + struct cudbg_buffer *dbg_buff, | |
| 411 | + struct cudbg_error *cudbg_err) | |
| 412 | +{ | |
| 413 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 6); | |
| 414 | +} | |
| 415 | + | |
| 416 | +int cudbg_collect_obq_sge_rx_q1(struct cudbg_init *pdbg_init, | |
| 417 | + struct cudbg_buffer *dbg_buff, | |
| 418 | + struct cudbg_error *cudbg_err) | |
| 419 | +{ | |
| 420 | + return cudbg_read_cim_obq(pdbg_init, dbg_buff, cudbg_err, 7); | |
| 421 | +} | |
| 422 | + | |
| 423 | +static int cudbg_read_fw_mem(struct cudbg_init *pdbg_init, | |
| 424 | + struct cudbg_buffer *dbg_buff, u8 mem_type, | |
| 425 | + unsigned long tot_len, | |
| 426 | + struct cudbg_error *cudbg_err) | |
| 427 | +{ | |
| 428 | + unsigned long bytes, bytes_left, bytes_read = 0; | |
| 429 | + struct adapter *padap = pdbg_init->adap; | |
| 430 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 431 | + int rc = 0; | |
| 432 | + | |
| 433 | + bytes_left = tot_len; | |
| 434 | + while (bytes_left > 0) { | |
| 435 | + bytes = min_t(unsigned long, bytes_left, | |
| 436 | + (unsigned long)CUDBG_CHUNK_SIZE); | |
| 437 | + rc = cudbg_get_buff(dbg_buff, bytes, &temp_buff); | |
| 438 | + if (rc) | |
| 439 | + return rc; | |
| 440 | + spin_lock(&padap->win0_lock); | |
| 441 | + rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type, | |
| 442 | + bytes_read, bytes, | |
| 443 | + (__be32 *)temp_buff.data, | |
| 444 | + 1); | |
| 445 | + spin_unlock(&padap->win0_lock); | |
| 446 | + if (rc) { | |
| 447 | + cudbg_err->sys_err = rc; | |
| 448 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 449 | + return rc; | |
| 450 | + } | |
| 451 | + bytes_left -= bytes; | |
| 452 | + bytes_read += bytes; | |
| 453 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 454 | + } | |
| 455 | + return rc; | |
| 456 | +} | |
| 457 | + | |
| 458 | +static void cudbg_collect_mem_info(struct cudbg_init *pdbg_init, | |
| 459 | + struct card_mem *mem_info) | |
| 460 | +{ | |
| 461 | + struct adapter *padap = pdbg_init->adap; | |
| 462 | + u32 value; | |
| 463 | + | |
| 464 | + value = t4_read_reg(padap, MA_EDRAM0_BAR_A); | |
| 465 | + value = EDRAM0_SIZE_G(value); | |
| 466 | + mem_info->size_edc0 = (u16)value; | |
| 467 | + | |
| 468 | + value = t4_read_reg(padap, MA_EDRAM1_BAR_A); | |
| 469 | + value = EDRAM1_SIZE_G(value); | |
| 470 | + mem_info->size_edc1 = (u16)value; | |
| 471 | + | |
| 472 | + value = t4_read_reg(padap, MA_TARGET_MEM_ENABLE_A); | |
| 473 | + if (value & EDRAM0_ENABLE_F) | |
| 474 | + mem_info->mem_flag |= (1 << EDC0_FLAG); | |
| 475 | + if (value & EDRAM1_ENABLE_F) | |
| 476 | + mem_info->mem_flag |= (1 << EDC1_FLAG); | |
| 477 | +} | |
| 478 | + | |
| 479 | +static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init, | |
| 480 | + struct cudbg_error *cudbg_err) | |
| 481 | +{ | |
| 482 | + struct adapter *padap = pdbg_init->adap; | |
| 483 | + int rc; | |
| 484 | + | |
| 485 | + if (is_fw_attached(pdbg_init)) { | |
| 486 | + /* Flush uP dcache before reading edcX/mcX */ | |
| 487 | + rc = t4_fwcache(padap, FW_PARAM_DEV_FWCACHE_FLUSH); | |
| 488 | + if (rc) | |
| 489 | + cudbg_err->sys_warn = rc; | |
| 490 | + } | |
| 491 | +} | |
| 492 | + | |
| 493 | +static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, | |
| 494 | + struct cudbg_buffer *dbg_buff, | |
| 495 | + struct cudbg_error *cudbg_err, | |
| 496 | + u8 mem_type) | |
| 497 | +{ | |
| 498 | + struct card_mem mem_info = {0}; | |
| 499 | + unsigned long flag, size; | |
| 500 | + int rc; | |
| 501 | + | |
| 502 | + cudbg_t4_fwcache(pdbg_init, cudbg_err); | |
| 503 | + cudbg_collect_mem_info(pdbg_init, &mem_info); | |
| 504 | + switch (mem_type) { | |
| 505 | + case MEM_EDC0: | |
| 506 | + flag = (1 << EDC0_FLAG); | |
| 507 | + size = cudbg_mbytes_to_bytes(mem_info.size_edc0); | |
| 508 | + break; | |
| 509 | + case MEM_EDC1: | |
| 510 | + flag = (1 << EDC1_FLAG); | |
| 511 | + size = cudbg_mbytes_to_bytes(mem_info.size_edc1); | |
| 512 | + break; | |
| 513 | + default: | |
| 514 | + rc = CUDBG_STATUS_ENTITY_NOT_FOUND; | |
| 515 | + goto err; | |
| 516 | + } | |
| 517 | + | |
| 518 | + if (mem_info.mem_flag & flag) { | |
| 519 | + rc = cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, | |
| 520 | + size, cudbg_err); | |
| 521 | + if (rc) | |
| 522 | + goto err; | |
| 523 | + } else { | |
| 524 | + rc = CUDBG_STATUS_ENTITY_NOT_FOUND; | |
| 525 | + goto err; | |
| 526 | + } | |
| 527 | +err: | |
| 528 | + return rc; | |
| 529 | +} | |
| 530 | + | |
| 531 | +int cudbg_collect_edc0_meminfo(struct cudbg_init *pdbg_init, | |
| 532 | + struct cudbg_buffer *dbg_buff, | |
| 533 | + struct cudbg_error *cudbg_err) | |
| 534 | +{ | |
| 535 | + return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, | |
| 536 | + MEM_EDC0); | |
| 537 | +} | |
| 538 | + | |
| 539 | +int cudbg_collect_edc1_meminfo(struct cudbg_init *pdbg_init, | |
| 540 | + struct cudbg_buffer *dbg_buff, | |
| 541 | + struct cudbg_error *cudbg_err) | |
| 542 | +{ | |
| 543 | + return cudbg_collect_mem_region(pdbg_init, dbg_buff, cudbg_err, | |
| 544 | + MEM_EDC1); | |
| 545 | +} | |
| 546 | + | |
| 547 | +int cudbg_collect_rss(struct cudbg_init *pdbg_init, | |
| 548 | + struct cudbg_buffer *dbg_buff, | |
| 549 | + struct cudbg_error *cudbg_err) | |
| 550 | +{ | |
| 551 | + struct adapter *padap = pdbg_init->adap; | |
| 552 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 553 | + int rc; | |
| 554 | + | |
| 555 | + rc = cudbg_get_buff(dbg_buff, RSS_NENTRIES * sizeof(u16), &temp_buff); | |
| 556 | + if (rc) | |
| 557 | + return rc; | |
| 558 | + | |
| 559 | + rc = t4_read_rss(padap, (u16 *)temp_buff.data); | |
| 560 | + if (rc) { | |
| 561 | + cudbg_err->sys_err = rc; | |
| 562 | + cudbg_put_buff(&temp_buff, dbg_buff); | |
| 563 | + return rc; | |
| 564 | + } | |
| 565 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 566 | + return rc; | |
| 567 | +} | |
| 568 | + | |
| 569 | +int cudbg_collect_rss_vf_config(struct cudbg_init *pdbg_init, | |
| 570 | + struct cudbg_buffer *dbg_buff, | |
| 571 | + struct cudbg_error *cudbg_err) | |
| 572 | +{ | |
| 573 | + struct adapter *padap = pdbg_init->adap; | |
| 574 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 575 | + struct cudbg_rss_vf_conf *vfconf; | |
| 576 | + int vf, rc, vf_count; | |
| 577 | + | |
| 578 | + vf_count = padap->params.arch.vfcount; | |
| 579 | + rc = cudbg_get_buff(dbg_buff, | |
| 580 | + vf_count * sizeof(struct cudbg_rss_vf_conf), | |
| 581 | + &temp_buff); | |
| 582 | + if (rc) | |
| 583 | + return rc; | |
| 584 | + | |
| 585 | + vfconf = (struct cudbg_rss_vf_conf *)temp_buff.data; | |
| 586 | + for (vf = 0; vf < vf_count; vf++) | |
| 587 | + t4_read_rss_vf_config(padap, vf, &vfconf[vf].rss_vf_vfl, | |
| 588 | + &vfconf[vf].rss_vf_vfh, true); | |
| 589 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 590 | + return rc; | |
| 591 | +} | |
| 592 | + | |
| 593 | +int cudbg_collect_path_mtu(struct cudbg_init *pdbg_init, | |
| 594 | + struct cudbg_buffer *dbg_buff, | |
| 595 | + struct cudbg_error *cudbg_err) | |
| 596 | +{ | |
| 597 | + struct adapter *padap = pdbg_init->adap; | |
| 598 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 599 | + int rc; | |
| 600 | + | |
| 601 | + rc = cudbg_get_buff(dbg_buff, NMTUS * sizeof(u16), &temp_buff); | |
| 602 | + if (rc) | |
| 603 | + return rc; | |
| 604 | + | |
| 605 | + t4_read_mtu_tbl(padap, (u16 *)temp_buff.data, NULL); | |
| 606 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 607 | + return rc; | |
| 608 | +} | |
| 609 | + | |
| 610 | +int cudbg_collect_pm_stats(struct cudbg_init *pdbg_init, | |
| 611 | + struct cudbg_buffer *dbg_buff, | |
| 612 | + struct cudbg_error *cudbg_err) | |
| 613 | +{ | |
| 614 | + struct adapter *padap = pdbg_init->adap; | |
| 615 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 616 | + struct cudbg_pm_stats *pm_stats_buff; | |
| 617 | + int rc; | |
| 618 | + | |
| 619 | + rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_pm_stats), | |
| 620 | + &temp_buff); | |
| 621 | + if (rc) | |
| 622 | + return rc; | |
| 623 | + | |
| 624 | + pm_stats_buff = (struct cudbg_pm_stats *)temp_buff.data; | |
| 625 | + t4_pmtx_get_stats(padap, pm_stats_buff->tx_cnt, pm_stats_buff->tx_cyc); | |
| 626 | + t4_pmrx_get_stats(padap, pm_stats_buff->rx_cnt, pm_stats_buff->rx_cyc); | |
| 627 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 628 | + return rc; | |
| 629 | +} | |
| 630 | + | |
| 631 | +int cudbg_collect_hw_sched(struct cudbg_init *pdbg_init, | |
| 632 | + struct cudbg_buffer *dbg_buff, | |
| 633 | + struct cudbg_error *cudbg_err) | |
| 634 | +{ | |
| 635 | + struct adapter *padap = pdbg_init->adap; | |
| 636 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 637 | + struct cudbg_hw_sched *hw_sched_buff; | |
| 638 | + int i, rc = 0; | |
| 639 | + | |
| 640 | + if (!padap->params.vpd.cclk) | |
| 641 | + return CUDBG_STATUS_CCLK_NOT_DEFINED; | |
| 642 | + | |
| 643 | + rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_hw_sched), | |
| 644 | + &temp_buff); | |
| 645 | + hw_sched_buff = (struct cudbg_hw_sched *)temp_buff.data; | |
| 646 | + hw_sched_buff->map = t4_read_reg(padap, TP_TX_MOD_QUEUE_REQ_MAP_A); | |
| 647 | + hw_sched_buff->mode = TIMERMODE_G(t4_read_reg(padap, TP_MOD_CONFIG_A)); | |
| 648 | + t4_read_pace_tbl(padap, hw_sched_buff->pace_tab); | |
| 649 | + for (i = 0; i < NTX_SCHED; ++i) | |
| 650 | + t4_get_tx_sched(padap, i, &hw_sched_buff->kbps[i], | |
| 651 | + &hw_sched_buff->ipg[i], true); | |
| 652 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 653 | + return rc; | |
| 654 | +} | |
| 655 | + | |
| 656 | +int cudbg_collect_tp_indirect(struct cudbg_init *pdbg_init, | |
| 657 | + struct cudbg_buffer *dbg_buff, | |
| 658 | + struct cudbg_error *cudbg_err) | |
| 659 | +{ | |
| 660 | + struct adapter *padap = pdbg_init->adap; | |
| 661 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 662 | + struct ireg_buf *ch_tp_pio; | |
| 663 | + int i, rc, n = 0; | |
| 664 | + u32 size; | |
| 665 | + | |
| 666 | + if (is_t5(padap->params.chip)) | |
| 667 | + n = sizeof(t5_tp_pio_array) + | |
| 668 | + sizeof(t5_tp_tm_pio_array) + | |
| 669 | + sizeof(t5_tp_mib_index_array); | |
| 670 | + else | |
| 671 | + n = sizeof(t6_tp_pio_array) + | |
| 672 | + sizeof(t6_tp_tm_pio_array) + | |
| 673 | + sizeof(t6_tp_mib_index_array); | |
| 674 | + | |
| 675 | + n = n / (IREG_NUM_ELEM * sizeof(u32)); | |
| 676 | + size = sizeof(struct ireg_buf) * n; | |
| 677 | + rc = cudbg_get_buff(dbg_buff, size, &temp_buff); | |
| 678 | + if (rc) | |
| 679 | + return rc; | |
| 680 | + | |
| 681 | + ch_tp_pio = (struct ireg_buf *)temp_buff.data; | |
| 682 | + | |
| 683 | + /* TP_PIO */ | |
| 684 | + if (is_t5(padap->params.chip)) | |
| 685 | + n = sizeof(t5_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
| 686 | + else if (is_t6(padap->params.chip)) | |
| 687 | + n = sizeof(t6_tp_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
| 688 | + | |
| 689 | + for (i = 0; i < n; i++) { | |
| 690 | + struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; | |
| 691 | + u32 *buff = ch_tp_pio->outbuf; | |
| 692 | + | |
| 693 | + if (is_t5(padap->params.chip)) { | |
| 694 | + tp_pio->ireg_addr = t5_tp_pio_array[i][0]; | |
| 695 | + tp_pio->ireg_data = t5_tp_pio_array[i][1]; | |
| 696 | + tp_pio->ireg_local_offset = t5_tp_pio_array[i][2]; | |
| 697 | + tp_pio->ireg_offset_range = t5_tp_pio_array[i][3]; | |
| 698 | + } else if (is_t6(padap->params.chip)) { | |
| 699 | + tp_pio->ireg_addr = t6_tp_pio_array[i][0]; | |
| 700 | + tp_pio->ireg_data = t6_tp_pio_array[i][1]; | |
| 701 | + tp_pio->ireg_local_offset = t6_tp_pio_array[i][2]; | |
| 702 | + tp_pio->ireg_offset_range = t6_tp_pio_array[i][3]; | |
| 703 | + } | |
| 704 | + t4_tp_pio_read(padap, buff, tp_pio->ireg_offset_range, | |
| 705 | + tp_pio->ireg_local_offset, true); | |
| 706 | + ch_tp_pio++; | |
| 707 | + } | |
| 708 | + | |
| 709 | + /* TP_TM_PIO */ | |
| 710 | + if (is_t5(padap->params.chip)) | |
| 711 | + n = sizeof(t5_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
| 712 | + else if (is_t6(padap->params.chip)) | |
| 713 | + n = sizeof(t6_tp_tm_pio_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
| 714 | + | |
| 715 | + for (i = 0; i < n; i++) { | |
| 716 | + struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; | |
| 717 | + u32 *buff = ch_tp_pio->outbuf; | |
| 718 | + | |
| 719 | + if (is_t5(padap->params.chip)) { | |
| 720 | + tp_pio->ireg_addr = t5_tp_tm_pio_array[i][0]; | |
| 721 | + tp_pio->ireg_data = t5_tp_tm_pio_array[i][1]; | |
| 722 | + tp_pio->ireg_local_offset = t5_tp_tm_pio_array[i][2]; | |
| 723 | + tp_pio->ireg_offset_range = t5_tp_tm_pio_array[i][3]; | |
| 724 | + } else if (is_t6(padap->params.chip)) { | |
| 725 | + tp_pio->ireg_addr = t6_tp_tm_pio_array[i][0]; | |
| 726 | + tp_pio->ireg_data = t6_tp_tm_pio_array[i][1]; | |
| 727 | + tp_pio->ireg_local_offset = t6_tp_tm_pio_array[i][2]; | |
| 728 | + tp_pio->ireg_offset_range = t6_tp_tm_pio_array[i][3]; | |
| 729 | + } | |
| 730 | + t4_tp_tm_pio_read(padap, buff, tp_pio->ireg_offset_range, | |
| 731 | + tp_pio->ireg_local_offset, true); | |
| 732 | + ch_tp_pio++; | |
| 733 | + } | |
| 734 | + | |
| 735 | + /* TP_MIB_INDEX */ | |
| 736 | + if (is_t5(padap->params.chip)) | |
| 737 | + n = sizeof(t5_tp_mib_index_array) / | |
| 738 | + (IREG_NUM_ELEM * sizeof(u32)); | |
| 739 | + else if (is_t6(padap->params.chip)) | |
| 740 | + n = sizeof(t6_tp_mib_index_array) / | |
| 741 | + (IREG_NUM_ELEM * sizeof(u32)); | |
| 742 | + | |
| 743 | + for (i = 0; i < n ; i++) { | |
| 744 | + struct ireg_field *tp_pio = &ch_tp_pio->tp_pio; | |
| 745 | + u32 *buff = ch_tp_pio->outbuf; | |
| 746 | + | |
| 747 | + if (is_t5(padap->params.chip)) { | |
| 748 | + tp_pio->ireg_addr = t5_tp_mib_index_array[i][0]; | |
| 749 | + tp_pio->ireg_data = t5_tp_mib_index_array[i][1]; | |
| 750 | + tp_pio->ireg_local_offset = | |
| 751 | + t5_tp_mib_index_array[i][2]; | |
| 752 | + tp_pio->ireg_offset_range = | |
| 753 | + t5_tp_mib_index_array[i][3]; | |
| 754 | + } else if (is_t6(padap->params.chip)) { | |
| 755 | + tp_pio->ireg_addr = t6_tp_mib_index_array[i][0]; | |
| 756 | + tp_pio->ireg_data = t6_tp_mib_index_array[i][1]; | |
| 757 | + tp_pio->ireg_local_offset = | |
| 758 | + t6_tp_mib_index_array[i][2]; | |
| 759 | + tp_pio->ireg_offset_range = | |
| 760 | + t6_tp_mib_index_array[i][3]; | |
| 761 | + } | |
| 762 | + t4_tp_mib_read(padap, buff, tp_pio->ireg_offset_range, | |
| 763 | + tp_pio->ireg_local_offset, true); | |
| 764 | + ch_tp_pio++; | |
| 765 | + } | |
| 766 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 767 | + return rc; | |
| 768 | +} | |
| 769 | + | |
| 770 | +int cudbg_collect_sge_indirect(struct cudbg_init *pdbg_init, | |
| 771 | + struct cudbg_buffer *dbg_buff, | |
| 772 | + struct cudbg_error *cudbg_err) | |
| 773 | +{ | |
| 774 | + struct adapter *padap = pdbg_init->adap; | |
| 775 | + struct cudbg_buffer temp_buff = { 0 }; | |
| 776 | + struct ireg_buf *ch_sge_dbg; | |
| 777 | + int i, rc; | |
| 778 | + | |
| 779 | + rc = cudbg_get_buff(dbg_buff, sizeof(*ch_sge_dbg) * 2, &temp_buff); | |
| 780 | + if (rc) | |
| 781 | + return rc; | |
| 782 | + | |
| 783 | + ch_sge_dbg = (struct ireg_buf *)temp_buff.data; | |
| 784 | + for (i = 0; i < 2; i++) { | |
| 785 | + struct ireg_field *sge_pio = &ch_sge_dbg->tp_pio; | |
| 786 | + u32 *buff = ch_sge_dbg->outbuf; | |
| 787 | + | |
| 788 | + sge_pio->ireg_addr = t5_sge_dbg_index_array[i][0]; | |
| 789 | + sge_pio->ireg_data = t5_sge_dbg_index_array[i][1]; | |
| 790 | + sge_pio->ireg_local_offset = t5_sge_dbg_index_array[i][2]; | |
| 791 | + sge_pio->ireg_offset_range = t5_sge_dbg_index_array[i][3]; | |
| 792 | + t4_read_indirect(padap, | |
| 793 | + sge_pio->ireg_addr, | |
| 794 | + sge_pio->ireg_data, | |
| 795 | + buff, | |
| 796 | + sge_pio->ireg_offset_range, | |
| 797 | + sge_pio->ireg_local_offset); | |
| 798 | + ch_sge_dbg++; | |
| 799 | + } | |
| 800 | + cudbg_write_and_release_buff(&temp_buff, dbg_buff); | |
| 801 | + return rc; | |
| 802 | +} | |
1127 more lines aren’t shown here.
This diff is large: its 170 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 404 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 1199 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 290 lines aren’t shown here.
This diff is large: its 877 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 914 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 324 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 446 lines aren’t shown here.
This diff is large: its 348 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 2624 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 450 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 829 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 645 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 852 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 355 lines aren’t shown here.
This diff is large: its 730 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 333 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 318 lines aren’t shown here.
This diff is large: its 566 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 1343 lines aren’t shown here.
This diff is large: its 4222 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 523 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 290 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 332 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 453 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 486 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 424 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 716 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 258 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 620 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 332 lines aren’t shown here.
This diff is large: its 425 lines aren’t shown here.
This diff is large: its 359 lines aren’t shown here.
This diff is large: its 485 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 900 lines aren’t shown here.
This diff is large: its 388 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 1489 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 479 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 351 lines aren’t shown here.
This diff is large: its 526 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 1120 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 712 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 468 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 312 lines aren’t shown here.
This diff is large: its 1013 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 840 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 2393 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 855 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 1815 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 361 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 519 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 805 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 258 lines aren’t shown here.
This diff is large: its 392 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 845 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 212 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 270 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 319 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 485 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 195 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 713 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 1364 lines aren’t shown here.
This diff is large: its 600 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
Empty file added.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 198 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1847 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 412 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 483 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 468 lines aren’t shown here.
This diff is large: its 718 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 446 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 833 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 239 lines aren’t shown here.
This diff is large: its 886 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 315 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 368 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 683 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 303 lines aren’t shown here.
This diff is large: its 644 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 671 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 279 lines aren’t shown here.
This diff is large: its 1571 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 298 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 599 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 346 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 449 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 300 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 472 lines aren’t shown here.
This diff is large: its 316 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 649 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 707 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 195 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 677 lines aren’t shown here.
This diff is large: its 2984 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 456 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 285 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 405 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 470 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 320 lines aren’t shown here.
This diff is large: its 300 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 722 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 653 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 900 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 179 lines aren’t shown here.
This diff is large: its 1202 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 1181 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 460 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 650 lines aren’t shown here.
This diff is large: its 389 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 328 lines aren’t shown here.
This diff is large: its 1595 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 810 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 978 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 304 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 1464 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 1417 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 275 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 675 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 274 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 416 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 250 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 168 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 572 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 598 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 618 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 555 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 374 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 407 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 375 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 348 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 872 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 1265 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
Binary file not shown.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 528 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 366 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 610 lines aren’t shown here.
This diff is large: its 698 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 661 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 355 lines aren’t shown here.
This diff is large: its 406 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 357 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 332 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 900 lines aren’t shown here.
This diff is large: its 704 lines aren’t shown here.
This diff is large: its 316 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 327 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
File renamed without changes.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 272 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 298 lines aren’t shown here.
This diff is large: its 1253 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 313 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 470 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 224 lines aren’t shown here.
This diff is large: its 528 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 373 lines aren’t shown here.
This diff is large: its 1166 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 682 lines aren’t shown here.