diff options
325 files changed, 14274 insertions, 6823 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-mdio b/Documentation/ABI/testing/sysfs-bus-mdio new file mode 100644 index 000000000000..6349749ebc29 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-mdio | |||
@@ -0,0 +1,9 @@ | |||
1 | What: /sys/bus/mdio_bus/devices/.../phy_id | ||
2 | Date: November 2012 | ||
3 | KernelVersion: 3.8 | ||
4 | Contact: netdev@vger.kernel.org | ||
5 | Description: | ||
6 | This attribute contains the 32-bit PHY Identifier as reported | ||
7 | by the device during bus enumeration, encoded in hexadecimal. | ||
8 | This ID is used to match the device with the appropriate | ||
9 | driver. | ||
diff --git a/Documentation/devicetree/bindings/net/cdns-emac.txt b/Documentation/devicetree/bindings/net/cdns-emac.txt new file mode 100644 index 000000000000..09055c2495f0 --- /dev/null +++ b/Documentation/devicetree/bindings/net/cdns-emac.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | * Cadence EMAC Ethernet controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "cdns,[<chip>-]{emac}" | ||
5 | Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. | ||
6 | or the generic form: "cdns,emac". | ||
7 | - reg: Address and length of the register set for the device | ||
8 | - interrupts: Should contain macb interrupt | ||
9 | - phy-mode: String, operation mode of the PHY interface. | ||
10 | Supported values are: "mii", "rmii". | ||
11 | |||
12 | Optional properties: | ||
13 | - local-mac-address: 6 bytes, mac address | ||
14 | |||
15 | Examples: | ||
16 | |||
17 | macb0: ethernet@fffc4000 { | ||
18 | compatible = "cdns,at91rm9200-emac"; | ||
19 | reg = <0xfffc4000 0x4000>; | ||
20 | interrupts = <21>; | ||
21 | phy-mode = "rmii"; | ||
22 | local-mac-address = [3a 0e 03 04 05 06]; | ||
23 | }; | ||
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index dcaabe9fe869..221460714c56 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt | |||
@@ -16,12 +16,16 @@ Required properties: | |||
16 | - ale_entries : Specifies No of entries ALE can hold | 16 | - ale_entries : Specifies No of entries ALE can hold |
17 | - host_port_reg_ofs : Specifies host port register offset | 17 | - host_port_reg_ofs : Specifies host port register offset |
18 | - hw_stats_reg_ofs : Specifies hardware statistics register offset | 18 | - hw_stats_reg_ofs : Specifies hardware statistics register offset |
19 | - cpts_reg_ofs : Specifies the offset of the CPTS registers | ||
19 | - bd_ram_ofs : Specifies internal desciptor RAM offset | 20 | - bd_ram_ofs : Specifies internal desciptor RAM offset |
20 | - bd_ram_size : Specifies internal descriptor RAM size | 21 | - bd_ram_size : Specifies internal descriptor RAM size |
21 | - rx_descs : Specifies number of Rx descriptors | 22 | - rx_descs : Specifies number of Rx descriptors |
22 | - mac_control : Specifies Default MAC control register content | 23 | - mac_control : Specifies Default MAC control register content |
23 | for the specific platform | 24 | for the specific platform |
24 | - slaves : Specifies number for slaves | 25 | - slaves : Specifies number for slaves |
26 | - cpts_active_slave : Specifies the slave to use for time stamping | ||
27 | - cpts_clock_mult : Numerator to convert input clock ticks into nanoseconds | ||
28 | - cpts_clock_shift : Denominator to convert input clock ticks into nanoseconds | ||
25 | - slave_reg_ofs : Specifies slave register offset | 29 | - slave_reg_ofs : Specifies slave register offset |
26 | - sliver_reg_ofs : Specifies slave sliver register offset | 30 | - sliver_reg_ofs : Specifies slave sliver register offset |
27 | - phy_id : Specifies slave phy id | 31 | - phy_id : Specifies slave phy id |
@@ -52,21 +56,25 @@ Examples: | |||
52 | ale_entries = <1024>; | 56 | ale_entries = <1024>; |
53 | host_port_reg_ofs = <0x108>; | 57 | host_port_reg_ofs = <0x108>; |
54 | hw_stats_reg_ofs = <0x900>; | 58 | hw_stats_reg_ofs = <0x900>; |
59 | cpts_reg_ofs = <0xc00>; | ||
55 | bd_ram_ofs = <0x2000>; | 60 | bd_ram_ofs = <0x2000>; |
56 | bd_ram_size = <0x2000>; | 61 | bd_ram_size = <0x2000>; |
57 | no_bd_ram = <0>; | 62 | no_bd_ram = <0>; |
58 | rx_descs = <64>; | 63 | rx_descs = <64>; |
59 | mac_control = <0x20>; | 64 | mac_control = <0x20>; |
60 | slaves = <2>; | 65 | slaves = <2>; |
66 | cpts_active_slave = <0>; | ||
67 | cpts_clock_mult = <0x80000000>; | ||
68 | cpts_clock_shift = <29>; | ||
61 | cpsw_emac0: slave@0 { | 69 | cpsw_emac0: slave@0 { |
62 | slave_reg_ofs = <0x208>; | 70 | slave_reg_ofs = <0x200>; |
63 | sliver_reg_ofs = <0xd80>; | 71 | sliver_reg_ofs = <0xd80>; |
64 | phy_id = "davinci_mdio.16:00"; | 72 | phy_id = "davinci_mdio.16:00"; |
65 | /* Filled in by U-Boot */ | 73 | /* Filled in by U-Boot */ |
66 | mac-address = [ 00 00 00 00 00 00 ]; | 74 | mac-address = [ 00 00 00 00 00 00 ]; |
67 | }; | 75 | }; |
68 | cpsw_emac1: slave@1 { | 76 | cpsw_emac1: slave@1 { |
69 | slave_reg_ofs = <0x308>; | 77 | slave_reg_ofs = <0x300>; |
70 | sliver_reg_ofs = <0xdc0>; | 78 | sliver_reg_ofs = <0xdc0>; |
71 | phy_id = "davinci_mdio.16:01"; | 79 | phy_id = "davinci_mdio.16:01"; |
72 | /* Filled in by U-Boot */ | 80 | /* Filled in by U-Boot */ |
@@ -86,21 +94,25 @@ Examples: | |||
86 | ale_entries = <1024>; | 94 | ale_entries = <1024>; |
87 | host_port_reg_ofs = <0x108>; | 95 | host_port_reg_ofs = <0x108>; |
88 | hw_stats_reg_ofs = <0x900>; | 96 | hw_stats_reg_ofs = <0x900>; |
97 | cpts_reg_ofs = <0xc00>; | ||
89 | bd_ram_ofs = <0x2000>; | 98 | bd_ram_ofs = <0x2000>; |
90 | bd_ram_size = <0x2000>; | 99 | bd_ram_size = <0x2000>; |
91 | no_bd_ram = <0>; | 100 | no_bd_ram = <0>; |
92 | rx_descs = <64>; | 101 | rx_descs = <64>; |
93 | mac_control = <0x20>; | 102 | mac_control = <0x20>; |
94 | slaves = <2>; | 103 | slaves = <2>; |
104 | cpts_active_slave = <0>; | ||
105 | cpts_clock_mult = <0x80000000>; | ||
106 | cpts_clock_shift = <29>; | ||
95 | cpsw_emac0: slave@0 { | 107 | cpsw_emac0: slave@0 { |
96 | slave_reg_ofs = <0x208>; | 108 | slave_reg_ofs = <0x200>; |
97 | sliver_reg_ofs = <0xd80>; | 109 | sliver_reg_ofs = <0xd80>; |
98 | phy_id = "davinci_mdio.16:00"; | 110 | phy_id = "davinci_mdio.16:00"; |
99 | /* Filled in by U-Boot */ | 111 | /* Filled in by U-Boot */ |
100 | mac-address = [ 00 00 00 00 00 00 ]; | 112 | mac-address = [ 00 00 00 00 00 00 ]; |
101 | }; | 113 | }; |
102 | cpsw_emac1: slave@1 { | 114 | cpsw_emac1: slave@1 { |
103 | slave_reg_ofs = <0x308>; | 115 | slave_reg_ofs = <0x300>; |
104 | sliver_reg_ofs = <0xdc0>; | 116 | sliver_reg_ofs = <0xdc0>; |
105 | phy_id = "davinci_mdio.16:01"; | 117 | phy_id = "davinci_mdio.16:01"; |
106 | /* Filled in by U-Boot */ | 118 | /* Filled in by U-Boot */ |
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index a173d2a879f5..c1d82047a4b1 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt | |||
@@ -203,7 +203,8 @@ abled during run time. Following log_levels are defined: | |||
203 | 2 - Enable messages related to route added / changed / deleted | 203 | 2 - Enable messages related to route added / changed / deleted |
204 | 4 - Enable messages related to translation table operations | 204 | 4 - Enable messages related to translation table operations |
205 | 8 - Enable messages related to bridge loop avoidance | 205 | 8 - Enable messages related to bridge loop avoidance |
206 | 15 - enable all messages | 206 | 16 - Enable messaged related to DAT, ARP snooping and parsing |
207 | 31 - Enable all messages | ||
207 | 208 | ||
208 | The debug output can be changed at runtime using the file | 209 | The debug output can be changed at runtime using the file |
209 | /sys/class/net/bat0/mesh/log_level. e.g. | 210 | /sys/class/net/bat0/mesh/log_level. e.g. |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index c7fc10724948..98ac0d7552a1 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1514,6 +1514,20 @@ cookie_preserve_enable - BOOLEAN | |||
1514 | 1514 | ||
1515 | Default: 1 | 1515 | Default: 1 |
1516 | 1516 | ||
1517 | cookie_hmac_alg - STRING | ||
1518 | Select the hmac algorithm used when generating the cookie value sent by | ||
1519 | a listening sctp socket to a connecting client in the INIT-ACK chunk. | ||
1520 | Valid values are: | ||
1521 | * md5 | ||
1522 | * sha1 | ||
1523 | * none | ||
1524 | Ability to assign md5 or sha1 as the selected alg is predicated on the | ||
1525 | configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and | ||
1526 | CONFIG_CRYPTO_SHA1). | ||
1527 | |||
1528 | Default: Dependent on configuration. MD5 if available, else SHA1 if | ||
1529 | available, else none. | ||
1530 | |||
1517 | rcvbuf_policy - INTEGER | 1531 | rcvbuf_policy - INTEGER |
1518 | Determines if the receive buffer is attributed to the socket or to | 1532 | Determines if the receive buffer is attributed to the socket or to |
1519 | association. SCTP supports the capability to create multiple | 1533 | association. SCTP supports the capability to create multiple |
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index 1c08a4b0981f..94444b152fbc 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt | |||
@@ -3,9 +3,9 @@ | |||
3 | -------------------------------------------------------------------------------- | 3 | -------------------------------------------------------------------------------- |
4 | 4 | ||
5 | This file documents the mmap() facility available with the PACKET | 5 | This file documents the mmap() facility available with the PACKET |
6 | socket interface on 2.4 and 2.6 kernels. This type of sockets is used for | 6 | socket interface on 2.4/2.6/3.x kernels. This type of sockets is used for |
7 | capture network traffic with utilities like tcpdump or any other that needs | 7 | i) capture network traffic with utilities like tcpdump, ii) transmit network |
8 | raw access to network interface. | 8 | traffic, or any other that needs raw access to network interface. |
9 | 9 | ||
10 | You can find the latest version of this document at: | 10 | You can find the latest version of this document at: |
11 | http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap | 11 | http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap |
@@ -21,19 +21,18 @@ Please send your comments to | |||
21 | + Why use PACKET_MMAP | 21 | + Why use PACKET_MMAP |
22 | -------------------------------------------------------------------------------- | 22 | -------------------------------------------------------------------------------- |
23 | 23 | ||
24 | In Linux 2.4/2.6 if PACKET_MMAP is not enabled, the capture process is very | 24 | In Linux 2.4/2.6/3.x if PACKET_MMAP is not enabled, the capture process is very |
25 | inefficient. It uses very limited buffers and requires one system call | 25 | inefficient. It uses very limited buffers and requires one system call to |
26 | to capture each packet, it requires two if you want to get packet's | 26 | capture each packet, it requires two if you want to get packet's timestamp |
27 | timestamp (like libpcap always does). | 27 | (like libpcap always does). |
28 | 28 | ||
29 | In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size | 29 | In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size |
30 | configurable circular buffer mapped in user space that can be used to either | 30 | configurable circular buffer mapped in user space that can be used to either |
31 | send or receive packets. This way reading packets just needs to wait for them, | 31 | send or receive packets. This way reading packets just needs to wait for them, |
32 | most of the time there is no need to issue a single system call. Concerning | 32 | most of the time there is no need to issue a single system call. Concerning |
33 | transmission, multiple packets can be sent through one system call to get the | 33 | transmission, multiple packets can be sent through one system call to get the |
34 | highest bandwidth. | 34 | highest bandwidth. By using a shared buffer between the kernel and the user |
35 | By using a shared buffer between the kernel and the user also has the benefit | 35 | also has the benefit of minimizing packet copies. |
36 | of minimizing packet copies. | ||
37 | 36 | ||
38 | It's fine to use PACKET_MMAP to improve the performance of the capture and | 37 | It's fine to use PACKET_MMAP to improve the performance of the capture and |
39 | transmission process, but it isn't everything. At least, if you are capturing | 38 | transmission process, but it isn't everything. At least, if you are capturing |
@@ -41,7 +40,8 @@ at high speeds (this is relative to the cpu speed), you should check if the | |||
41 | device driver of your network interface card supports some sort of interrupt | 40 | device driver of your network interface card supports some sort of interrupt |
42 | load mitigation or (even better) if it supports NAPI, also make sure it is | 41 | load mitigation or (even better) if it supports NAPI, also make sure it is |
43 | enabled. For transmission, check the MTU (Maximum Transmission Unit) used and | 42 | enabled. For transmission, check the MTU (Maximum Transmission Unit) used and |
44 | supported by devices of your network. | 43 | supported by devices of your network. CPU IRQ pinning of your network interface |
44 | card can also be an advantage. | ||
45 | 45 | ||
46 | -------------------------------------------------------------------------------- | 46 | -------------------------------------------------------------------------------- |
47 | + How to use mmap() to improve capture process | 47 | + How to use mmap() to improve capture process |
@@ -87,9 +87,7 @@ the following process: | |||
87 | socket creation and destruction is straight forward, and is done | 87 | socket creation and destruction is straight forward, and is done |
88 | the same way with or without PACKET_MMAP: | 88 | the same way with or without PACKET_MMAP: |
89 | 89 | ||
90 | int fd; | 90 | int fd = socket(PF_PACKET, mode, htons(ETH_P_ALL)); |
91 | |||
92 | fd= socket(PF_PACKET, mode, htons(ETH_P_ALL)) | ||
93 | 91 | ||
94 | where mode is SOCK_RAW for the raw interface were link level | 92 | where mode is SOCK_RAW for the raw interface were link level |
95 | information can be captured or SOCK_DGRAM for the cooked | 93 | information can be captured or SOCK_DGRAM for the cooked |
@@ -163,11 +161,23 @@ As capture, each frame contains two parts: | |||
163 | 161 | ||
164 | A complete tutorial is available at: http://wiki.gnu-log.net/ | 162 | A complete tutorial is available at: http://wiki.gnu-log.net/ |
165 | 163 | ||
164 | By default, the user should put data at : | ||
165 | frame base + TPACKET_HDRLEN - sizeof(struct sockaddr_ll) | ||
166 | |||
167 | So, whatever you choose for the socket mode (SOCK_DGRAM or SOCK_RAW), | ||
168 | the beginning of the user data will be at : | ||
169 | frame base + TPACKET_ALIGN(sizeof(struct tpacket_hdr)) | ||
170 | |||
171 | If you wish to put user data at a custom offset from the beginning of | ||
172 | the frame (for payload alignment with SOCK_RAW mode for instance) you | ||
173 | can set tp_net (with SOCK_DGRAM) or tp_mac (with SOCK_RAW). In order | ||
174 | to make this work it must be enabled previously with setsockopt() | ||
175 | and the PACKET_TX_HAS_OFF option. | ||
176 | |||
166 | -------------------------------------------------------------------------------- | 177 | -------------------------------------------------------------------------------- |
167 | + PACKET_MMAP settings | 178 | + PACKET_MMAP settings |
168 | -------------------------------------------------------------------------------- | 179 | -------------------------------------------------------------------------------- |
169 | 180 | ||
170 | |||
171 | To setup PACKET_MMAP from user level code is done with a call like | 181 | To setup PACKET_MMAP from user level code is done with a call like |
172 | 182 | ||
173 | - Capture process | 183 | - Capture process |
@@ -201,7 +211,6 @@ indeed, packet_set_ring checks that the following condition is true | |||
201 | 211 | ||
202 | frames_per_block * tp_block_nr == tp_frame_nr | 212 | frames_per_block * tp_block_nr == tp_frame_nr |
203 | 213 | ||
204 | |||
205 | Lets see an example, with the following values: | 214 | Lets see an example, with the following values: |
206 | 215 | ||
207 | tp_block_size= 4096 | 216 | tp_block_size= 4096 |
@@ -227,7 +236,6 @@ be spawned across two blocks, so there are some details you have to take into | |||
227 | account when choosing the frame_size. See "Mapping and use of the circular | 236 | account when choosing the frame_size. See "Mapping and use of the circular |
228 | buffer (ring)". | 237 | buffer (ring)". |
229 | 238 | ||
230 | |||
231 | -------------------------------------------------------------------------------- | 239 | -------------------------------------------------------------------------------- |
232 | + PACKET_MMAP setting constraints | 240 | + PACKET_MMAP setting constraints |
233 | -------------------------------------------------------------------------------- | 241 | -------------------------------------------------------------------------------- |
@@ -264,7 +272,6 @@ User space programs can include /usr/include/sys/user.h and | |||
264 | The pagesize can also be determined dynamically with the getpagesize (2) | 272 | The pagesize can also be determined dynamically with the getpagesize (2) |
265 | system call. | 273 | system call. |
266 | 274 | ||
267 | |||
268 | Block number limit | 275 | Block number limit |
269 | -------------------- | 276 | -------------------- |
270 | 277 | ||
@@ -284,7 +291,6 @@ called pg_vec, its size limits the number of blocks that can be allocated. | |||
284 | v block #2 | 291 | v block #2 |
285 | block #1 | 292 | block #1 |
286 | 293 | ||
287 | |||
288 | kmalloc allocates any number of bytes of physically contiguous memory from | 294 | kmalloc allocates any number of bytes of physically contiguous memory from |
289 | a pool of pre-determined sizes. This pool of memory is maintained by the slab | 295 | a pool of pre-determined sizes. This pool of memory is maintained by the slab |
290 | allocator which is at the end the responsible for doing the allocation and | 296 | allocator which is at the end the responsible for doing the allocation and |
@@ -299,7 +305,6 @@ pointers to blocks is | |||
299 | 305 | ||
300 | 131072/4 = 32768 blocks | 306 | 131072/4 = 32768 blocks |
301 | 307 | ||
302 | |||
303 | PACKET_MMAP buffer size calculator | 308 | PACKET_MMAP buffer size calculator |
304 | ------------------------------------ | 309 | ------------------------------------ |
305 | 310 | ||
@@ -340,7 +345,6 @@ and a value for <frame size> of 2048 bytes. These parameters will yield | |||
340 | and hence the buffer will have a 262144 MiB size. So it can hold | 345 | and hence the buffer will have a 262144 MiB size. So it can hold |
341 | 262144 MiB / 2048 bytes = 134217728 frames | 346 | 262144 MiB / 2048 bytes = 134217728 frames |
342 | 347 | ||
343 | |||
344 | Actually, this buffer size is not possible with an i386 architecture. | 348 | Actually, this buffer size is not possible with an i386 architecture. |
345 | Remember that the memory is allocated in kernel space, in the case of | 349 | Remember that the memory is allocated in kernel space, in the case of |
346 | an i386 kernel's memory size is limited to 1GiB. | 350 | an i386 kernel's memory size is limited to 1GiB. |
@@ -372,7 +376,6 @@ the following (from include/linux/if_packet.h): | |||
372 | - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16. | 376 | - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16. |
373 | - Pad to align to TPACKET_ALIGNMENT=16 | 377 | - Pad to align to TPACKET_ALIGNMENT=16 |
374 | */ | 378 | */ |
375 | |||
376 | 379 | ||
377 | The following are conditions that are checked in packet_set_ring | 380 | The following are conditions that are checked in packet_set_ring |
378 | 381 | ||
@@ -413,7 +416,6 @@ and the following flags apply: | |||
413 | #define TP_STATUS_LOSING 4 | 416 | #define TP_STATUS_LOSING 4 |
414 | #define TP_STATUS_CSUMNOTREADY 8 | 417 | #define TP_STATUS_CSUMNOTREADY 8 |
415 | 418 | ||
416 | |||
417 | TP_STATUS_COPY : This flag indicates that the frame (and associated | 419 | TP_STATUS_COPY : This flag indicates that the frame (and associated |
418 | meta information) has been truncated because it's | 420 | meta information) has been truncated because it's |
419 | larger than tp_frame_size. This packet can be | 421 | larger than tp_frame_size. This packet can be |
@@ -462,7 +464,6 @@ packets are in the ring: | |||
462 | It doesn't incur in a race condition to first check the status value and | 464 | It doesn't incur in a race condition to first check the status value and |
463 | then poll for frames. | 465 | then poll for frames. |
464 | 466 | ||
465 | |||
466 | ++ Transmission process | 467 | ++ Transmission process |
467 | Those defines are also used for transmission: | 468 | Those defines are also used for transmission: |
468 | 469 | ||
@@ -494,6 +495,196 @@ The user can also use poll() to check if a buffer is available: | |||
494 | retval = poll(&pfd, 1, timeout); | 495 | retval = poll(&pfd, 1, timeout); |
495 | 496 | ||
496 | ------------------------------------------------------------------------------- | 497 | ------------------------------------------------------------------------------- |
498 | + What TPACKET versions are available and when to use them? | ||
499 | ------------------------------------------------------------------------------- | ||
500 | |||
501 | int val = tpacket_version; | ||
502 | setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)); | ||
503 | getsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)); | ||
504 | |||
505 | where 'tpacket_version' can be TPACKET_V1 (default), TPACKET_V2, TPACKET_V3. | ||
506 | |||
507 | TPACKET_V1: | ||
508 | - Default if not otherwise specified by setsockopt(2) | ||
509 | - RX_RING, TX_RING available | ||
510 | - VLAN metadata information available for packets | ||
511 | (TP_STATUS_VLAN_VALID) | ||
512 | |||
513 | TPACKET_V1 --> TPACKET_V2: | ||
514 | - Made 64 bit clean due to unsigned long usage in TPACKET_V1 | ||
515 | structures, thus this also works on 64 bit kernel with 32 bit | ||
516 | userspace and the like | ||
517 | - Timestamp resolution in nanoseconds instead of microseconds | ||
518 | - RX_RING, TX_RING available | ||
519 | - How to switch to TPACKET_V2: | ||
520 | 1. Replace struct tpacket_hdr by struct tpacket2_hdr | ||
521 | 2. Query header len and save | ||
522 | 3. Set protocol version to 2, set up ring as usual | ||
523 | 4. For getting the sockaddr_ll, | ||
524 | use (void *)hdr + TPACKET_ALIGN(hdrlen) instead of | ||
525 | (void *)hdr + TPACKET_ALIGN(sizeof(struct tpacket_hdr)) | ||
526 | |||
527 | TPACKET_V2 --> TPACKET_V3: | ||
528 | - Flexible buffer implementation: | ||
529 | 1. Blocks can be configured with non-static frame-size | ||
530 | 2. Read/poll is at a block-level (as opposed to packet-level) | ||
531 | 3. Added poll timeout to avoid indefinite user-space wait | ||
532 | on idle links | ||
533 | 4. Added user-configurable knobs: | ||
534 | 4.1 block::timeout | ||
535 | 4.2 tpkt_hdr::sk_rxhash | ||
536 | - RX Hash data available in user space | ||
537 | - Currently only RX_RING available | ||
538 | |||
539 | ------------------------------------------------------------------------------- | ||
540 | + AF_PACKET fanout mode | ||
541 | ------------------------------------------------------------------------------- | ||
542 | |||
543 | In the AF_PACKET fanout mode, packet reception can be load balanced among | ||
544 | processes. This also works in combination with mmap(2) on packet sockets. | ||
545 | |||
546 | Minimal example code by David S. Miller (try things like "./test eth0 hash", | ||
547 | "./test eth0 lb", etc.): | ||
548 | |||
549 | #include <stddef.h> | ||
550 | #include <stdlib.h> | ||
551 | #include <stdio.h> | ||
552 | #include <string.h> | ||
553 | |||
554 | #include <sys/types.h> | ||
555 | #include <sys/wait.h> | ||
556 | #include <sys/socket.h> | ||
557 | #include <sys/ioctl.h> | ||
558 | |||
559 | #include <unistd.h> | ||
560 | |||
561 | #include <linux/if_ether.h> | ||
562 | #include <linux/if_packet.h> | ||
563 | |||
564 | #include <net/if.h> | ||
565 | |||
566 | static const char *device_name; | ||
567 | static int fanout_type; | ||
568 | static int fanout_id; | ||
569 | |||
570 | #ifndef PACKET_FANOUT | ||
571 | # define PACKET_FANOUT 18 | ||
572 | # define PACKET_FANOUT_HASH 0 | ||
573 | # define PACKET_FANOUT_LB 1 | ||
574 | #endif | ||
575 | |||
576 | static int setup_socket(void) | ||
577 | { | ||
578 | int err, fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)); | ||
579 | struct sockaddr_ll ll; | ||
580 | struct ifreq ifr; | ||
581 | int fanout_arg; | ||
582 | |||
583 | if (fd < 0) { | ||
584 | perror("socket"); | ||
585 | return EXIT_FAILURE; | ||
586 | } | ||
587 | |||
588 | memset(&ifr, 0, sizeof(ifr)); | ||
589 | strcpy(ifr.ifr_name, device_name); | ||
590 | err = ioctl(fd, SIOCGIFINDEX, &ifr); | ||
591 | if (err < 0) { | ||
592 | perror("SIOCGIFINDEX"); | ||
593 | return EXIT_FAILURE; | ||
594 | } | ||
595 | |||
596 | memset(&ll, 0, sizeof(ll)); | ||
597 | ll.sll_family = AF_PACKET; | ||
598 | ll.sll_ifindex = ifr.ifr_ifindex; | ||
599 | err = bind(fd, (struct sockaddr *) &ll, sizeof(ll)); | ||
600 | if (err < 0) { | ||
601 | perror("bind"); | ||
602 | return EXIT_FAILURE; | ||
603 | } | ||
604 | |||
605 | fanout_arg = (fanout_id | (fanout_type << 16)); | ||
606 | err = setsockopt(fd, SOL_PACKET, PACKET_FANOUT, | ||
607 | &fanout_arg, sizeof(fanout_arg)); | ||
608 | if (err) { | ||
609 | perror("setsockopt"); | ||
610 | return EXIT_FAILURE; | ||
611 | } | ||
612 | |||
613 | return fd; | ||
614 | } | ||
615 | |||
616 | static void fanout_thread(void) | ||
617 | { | ||
618 | int fd = setup_socket(); | ||
619 | int limit = 10000; | ||
620 | |||
621 | if (fd < 0) | ||
622 | exit(fd); | ||
623 | |||
624 | while (limit-- > 0) { | ||
625 | char buf[1600]; | ||
626 | int err; | ||
627 | |||
628 | err = read(fd, buf, sizeof(buf)); | ||
629 | if (err < 0) { | ||
630 | perror("read"); | ||
631 | exit(EXIT_FAILURE); | ||
632 | } | ||
633 | if ((limit % 10) == 0) | ||
634 | fprintf(stdout, "(%d) \n", getpid()); | ||
635 | } | ||
636 | |||
637 | fprintf(stdout, "%d: Received 10000 packets\n", getpid()); | ||
638 | |||
639 | close(fd); | ||
640 | exit(0); | ||
641 | } | ||
642 | |||
643 | int main(int argc, char **argp) | ||
644 | { | ||
645 | int fd, err; | ||
646 | int i; | ||
647 | |||
648 | if (argc != 3) { | ||
649 | fprintf(stderr, "Usage: %s INTERFACE {hash|lb}\n", argp[0]); | ||
650 | return EXIT_FAILURE; | ||
651 | } | ||
652 | |||
653 | if (!strcmp(argp[2], "hash")) | ||
654 | fanout_type = PACKET_FANOUT_HASH; | ||
655 | else if (!strcmp(argp[2], "lb")) | ||
656 | fanout_type = PACKET_FANOUT_LB; | ||
657 | else { | ||
658 | fprintf(stderr, "Unknown fanout type [%s]\n", argp[2]); | ||
659 | exit(EXIT_FAILURE); | ||
660 | } | ||
661 | |||
662 | device_name = argp[1]; | ||
663 | fanout_id = getpid() & 0xffff; | ||
664 | |||
665 | for (i = 0; i < 4; i++) { | ||
666 | pid_t pid = fork(); | ||
667 | |||
668 | switch (pid) { | ||
669 | case 0: | ||
670 | fanout_thread(); | ||
671 | |||
672 | case -1: | ||
673 | perror("fork"); | ||
674 | exit(EXIT_FAILURE); | ||
675 | } | ||
676 | } | ||
677 | |||
678 | for (i = 0; i < 4; i++) { | ||
679 | int status; | ||
680 | |||
681 | wait(&status); | ||
682 | } | ||
683 | |||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | ------------------------------------------------------------------------------- | ||
497 | + PACKET_TIMESTAMP | 688 | + PACKET_TIMESTAMP |
498 | ------------------------------------------------------------------------------- | 689 | ------------------------------------------------------------------------------- |
499 | 690 | ||
@@ -519,6 +710,13 @@ the networking stack is used (the behavior before this setting was added). | |||
519 | See include/linux/net_tstamp.h and Documentation/networking/timestamping | 710 | See include/linux/net_tstamp.h and Documentation/networking/timestamping |
520 | for more information on hardware timestamps. | 711 | for more information on hardware timestamps. |
521 | 712 | ||
713 | ------------------------------------------------------------------------------- | ||
714 | + Miscellaneous bits | ||
715 | ------------------------------------------------------------------------------- | ||
716 | |||
717 | - Packet sockets work well together with Linux socket filters, thus you also | ||
718 | might want to have a look at Documentation/networking/filter.txt | ||
719 | |||
522 | -------------------------------------------------------------------------------- | 720 | -------------------------------------------------------------------------------- |
523 | + THANKS | 721 | + THANKS |
524 | -------------------------------------------------------------------------------- | 722 | -------------------------------------------------------------------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index 28eeaece87c0..4b062ff7441c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3878,7 +3878,9 @@ M: Greg Rose <gregory.v.rose@intel.com> | |||
3878 | M: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> | 3878 | M: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> |
3879 | M: Alex Duyck <alexander.h.duyck@intel.com> | 3879 | M: Alex Duyck <alexander.h.duyck@intel.com> |
3880 | M: John Ronciak <john.ronciak@intel.com> | 3880 | M: John Ronciak <john.ronciak@intel.com> |
3881 | M: Tushar Dave <tushar.n.dave@intel.com> | ||
3881 | L: e1000-devel@lists.sourceforge.net | 3882 | L: e1000-devel@lists.sourceforge.net |
3883 | W: http://www.intel.com/support/feedback.htm | ||
3882 | W: http://e1000.sourceforge.net/ | 3884 | W: http://e1000.sourceforge.net/ |
3883 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net.git | 3885 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net.git |
3884 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next.git | 3886 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next.git |
@@ -6365,6 +6367,7 @@ F: drivers/scsi/st* | |||
6365 | SCTP PROTOCOL | 6367 | SCTP PROTOCOL |
6366 | M: Vlad Yasevich <vyasevich@gmail.com> | 6368 | M: Vlad Yasevich <vyasevich@gmail.com> |
6367 | M: Sridhar Samudrala <sri@us.ibm.com> | 6369 | M: Sridhar Samudrala <sri@us.ibm.com> |
6370 | M: Neil Horman <nhorman@tuxdriver.com> | ||
6368 | L: linux-sctp@vger.kernel.org | 6371 | L: linux-sctp@vger.kernel.org |
6369 | W: http://lksctp.sourceforge.net | 6372 | W: http://lksctp.sourceforge.net |
6370 | S: Maintained | 6373 | S: Maintained |
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index 7d2f75be932e..0087d053b77f 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Socket filtering */ | 47 | /* Socket filtering */ |
48 | #define SO_ATTACH_FILTER 26 | 48 | #define SO_ATTACH_FILTER 26 |
49 | #define SO_DETACH_FILTER 27 | 49 | #define SO_DETACH_FILTER 27 |
50 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
50 | 51 | ||
51 | #define SO_PEERNAME 28 | 52 | #define SO_PEERNAME 28 |
52 | #define SO_TIMESTAMP 29 | 53 | #define SO_TIMESTAMP 29 |
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index f3990b04fecf..3290e61be3e1 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi | |||
@@ -580,6 +580,7 @@ | |||
580 | 66 0x1b0b0 /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */ | 580 | 66 0x1b0b0 /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */ |
581 | 70 0x1b0b0 /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */ | 581 | 70 0x1b0b0 /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */ |
582 | 48 0x1b0b0 /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */ | 582 | 48 0x1b0b0 /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */ |
583 | 1033 0x4001b0a8 /* MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/ | ||
583 | >; | 584 | >; |
584 | }; | 585 | }; |
585 | 586 | ||
@@ -833,8 +834,8 @@ | |||
833 | compatible = "fsl,imx6q-fec"; | 834 | compatible = "fsl,imx6q-fec"; |
834 | reg = <0x02188000 0x4000>; | 835 | reg = <0x02188000 0x4000>; |
835 | interrupts = <0 118 0x04 0 119 0x04>; | 836 | interrupts = <0 118 0x04 0 119 0x04>; |
836 | clocks = <&clks 117>, <&clks 117>; | 837 | clocks = <&clks 117>, <&clks 117>, <&clks 177>; |
837 | clock-names = "ipg", "ahb"; | 838 | clock-names = "ipg", "ahb", "ptp"; |
838 | status = "disabled"; | 839 | status = "disabled"; |
839 | }; | 840 | }; |
840 | 841 | ||
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 043624219b55..92857683cb61 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -39,7 +39,6 @@ config SOC_AT91RM9200 | |||
39 | config SOC_AT91SAM9260 | 39 | config SOC_AT91SAM9260 |
40 | bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" | 40 | bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" |
41 | select HAVE_AT91_DBGU0 | 41 | select HAVE_AT91_DBGU0 |
42 | select HAVE_NET_MACB | ||
43 | select SOC_AT91SAM9 | 42 | select SOC_AT91SAM9 |
44 | help | 43 | help |
45 | Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE | 44 | Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE |
@@ -57,7 +56,6 @@ config SOC_AT91SAM9263 | |||
57 | bool "AT91SAM9263" | 56 | bool "AT91SAM9263" |
58 | select HAVE_AT91_DBGU1 | 57 | select HAVE_AT91_DBGU1 |
59 | select HAVE_FB_ATMEL | 58 | select HAVE_FB_ATMEL |
60 | select HAVE_NET_MACB | ||
61 | select SOC_AT91SAM9 | 59 | select SOC_AT91SAM9 |
62 | 60 | ||
63 | config SOC_AT91SAM9RL | 61 | config SOC_AT91SAM9RL |
@@ -70,7 +68,6 @@ config SOC_AT91SAM9G45 | |||
70 | bool "AT91SAM9G45 or AT91SAM9M10 families" | 68 | bool "AT91SAM9G45 or AT91SAM9M10 families" |
71 | select HAVE_AT91_DBGU1 | 69 | select HAVE_AT91_DBGU1 |
72 | select HAVE_FB_ATMEL | 70 | select HAVE_FB_ATMEL |
73 | select HAVE_NET_MACB | ||
74 | select SOC_AT91SAM9 | 71 | select SOC_AT91SAM9 |
75 | help | 72 | help |
76 | Select this if you are using one of Atmel's AT91SAM9G45 family SoC. | 73 | Select this if you are using one of Atmel's AT91SAM9G45 family SoC. |
@@ -80,7 +77,6 @@ config SOC_AT91SAM9X5 | |||
80 | bool "AT91SAM9x5 family" | 77 | bool "AT91SAM9x5 family" |
81 | select HAVE_AT91_DBGU0 | 78 | select HAVE_AT91_DBGU0 |
82 | select HAVE_FB_ATMEL | 79 | select HAVE_FB_ATMEL |
83 | select HAVE_NET_MACB | ||
84 | select SOC_AT91SAM9 | 80 | select SOC_AT91SAM9 |
85 | help | 81 | help |
86 | Select this if you are using one of Atmel's AT91SAM9x5 family SoC. | 82 | Select this if you are using one of Atmel's AT91SAM9x5 family SoC. |
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index 3e37437a7a61..aa9b320bad59 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c | |||
@@ -53,6 +53,8 @@ static void __init csb337_init_early(void) | |||
53 | static struct macb_platform_data __initdata csb337_eth_data = { | 53 | static struct macb_platform_data __initdata csb337_eth_data = { |
54 | .phy_irq_pin = AT91_PIN_PC2, | 54 | .phy_irq_pin = AT91_PIN_PC2, |
55 | .is_rmii = 0, | 55 | .is_rmii = 0, |
56 | /* The CSB337 bootloader stores the MAC the wrong-way around */ | ||
57 | .rev_eth_addr = 1, | ||
56 | }; | 58 | }; |
57 | 59 | ||
58 | static struct at91_usbh_data __initdata csb337_usbh_data = { | 60 | static struct at91_usbh_data __initdata csb337_usbh_data = { |
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_emac.h b/arch/arm/mach-at91/include/mach/at91rm9200_emac.h deleted file mode 100644 index b8260cd8041c..000000000000 --- a/arch/arm/mach-at91/include/mach/at91rm9200_emac.h +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/include/mach/at91rm9200_emac.h | ||
3 | * | ||
4 | * Copyright (C) 2005 Ivan Kokshaysky | ||
5 | * Copyright (C) SAN People | ||
6 | * | ||
7 | * Ethernet MAC registers. | ||
8 | * Based on AT91RM9200 datasheet revision E. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef AT91RM9200_EMAC_H | ||
17 | #define AT91RM9200_EMAC_H | ||
18 | |||
19 | #define AT91_EMAC_CTL 0x00 /* Control Register */ | ||
20 | #define AT91_EMAC_LB (1 << 0) /* Loopback */ | ||
21 | #define AT91_EMAC_LBL (1 << 1) /* Loopback Local */ | ||
22 | #define AT91_EMAC_RE (1 << 2) /* Receive Enable */ | ||
23 | #define AT91_EMAC_TE (1 << 3) /* Transmit Enable */ | ||
24 | #define AT91_EMAC_MPE (1 << 4) /* Management Port Enable */ | ||
25 | #define AT91_EMAC_CSR (1 << 5) /* Clear Statistics Registers */ | ||
26 | #define AT91_EMAC_INCSTAT (1 << 6) /* Increment Statistics Registers */ | ||
27 | #define AT91_EMAC_WES (1 << 7) /* Write Enable for Statistics Registers */ | ||
28 | #define AT91_EMAC_BP (1 << 8) /* Back Pressure */ | ||
29 | |||
30 | #define AT91_EMAC_CFG 0x04 /* Configuration Register */ | ||
31 | #define AT91_EMAC_SPD (1 << 0) /* Speed */ | ||
32 | #define AT91_EMAC_FD (1 << 1) /* Full Duplex */ | ||
33 | #define AT91_EMAC_BR (1 << 2) /* Bit Rate */ | ||
34 | #define AT91_EMAC_CAF (1 << 4) /* Copy All Frames */ | ||
35 | #define AT91_EMAC_NBC (1 << 5) /* No Broadcast */ | ||
36 | #define AT91_EMAC_MTI (1 << 6) /* Multicast Hash Enable */ | ||
37 | #define AT91_EMAC_UNI (1 << 7) /* Unicast Hash Enable */ | ||
38 | #define AT91_EMAC_BIG (1 << 8) /* Receive 1522 Bytes */ | ||
39 | #define AT91_EMAC_EAE (1 << 9) /* External Address Match Enable */ | ||
40 | #define AT91_EMAC_CLK (3 << 10) /* MDC Clock Divisor */ | ||
41 | #define AT91_EMAC_CLK_DIV8 (0 << 10) | ||
42 | #define AT91_EMAC_CLK_DIV16 (1 << 10) | ||
43 | #define AT91_EMAC_CLK_DIV32 (2 << 10) | ||
44 | #define AT91_EMAC_CLK_DIV64 (3 << 10) | ||
45 | #define AT91_EMAC_RTY (1 << 12) /* Retry Test */ | ||
46 | #define AT91_EMAC_RMII (1 << 13) /* Reduce MII (RMII) */ | ||
47 | |||
48 | #define AT91_EMAC_SR 0x08 /* Status Register */ | ||
49 | #define AT91_EMAC_SR_LINK (1 << 0) /* Link */ | ||
50 | #define AT91_EMAC_SR_MDIO (1 << 1) /* MDIO pin */ | ||
51 | #define AT91_EMAC_SR_IDLE (1 << 2) /* PHY idle */ | ||
52 | |||
53 | #define AT91_EMAC_TAR 0x0c /* Transmit Address Register */ | ||
54 | |||
55 | #define AT91_EMAC_TCR 0x10 /* Transmit Control Register */ | ||
56 | #define AT91_EMAC_LEN (0x7ff << 0) /* Transmit Frame Length */ | ||
57 | #define AT91_EMAC_NCRC (1 << 15) /* No CRC */ | ||
58 | |||
59 | #define AT91_EMAC_TSR 0x14 /* Transmit Status Register */ | ||
60 | #define AT91_EMAC_TSR_OVR (1 << 0) /* Transmit Buffer Overrun */ | ||
61 | #define AT91_EMAC_TSR_COL (1 << 1) /* Collision Occurred */ | ||
62 | #define AT91_EMAC_TSR_RLE (1 << 2) /* Retry Limit Exceeded */ | ||
63 | #define AT91_EMAC_TSR_IDLE (1 << 3) /* Transmitter Idle */ | ||
64 | #define AT91_EMAC_TSR_BNQ (1 << 4) /* Transmit Buffer not Queued */ | ||
65 | #define AT91_EMAC_TSR_COMP (1 << 5) /* Transmit Complete */ | ||
66 | #define AT91_EMAC_TSR_UND (1 << 6) /* Transmit Underrun */ | ||
67 | |||
68 | #define AT91_EMAC_RBQP 0x18 /* Receive Buffer Queue Pointer */ | ||
69 | |||
70 | #define AT91_EMAC_RSR 0x20 /* Receive Status Register */ | ||
71 | #define AT91_EMAC_RSR_BNA (1 << 0) /* Buffer Not Available */ | ||
72 | #define AT91_EMAC_RSR_REC (1 << 1) /* Frame Received */ | ||
73 | #define AT91_EMAC_RSR_OVR (1 << 2) /* RX Overrun */ | ||
74 | |||
75 | #define AT91_EMAC_ISR 0x24 /* Interrupt Status Register */ | ||
76 | #define AT91_EMAC_DONE (1 << 0) /* Management Done */ | ||
77 | #define AT91_EMAC_RCOM (1 << 1) /* Receive Complete */ | ||
78 | #define AT91_EMAC_RBNA (1 << 2) /* Receive Buffer Not Available */ | ||
79 | #define AT91_EMAC_TOVR (1 << 3) /* Transmit Buffer Overrun */ | ||
80 | #define AT91_EMAC_TUND (1 << 4) /* Transmit Buffer Underrun */ | ||
81 | #define AT91_EMAC_RTRY (1 << 5) /* Retry Limit */ | ||
82 | #define AT91_EMAC_TBRE (1 << 6) /* Transmit Buffer Register Empty */ | ||
83 | #define AT91_EMAC_TCOM (1 << 7) /* Transmit Complete */ | ||
84 | #define AT91_EMAC_TIDLE (1 << 8) /* Transmit Idle */ | ||
85 | #define AT91_EMAC_LINK (1 << 9) /* Link */ | ||
86 | #define AT91_EMAC_ROVR (1 << 10) /* RX Overrun */ | ||
87 | #define AT91_EMAC_ABT (1 << 11) /* Abort */ | ||
88 | |||
89 | #define AT91_EMAC_IER 0x28 /* Interrupt Enable Register */ | ||
90 | #define AT91_EMAC_IDR 0x2c /* Interrupt Disable Register */ | ||
91 | #define AT91_EMAC_IMR 0x30 /* Interrupt Mask Register */ | ||
92 | |||
93 | #define AT91_EMAC_MAN 0x34 /* PHY Maintenance Register */ | ||
94 | #define AT91_EMAC_DATA (0xffff << 0) /* MDIO Data */ | ||
95 | #define AT91_EMAC_REGA (0x1f << 18) /* MDIO Register */ | ||
96 | #define AT91_EMAC_PHYA (0x1f << 23) /* MDIO PHY Address */ | ||
97 | #define AT91_EMAC_RW (3 << 28) /* Read/Write operation */ | ||
98 | #define AT91_EMAC_RW_W (1 << 28) | ||
99 | #define AT91_EMAC_RW_R (2 << 28) | ||
100 | #define AT91_EMAC_MAN_802_3 0x40020000 /* IEEE 802.3 value */ | ||
101 | |||
102 | /* | ||
103 | * Statistics Registers. | ||
104 | */ | ||
105 | #define AT91_EMAC_FRA 0x40 /* Frames Transmitted OK */ | ||
106 | #define AT91_EMAC_SCOL 0x44 /* Single Collision Frame */ | ||
107 | #define AT91_EMAC_MCOL 0x48 /* Multiple Collision Frame */ | ||
108 | #define AT91_EMAC_OK 0x4c /* Frames Received OK */ | ||
109 | #define AT91_EMAC_SEQE 0x50 /* Frame Check Sequence Error */ | ||
110 | #define AT91_EMAC_ALE 0x54 /* Alignmemt Error */ | ||
111 | #define AT91_EMAC_DTE 0x58 /* Deffered Transmission Frame */ | ||
112 | #define AT91_EMAC_LCOL 0x5c /* Late Collision */ | ||
113 | #define AT91_EMAC_ECOL 0x60 /* Excessive Collision */ | ||
114 | #define AT91_EMAC_TUE 0x64 /* Transmit Underrun Error */ | ||
115 | #define AT91_EMAC_CSE 0x68 /* Carrier Sense Error */ | ||
116 | #define AT91_EMAC_DRFC 0x6c /* Discard RX Frame */ | ||
117 | #define AT91_EMAC_ROV 0x70 /* Receive Overrun */ | ||
118 | #define AT91_EMAC_CDE 0x74 /* Code Error */ | ||
119 | #define AT91_EMAC_ELR 0x78 /* Excessive Length Error */ | ||
120 | #define AT91_EMAC_RJB 0x7c /* Receive Jabber */ | ||
121 | #define AT91_EMAC_USF 0x80 /* Undersize Frame */ | ||
122 | #define AT91_EMAC_SQEE 0x84 /* SQE Test Error */ | ||
123 | |||
124 | /* | ||
125 | * Address Registers. | ||
126 | */ | ||
127 | #define AT91_EMAC_HSL 0x90 /* Hash Address Low [31:0] */ | ||
128 | #define AT91_EMAC_HSH 0x94 /* Hash Address High [63:32] */ | ||
129 | #define AT91_EMAC_SA1L 0x98 /* Specific Address 1 Low, bytes 0-3 */ | ||
130 | #define AT91_EMAC_SA1H 0x9c /* Specific Address 1 High, bytes 4-5 */ | ||
131 | #define AT91_EMAC_SA2L 0xa0 /* Specific Address 2 Low, bytes 0-3 */ | ||
132 | #define AT91_EMAC_SA2H 0xa4 /* Specific Address 2 High, bytes 4-5 */ | ||
133 | #define AT91_EMAC_SA3L 0xa8 /* Specific Address 3 Low, bytes 0-3 */ | ||
134 | #define AT91_EMAC_SA3H 0xac /* Specific Address 3 High, bytes 4-5 */ | ||
135 | #define AT91_EMAC_SA4L 0xb0 /* Specific Address 4 Low, bytes 0-3 */ | ||
136 | #define AT91_EMAC_SA4H 0xb4 /* Specific Address 4 High, bytes 4-5 */ | ||
137 | |||
138 | #endif | ||
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 47c91f7185d2..38d69100398d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -117,6 +117,17 @@ static void __init imx6q_sabrelite_init(void) | |||
117 | imx6q_sabrelite_cko1_setup(); | 117 | imx6q_sabrelite_cko1_setup(); |
118 | } | 118 | } |
119 | 119 | ||
120 | static void __init imx6q_1588_init(void) | ||
121 | { | ||
122 | struct regmap *gpr; | ||
123 | |||
124 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); | ||
125 | if (!IS_ERR(gpr)) | ||
126 | regmap_update_bits(gpr, 0x4, 1 << 21, 1 << 21); | ||
127 | else | ||
128 | pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n"); | ||
129 | |||
130 | } | ||
120 | static void __init imx6q_usb_init(void) | 131 | static void __init imx6q_usb_init(void) |
121 | { | 132 | { |
122 | struct regmap *anatop; | 133 | struct regmap *anatop; |
@@ -153,6 +164,7 @@ static void __init imx6q_init_machine(void) | |||
153 | 164 | ||
154 | imx6q_pm_init(); | 165 | imx6q_pm_init(); |
155 | imx6q_usb_init(); | 166 | imx6q_usb_init(); |
167 | imx6q_1588_init(); | ||
156 | } | 168 | } |
157 | 169 | ||
158 | static struct cpuidle_driver imx6q_cpuidle_driver = { | 170 | static struct cpuidle_driver imx6q_cpuidle_driver = { |
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 06e73bf665e9..09f9fa800b33 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig | |||
@@ -80,7 +80,6 @@ config PLATFORM_AT32AP | |||
80 | select ARCH_REQUIRE_GPIOLIB | 80 | select ARCH_REQUIRE_GPIOLIB |
81 | select GENERIC_ALLOCATOR | 81 | select GENERIC_ALLOCATOR |
82 | select HAVE_FB_ATMEL | 82 | select HAVE_FB_ATMEL |
83 | select HAVE_NET_MACB | ||
84 | 83 | ||
85 | # | 84 | # |
86 | # CPU types | 85 | # CPU types |
diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index a473f8c6a9aa..486df68abeec 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h index ae52825021af..b681b043f6c8 100644 --- a/arch/cris/include/asm/socket.h +++ b/arch/cris/include/asm/socket.h | |||
@@ -42,6 +42,7 @@ | |||
42 | /* Socket filtering */ | 42 | /* Socket filtering */ |
43 | #define SO_ATTACH_FILTER 26 | 43 | #define SO_ATTACH_FILTER 26 |
44 | #define SO_DETACH_FILTER 27 | 44 | #define SO_DETACH_FILTER 27 |
45 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
45 | 46 | ||
46 | #define SO_PEERNAME 28 | 47 | #define SO_PEERNAME 28 |
47 | #define SO_TIMESTAMP 29 | 48 | #define SO_TIMESTAMP 29 |
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index a5b1d7dbb205..871f89b7fbda 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h index ec4554e7b04b..90a2e573c7e6 100644 --- a/arch/h8300/include/asm/socket.h +++ b/arch/h8300/include/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 41fc28a4a18a..23d6759bb57b 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h | |||
@@ -49,6 +49,7 @@ | |||
49 | /* Socket filtering */ | 49 | /* Socket filtering */ |
50 | #define SO_ATTACH_FILTER 26 | 50 | #define SO_ATTACH_FILTER 26 |
51 | #define SO_DETACH_FILTER 27 | 51 | #define SO_DETACH_FILTER 27 |
52 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
52 | 53 | ||
53 | #define SO_PEERNAME 28 | 54 | #define SO_PEERNAME 28 |
54 | #define SO_TIMESTAMP 29 | 55 | #define SO_TIMESTAMP 29 |
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h index a15f40b52783..5e7088a26726 100644 --- a/arch/m32r/include/asm/socket.h +++ b/arch/m32r/include/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/m68k/include/uapi/asm/socket.h b/arch/m68k/include/uapi/asm/socket.h index d1be684edf97..285da3b6ad92 100644 --- a/arch/m68k/include/uapi/asm/socket.h +++ b/arch/m68k/include/uapi/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index c5ed59549cb8..17307ab90474 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h | |||
@@ -63,6 +63,7 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ | |||
63 | /* Socket filtering */ | 63 | /* Socket filtering */ |
64 | #define SO_ATTACH_FILTER 26 | 64 | #define SO_ATTACH_FILTER 26 |
65 | #define SO_DETACH_FILTER 27 | 65 | #define SO_DETACH_FILTER 27 |
66 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
66 | 67 | ||
67 | #define SO_PEERNAME 28 | 68 | #define SO_PEERNAME 28 |
68 | #define SO_TIMESTAMP 29 | 69 | #define SO_TIMESTAMP 29 |
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index 820463a484b8..af5366bbfe62 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h | |||
@@ -40,6 +40,7 @@ | |||
40 | /* Socket filtering */ | 40 | /* Socket filtering */ |
41 | #define SO_ATTACH_FILTER 26 | 41 | #define SO_ATTACH_FILTER 26 |
42 | #define SO_DETACH_FILTER 27 | 42 | #define SO_DETACH_FILTER 27 |
43 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
43 | 44 | ||
44 | #define SO_PEERNAME 28 | 45 | #define SO_PEERNAME 28 |
45 | #define SO_TIMESTAMP 29 | 46 | #define SO_TIMESTAMP 29 |
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 1b52c2c31a7a..d9ff4731253b 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h | |||
@@ -48,6 +48,7 @@ | |||
48 | /* Socket filtering */ | 48 | /* Socket filtering */ |
49 | #define SO_ATTACH_FILTER 0x401a | 49 | #define SO_ATTACH_FILTER 0x401a |
50 | #define SO_DETACH_FILTER 0x401b | 50 | #define SO_DETACH_FILTER 0x401b |
51 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
51 | 52 | ||
52 | #define SO_ACCEPTCONN 0x401c | 53 | #define SO_ACCEPTCONN 0x401c |
53 | 54 | ||
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index 3d5179bb122f..eb0b1864d400 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Socket filtering */ | 47 | /* Socket filtering */ |
48 | #define SO_ATTACH_FILTER 26 | 48 | #define SO_ATTACH_FILTER 26 |
49 | #define SO_DETACH_FILTER 27 | 49 | #define SO_DETACH_FILTER 27 |
50 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
50 | 51 | ||
51 | #define SO_PEERNAME 28 | 52 | #define SO_PEERNAME 28 |
52 | #define SO_TIMESTAMP 29 | 53 | #define SO_TIMESTAMP 29 |
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 69718cd6d635..436d07c23be8 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h | |||
@@ -46,6 +46,7 @@ | |||
46 | /* Socket filtering */ | 46 | /* Socket filtering */ |
47 | #define SO_ATTACH_FILTER 26 | 47 | #define SO_ATTACH_FILTER 26 |
48 | #define SO_DETACH_FILTER 27 | 48 | #define SO_DETACH_FILTER 27 |
49 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
49 | 50 | ||
50 | #define SO_PEERNAME 28 | 51 | #define SO_PEERNAME 28 |
51 | #define SO_TIMESTAMP 29 | 52 | #define SO_TIMESTAMP 29 |
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index bea1568ae4af..c83a937ead00 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | #define SO_ATTACH_FILTER 0x001a | 42 | #define SO_ATTACH_FILTER 0x001a |
43 | #define SO_DETACH_FILTER 0x001b | 43 | #define SO_DETACH_FILTER 0x001b |
44 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
44 | 45 | ||
45 | #define SO_PEERNAME 0x001c | 46 | #define SO_PEERNAME 0x001c |
46 | #define SO_TIMESTAMP 0x001d | 47 | #define SO_TIMESTAMP 0x001d |
diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 28368701ef79..3109ca684a99 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/netdevice.h> | 3 | #include <linux/netdevice.h> |
4 | #include <linux/filter.h> | 4 | #include <linux/filter.h> |
5 | #include <linux/cache.h> | 5 | #include <linux/cache.h> |
6 | #include <linux/if_vlan.h> | ||
6 | 7 | ||
7 | #include <asm/cacheflush.h> | 8 | #include <asm/cacheflush.h> |
8 | #include <asm/ptrace.h> | 9 | #include <asm/ptrace.h> |
@@ -312,6 +313,12 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \ | |||
312 | #define emit_addi(R1, IMM, R3) \ | 313 | #define emit_addi(R1, IMM, R3) \ |
313 | *prog++ = (ADD | IMMED | RS1(R1) | S13(IMM) | RD(R3)) | 314 | *prog++ = (ADD | IMMED | RS1(R1) | S13(IMM) | RD(R3)) |
314 | 315 | ||
316 | #define emit_and(R1, R2, R3) \ | ||
317 | *prog++ = (AND | RS1(R1) | RS2(R2) | RD(R3)) | ||
318 | |||
319 | #define emit_andi(R1, IMM, R3) \ | ||
320 | *prog++ = (AND | IMMED | RS1(R1) | S13(IMM) | RD(R3)) | ||
321 | |||
315 | #define emit_alloc_stack(SZ) \ | 322 | #define emit_alloc_stack(SZ) \ |
316 | *prog++ = (SUB | IMMED | RS1(SP) | S13(SZ) | RD(SP)) | 323 | *prog++ = (SUB | IMMED | RS1(SP) | S13(SZ) | RD(SP)) |
317 | 324 | ||
@@ -415,6 +422,8 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
415 | case BPF_S_ANC_IFINDEX: | 422 | case BPF_S_ANC_IFINDEX: |
416 | case BPF_S_ANC_MARK: | 423 | case BPF_S_ANC_MARK: |
417 | case BPF_S_ANC_RXHASH: | 424 | case BPF_S_ANC_RXHASH: |
425 | case BPF_S_ANC_VLAN_TAG: | ||
426 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
418 | case BPF_S_ANC_CPU: | 427 | case BPF_S_ANC_CPU: |
419 | case BPF_S_ANC_QUEUE: | 428 | case BPF_S_ANC_QUEUE: |
420 | case BPF_S_LD_W_ABS: | 429 | case BPF_S_LD_W_ABS: |
@@ -600,6 +609,16 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
600 | case BPF_S_ANC_RXHASH: | 609 | case BPF_S_ANC_RXHASH: |
601 | emit_skb_load32(rxhash, r_A); | 610 | emit_skb_load32(rxhash, r_A); |
602 | break; | 611 | break; |
612 | case BPF_S_ANC_VLAN_TAG: | ||
613 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
614 | emit_skb_load16(vlan_tci, r_A); | ||
615 | if (filter[i].code == BPF_S_ANC_VLAN_TAG) { | ||
616 | emit_andi(r_A, VLAN_VID_MASK, r_A); | ||
617 | } else { | ||
618 | emit_loadimm(VLAN_TAG_PRESENT, r_TMP); | ||
619 | emit_and(r_A, r_TMP, r_A); | ||
620 | } | ||
621 | break; | ||
603 | 622 | ||
604 | case BPF_S_LD_IMM: | 623 | case BPF_S_LD_IMM: |
605 | emit_loadimm(K, r_A); | 624 | emit_loadimm(K, r_A); |
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 520d2bd0b9c5..d11a47099d33 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/cacheflush.h> | 11 | #include <asm/cacheflush.h> |
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/filter.h> | 13 | #include <linux/filter.h> |
14 | #include <linux/if_vlan.h> | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * Conventions : | 17 | * Conventions : |
@@ -212,6 +213,8 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
212 | case BPF_S_ANC_MARK: | 213 | case BPF_S_ANC_MARK: |
213 | case BPF_S_ANC_RXHASH: | 214 | case BPF_S_ANC_RXHASH: |
214 | case BPF_S_ANC_CPU: | 215 | case BPF_S_ANC_CPU: |
216 | case BPF_S_ANC_VLAN_TAG: | ||
217 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
215 | case BPF_S_ANC_QUEUE: | 218 | case BPF_S_ANC_QUEUE: |
216 | case BPF_S_LD_W_ABS: | 219 | case BPF_S_LD_W_ABS: |
217 | case BPF_S_LD_H_ABS: | 220 | case BPF_S_LD_H_ABS: |
@@ -515,6 +518,24 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
515 | CLEAR_A(); | 518 | CLEAR_A(); |
516 | #endif | 519 | #endif |
517 | break; | 520 | break; |
521 | case BPF_S_ANC_VLAN_TAG: | ||
522 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
523 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); | ||
524 | if (is_imm8(offsetof(struct sk_buff, vlan_tci))) { | ||
525 | /* movzwl off8(%rdi),%eax */ | ||
526 | EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, vlan_tci)); | ||
527 | } else { | ||
528 | EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */ | ||
529 | EMIT(offsetof(struct sk_buff, vlan_tci), 4); | ||
530 | } | ||
531 | BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000); | ||
532 | if (filter[i].code == BPF_S_ANC_VLAN_TAG) { | ||
533 | EMIT3(0x80, 0xe4, 0xef); /* and $0xef,%ah */ | ||
534 | } else { | ||
535 | EMIT3(0xc1, 0xe8, 0x0c); /* shr $0xc,%eax */ | ||
536 | EMIT3(0x83, 0xe0, 0x01); /* and $0x1,%eax */ | ||
537 | } | ||
538 | break; | ||
518 | case BPF_S_LD_W_ABS: | 539 | case BPF_S_LD_W_ABS: |
519 | func = CHOOSE_LOAD_FUNC(K, sk_load_word); | 540 | func = CHOOSE_LOAD_FUNC(K, sk_load_word); |
520 | common_load: seen |= SEEN_DATAREF; | 541 | common_load: seen |= SEEN_DATAREF; |
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index e36c68184920..38079be1cf1e 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h | |||
@@ -52,6 +52,7 @@ | |||
52 | 52 | ||
53 | #define SO_ATTACH_FILTER 26 | 53 | #define SO_ATTACH_FILTER 26 |
54 | #define SO_DETACH_FILTER 27 | 54 | #define SO_DETACH_FILTER 27 |
55 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
55 | 56 | ||
56 | #define SO_PEERNAME 28 | 57 | #define SO_PEERNAME 28 |
57 | #define SO_TIMESTAMP 29 | 58 | #define SO_TIMESTAMP 29 |
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 81363ffa5357..6e99d73563b8 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c | |||
@@ -490,7 +490,7 @@ receive_dmsg(struct hfc_pci *hc) | |||
490 | (df->data[le16_to_cpu(zp->z1)])) { | 490 | (df->data[le16_to_cpu(zp->z1)])) { |
491 | if (dch->debug & DEBUG_HW) | 491 | if (dch->debug & DEBUG_HW) |
492 | printk(KERN_DEBUG | 492 | printk(KERN_DEBUG |
493 | "empty_fifo hfcpci paket inv. len " | 493 | "empty_fifo hfcpci packet inv. len " |
494 | "%d or crc %d\n", | 494 | "%d or crc %d\n", |
495 | rcnt, | 495 | rcnt, |
496 | df->data[le16_to_cpu(zp->z1)]); | 496 | df->data[le16_to_cpu(zp->z1)]); |
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index 182ecf0626c2..feafa91c2ed9 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c | |||
@@ -1302,7 +1302,7 @@ modeisar(struct isar_ch *ch, u32 bprotocol) | |||
1302 | &ch->is->Flags)) | 1302 | &ch->is->Flags)) |
1303 | ch->dpath = 1; | 1303 | ch->dpath = 1; |
1304 | else { | 1304 | else { |
1305 | pr_info("modeisar both pathes in use\n"); | 1305 | pr_info("modeisar both paths in use\n"); |
1306 | return -EBUSY; | 1306 | return -EBUSY; |
1307 | } | 1307 | } |
1308 | if (bprotocol == ISDN_P_B_HDLC) | 1308 | if (bprotocol == ISDN_P_B_HDLC) |
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index a47637be0cc5..ddec47a911a0 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c | |||
@@ -35,7 +35,7 @@ static int chancount; | |||
35 | /* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */ | 35 | /* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */ |
36 | #define ALERT_REJECT 0 | 36 | #define ALERT_REJECT 0 |
37 | 37 | ||
38 | /* Value to delay the sending of the first B-channel paket after CONNECT | 38 | /* Value to delay the sending of the first B-channel packet after CONNECT |
39 | * here is no value given by ITU, but experience shows that 300 ms will | 39 | * here is no value given by ITU, but experience shows that 300 ms will |
40 | * work on many networks, if you or your other side is behind local exchanges | 40 | * work on many networks, if you or your other side is behind local exchanges |
41 | * a greater value may be recommented. If the delay is to short the first paket | 41 | * a greater value may be recommented. If the delay is to short the first paket |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 334fa90bed8e..f60d4be58941 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -354,7 +354,7 @@ receive_dmsg(struct IsdnCardState *cs) | |||
354 | if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || | 354 | if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || |
355 | (df->data[zp->z1])) { | 355 | (df->data[zp->z1])) { |
356 | if (cs->debug & L1_DEB_WARN) | 356 | if (cs->debug & L1_DEB_WARN) |
357 | debugl1(cs, "empty_fifo hfcpci paket inv. len %d or crc %d", rcnt, df->data[zp->z1]); | 357 | debugl1(cs, "empty_fifo hfcpci packet inv. len %d or crc %d", rcnt, df->data[zp->z1]); |
358 | #ifdef ERROR_STATISTIC | 358 | #ifdef ERROR_STATISTIC |
359 | cs->err_rx++; | 359 | cs->err_rx++; |
360 | #endif | 360 | #endif |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 4db846be4369..4ec279ce052f 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
@@ -270,7 +270,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) | |||
270 | 270 | ||
271 | if ((count > fifo_size) || (count < 4)) { | 271 | if ((count > fifo_size) || (count < 4)) { |
272 | if (cs->debug & L1_DEB_WARN) | 272 | if (cs->debug & L1_DEB_WARN) |
273 | debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count); | 273 | debugl1(cs, "hfcsx_read_fifo %d packet inv. len %d ", fifo , count); |
274 | while (count) { | 274 | while (count) { |
275 | count--; /* empty fifo */ | 275 | count--; /* empty fifo */ |
276 | Read_hfc(cs, HFCSX_FIF_DRD); | 276 | Read_hfc(cs, HFCSX_FIF_DRD); |
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index db50f788855d..f8e405c383a0 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -277,7 +277,6 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
277 | u16 timebase, u8 *buf, int len) | 277 | u16 timebase, u8 *buf, int len) |
278 | { | 278 | { |
279 | u8 *p; | 279 | u8 *p; |
280 | int multi = 0; | ||
281 | u8 frame[len + 32]; | 280 | u8 frame[len + 32]; |
282 | struct socket *socket = NULL; | 281 | struct socket *socket = NULL; |
283 | 282 | ||
@@ -317,9 +316,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
317 | *p++ = hc->id >> 8; | 316 | *p++ = hc->id >> 8; |
318 | *p++ = hc->id; | 317 | *p++ = hc->id; |
319 | } | 318 | } |
320 | *p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */ | 319 | *p++ = 0x00 + channel; /* m-flag, channel */ |
321 | if (multi == 1) | ||
322 | *p++ = len; /* length */ | ||
323 | *p++ = timebase >> 8; /* time base */ | 320 | *p++ = timebase >> 8; /* time base */ |
324 | *p++ = timebase; | 321 | *p++ = timebase; |
325 | 322 | ||
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c index a18e639b40d7..42ecfef80132 100644 --- a/drivers/isdn/pcbit/layer2.c +++ b/drivers/isdn/pcbit/layer2.c | |||
@@ -508,7 +508,7 @@ pcbit_irq_handler(int interrupt, void *devptr) | |||
508 | return IRQ_NONE; | 508 | return IRQ_NONE; |
509 | } | 509 | } |
510 | if (dev->interrupt) { | 510 | if (dev->interrupt) { |
511 | printk(KERN_DEBUG "pcbit: reentering interrupt hander\n"); | 511 | printk(KERN_DEBUG "pcbit: reentering interrupt handler\n"); |
512 | return IRQ_HANDLED; | 512 | return IRQ_HANDLED; |
513 | } | 513 | } |
514 | dev->interrupt = 1; | 514 | dev->interrupt = 1; |
diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig index 49a30d37ae4a..e49c0eff040b 100644 --- a/drivers/net/ethernet/adi/Kconfig +++ b/drivers/net/ethernet/adi/Kconfig | |||
@@ -61,7 +61,7 @@ config BFIN_RX_DESC_NUM | |||
61 | 61 | ||
62 | config BFIN_MAC_USE_HWSTAMP | 62 | config BFIN_MAC_USE_HWSTAMP |
63 | bool "Use IEEE 1588 hwstamp" | 63 | bool "Use IEEE 1588 hwstamp" |
64 | depends on BFIN_MAC && BF518 | 64 | select PTP_1588_CLOCK |
65 | default y | 65 | default y |
66 | ---help--- | 66 | ---help--- |
67 | To support the IEEE 1588 Precision Time Protocol (PTP), select y here | 67 | To support the IEEE 1588 Precision Time Protocol (PTP), select y here |
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index f816426e1085..f1c458dc039a 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c | |||
@@ -548,14 +548,17 @@ static int bfin_mac_ethtool_setwol(struct net_device *dev, | |||
548 | return 0; | 548 | return 0; |
549 | } | 549 | } |
550 | 550 | ||
551 | #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP | ||
551 | static int bfin_mac_ethtool_get_ts_info(struct net_device *dev, | 552 | static int bfin_mac_ethtool_get_ts_info(struct net_device *dev, |
552 | struct ethtool_ts_info *info) | 553 | struct ethtool_ts_info *info) |
553 | { | 554 | { |
555 | struct bfin_mac_local *lp = netdev_priv(dev); | ||
556 | |||
554 | info->so_timestamping = | 557 | info->so_timestamping = |
555 | SOF_TIMESTAMPING_TX_HARDWARE | | 558 | SOF_TIMESTAMPING_TX_HARDWARE | |
556 | SOF_TIMESTAMPING_RX_HARDWARE | | 559 | SOF_TIMESTAMPING_RX_HARDWARE | |
557 | SOF_TIMESTAMPING_SYS_HARDWARE; | 560 | SOF_TIMESTAMPING_RAW_HARDWARE; |
558 | info->phc_index = -1; | 561 | info->phc_index = lp->phc_index; |
559 | info->tx_types = | 562 | info->tx_types = |
560 | (1 << HWTSTAMP_TX_OFF) | | 563 | (1 << HWTSTAMP_TX_OFF) | |
561 | (1 << HWTSTAMP_TX_ON); | 564 | (1 << HWTSTAMP_TX_ON); |
@@ -566,6 +569,7 @@ static int bfin_mac_ethtool_get_ts_info(struct net_device *dev, | |||
566 | (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT); | 569 | (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT); |
567 | return 0; | 570 | return 0; |
568 | } | 571 | } |
572 | #endif | ||
569 | 573 | ||
570 | static const struct ethtool_ops bfin_mac_ethtool_ops = { | 574 | static const struct ethtool_ops bfin_mac_ethtool_ops = { |
571 | .get_settings = bfin_mac_ethtool_getsettings, | 575 | .get_settings = bfin_mac_ethtool_getsettings, |
@@ -574,7 +578,9 @@ static const struct ethtool_ops bfin_mac_ethtool_ops = { | |||
574 | .get_drvinfo = bfin_mac_ethtool_getdrvinfo, | 578 | .get_drvinfo = bfin_mac_ethtool_getdrvinfo, |
575 | .get_wol = bfin_mac_ethtool_getwol, | 579 | .get_wol = bfin_mac_ethtool_getwol, |
576 | .set_wol = bfin_mac_ethtool_setwol, | 580 | .set_wol = bfin_mac_ethtool_setwol, |
581 | #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP | ||
577 | .get_ts_info = bfin_mac_ethtool_get_ts_info, | 582 | .get_ts_info = bfin_mac_ethtool_get_ts_info, |
583 | #endif | ||
578 | }; | 584 | }; |
579 | 585 | ||
580 | /**************************************************************************/ | 586 | /**************************************************************************/ |
@@ -649,6 +655,20 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p) | |||
649 | #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP | 655 | #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP |
650 | #define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE) | 656 | #define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE) |
651 | 657 | ||
658 | static u32 bfin_select_phc_clock(u32 input_clk, unsigned int *shift_result) | ||
659 | { | ||
660 | u32 ipn = 1000000000UL / input_clk; | ||
661 | u32 ppn = 1; | ||
662 | unsigned int shift = 0; | ||
663 | |||
664 | while (ppn <= ipn) { | ||
665 | ppn <<= 1; | ||
666 | shift++; | ||
667 | } | ||
668 | *shift_result = shift; | ||
669 | return 1000000000UL / ppn; | ||
670 | } | ||
671 | |||
652 | static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, | 672 | static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, |
653 | struct ifreq *ifr, int cmd) | 673 | struct ifreq *ifr, int cmd) |
654 | { | 674 | { |
@@ -798,19 +818,7 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, | |||
798 | bfin_read_EMAC_PTP_TXSNAPLO(); | 818 | bfin_read_EMAC_PTP_TXSNAPLO(); |
799 | bfin_read_EMAC_PTP_TXSNAPHI(); | 819 | bfin_read_EMAC_PTP_TXSNAPHI(); |
800 | 820 | ||
801 | /* | ||
802 | * Set registers so that rollover occurs soon to test this. | ||
803 | */ | ||
804 | bfin_write_EMAC_PTP_TIMELO(0x00000000); | ||
805 | bfin_write_EMAC_PTP_TIMEHI(0xFF800000); | ||
806 | |||
807 | SSYNC(); | 821 | SSYNC(); |
808 | |||
809 | lp->compare.last_update = 0; | ||
810 | timecounter_init(&lp->clock, | ||
811 | &lp->cycles, | ||
812 | ktime_to_ns(ktime_get_real())); | ||
813 | timecompare_update(&lp->compare, 0); | ||
814 | } | 822 | } |
815 | 823 | ||
816 | lp->stamp_cfg = config; | 824 | lp->stamp_cfg = config; |
@@ -818,15 +826,6 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, | |||
818 | -EFAULT : 0; | 826 | -EFAULT : 0; |
819 | } | 827 | } |
820 | 828 | ||
821 | static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompare *cmp) | ||
822 | { | ||
823 | ktime_t sys = ktime_get_real(); | ||
824 | |||
825 | pr_debug("%s %s hardware:%d,%d transform system:%d,%d system:%d,%d, cmp:%lld, %lld\n", | ||
826 | __func__, s, hw->tv.sec, hw->tv.nsec, ts->tv.sec, ts->tv.nsec, sys.tv.sec, | ||
827 | sys.tv.nsec, cmp->offset, cmp->skew); | ||
828 | } | ||
829 | |||
830 | static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) | 829 | static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) |
831 | { | 830 | { |
832 | struct bfin_mac_local *lp = netdev_priv(netdev); | 831 | struct bfin_mac_local *lp = netdev_priv(netdev); |
@@ -857,15 +856,9 @@ static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) | |||
857 | regval = bfin_read_EMAC_PTP_TXSNAPLO(); | 856 | regval = bfin_read_EMAC_PTP_TXSNAPLO(); |
858 | regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32; | 857 | regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32; |
859 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | 858 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); |
860 | ns = timecounter_cyc2time(&lp->clock, | 859 | ns = regval << lp->shift; |
861 | regval); | ||
862 | timecompare_update(&lp->compare, ns); | ||
863 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | 860 | shhwtstamps.hwtstamp = ns_to_ktime(ns); |
864 | shhwtstamps.syststamp = | ||
865 | timecompare_transform(&lp->compare, ns); | ||
866 | skb_tstamp_tx(skb, &shhwtstamps); | 861 | skb_tstamp_tx(skb, &shhwtstamps); |
867 | |||
868 | bfin_dump_hwtamp("TX", &shhwtstamps.hwtstamp, &shhwtstamps.syststamp, &lp->compare); | ||
869 | } | 862 | } |
870 | } | 863 | } |
871 | } | 864 | } |
@@ -888,55 +881,184 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) | |||
888 | 881 | ||
889 | regval = bfin_read_EMAC_PTP_RXSNAPLO(); | 882 | regval = bfin_read_EMAC_PTP_RXSNAPLO(); |
890 | regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32; | 883 | regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32; |
891 | ns = timecounter_cyc2time(&lp->clock, regval); | 884 | ns = regval << lp->shift; |
892 | timecompare_update(&lp->compare, ns); | ||
893 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | 885 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); |
894 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | 886 | shhwtstamps->hwtstamp = ns_to_ktime(ns); |
895 | shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns); | 887 | } |
888 | |||
889 | static void bfin_mac_hwtstamp_init(struct net_device *netdev) | ||
890 | { | ||
891 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
892 | u64 addend, ppb; | ||
893 | u32 input_clk, phc_clk; | ||
894 | |||
895 | /* Initialize hardware timer */ | ||
896 | input_clk = get_sclk(); | ||
897 | phc_clk = bfin_select_phc_clock(input_clk, &lp->shift); | ||
898 | addend = phc_clk * (1ULL << 32); | ||
899 | do_div(addend, input_clk); | ||
900 | bfin_write_EMAC_PTP_ADDEND((u32)addend); | ||
901 | |||
902 | lp->addend = addend; | ||
903 | ppb = 1000000000ULL * input_clk; | ||
904 | do_div(ppb, phc_clk); | ||
905 | lp->max_ppb = ppb - 1000000000ULL - 1ULL; | ||
896 | 906 | ||
897 | bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare); | 907 | /* Initialize hwstamp config */ |
908 | lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; | ||
909 | lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF; | ||
898 | } | 910 | } |
899 | 911 | ||
900 | /* | 912 | static u64 bfin_ptp_time_read(struct bfin_mac_local *lp) |
901 | * bfin_read_clock - read raw cycle counter (to be used by time counter) | ||
902 | */ | ||
903 | static cycle_t bfin_read_clock(const struct cyclecounter *tc) | ||
904 | { | 913 | { |
905 | u64 stamp; | 914 | u64 ns; |
915 | u32 lo, hi; | ||
916 | |||
917 | lo = bfin_read_EMAC_PTP_TIMELO(); | ||
918 | hi = bfin_read_EMAC_PTP_TIMEHI(); | ||
906 | 919 | ||
907 | stamp = bfin_read_EMAC_PTP_TIMELO(); | 920 | ns = ((u64) hi) << 32; |
908 | stamp |= (u64)bfin_read_EMAC_PTP_TIMEHI() << 32ULL; | 921 | ns |= lo; |
922 | ns <<= lp->shift; | ||
909 | 923 | ||
910 | return stamp; | 924 | return ns; |
911 | } | 925 | } |
912 | 926 | ||
913 | #define PTP_CLK 25000000 | 927 | static void bfin_ptp_time_write(struct bfin_mac_local *lp, u64 ns) |
928 | { | ||
929 | u32 hi, lo; | ||
914 | 930 | ||
915 | static void bfin_mac_hwtstamp_init(struct net_device *netdev) | 931 | ns >>= lp->shift; |
932 | hi = ns >> 32; | ||
933 | lo = ns & 0xffffffff; | ||
934 | |||
935 | bfin_write_EMAC_PTP_TIMELO(lo); | ||
936 | bfin_write_EMAC_PTP_TIMEHI(hi); | ||
937 | } | ||
938 | |||
939 | /* PTP Hardware Clock operations */ | ||
940 | |||
941 | static int bfin_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | ||
942 | { | ||
943 | u64 adj; | ||
944 | u32 diff, addend; | ||
945 | int neg_adj = 0; | ||
946 | struct bfin_mac_local *lp = | ||
947 | container_of(ptp, struct bfin_mac_local, caps); | ||
948 | |||
949 | if (ppb < 0) { | ||
950 | neg_adj = 1; | ||
951 | ppb = -ppb; | ||
952 | } | ||
953 | addend = lp->addend; | ||
954 | adj = addend; | ||
955 | adj *= ppb; | ||
956 | diff = div_u64(adj, 1000000000ULL); | ||
957 | |||
958 | addend = neg_adj ? addend - diff : addend + diff; | ||
959 | |||
960 | bfin_write_EMAC_PTP_ADDEND(addend); | ||
961 | |||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | static int bfin_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | ||
966 | { | ||
967 | s64 now; | ||
968 | unsigned long flags; | ||
969 | struct bfin_mac_local *lp = | ||
970 | container_of(ptp, struct bfin_mac_local, caps); | ||
971 | |||
972 | spin_lock_irqsave(&lp->phc_lock, flags); | ||
973 | |||
974 | now = bfin_ptp_time_read(lp); | ||
975 | now += delta; | ||
976 | bfin_ptp_time_write(lp, now); | ||
977 | |||
978 | spin_unlock_irqrestore(&lp->phc_lock, flags); | ||
979 | |||
980 | return 0; | ||
981 | } | ||
982 | |||
983 | static int bfin_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | ||
984 | { | ||
985 | u64 ns; | ||
986 | u32 remainder; | ||
987 | unsigned long flags; | ||
988 | struct bfin_mac_local *lp = | ||
989 | container_of(ptp, struct bfin_mac_local, caps); | ||
990 | |||
991 | spin_lock_irqsave(&lp->phc_lock, flags); | ||
992 | |||
993 | ns = bfin_ptp_time_read(lp); | ||
994 | |||
995 | spin_unlock_irqrestore(&lp->phc_lock, flags); | ||
996 | |||
997 | ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); | ||
998 | ts->tv_nsec = remainder; | ||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | static int bfin_ptp_settime(struct ptp_clock_info *ptp, | ||
1003 | const struct timespec *ts) | ||
1004 | { | ||
1005 | u64 ns; | ||
1006 | unsigned long flags; | ||
1007 | struct bfin_mac_local *lp = | ||
1008 | container_of(ptp, struct bfin_mac_local, caps); | ||
1009 | |||
1010 | ns = ts->tv_sec * 1000000000ULL; | ||
1011 | ns += ts->tv_nsec; | ||
1012 | |||
1013 | spin_lock_irqsave(&lp->phc_lock, flags); | ||
1014 | |||
1015 | bfin_ptp_time_write(lp, ns); | ||
1016 | |||
1017 | spin_unlock_irqrestore(&lp->phc_lock, flags); | ||
1018 | |||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | static int bfin_ptp_enable(struct ptp_clock_info *ptp, | ||
1023 | struct ptp_clock_request *rq, int on) | ||
1024 | { | ||
1025 | return -EOPNOTSUPP; | ||
1026 | } | ||
1027 | |||
1028 | static struct ptp_clock_info bfin_ptp_caps = { | ||
1029 | .owner = THIS_MODULE, | ||
1030 | .name = "BF518 clock", | ||
1031 | .max_adj = 0, | ||
1032 | .n_alarm = 0, | ||
1033 | .n_ext_ts = 0, | ||
1034 | .n_per_out = 0, | ||
1035 | .pps = 0, | ||
1036 | .adjfreq = bfin_ptp_adjfreq, | ||
1037 | .adjtime = bfin_ptp_adjtime, | ||
1038 | .gettime = bfin_ptp_gettime, | ||
1039 | .settime = bfin_ptp_settime, | ||
1040 | .enable = bfin_ptp_enable, | ||
1041 | }; | ||
1042 | |||
1043 | static int bfin_phc_init(struct net_device *netdev, struct device *dev) | ||
916 | { | 1044 | { |
917 | struct bfin_mac_local *lp = netdev_priv(netdev); | 1045 | struct bfin_mac_local *lp = netdev_priv(netdev); |
918 | u64 append; | ||
919 | 1046 | ||
920 | /* Initialize hardware timer */ | 1047 | lp->caps = bfin_ptp_caps; |
921 | append = PTP_CLK * (1ULL << 32); | 1048 | lp->caps.max_adj = lp->max_ppb; |
922 | do_div(append, get_sclk()); | 1049 | lp->clock = ptp_clock_register(&lp->caps, dev); |
923 | bfin_write_EMAC_PTP_ADDEND((u32)append); | 1050 | if (IS_ERR(lp->clock)) |
924 | 1051 | return PTR_ERR(lp->clock); | |
925 | memset(&lp->cycles, 0, sizeof(lp->cycles)); | ||
926 | lp->cycles.read = bfin_read_clock; | ||
927 | lp->cycles.mask = CLOCKSOURCE_MASK(64); | ||
928 | lp->cycles.mult = 1000000000 / PTP_CLK; | ||
929 | lp->cycles.shift = 0; | ||
930 | |||
931 | /* Synchronize our NIC clock against system wall clock */ | ||
932 | memset(&lp->compare, 0, sizeof(lp->compare)); | ||
933 | lp->compare.source = &lp->clock; | ||
934 | lp->compare.target = ktime_get_real; | ||
935 | lp->compare.num_samples = 10; | ||
936 | 1052 | ||
937 | /* Initialize hwstamp config */ | 1053 | lp->phc_index = ptp_clock_index(lp->clock); |
938 | lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; | 1054 | spin_lock_init(&lp->phc_lock); |
939 | lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF; | 1055 | |
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static void bfin_phc_release(struct bfin_mac_local *lp) | ||
1060 | { | ||
1061 | ptp_clock_unregister(lp->clock); | ||
940 | } | 1062 | } |
941 | 1063 | ||
942 | #else | 1064 | #else |
@@ -945,6 +1067,8 @@ static void bfin_mac_hwtstamp_init(struct net_device *netdev) | |||
945 | # define bfin_mac_hwtstamp_ioctl(dev, ifr, cmd) (-EOPNOTSUPP) | 1067 | # define bfin_mac_hwtstamp_ioctl(dev, ifr, cmd) (-EOPNOTSUPP) |
946 | # define bfin_rx_hwtstamp(dev, skb) | 1068 | # define bfin_rx_hwtstamp(dev, skb) |
947 | # define bfin_tx_hwtstamp(dev, skb) | 1069 | # define bfin_tx_hwtstamp(dev, skb) |
1070 | # define bfin_phc_init(netdev, dev) 0 | ||
1071 | # define bfin_phc_release(lp) | ||
948 | #endif | 1072 | #endif |
949 | 1073 | ||
950 | static inline void _tx_reclaim_skb(void) | 1074 | static inline void _tx_reclaim_skb(void) |
@@ -1579,12 +1703,17 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) | |||
1579 | } | 1703 | } |
1580 | 1704 | ||
1581 | bfin_mac_hwtstamp_init(ndev); | 1705 | bfin_mac_hwtstamp_init(ndev); |
1706 | if (bfin_phc_init(ndev, &pdev->dev)) { | ||
1707 | dev_err(&pdev->dev, "Cannot register PHC device!\n"); | ||
1708 | goto out_err_phc; | ||
1709 | } | ||
1582 | 1710 | ||
1583 | /* now, print out the card info, in a short format.. */ | 1711 | /* now, print out the card info, in a short format.. */ |
1584 | netdev_info(ndev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); | 1712 | netdev_info(ndev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); |
1585 | 1713 | ||
1586 | return 0; | 1714 | return 0; |
1587 | 1715 | ||
1716 | out_err_phc: | ||
1588 | out_err_reg_ndev: | 1717 | out_err_reg_ndev: |
1589 | free_irq(IRQ_MAC_RX, ndev); | 1718 | free_irq(IRQ_MAC_RX, ndev); |
1590 | out_err_request_irq: | 1719 | out_err_request_irq: |
@@ -1603,6 +1732,8 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev) | |||
1603 | struct net_device *ndev = platform_get_drvdata(pdev); | 1732 | struct net_device *ndev = platform_get_drvdata(pdev); |
1604 | struct bfin_mac_local *lp = netdev_priv(ndev); | 1733 | struct bfin_mac_local *lp = netdev_priv(ndev); |
1605 | 1734 | ||
1735 | bfin_phc_release(lp); | ||
1736 | |||
1606 | platform_set_drvdata(pdev, NULL); | 1737 | platform_set_drvdata(pdev, NULL); |
1607 | 1738 | ||
1608 | lp->mii_bus->priv = NULL; | 1739 | lp->mii_bus->priv = NULL; |
diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h index 960905c08223..7a07ee07906b 100644 --- a/drivers/net/ethernet/adi/bfin_mac.h +++ b/drivers/net/ethernet/adi/bfin_mac.h | |||
@@ -11,8 +11,7 @@ | |||
11 | #define _BFIN_MAC_H_ | 11 | #define _BFIN_MAC_H_ |
12 | 12 | ||
13 | #include <linux/net_tstamp.h> | 13 | #include <linux/net_tstamp.h> |
14 | #include <linux/clocksource.h> | 14 | #include <linux/ptp_clock_kernel.h> |
15 | #include <linux/timecompare.h> | ||
16 | #include <linux/timer.h> | 15 | #include <linux/timer.h> |
17 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
18 | #include <linux/bfin_mac.h> | 17 | #include <linux/bfin_mac.h> |
@@ -94,10 +93,14 @@ struct bfin_mac_local { | |||
94 | struct mii_bus *mii_bus; | 93 | struct mii_bus *mii_bus; |
95 | 94 | ||
96 | #if defined(CONFIG_BFIN_MAC_USE_HWSTAMP) | 95 | #if defined(CONFIG_BFIN_MAC_USE_HWSTAMP) |
97 | struct cyclecounter cycles; | 96 | u32 addend; |
98 | struct timecounter clock; | 97 | unsigned int shift; |
99 | struct timecompare compare; | 98 | s32 max_ppb; |
100 | struct hwtstamp_config stamp_cfg; | 99 | struct hwtstamp_config stamp_cfg; |
100 | struct ptp_clock_info caps; | ||
101 | struct ptp_clock *clock; | ||
102 | int phc_index; | ||
103 | spinlock_t phc_lock; /* protects time lo/hi registers */ | ||
101 | #endif | 104 | #endif |
102 | }; | 105 | }; |
103 | 106 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 72897c47b8c8..de121ccd675e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -34,18 +34,10 @@ | |||
34 | 34 | ||
35 | #include "bnx2x_hsi.h" | 35 | #include "bnx2x_hsi.h" |
36 | 36 | ||
37 | #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) | ||
38 | #define BCM_CNIC 1 | ||
39 | #include "../cnic_if.h" | 37 | #include "../cnic_if.h" |
40 | #endif | ||
41 | 38 | ||
42 | #ifdef BCM_CNIC | 39 | |
43 | #define BNX2X_MIN_MSIX_VEC_CNT 3 | 40 | #define BNX2X_MIN_MSIX_VEC_CNT(bp) ((bp)->min_msix_vec_cnt) |
44 | #define BNX2X_MSIX_VEC_FP_START 2 | ||
45 | #else | ||
46 | #define BNX2X_MIN_MSIX_VEC_CNT 2 | ||
47 | #define BNX2X_MSIX_VEC_FP_START 1 | ||
48 | #endif | ||
49 | 41 | ||
50 | #include <linux/mdio.h> | 42 | #include <linux/mdio.h> |
51 | 43 | ||
@@ -256,15 +248,10 @@ enum { | |||
256 | /* FCoE L2 */ | 248 | /* FCoE L2 */ |
257 | #define BNX2X_FCOE_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp) + 1) | 249 | #define BNX2X_FCOE_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp) + 1) |
258 | 250 | ||
259 | /** Additional rings budgeting */ | 251 | #define CNIC_SUPPORT(bp) ((bp)->cnic_support) |
260 | #ifdef BCM_CNIC | 252 | #define CNIC_ENABLED(bp) ((bp)->cnic_enabled) |
261 | #define CNIC_PRESENT 1 | 253 | #define CNIC_LOADED(bp) ((bp)->cnic_loaded) |
262 | #define FCOE_PRESENT 1 | 254 | #define FCOE_INIT(bp) ((bp)->fcoe_init) |
263 | #else | ||
264 | #define CNIC_PRESENT 0 | ||
265 | #define FCOE_PRESENT 0 | ||
266 | #endif /* BCM_CNIC */ | ||
267 | #define NON_ETH_CONTEXT_USE (FCOE_PRESENT) | ||
268 | 255 | ||
269 | #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ | 256 | #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ |
270 | AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR | 257 | AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |
@@ -297,9 +284,7 @@ enum { | |||
297 | OOO_TXQ_IDX_OFFSET, | 284 | OOO_TXQ_IDX_OFFSET, |
298 | }; | 285 | }; |
299 | #define MAX_ETH_TXQ_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) * (bp)->max_cos) | 286 | #define MAX_ETH_TXQ_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) * (bp)->max_cos) |
300 | #ifdef BCM_CNIC | ||
301 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp) + FCOE_TXQ_IDX_OFFSET) | 287 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp) + FCOE_TXQ_IDX_OFFSET) |
302 | #endif | ||
303 | 288 | ||
304 | /* fast path */ | 289 | /* fast path */ |
305 | /* | 290 | /* |
@@ -585,15 +570,9 @@ struct bnx2x_fastpath { | |||
585 | ->var) | 570 | ->var) |
586 | 571 | ||
587 | 572 | ||
588 | #define IS_ETH_FP(fp) (fp->index < \ | 573 | #define IS_ETH_FP(fp) ((fp)->index < BNX2X_NUM_ETH_QUEUES((fp)->bp)) |
589 | BNX2X_NUM_ETH_QUEUES(fp->bp)) | 574 | #define IS_FCOE_FP(fp) ((fp)->index == FCOE_IDX((fp)->bp)) |
590 | #ifdef BCM_CNIC | 575 | #define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX(bp)) |
591 | #define IS_FCOE_FP(fp) (fp->index == FCOE_IDX(fp->bp)) | ||
592 | #define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX(bp)) | ||
593 | #else | ||
594 | #define IS_FCOE_FP(fp) false | ||
595 | #define IS_FCOE_IDX(idx) false | ||
596 | #endif | ||
597 | 576 | ||
598 | 577 | ||
599 | /* MC hsi */ | 578 | /* MC hsi */ |
@@ -886,6 +865,18 @@ struct bnx2x_common { | |||
886 | (CHIP_REV(bp) == CHIP_REV_Bx)) | 865 | (CHIP_REV(bp) == CHIP_REV_Bx)) |
887 | #define CHIP_IS_E3A0(bp) (CHIP_IS_E3(bp) && \ | 866 | #define CHIP_IS_E3A0(bp) (CHIP_IS_E3(bp) && \ |
888 | (CHIP_REV(bp) == CHIP_REV_Ax)) | 867 | (CHIP_REV(bp) == CHIP_REV_Ax)) |
868 | /* This define is used in two main places: | ||
869 | * 1. In the early stages of nic_load, to know if to configrue Parser / Searcher | ||
870 | * to nic-only mode or to offload mode. Offload mode is configured if either the | ||
871 | * chip is E1x (where MIC_MODE register is not applicable), or if cnic already | ||
872 | * registered for this port (which means that the user wants storage services). | ||
873 | * 2. During cnic-related load, to know if offload mode is already configured in | ||
874 | * the HW or needs to be configrued. | ||
875 | * Since the transition from nic-mode to offload-mode in HW causes traffic | ||
876 | * coruption, nic-mode is configured only in ports on which storage services | ||
877 | * where never requested. | ||
878 | */ | ||
879 | #define CONFIGURE_NIC_MODE(bp) (!CHIP_IS_E1x(bp) && !CNIC_ENABLED(bp)) | ||
889 | 880 | ||
890 | int flash_size; | 881 | int flash_size; |
891 | #define BNX2X_NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ | 882 | #define BNX2X_NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ |
@@ -1003,18 +994,15 @@ union cdu_context { | |||
1003 | #define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */ | 994 | #define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */ |
1004 | #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) | 995 | #define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) |
1005 | 996 | ||
1006 | #ifdef BCM_CNIC | ||
1007 | #define CNIC_ISCSI_CID_MAX 256 | 997 | #define CNIC_ISCSI_CID_MAX 256 |
1008 | #define CNIC_FCOE_CID_MAX 2048 | 998 | #define CNIC_FCOE_CID_MAX 2048 |
1009 | #define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX) | 999 | #define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX) |
1010 | #define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) | 1000 | #define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) |
1011 | #endif | ||
1012 | 1001 | ||
1013 | #define QM_ILT_PAGE_SZ_HW 0 | 1002 | #define QM_ILT_PAGE_SZ_HW 0 |
1014 | #define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 4K */ | 1003 | #define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 4K */ |
1015 | #define QM_CID_ROUND 1024 | 1004 | #define QM_CID_ROUND 1024 |
1016 | 1005 | ||
1017 | #ifdef BCM_CNIC | ||
1018 | /* TM (timers) host DB constants */ | 1006 | /* TM (timers) host DB constants */ |
1019 | #define TM_ILT_PAGE_SZ_HW 0 | 1007 | #define TM_ILT_PAGE_SZ_HW 0 |
1020 | #define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */ | 1008 | #define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */ |
@@ -1032,8 +1020,6 @@ union cdu_context { | |||
1032 | #define SRC_T2_SZ SRC_ILT_SZ | 1020 | #define SRC_T2_SZ SRC_ILT_SZ |
1033 | #define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) | 1021 | #define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) |
1034 | 1022 | ||
1035 | #endif | ||
1036 | |||
1037 | #define MAX_DMAE_C 8 | 1023 | #define MAX_DMAE_C 8 |
1038 | 1024 | ||
1039 | /* DMA memory not used in fastpath */ | 1025 | /* DMA memory not used in fastpath */ |
@@ -1227,7 +1213,6 @@ struct bnx2x { | |||
1227 | struct bnx2x_sp_objs *sp_objs; | 1213 | struct bnx2x_sp_objs *sp_objs; |
1228 | struct bnx2x_fp_stats *fp_stats; | 1214 | struct bnx2x_fp_stats *fp_stats; |
1229 | struct bnx2x_fp_txdata *bnx2x_txq; | 1215 | struct bnx2x_fp_txdata *bnx2x_txq; |
1230 | int bnx2x_txq_size; | ||
1231 | void __iomem *regview; | 1216 | void __iomem *regview; |
1232 | void __iomem *doorbells; | 1217 | void __iomem *doorbells; |
1233 | u16 db_size; | 1218 | u16 db_size; |
@@ -1350,6 +1335,15 @@ struct bnx2x { | |||
1350 | #define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG) | 1335 | #define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG) |
1351 | #define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) | 1336 | #define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) |
1352 | 1337 | ||
1338 | u8 cnic_support; | ||
1339 | bool cnic_enabled; | ||
1340 | bool cnic_loaded; | ||
1341 | |||
1342 | /* Flag that indicates that we can start looking for FCoE L2 queue | ||
1343 | * completions in the default status block. | ||
1344 | */ | ||
1345 | bool fcoe_init; | ||
1346 | |||
1353 | int pm_cap; | 1347 | int pm_cap; |
1354 | int mrrs; | 1348 | int mrrs; |
1355 | 1349 | ||
@@ -1420,6 +1414,8 @@ struct bnx2x { | |||
1420 | #define BNX2X_MAX_COS 3 | 1414 | #define BNX2X_MAX_COS 3 |
1421 | #define BNX2X_MAX_TX_COS 2 | 1415 | #define BNX2X_MAX_TX_COS 2 |
1422 | int num_queues; | 1416 | int num_queues; |
1417 | uint num_ethernet_queues; | ||
1418 | uint num_cnic_queues; | ||
1423 | int num_napi_queues; | 1419 | int num_napi_queues; |
1424 | int disable_tpa; | 1420 | int disable_tpa; |
1425 | 1421 | ||
@@ -1433,6 +1429,7 @@ struct bnx2x { | |||
1433 | u8 igu_dsb_id; | 1429 | u8 igu_dsb_id; |
1434 | u8 igu_base_sb; | 1430 | u8 igu_base_sb; |
1435 | u8 igu_sb_cnt; | 1431 | u8 igu_sb_cnt; |
1432 | u8 min_msix_vec_cnt; | ||
1436 | 1433 | ||
1437 | dma_addr_t def_status_blk_mapping; | 1434 | dma_addr_t def_status_blk_mapping; |
1438 | 1435 | ||
@@ -1478,16 +1475,16 @@ struct bnx2x { | |||
1478 | * Maximum supported number of RSS queues: number of IGU SBs minus one that goes | 1475 | * Maximum supported number of RSS queues: number of IGU SBs minus one that goes |
1479 | * to CNIC. | 1476 | * to CNIC. |
1480 | */ | 1477 | */ |
1481 | #define BNX2X_MAX_RSS_COUNT(bp) ((bp)->igu_sb_cnt - CNIC_PRESENT) | 1478 | #define BNX2X_MAX_RSS_COUNT(bp) ((bp)->igu_sb_cnt - CNIC_SUPPORT(bp)) |
1482 | 1479 | ||
1483 | /* | 1480 | /* |
1484 | * Maximum CID count that might be required by the bnx2x: | 1481 | * Maximum CID count that might be required by the bnx2x: |
1485 | * Max RSS * Max_Tx_Multi_Cos + FCoE + iSCSI | 1482 | * Max RSS * Max_Tx_Multi_Cos + FCoE + iSCSI |
1486 | */ | 1483 | */ |
1487 | #define BNX2X_L2_CID_COUNT(bp) (BNX2X_NUM_ETH_QUEUES(bp) * BNX2X_MULTI_TX_COS \ | 1484 | #define BNX2X_L2_CID_COUNT(bp) (BNX2X_NUM_ETH_QUEUES(bp) * BNX2X_MULTI_TX_COS \ |
1488 | + NON_ETH_CONTEXT_USE + CNIC_PRESENT) | 1485 | + 2 * CNIC_SUPPORT(bp)) |
1489 | #define BNX2X_L2_MAX_CID(bp) (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS \ | 1486 | #define BNX2X_L2_MAX_CID(bp) (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS \ |
1490 | + NON_ETH_CONTEXT_USE + CNIC_PRESENT) | 1487 | + 2 * CNIC_SUPPORT(bp)) |
1491 | #define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\ | 1488 | #define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\ |
1492 | ILT_PAGE_CIDS)) | 1489 | ILT_PAGE_CIDS)) |
1493 | 1490 | ||
@@ -1495,9 +1492,6 @@ struct bnx2x { | |||
1495 | 1492 | ||
1496 | int dropless_fc; | 1493 | int dropless_fc; |
1497 | 1494 | ||
1498 | #ifdef BCM_CNIC | ||
1499 | u32 cnic_flags; | ||
1500 | #define BNX2X_CNIC_FLAG_MAC_SET 1 | ||
1501 | void *t2; | 1495 | void *t2; |
1502 | dma_addr_t t2_mapping; | 1496 | dma_addr_t t2_mapping; |
1503 | struct cnic_ops __rcu *cnic_ops; | 1497 | struct cnic_ops __rcu *cnic_ops; |
@@ -1518,7 +1512,6 @@ struct bnx2x { | |||
1518 | 1512 | ||
1519 | /* Start index of the "special" (CNIC related) L2 cleints */ | 1513 | /* Start index of the "special" (CNIC related) L2 cleints */ |
1520 | u8 cnic_base_cl_id; | 1514 | u8 cnic_base_cl_id; |
1521 | #endif | ||
1522 | 1515 | ||
1523 | int dmae_ready; | 1516 | int dmae_ready; |
1524 | /* used to synchronize dmae accesses */ | 1517 | /* used to synchronize dmae accesses */ |
@@ -1647,9 +1640,9 @@ struct bnx2x { | |||
1647 | /* Tx queues may be less or equal to Rx queues */ | 1640 | /* Tx queues may be less or equal to Rx queues */ |
1648 | extern int num_queues; | 1641 | extern int num_queues; |
1649 | #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) | 1642 | #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) |
1650 | #define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE) | 1643 | #define BNX2X_NUM_ETH_QUEUES(bp) ((bp)->num_ethernet_queues) |
1651 | #define BNX2X_NUM_NON_CNIC_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - \ | 1644 | #define BNX2X_NUM_NON_CNIC_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - \ |
1652 | NON_ETH_CONTEXT_USE) | 1645 | (bp)->num_cnic_queues) |
1653 | #define BNX2X_NUM_RX_QUEUES(bp) BNX2X_NUM_QUEUES(bp) | 1646 | #define BNX2X_NUM_RX_QUEUES(bp) BNX2X_NUM_QUEUES(bp) |
1654 | 1647 | ||
1655 | #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) | 1648 | #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) |
@@ -1689,6 +1682,13 @@ struct bnx2x_func_init_params { | |||
1689 | u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ | 1682 | u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ |
1690 | }; | 1683 | }; |
1691 | 1684 | ||
1685 | #define for_each_cnic_queue(bp, var) \ | ||
1686 | for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \ | ||
1687 | (var)++) \ | ||
1688 | if (skip_queue(bp, var)) \ | ||
1689 | continue; \ | ||
1690 | else | ||
1691 | |||
1692 | #define for_each_eth_queue(bp, var) \ | 1692 | #define for_each_eth_queue(bp, var) \ |
1693 | for ((var) = 0; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++) | 1693 | for ((var) = 0; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++) |
1694 | 1694 | ||
@@ -1702,6 +1702,22 @@ struct bnx2x_func_init_params { | |||
1702 | else | 1702 | else |
1703 | 1703 | ||
1704 | /* Skip forwarding FP */ | 1704 | /* Skip forwarding FP */ |
1705 | #define for_each_valid_rx_queue(bp, var) \ | ||
1706 | for ((var) = 0; \ | ||
1707 | (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) : \ | ||
1708 | BNX2X_NUM_ETH_QUEUES(bp)); \ | ||
1709 | (var)++) \ | ||
1710 | if (skip_rx_queue(bp, var)) \ | ||
1711 | continue; \ | ||
1712 | else | ||
1713 | |||
1714 | #define for_each_rx_queue_cnic(bp, var) \ | ||
1715 | for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \ | ||
1716 | (var)++) \ | ||
1717 | if (skip_rx_queue(bp, var)) \ | ||
1718 | continue; \ | ||
1719 | else | ||
1720 | |||
1705 | #define for_each_rx_queue(bp, var) \ | 1721 | #define for_each_rx_queue(bp, var) \ |
1706 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ | 1722 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ |
1707 | if (skip_rx_queue(bp, var)) \ | 1723 | if (skip_rx_queue(bp, var)) \ |
@@ -1709,6 +1725,22 @@ struct bnx2x_func_init_params { | |||
1709 | else | 1725 | else |
1710 | 1726 | ||
1711 | /* Skip OOO FP */ | 1727 | /* Skip OOO FP */ |
1728 | #define for_each_valid_tx_queue(bp, var) \ | ||
1729 | for ((var) = 0; \ | ||
1730 | (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) : \ | ||
1731 | BNX2X_NUM_ETH_QUEUES(bp)); \ | ||
1732 | (var)++) \ | ||
1733 | if (skip_tx_queue(bp, var)) \ | ||
1734 | continue; \ | ||
1735 | else | ||
1736 | |||
1737 | #define for_each_tx_queue_cnic(bp, var) \ | ||
1738 | for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \ | ||
1739 | (var)++) \ | ||
1740 | if (skip_tx_queue(bp, var)) \ | ||
1741 | continue; \ | ||
1742 | else | ||
1743 | |||
1712 | #define for_each_tx_queue(bp, var) \ | 1744 | #define for_each_tx_queue(bp, var) \ |
1713 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ | 1745 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ |
1714 | if (skip_tx_queue(bp, var)) \ | 1746 | if (skip_tx_queue(bp, var)) \ |
@@ -2179,7 +2211,6 @@ void bnx2x_notify_link_changed(struct bnx2x *bp); | |||
2179 | #define BNX2X_MF_SD_PROTOCOL(bp) \ | 2211 | #define BNX2X_MF_SD_PROTOCOL(bp) \ |
2180 | ((bp)->mf_config[BP_VN(bp)] & FUNC_MF_CFG_PROTOCOL_MASK) | 2212 | ((bp)->mf_config[BP_VN(bp)] & FUNC_MF_CFG_PROTOCOL_MASK) |
2181 | 2213 | ||
2182 | #ifdef BCM_CNIC | ||
2183 | #define BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) \ | 2214 | #define BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) \ |
2184 | (BNX2X_MF_SD_PROTOCOL(bp) == FUNC_MF_CFG_PROTOCOL_ISCSI) | 2215 | (BNX2X_MF_SD_PROTOCOL(bp) == FUNC_MF_CFG_PROTOCOL_ISCSI) |
2185 | 2216 | ||
@@ -2196,9 +2227,12 @@ void bnx2x_notify_link_changed(struct bnx2x *bp); | |||
2196 | #define IS_MF_STORAGE_SD(bp) (IS_MF_SD(bp) && \ | 2227 | #define IS_MF_STORAGE_SD(bp) (IS_MF_SD(bp) && \ |
2197 | (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \ | 2228 | (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \ |
2198 | BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp))) | 2229 | BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp))) |
2199 | #else | ||
2200 | #define IS_MF_FCOE_AFEX(bp) false | ||
2201 | #endif | ||
2202 | 2230 | ||
2231 | enum { | ||
2232 | SWITCH_UPDATE, | ||
2233 | AFEX_UPDATE, | ||
2234 | }; | ||
2235 | |||
2236 | #define NUM_MACS 8 | ||
2203 | 2237 | ||
2204 | #endif /* bnx2x.h */ | 2238 | #endif /* bnx2x.h */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4833b6a9031c..54d522da1aa7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1152,6 +1152,25 @@ static void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
1152 | } | 1152 | } |
1153 | } | 1153 | } |
1154 | 1154 | ||
1155 | void bnx2x_init_rx_rings_cnic(struct bnx2x *bp) | ||
1156 | { | ||
1157 | int j; | ||
1158 | |||
1159 | for_each_rx_queue_cnic(bp, j) { | ||
1160 | struct bnx2x_fastpath *fp = &bp->fp[j]; | ||
1161 | |||
1162 | fp->rx_bd_cons = 0; | ||
1163 | |||
1164 | /* Activate BD ring */ | ||
1165 | /* Warning! | ||
1166 | * this will generate an interrupt (to the TSTORM) | ||
1167 | * must only be done after chip is initialized | ||
1168 | */ | ||
1169 | bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, | ||
1170 | fp->rx_sge_prod); | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1155 | void bnx2x_init_rx_rings(struct bnx2x *bp) | 1174 | void bnx2x_init_rx_rings(struct bnx2x *bp) |
1156 | { | 1175 | { |
1157 | int func = BP_FUNC(bp); | 1176 | int func = BP_FUNC(bp); |
@@ -1159,7 +1178,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1159 | int i, j; | 1178 | int i, j; |
1160 | 1179 | ||
1161 | /* Allocate TPA resources */ | 1180 | /* Allocate TPA resources */ |
1162 | for_each_rx_queue(bp, j) { | 1181 | for_each_eth_queue(bp, j) { |
1163 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 1182 | struct bnx2x_fastpath *fp = &bp->fp[j]; |
1164 | 1183 | ||
1165 | DP(NETIF_MSG_IFUP, | 1184 | DP(NETIF_MSG_IFUP, |
@@ -1217,7 +1236,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1217 | } | 1236 | } |
1218 | } | 1237 | } |
1219 | 1238 | ||
1220 | for_each_rx_queue(bp, j) { | 1239 | for_each_eth_queue(bp, j) { |
1221 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 1240 | struct bnx2x_fastpath *fp = &bp->fp[j]; |
1222 | 1241 | ||
1223 | fp->rx_bd_cons = 0; | 1242 | fp->rx_bd_cons = 0; |
@@ -1244,29 +1263,45 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1244 | } | 1263 | } |
1245 | } | 1264 | } |
1246 | 1265 | ||
1247 | static void bnx2x_free_tx_skbs(struct bnx2x *bp) | 1266 | static void bnx2x_free_tx_skbs_queue(struct bnx2x_fastpath *fp) |
1248 | { | 1267 | { |
1249 | int i; | ||
1250 | u8 cos; | 1268 | u8 cos; |
1269 | struct bnx2x *bp = fp->bp; | ||
1251 | 1270 | ||
1252 | for_each_tx_queue(bp, i) { | 1271 | for_each_cos_in_tx_queue(fp, cos) { |
1253 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1272 | struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; |
1254 | for_each_cos_in_tx_queue(fp, cos) { | 1273 | unsigned pkts_compl = 0, bytes_compl = 0; |
1255 | struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; | ||
1256 | unsigned pkts_compl = 0, bytes_compl = 0; | ||
1257 | 1274 | ||
1258 | u16 sw_prod = txdata->tx_pkt_prod; | 1275 | u16 sw_prod = txdata->tx_pkt_prod; |
1259 | u16 sw_cons = txdata->tx_pkt_cons; | 1276 | u16 sw_cons = txdata->tx_pkt_cons; |
1260 | 1277 | ||
1261 | while (sw_cons != sw_prod) { | 1278 | while (sw_cons != sw_prod) { |
1262 | bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons), | 1279 | bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons), |
1263 | &pkts_compl, &bytes_compl); | 1280 | &pkts_compl, &bytes_compl); |
1264 | sw_cons++; | 1281 | sw_cons++; |
1265 | } | ||
1266 | netdev_tx_reset_queue( | ||
1267 | netdev_get_tx_queue(bp->dev, | ||
1268 | txdata->txq_index)); | ||
1269 | } | 1282 | } |
1283 | |||
1284 | netdev_tx_reset_queue( | ||
1285 | netdev_get_tx_queue(bp->dev, | ||
1286 | txdata->txq_index)); | ||
1287 | } | ||
1288 | } | ||
1289 | |||
1290 | static void bnx2x_free_tx_skbs_cnic(struct bnx2x *bp) | ||
1291 | { | ||
1292 | int i; | ||
1293 | |||
1294 | for_each_tx_queue_cnic(bp, i) { | ||
1295 | bnx2x_free_tx_skbs_queue(&bp->fp[i]); | ||
1296 | } | ||
1297 | } | ||
1298 | |||
1299 | static void bnx2x_free_tx_skbs(struct bnx2x *bp) | ||
1300 | { | ||
1301 | int i; | ||
1302 | |||
1303 | for_each_eth_queue(bp, i) { | ||
1304 | bnx2x_free_tx_skbs_queue(&bp->fp[i]); | ||
1270 | } | 1305 | } |
1271 | } | 1306 | } |
1272 | 1307 | ||
@@ -1294,11 +1329,20 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) | |||
1294 | } | 1329 | } |
1295 | } | 1330 | } |
1296 | 1331 | ||
1332 | static void bnx2x_free_rx_skbs_cnic(struct bnx2x *bp) | ||
1333 | { | ||
1334 | int j; | ||
1335 | |||
1336 | for_each_rx_queue_cnic(bp, j) { | ||
1337 | bnx2x_free_rx_bds(&bp->fp[j]); | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1297 | static void bnx2x_free_rx_skbs(struct bnx2x *bp) | 1341 | static void bnx2x_free_rx_skbs(struct bnx2x *bp) |
1298 | { | 1342 | { |
1299 | int j; | 1343 | int j; |
1300 | 1344 | ||
1301 | for_each_rx_queue(bp, j) { | 1345 | for_each_eth_queue(bp, j) { |
1302 | struct bnx2x_fastpath *fp = &bp->fp[j]; | 1346 | struct bnx2x_fastpath *fp = &bp->fp[j]; |
1303 | 1347 | ||
1304 | bnx2x_free_rx_bds(fp); | 1348 | bnx2x_free_rx_bds(fp); |
@@ -1308,6 +1352,12 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) | |||
1308 | } | 1352 | } |
1309 | } | 1353 | } |
1310 | 1354 | ||
1355 | void bnx2x_free_skbs_cnic(struct bnx2x *bp) | ||
1356 | { | ||
1357 | bnx2x_free_tx_skbs_cnic(bp); | ||
1358 | bnx2x_free_rx_skbs_cnic(bp); | ||
1359 | } | ||
1360 | |||
1311 | void bnx2x_free_skbs(struct bnx2x *bp) | 1361 | void bnx2x_free_skbs(struct bnx2x *bp) |
1312 | { | 1362 | { |
1313 | bnx2x_free_tx_skbs(bp); | 1363 | bnx2x_free_tx_skbs(bp); |
@@ -1347,11 +1397,12 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp, int nvecs) | |||
1347 | DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", | 1397 | DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", |
1348 | bp->msix_table[offset].vector); | 1398 | bp->msix_table[offset].vector); |
1349 | offset++; | 1399 | offset++; |
1350 | #ifdef BCM_CNIC | 1400 | |
1351 | if (nvecs == offset) | 1401 | if (CNIC_SUPPORT(bp)) { |
1352 | return; | 1402 | if (nvecs == offset) |
1353 | offset++; | 1403 | return; |
1354 | #endif | 1404 | offset++; |
1405 | } | ||
1355 | 1406 | ||
1356 | for_each_eth_queue(bp, i) { | 1407 | for_each_eth_queue(bp, i) { |
1357 | if (nvecs == offset) | 1408 | if (nvecs == offset) |
@@ -1368,7 +1419,7 @@ void bnx2x_free_irq(struct bnx2x *bp) | |||
1368 | if (bp->flags & USING_MSIX_FLAG && | 1419 | if (bp->flags & USING_MSIX_FLAG && |
1369 | !(bp->flags & USING_SINGLE_MSIX_FLAG)) | 1420 | !(bp->flags & USING_SINGLE_MSIX_FLAG)) |
1370 | bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) + | 1421 | bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) + |
1371 | CNIC_PRESENT + 1); | 1422 | CNIC_SUPPORT(bp) + 1); |
1372 | else | 1423 | else |
1373 | free_irq(bp->dev->irq, bp->dev); | 1424 | free_irq(bp->dev->irq, bp->dev); |
1374 | } | 1425 | } |
@@ -1382,12 +1433,14 @@ int bnx2x_enable_msix(struct bnx2x *bp) | |||
1382 | bp->msix_table[0].entry); | 1433 | bp->msix_table[0].entry); |
1383 | msix_vec++; | 1434 | msix_vec++; |
1384 | 1435 | ||
1385 | #ifdef BCM_CNIC | 1436 | /* Cnic requires an msix vector for itself */ |
1386 | bp->msix_table[msix_vec].entry = msix_vec; | 1437 | if (CNIC_SUPPORT(bp)) { |
1387 | BNX2X_DEV_INFO("msix_table[%d].entry = %d (CNIC)\n", | 1438 | bp->msix_table[msix_vec].entry = msix_vec; |
1388 | bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); | 1439 | BNX2X_DEV_INFO("msix_table[%d].entry = %d (CNIC)\n", |
1389 | msix_vec++; | 1440 | msix_vec, bp->msix_table[msix_vec].entry); |
1390 | #endif | 1441 | msix_vec++; |
1442 | } | ||
1443 | |||
1391 | /* We need separate vectors for ETH queues only (not FCoE) */ | 1444 | /* We need separate vectors for ETH queues only (not FCoE) */ |
1392 | for_each_eth_queue(bp, i) { | 1445 | for_each_eth_queue(bp, i) { |
1393 | bp->msix_table[msix_vec].entry = msix_vec; | 1446 | bp->msix_table[msix_vec].entry = msix_vec; |
@@ -1396,7 +1449,7 @@ int bnx2x_enable_msix(struct bnx2x *bp) | |||
1396 | msix_vec++; | 1449 | msix_vec++; |
1397 | } | 1450 | } |
1398 | 1451 | ||
1399 | req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_PRESENT + 1; | 1452 | req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_SUPPORT(bp) + 1; |
1400 | 1453 | ||
1401 | rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); | 1454 | rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); |
1402 | 1455 | ||
@@ -1404,7 +1457,7 @@ int bnx2x_enable_msix(struct bnx2x *bp) | |||
1404 | * reconfigure number of tx/rx queues according to available | 1457 | * reconfigure number of tx/rx queues according to available |
1405 | * MSI-X vectors | 1458 | * MSI-X vectors |
1406 | */ | 1459 | */ |
1407 | if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { | 1460 | if (rc >= BNX2X_MIN_MSIX_VEC_CNT(bp)) { |
1408 | /* how less vectors we will have? */ | 1461 | /* how less vectors we will have? */ |
1409 | int diff = req_cnt - rc; | 1462 | int diff = req_cnt - rc; |
1410 | 1463 | ||
@@ -1419,7 +1472,8 @@ int bnx2x_enable_msix(struct bnx2x *bp) | |||
1419 | /* | 1472 | /* |
1420 | * decrease number of queues by number of unallocated entries | 1473 | * decrease number of queues by number of unallocated entries |
1421 | */ | 1474 | */ |
1422 | bp->num_queues -= diff; | 1475 | bp->num_ethernet_queues -= diff; |
1476 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
1423 | 1477 | ||
1424 | BNX2X_DEV_INFO("New queue configuration set: %d\n", | 1478 | BNX2X_DEV_INFO("New queue configuration set: %d\n", |
1425 | bp->num_queues); | 1479 | bp->num_queues); |
@@ -1435,6 +1489,9 @@ int bnx2x_enable_msix(struct bnx2x *bp) | |||
1435 | BNX2X_DEV_INFO("Using single MSI-X vector\n"); | 1489 | BNX2X_DEV_INFO("Using single MSI-X vector\n"); |
1436 | bp->flags |= USING_SINGLE_MSIX_FLAG; | 1490 | bp->flags |= USING_SINGLE_MSIX_FLAG; |
1437 | 1491 | ||
1492 | BNX2X_DEV_INFO("set number of queues to 1\n"); | ||
1493 | bp->num_ethernet_queues = 1; | ||
1494 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
1438 | } else if (rc < 0) { | 1495 | } else if (rc < 0) { |
1439 | BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); | 1496 | BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); |
1440 | goto no_msix; | 1497 | goto no_msix; |
@@ -1464,9 +1521,9 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) | |||
1464 | return -EBUSY; | 1521 | return -EBUSY; |
1465 | } | 1522 | } |
1466 | 1523 | ||
1467 | #ifdef BCM_CNIC | 1524 | if (CNIC_SUPPORT(bp)) |
1468 | offset++; | 1525 | offset++; |
1469 | #endif | 1526 | |
1470 | for_each_eth_queue(bp, i) { | 1527 | for_each_eth_queue(bp, i) { |
1471 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1528 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
1472 | snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", | 1529 | snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", |
@@ -1485,7 +1542,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) | |||
1485 | } | 1542 | } |
1486 | 1543 | ||
1487 | i = BNX2X_NUM_ETH_QUEUES(bp); | 1544 | i = BNX2X_NUM_ETH_QUEUES(bp); |
1488 | offset = 1 + CNIC_PRESENT; | 1545 | offset = 1 + CNIC_SUPPORT(bp); |
1489 | netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d ... fp[%d] %d\n", | 1546 | netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d ... fp[%d] %d\n", |
1490 | bp->msix_table[0].vector, | 1547 | bp->msix_table[0].vector, |
1491 | 0, bp->msix_table[offset].vector, | 1548 | 0, bp->msix_table[offset].vector, |
@@ -1556,19 +1613,35 @@ static int bnx2x_setup_irqs(struct bnx2x *bp) | |||
1556 | return 0; | 1613 | return 0; |
1557 | } | 1614 | } |
1558 | 1615 | ||
1616 | static void bnx2x_napi_enable_cnic(struct bnx2x *bp) | ||
1617 | { | ||
1618 | int i; | ||
1619 | |||
1620 | for_each_rx_queue_cnic(bp, i) | ||
1621 | napi_enable(&bnx2x_fp(bp, i, napi)); | ||
1622 | } | ||
1623 | |||
1559 | static void bnx2x_napi_enable(struct bnx2x *bp) | 1624 | static void bnx2x_napi_enable(struct bnx2x *bp) |
1560 | { | 1625 | { |
1561 | int i; | 1626 | int i; |
1562 | 1627 | ||
1563 | for_each_rx_queue(bp, i) | 1628 | for_each_eth_queue(bp, i) |
1564 | napi_enable(&bnx2x_fp(bp, i, napi)); | 1629 | napi_enable(&bnx2x_fp(bp, i, napi)); |
1565 | } | 1630 | } |
1566 | 1631 | ||
1632 | static void bnx2x_napi_disable_cnic(struct bnx2x *bp) | ||
1633 | { | ||
1634 | int i; | ||
1635 | |||
1636 | for_each_rx_queue_cnic(bp, i) | ||
1637 | napi_disable(&bnx2x_fp(bp, i, napi)); | ||
1638 | } | ||
1639 | |||
1567 | static void bnx2x_napi_disable(struct bnx2x *bp) | 1640 | static void bnx2x_napi_disable(struct bnx2x *bp) |
1568 | { | 1641 | { |
1569 | int i; | 1642 | int i; |
1570 | 1643 | ||
1571 | for_each_rx_queue(bp, i) | 1644 | for_each_eth_queue(bp, i) |
1572 | napi_disable(&bnx2x_fp(bp, i, napi)); | 1645 | napi_disable(&bnx2x_fp(bp, i, napi)); |
1573 | } | 1646 | } |
1574 | 1647 | ||
@@ -1576,6 +1649,8 @@ void bnx2x_netif_start(struct bnx2x *bp) | |||
1576 | { | 1649 | { |
1577 | if (netif_running(bp->dev)) { | 1650 | if (netif_running(bp->dev)) { |
1578 | bnx2x_napi_enable(bp); | 1651 | bnx2x_napi_enable(bp); |
1652 | if (CNIC_LOADED(bp)) | ||
1653 | bnx2x_napi_enable_cnic(bp); | ||
1579 | bnx2x_int_enable(bp); | 1654 | bnx2x_int_enable(bp); |
1580 | if (bp->state == BNX2X_STATE_OPEN) | 1655 | if (bp->state == BNX2X_STATE_OPEN) |
1581 | netif_tx_wake_all_queues(bp->dev); | 1656 | netif_tx_wake_all_queues(bp->dev); |
@@ -1586,14 +1661,15 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) | |||
1586 | { | 1661 | { |
1587 | bnx2x_int_disable_sync(bp, disable_hw); | 1662 | bnx2x_int_disable_sync(bp, disable_hw); |
1588 | bnx2x_napi_disable(bp); | 1663 | bnx2x_napi_disable(bp); |
1664 | if (CNIC_LOADED(bp)) | ||
1665 | bnx2x_napi_disable_cnic(bp); | ||
1589 | } | 1666 | } |
1590 | 1667 | ||
1591 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) | 1668 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) |
1592 | { | 1669 | { |
1593 | struct bnx2x *bp = netdev_priv(dev); | 1670 | struct bnx2x *bp = netdev_priv(dev); |
1594 | 1671 | ||
1595 | #ifdef BCM_CNIC | 1672 | if (CNIC_LOADED(bp) && !NO_FCOE(bp)) { |
1596 | if (!NO_FCOE(bp)) { | ||
1597 | struct ethhdr *hdr = (struct ethhdr *)skb->data; | 1673 | struct ethhdr *hdr = (struct ethhdr *)skb->data; |
1598 | u16 ether_type = ntohs(hdr->h_proto); | 1674 | u16 ether_type = ntohs(hdr->h_proto); |
1599 | 1675 | ||
@@ -1609,7 +1685,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
1609 | if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP)) | 1685 | if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP)) |
1610 | return bnx2x_fcoe_tx(bp, txq_index); | 1686 | return bnx2x_fcoe_tx(bp, txq_index); |
1611 | } | 1687 | } |
1612 | #endif | 1688 | |
1613 | /* select a non-FCoE queue */ | 1689 | /* select a non-FCoE queue */ |
1614 | return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp)); | 1690 | return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp)); |
1615 | } | 1691 | } |
@@ -1618,15 +1694,15 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
1618 | void bnx2x_set_num_queues(struct bnx2x *bp) | 1694 | void bnx2x_set_num_queues(struct bnx2x *bp) |
1619 | { | 1695 | { |
1620 | /* RSS queues */ | 1696 | /* RSS queues */ |
1621 | bp->num_queues = bnx2x_calc_num_queues(bp); | 1697 | bp->num_ethernet_queues = bnx2x_calc_num_queues(bp); |
1622 | 1698 | ||
1623 | #ifdef BCM_CNIC | ||
1624 | /* override in STORAGE SD modes */ | 1699 | /* override in STORAGE SD modes */ |
1625 | if (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) | 1700 | if (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) |
1626 | bp->num_queues = 1; | 1701 | bp->num_ethernet_queues = 1; |
1627 | #endif | 1702 | |
1628 | /* Add special queues */ | 1703 | /* Add special queues */ |
1629 | bp->num_queues += NON_ETH_CONTEXT_USE; | 1704 | bp->num_cnic_queues = CNIC_SUPPORT(bp); /* For FCOE */ |
1705 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
1630 | 1706 | ||
1631 | BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues); | 1707 | BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues); |
1632 | } | 1708 | } |
@@ -1653,20 +1729,18 @@ void bnx2x_set_num_queues(struct bnx2x *bp) | |||
1653 | * bnx2x_setup_tc() takes care of the proper TC mappings so that __skb_tx_hash() | 1729 | * bnx2x_setup_tc() takes care of the proper TC mappings so that __skb_tx_hash() |
1654 | * will return a proper Tx index if TC is enabled (netdev->num_tc > 0). | 1730 | * will return a proper Tx index if TC is enabled (netdev->num_tc > 0). |
1655 | */ | 1731 | */ |
1656 | static int bnx2x_set_real_num_queues(struct bnx2x *bp) | 1732 | static int bnx2x_set_real_num_queues(struct bnx2x *bp, int include_cnic) |
1657 | { | 1733 | { |
1658 | int rc, tx, rx; | 1734 | int rc, tx, rx; |
1659 | 1735 | ||
1660 | tx = BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos; | 1736 | tx = BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos; |
1661 | rx = BNX2X_NUM_QUEUES(bp) - NON_ETH_CONTEXT_USE; | 1737 | rx = BNX2X_NUM_ETH_QUEUES(bp); |
1662 | 1738 | ||
1663 | /* account for fcoe queue */ | 1739 | /* account for fcoe queue */ |
1664 | #ifdef BCM_CNIC | 1740 | if (include_cnic && !NO_FCOE(bp)) { |
1665 | if (!NO_FCOE(bp)) { | 1741 | rx++; |
1666 | rx += FCOE_PRESENT; | 1742 | tx++; |
1667 | tx += FCOE_PRESENT; | ||
1668 | } | 1743 | } |
1669 | #endif | ||
1670 | 1744 | ||
1671 | rc = netif_set_real_num_tx_queues(bp->dev, tx); | 1745 | rc = netif_set_real_num_tx_queues(bp->dev, tx); |
1672 | if (rc) { | 1746 | if (rc) { |
@@ -1859,14 +1933,26 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp) | |||
1859 | (bp)->state = BNX2X_STATE_ERROR; \ | 1933 | (bp)->state = BNX2X_STATE_ERROR; \ |
1860 | goto label; \ | 1934 | goto label; \ |
1861 | } while (0) | 1935 | } while (0) |
1862 | #else | 1936 | |
1937 | #define LOAD_ERROR_EXIT_CNIC(bp, label) \ | ||
1938 | do { \ | ||
1939 | bp->cnic_loaded = false; \ | ||
1940 | goto label; \ | ||
1941 | } while (0) | ||
1942 | #else /*BNX2X_STOP_ON_ERROR*/ | ||
1863 | #define LOAD_ERROR_EXIT(bp, label) \ | 1943 | #define LOAD_ERROR_EXIT(bp, label) \ |
1864 | do { \ | 1944 | do { \ |
1865 | (bp)->state = BNX2X_STATE_ERROR; \ | 1945 | (bp)->state = BNX2X_STATE_ERROR; \ |
1866 | (bp)->panic = 1; \ | 1946 | (bp)->panic = 1; \ |
1867 | return -EBUSY; \ | 1947 | return -EBUSY; \ |
1868 | } while (0) | 1948 | } while (0) |
1869 | #endif | 1949 | #define LOAD_ERROR_EXIT_CNIC(bp, label) \ |
1950 | do { \ | ||
1951 | bp->cnic_loaded = false; \ | ||
1952 | (bp)->panic = 1; \ | ||
1953 | return -EBUSY; \ | ||
1954 | } while (0) | ||
1955 | #endif /*BNX2X_STOP_ON_ERROR*/ | ||
1870 | 1956 | ||
1871 | bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err) | 1957 | bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err) |
1872 | { | 1958 | { |
@@ -1959,10 +2045,8 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) | |||
1959 | fp->max_cos = 1; | 2045 | fp->max_cos = 1; |
1960 | 2046 | ||
1961 | /* Init txdata pointers */ | 2047 | /* Init txdata pointers */ |
1962 | #ifdef BCM_CNIC | ||
1963 | if (IS_FCOE_FP(fp)) | 2048 | if (IS_FCOE_FP(fp)) |
1964 | fp->txdata_ptr[0] = &bp->bnx2x_txq[FCOE_TXQ_IDX(bp)]; | 2049 | fp->txdata_ptr[0] = &bp->bnx2x_txq[FCOE_TXQ_IDX(bp)]; |
1965 | #endif | ||
1966 | if (IS_ETH_FP(fp)) | 2050 | if (IS_ETH_FP(fp)) |
1967 | for_each_cos_in_tx_queue(fp, cos) | 2051 | for_each_cos_in_tx_queue(fp, cos) |
1968 | fp->txdata_ptr[cos] = &bp->bnx2x_txq[cos * | 2052 | fp->txdata_ptr[cos] = &bp->bnx2x_txq[cos * |
@@ -1980,11 +2064,95 @@ static void bnx2x_bz_fp(struct bnx2x *bp, int index) | |||
1980 | else if (bp->flags & GRO_ENABLE_FLAG) | 2064 | else if (bp->flags & GRO_ENABLE_FLAG) |
1981 | fp->mode = TPA_MODE_GRO; | 2065 | fp->mode = TPA_MODE_GRO; |
1982 | 2066 | ||
1983 | #ifdef BCM_CNIC | ||
1984 | /* We don't want TPA on an FCoE L2 ring */ | 2067 | /* We don't want TPA on an FCoE L2 ring */ |
1985 | if (IS_FCOE_FP(fp)) | 2068 | if (IS_FCOE_FP(fp)) |
1986 | fp->disable_tpa = 1; | 2069 | fp->disable_tpa = 1; |
1987 | #endif | 2070 | } |
2071 | |||
2072 | int bnx2x_load_cnic(struct bnx2x *bp) | ||
2073 | { | ||
2074 | int i, rc, port = BP_PORT(bp); | ||
2075 | |||
2076 | DP(NETIF_MSG_IFUP, "Starting CNIC-related load\n"); | ||
2077 | |||
2078 | mutex_init(&bp->cnic_mutex); | ||
2079 | |||
2080 | rc = bnx2x_alloc_mem_cnic(bp); | ||
2081 | if (rc) { | ||
2082 | BNX2X_ERR("Unable to allocate bp memory for cnic\n"); | ||
2083 | LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0); | ||
2084 | } | ||
2085 | |||
2086 | rc = bnx2x_alloc_fp_mem_cnic(bp); | ||
2087 | if (rc) { | ||
2088 | BNX2X_ERR("Unable to allocate memory for cnic fps\n"); | ||
2089 | LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0); | ||
2090 | } | ||
2091 | |||
2092 | /* Update the number of queues with the cnic queues */ | ||
2093 | rc = bnx2x_set_real_num_queues(bp, 1); | ||
2094 | if (rc) { | ||
2095 | BNX2X_ERR("Unable to set real_num_queues including cnic\n"); | ||
2096 | LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0); | ||
2097 | } | ||
2098 | |||
2099 | /* Add all CNIC NAPI objects */ | ||
2100 | bnx2x_add_all_napi_cnic(bp); | ||
2101 | DP(NETIF_MSG_IFUP, "cnic napi added\n"); | ||
2102 | bnx2x_napi_enable_cnic(bp); | ||
2103 | |||
2104 | rc = bnx2x_init_hw_func_cnic(bp); | ||
2105 | if (rc) | ||
2106 | LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic1); | ||
2107 | |||
2108 | bnx2x_nic_init_cnic(bp); | ||
2109 | |||
2110 | /* Enable Timer scan */ | ||
2111 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 1); | ||
2112 | |||
2113 | for_each_cnic_queue(bp, i) { | ||
2114 | rc = bnx2x_setup_queue(bp, &bp->fp[i], 0); | ||
2115 | if (rc) { | ||
2116 | BNX2X_ERR("Queue setup failed\n"); | ||
2117 | LOAD_ERROR_EXIT(bp, load_error_cnic2); | ||
2118 | } | ||
2119 | } | ||
2120 | |||
2121 | /* Initialize Rx filter. */ | ||
2122 | netif_addr_lock_bh(bp->dev); | ||
2123 | bnx2x_set_rx_mode(bp->dev); | ||
2124 | netif_addr_unlock_bh(bp->dev); | ||
2125 | |||
2126 | /* re-read iscsi info */ | ||
2127 | bnx2x_get_iscsi_info(bp); | ||
2128 | bnx2x_setup_cnic_irq_info(bp); | ||
2129 | bnx2x_setup_cnic_info(bp); | ||
2130 | bp->cnic_loaded = true; | ||
2131 | if (bp->state == BNX2X_STATE_OPEN) | ||
2132 | bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); | ||
2133 | |||
2134 | |||
2135 | DP(NETIF_MSG_IFUP, "Ending successfully CNIC-related load\n"); | ||
2136 | |||
2137 | return 0; | ||
2138 | |||
2139 | #ifndef BNX2X_STOP_ON_ERROR | ||
2140 | load_error_cnic2: | ||
2141 | /* Disable Timer scan */ | ||
2142 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); | ||
2143 | |||
2144 | load_error_cnic1: | ||
2145 | bnx2x_napi_disable_cnic(bp); | ||
2146 | /* Update the number of queues without the cnic queues */ | ||
2147 | rc = bnx2x_set_real_num_queues(bp, 0); | ||
2148 | if (rc) | ||
2149 | BNX2X_ERR("Unable to set real_num_queues not including cnic\n"); | ||
2150 | load_error_cnic0: | ||
2151 | BNX2X_ERR("CNIC-related load failed\n"); | ||
2152 | bnx2x_free_fp_mem_cnic(bp); | ||
2153 | bnx2x_free_mem_cnic(bp); | ||
2154 | return rc; | ||
2155 | #endif /* ! BNX2X_STOP_ON_ERROR */ | ||
1988 | } | 2156 | } |
1989 | 2157 | ||
1990 | 2158 | ||
@@ -1995,6 +2163,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1995 | u32 load_code; | 2163 | u32 load_code; |
1996 | int i, rc; | 2164 | int i, rc; |
1997 | 2165 | ||
2166 | DP(NETIF_MSG_IFUP, "Starting NIC load\n"); | ||
2167 | DP(NETIF_MSG_IFUP, | ||
2168 | "CNIC is %s\n", CNIC_ENABLED(bp) ? "enabled" : "disabled"); | ||
2169 | |||
1998 | #ifdef BNX2X_STOP_ON_ERROR | 2170 | #ifdef BNX2X_STOP_ON_ERROR |
1999 | if (unlikely(bp->panic)) { | 2171 | if (unlikely(bp->panic)) { |
2000 | BNX2X_ERR("Can't load NIC when there is panic\n"); | 2172 | BNX2X_ERR("Can't load NIC when there is panic\n"); |
@@ -2022,9 +2194,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2022 | DP(NETIF_MSG_IFUP, "num queues: %d", bp->num_queues); | 2194 | DP(NETIF_MSG_IFUP, "num queues: %d", bp->num_queues); |
2023 | for_each_queue(bp, i) | 2195 | for_each_queue(bp, i) |
2024 | bnx2x_bz_fp(bp, i); | 2196 | bnx2x_bz_fp(bp, i); |
2025 | memset(bp->bnx2x_txq, 0, bp->bnx2x_txq_size * | 2197 | memset(bp->bnx2x_txq, 0, (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS + |
2026 | sizeof(struct bnx2x_fp_txdata)); | 2198 | bp->num_cnic_queues) * |
2199 | sizeof(struct bnx2x_fp_txdata)); | ||
2027 | 2200 | ||
2201 | bp->fcoe_init = false; | ||
2028 | 2202 | ||
2029 | /* Set the receive queues buffer size */ | 2203 | /* Set the receive queues buffer size */ |
2030 | bnx2x_set_rx_buf_size(bp); | 2204 | bnx2x_set_rx_buf_size(bp); |
@@ -2034,9 +2208,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2034 | 2208 | ||
2035 | /* As long as bnx2x_alloc_mem() may possibly update | 2209 | /* As long as bnx2x_alloc_mem() may possibly update |
2036 | * bp->num_queues, bnx2x_set_real_num_queues() should always | 2210 | * bp->num_queues, bnx2x_set_real_num_queues() should always |
2037 | * come after it. | 2211 | * come after it. At this stage cnic queues are not counted. |
2038 | */ | 2212 | */ |
2039 | rc = bnx2x_set_real_num_queues(bp); | 2213 | rc = bnx2x_set_real_num_queues(bp, 0); |
2040 | if (rc) { | 2214 | if (rc) { |
2041 | BNX2X_ERR("Unable to set real_num_queues\n"); | 2215 | BNX2X_ERR("Unable to set real_num_queues\n"); |
2042 | LOAD_ERROR_EXIT(bp, load_error0); | 2216 | LOAD_ERROR_EXIT(bp, load_error0); |
@@ -2050,6 +2224,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2050 | 2224 | ||
2051 | /* Add all NAPI objects */ | 2225 | /* Add all NAPI objects */ |
2052 | bnx2x_add_all_napi(bp); | 2226 | bnx2x_add_all_napi(bp); |
2227 | DP(NETIF_MSG_IFUP, "napi added\n"); | ||
2053 | bnx2x_napi_enable(bp); | 2228 | bnx2x_napi_enable(bp); |
2054 | 2229 | ||
2055 | /* set pf load just before approaching the MCP */ | 2230 | /* set pf load just before approaching the MCP */ |
@@ -2191,23 +2366,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2191 | LOAD_ERROR_EXIT(bp, load_error3); | 2366 | LOAD_ERROR_EXIT(bp, load_error3); |
2192 | } | 2367 | } |
2193 | 2368 | ||
2194 | #ifdef BCM_CNIC | 2369 | for_each_nondefault_eth_queue(bp, i) { |
2195 | /* Enable Timer scan */ | ||
2196 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 1); | ||
2197 | #endif | ||
2198 | |||
2199 | for_each_nondefault_queue(bp, i) { | ||
2200 | rc = bnx2x_setup_queue(bp, &bp->fp[i], 0); | 2370 | rc = bnx2x_setup_queue(bp, &bp->fp[i], 0); |
2201 | if (rc) { | 2371 | if (rc) { |
2202 | BNX2X_ERR("Queue setup failed\n"); | 2372 | BNX2X_ERR("Queue setup failed\n"); |
2203 | LOAD_ERROR_EXIT(bp, load_error4); | 2373 | LOAD_ERROR_EXIT(bp, load_error3); |
2204 | } | 2374 | } |
2205 | } | 2375 | } |
2206 | 2376 | ||
2207 | rc = bnx2x_init_rss_pf(bp); | 2377 | rc = bnx2x_init_rss_pf(bp); |
2208 | if (rc) { | 2378 | if (rc) { |
2209 | BNX2X_ERR("PF RSS init failed\n"); | 2379 | BNX2X_ERR("PF RSS init failed\n"); |
2210 | LOAD_ERROR_EXIT(bp, load_error4); | 2380 | LOAD_ERROR_EXIT(bp, load_error3); |
2211 | } | 2381 | } |
2212 | 2382 | ||
2213 | /* Now when Clients are configured we are ready to work */ | 2383 | /* Now when Clients are configured we are ready to work */ |
@@ -2217,7 +2387,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2217 | rc = bnx2x_set_eth_mac(bp, true); | 2387 | rc = bnx2x_set_eth_mac(bp, true); |
2218 | if (rc) { | 2388 | if (rc) { |
2219 | BNX2X_ERR("Setting Ethernet MAC failed\n"); | 2389 | BNX2X_ERR("Setting Ethernet MAC failed\n"); |
2220 | LOAD_ERROR_EXIT(bp, load_error4); | 2390 | LOAD_ERROR_EXIT(bp, load_error3); |
2221 | } | 2391 | } |
2222 | 2392 | ||
2223 | if (bp->pending_max) { | 2393 | if (bp->pending_max) { |
@@ -2264,14 +2434,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2264 | /* start the timer */ | 2434 | /* start the timer */ |
2265 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 2435 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
2266 | 2436 | ||
2267 | #ifdef BCM_CNIC | 2437 | if (CNIC_ENABLED(bp)) |
2268 | /* re-read iscsi info */ | 2438 | bnx2x_load_cnic(bp); |
2269 | bnx2x_get_iscsi_info(bp); | ||
2270 | bnx2x_setup_cnic_irq_info(bp); | ||
2271 | bnx2x_setup_cnic_info(bp); | ||
2272 | if (bp->state == BNX2X_STATE_OPEN) | ||
2273 | bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); | ||
2274 | #endif | ||
2275 | 2439 | ||
2276 | /* mark driver is loaded in shmem2 */ | 2440 | /* mark driver is loaded in shmem2 */ |
2277 | if (SHMEM2_HAS(bp, drv_capabilities_flag)) { | 2441 | if (SHMEM2_HAS(bp, drv_capabilities_flag)) { |
@@ -2293,14 +2457,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2293 | if (bp->port.pmf && (bp->state != BNX2X_STATE_DIAG)) | 2457 | if (bp->port.pmf && (bp->state != BNX2X_STATE_DIAG)) |
2294 | bnx2x_dcbx_init(bp, false); | 2458 | bnx2x_dcbx_init(bp, false); |
2295 | 2459 | ||
2460 | DP(NETIF_MSG_IFUP, "Ending successfully NIC load\n"); | ||
2461 | |||
2296 | return 0; | 2462 | return 0; |
2297 | 2463 | ||
2298 | #ifndef BNX2X_STOP_ON_ERROR | 2464 | #ifndef BNX2X_STOP_ON_ERROR |
2299 | load_error4: | ||
2300 | #ifdef BCM_CNIC | ||
2301 | /* Disable Timer scan */ | ||
2302 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); | ||
2303 | #endif | ||
2304 | load_error3: | 2465 | load_error3: |
2305 | bnx2x_int_disable_sync(bp, 1); | 2466 | bnx2x_int_disable_sync(bp, 1); |
2306 | 2467 | ||
@@ -2338,6 +2499,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
2338 | int i; | 2499 | int i; |
2339 | bool global = false; | 2500 | bool global = false; |
2340 | 2501 | ||
2502 | DP(NETIF_MSG_IFUP, "Starting NIC unload\n"); | ||
2503 | |||
2341 | /* mark driver is unloaded in shmem2 */ | 2504 | /* mark driver is unloaded in shmem2 */ |
2342 | if (SHMEM2_HAS(bp, drv_capabilities_flag)) { | 2505 | if (SHMEM2_HAS(bp, drv_capabilities_flag)) { |
2343 | u32 val; | 2506 | u32 val; |
@@ -2373,14 +2536,13 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
2373 | bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; | 2536 | bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; |
2374 | smp_mb(); | 2537 | smp_mb(); |
2375 | 2538 | ||
2539 | if (CNIC_LOADED(bp)) | ||
2540 | bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); | ||
2541 | |||
2376 | /* Stop Tx */ | 2542 | /* Stop Tx */ |
2377 | bnx2x_tx_disable(bp); | 2543 | bnx2x_tx_disable(bp); |
2378 | netdev_reset_tc(bp->dev); | 2544 | netdev_reset_tc(bp->dev); |
2379 | 2545 | ||
2380 | #ifdef BCM_CNIC | ||
2381 | bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); | ||
2382 | #endif | ||
2383 | |||
2384 | bp->rx_mode = BNX2X_RX_MODE_NONE; | 2546 | bp->rx_mode = BNX2X_RX_MODE_NONE; |
2385 | 2547 | ||
2386 | del_timer_sync(&bp->timer); | 2548 | del_timer_sync(&bp->timer); |
@@ -2414,7 +2576,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
2414 | bnx2x_netif_stop(bp, 1); | 2576 | bnx2x_netif_stop(bp, 1); |
2415 | /* Delete all NAPI objects */ | 2577 | /* Delete all NAPI objects */ |
2416 | bnx2x_del_all_napi(bp); | 2578 | bnx2x_del_all_napi(bp); |
2417 | 2579 | if (CNIC_LOADED(bp)) | |
2580 | bnx2x_del_all_napi_cnic(bp); | ||
2418 | /* Release IRQs */ | 2581 | /* Release IRQs */ |
2419 | bnx2x_free_irq(bp); | 2582 | bnx2x_free_irq(bp); |
2420 | 2583 | ||
@@ -2435,12 +2598,19 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
2435 | 2598 | ||
2436 | /* Free SKBs, SGEs, TPA pool and driver internals */ | 2599 | /* Free SKBs, SGEs, TPA pool and driver internals */ |
2437 | bnx2x_free_skbs(bp); | 2600 | bnx2x_free_skbs(bp); |
2601 | if (CNIC_LOADED(bp)) | ||
2602 | bnx2x_free_skbs_cnic(bp); | ||
2438 | for_each_rx_queue(bp, i) | 2603 | for_each_rx_queue(bp, i) |
2439 | bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); | 2604 | bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); |
2440 | 2605 | ||
2606 | if (CNIC_LOADED(bp)) { | ||
2607 | bnx2x_free_fp_mem_cnic(bp); | ||
2608 | bnx2x_free_mem_cnic(bp); | ||
2609 | } | ||
2441 | bnx2x_free_mem(bp); | 2610 | bnx2x_free_mem(bp); |
2442 | 2611 | ||
2443 | bp->state = BNX2X_STATE_CLOSED; | 2612 | bp->state = BNX2X_STATE_CLOSED; |
2613 | bp->cnic_loaded = false; | ||
2444 | 2614 | ||
2445 | /* Check if there are pending parity attentions. If there are - set | 2615 | /* Check if there are pending parity attentions. If there are - set |
2446 | * RECOVERY_IN_PROGRESS. | 2616 | * RECOVERY_IN_PROGRESS. |
@@ -2460,6 +2630,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
2460 | if (!bnx2x_clear_pf_load(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) | 2630 | if (!bnx2x_clear_pf_load(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) |
2461 | bnx2x_disable_close_the_gate(bp); | 2631 | bnx2x_disable_close_the_gate(bp); |
2462 | 2632 | ||
2633 | DP(NETIF_MSG_IFUP, "Ending NIC unload\n"); | ||
2634 | |||
2463 | return 0; | 2635 | return 0; |
2464 | } | 2636 | } |
2465 | 2637 | ||
@@ -2550,7 +2722,7 @@ int bnx2x_poll(struct napi_struct *napi, int budget) | |||
2550 | 2722 | ||
2551 | /* Fall out from the NAPI loop if needed */ | 2723 | /* Fall out from the NAPI loop if needed */ |
2552 | if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { | 2724 | if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { |
2553 | #ifdef BCM_CNIC | 2725 | |
2554 | /* No need to update SB for FCoE L2 ring as long as | 2726 | /* No need to update SB for FCoE L2 ring as long as |
2555 | * it's connected to the default SB and the SB | 2727 | * it's connected to the default SB and the SB |
2556 | * has been updated when NAPI was scheduled. | 2728 | * has been updated when NAPI was scheduled. |
@@ -2559,8 +2731,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) | |||
2559 | napi_complete(napi); | 2731 | napi_complete(napi); |
2560 | break; | 2732 | break; |
2561 | } | 2733 | } |
2562 | #endif | ||
2563 | |||
2564 | bnx2x_update_fpsb_idx(fp); | 2734 | bnx2x_update_fpsb_idx(fp); |
2565 | /* bnx2x_has_rx_work() reads the status block, | 2735 | /* bnx2x_has_rx_work() reads the status block, |
2566 | * thus we need to ensure that status block indices | 2736 | * thus we need to ensure that status block indices |
@@ -2940,7 +3110,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2940 | txq_index = skb_get_queue_mapping(skb); | 3110 | txq_index = skb_get_queue_mapping(skb); |
2941 | txq = netdev_get_tx_queue(dev, txq_index); | 3111 | txq = netdev_get_tx_queue(dev, txq_index); |
2942 | 3112 | ||
2943 | BUG_ON(txq_index >= MAX_ETH_TXQ_IDX(bp) + FCOE_PRESENT); | 3113 | BUG_ON(txq_index >= MAX_ETH_TXQ_IDX(bp) + (CNIC_LOADED(bp) ? 1 : 0)); |
2944 | 3114 | ||
2945 | txdata = &bp->bnx2x_txq[txq_index]; | 3115 | txdata = &bp->bnx2x_txq[txq_index]; |
2946 | 3116 | ||
@@ -3339,13 +3509,11 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) | |||
3339 | return -EINVAL; | 3509 | return -EINVAL; |
3340 | } | 3510 | } |
3341 | 3511 | ||
3342 | #ifdef BCM_CNIC | ||
3343 | if ((IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) && | 3512 | if ((IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) && |
3344 | !is_zero_ether_addr(addr->sa_data)) { | 3513 | !is_zero_ether_addr(addr->sa_data)) { |
3345 | BNX2X_ERR("Can't configure non-zero address on iSCSI or FCoE functions in MF-SD mode\n"); | 3514 | BNX2X_ERR("Can't configure non-zero address on iSCSI or FCoE functions in MF-SD mode\n"); |
3346 | return -EINVAL; | 3515 | return -EINVAL; |
3347 | } | 3516 | } |
3348 | #endif | ||
3349 | 3517 | ||
3350 | if (netif_running(dev)) { | 3518 | if (netif_running(dev)) { |
3351 | rc = bnx2x_set_eth_mac(bp, false); | 3519 | rc = bnx2x_set_eth_mac(bp, false); |
@@ -3369,13 +3537,11 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) | |||
3369 | u8 cos; | 3537 | u8 cos; |
3370 | 3538 | ||
3371 | /* Common */ | 3539 | /* Common */ |
3372 | #ifdef BCM_CNIC | 3540 | |
3373 | if (IS_FCOE_IDX(fp_index)) { | 3541 | if (IS_FCOE_IDX(fp_index)) { |
3374 | memset(sb, 0, sizeof(union host_hc_status_block)); | 3542 | memset(sb, 0, sizeof(union host_hc_status_block)); |
3375 | fp->status_blk_mapping = 0; | 3543 | fp->status_blk_mapping = 0; |
3376 | |||
3377 | } else { | 3544 | } else { |
3378 | #endif | ||
3379 | /* status blocks */ | 3545 | /* status blocks */ |
3380 | if (!CHIP_IS_E1x(bp)) | 3546 | if (!CHIP_IS_E1x(bp)) |
3381 | BNX2X_PCI_FREE(sb->e2_sb, | 3547 | BNX2X_PCI_FREE(sb->e2_sb, |
@@ -3387,9 +3553,8 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) | |||
3387 | bnx2x_fp(bp, fp_index, | 3553 | bnx2x_fp(bp, fp_index, |
3388 | status_blk_mapping), | 3554 | status_blk_mapping), |
3389 | sizeof(struct host_hc_status_block_e1x)); | 3555 | sizeof(struct host_hc_status_block_e1x)); |
3390 | #ifdef BCM_CNIC | ||
3391 | } | 3556 | } |
3392 | #endif | 3557 | |
3393 | /* Rx */ | 3558 | /* Rx */ |
3394 | if (!skip_rx_queue(bp, fp_index)) { | 3559 | if (!skip_rx_queue(bp, fp_index)) { |
3395 | bnx2x_free_rx_bds(fp); | 3560 | bnx2x_free_rx_bds(fp); |
@@ -3431,10 +3596,17 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index) | |||
3431 | /* end of fastpath */ | 3596 | /* end of fastpath */ |
3432 | } | 3597 | } |
3433 | 3598 | ||
3599 | void bnx2x_free_fp_mem_cnic(struct bnx2x *bp) | ||
3600 | { | ||
3601 | int i; | ||
3602 | for_each_cnic_queue(bp, i) | ||
3603 | bnx2x_free_fp_mem_at(bp, i); | ||
3604 | } | ||
3605 | |||
3434 | void bnx2x_free_fp_mem(struct bnx2x *bp) | 3606 | void bnx2x_free_fp_mem(struct bnx2x *bp) |
3435 | { | 3607 | { |
3436 | int i; | 3608 | int i; |
3437 | for_each_queue(bp, i) | 3609 | for_each_eth_queue(bp, i) |
3438 | bnx2x_free_fp_mem_at(bp, i); | 3610 | bnx2x_free_fp_mem_at(bp, i); |
3439 | } | 3611 | } |
3440 | 3612 | ||
@@ -3519,14 +3691,11 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) | |||
3519 | u8 cos; | 3691 | u8 cos; |
3520 | int rx_ring_size = 0; | 3692 | int rx_ring_size = 0; |
3521 | 3693 | ||
3522 | #ifdef BCM_CNIC | ||
3523 | if (!bp->rx_ring_size && | 3694 | if (!bp->rx_ring_size && |
3524 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) { | 3695 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) { |
3525 | rx_ring_size = MIN_RX_SIZE_NONTPA; | 3696 | rx_ring_size = MIN_RX_SIZE_NONTPA; |
3526 | bp->rx_ring_size = rx_ring_size; | 3697 | bp->rx_ring_size = rx_ring_size; |
3527 | } else | 3698 | } else if (!bp->rx_ring_size) { |
3528 | #endif | ||
3529 | if (!bp->rx_ring_size) { | ||
3530 | rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp); | 3699 | rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp); |
3531 | 3700 | ||
3532 | if (CHIP_IS_E3(bp)) { | 3701 | if (CHIP_IS_E3(bp)) { |
@@ -3550,9 +3719,8 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) | |||
3550 | 3719 | ||
3551 | /* Common */ | 3720 | /* Common */ |
3552 | sb = &bnx2x_fp(bp, index, status_blk); | 3721 | sb = &bnx2x_fp(bp, index, status_blk); |
3553 | #ifdef BCM_CNIC | 3722 | |
3554 | if (!IS_FCOE_IDX(index)) { | 3723 | if (!IS_FCOE_IDX(index)) { |
3555 | #endif | ||
3556 | /* status blocks */ | 3724 | /* status blocks */ |
3557 | if (!CHIP_IS_E1x(bp)) | 3725 | if (!CHIP_IS_E1x(bp)) |
3558 | BNX2X_PCI_ALLOC(sb->e2_sb, | 3726 | BNX2X_PCI_ALLOC(sb->e2_sb, |
@@ -3562,9 +3730,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) | |||
3562 | BNX2X_PCI_ALLOC(sb->e1x_sb, | 3730 | BNX2X_PCI_ALLOC(sb->e1x_sb, |
3563 | &bnx2x_fp(bp, index, status_blk_mapping), | 3731 | &bnx2x_fp(bp, index, status_blk_mapping), |
3564 | sizeof(struct host_hc_status_block_e1x)); | 3732 | sizeof(struct host_hc_status_block_e1x)); |
3565 | #ifdef BCM_CNIC | ||
3566 | } | 3733 | } |
3567 | #endif | ||
3568 | 3734 | ||
3569 | /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to | 3735 | /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to |
3570 | * set shortcuts for it. | 3736 | * set shortcuts for it. |
@@ -3641,31 +3807,31 @@ alloc_mem_err: | |||
3641 | return 0; | 3807 | return 0; |
3642 | } | 3808 | } |
3643 | 3809 | ||
3810 | int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp) | ||
3811 | { | ||
3812 | if (!NO_FCOE(bp)) | ||
3813 | /* FCoE */ | ||
3814 | if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX(bp))) | ||
3815 | /* we will fail load process instead of mark | ||
3816 | * NO_FCOE_FLAG | ||
3817 | */ | ||
3818 | return -ENOMEM; | ||
3819 | |||
3820 | return 0; | ||
3821 | } | ||
3822 | |||
3644 | int bnx2x_alloc_fp_mem(struct bnx2x *bp) | 3823 | int bnx2x_alloc_fp_mem(struct bnx2x *bp) |
3645 | { | 3824 | { |
3646 | int i; | 3825 | int i; |
3647 | 3826 | ||
3648 | /** | 3827 | /* 1. Allocate FP for leading - fatal if error |
3649 | * 1. Allocate FP for leading - fatal if error | 3828 | * 2. Allocate RSS - fix number of queues if error |
3650 | * 2. {CNIC} Allocate FCoE FP - fatal if error | ||
3651 | * 3. {CNIC} Allocate OOO + FWD - disable OOO if error | ||
3652 | * 4. Allocate RSS - fix number of queues if error | ||
3653 | */ | 3829 | */ |
3654 | 3830 | ||
3655 | /* leading */ | 3831 | /* leading */ |
3656 | if (bnx2x_alloc_fp_mem_at(bp, 0)) | 3832 | if (bnx2x_alloc_fp_mem_at(bp, 0)) |
3657 | return -ENOMEM; | 3833 | return -ENOMEM; |
3658 | 3834 | ||
3659 | #ifdef BCM_CNIC | ||
3660 | if (!NO_FCOE(bp)) | ||
3661 | /* FCoE */ | ||
3662 | if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX(bp))) | ||
3663 | /* we will fail load process instead of mark | ||
3664 | * NO_FCOE_FLAG | ||
3665 | */ | ||
3666 | return -ENOMEM; | ||
3667 | #endif | ||
3668 | |||
3669 | /* RSS */ | 3835 | /* RSS */ |
3670 | for_each_nondefault_eth_queue(bp, i) | 3836 | for_each_nondefault_eth_queue(bp, i) |
3671 | if (bnx2x_alloc_fp_mem_at(bp, i)) | 3837 | if (bnx2x_alloc_fp_mem_at(bp, i)) |
@@ -3676,17 +3842,17 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) | |||
3676 | int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; | 3842 | int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; |
3677 | 3843 | ||
3678 | WARN_ON(delta < 0); | 3844 | WARN_ON(delta < 0); |
3679 | #ifdef BCM_CNIC | 3845 | if (CNIC_SUPPORT(bp)) |
3680 | /** | 3846 | /* move non eth FPs next to last eth FP |
3681 | * move non eth FPs next to last eth FP | 3847 | * must be done in that order |
3682 | * must be done in that order | 3848 | * FCOE_IDX < FWD_IDX < OOO_IDX |
3683 | * FCOE_IDX < FWD_IDX < OOO_IDX | 3849 | */ |
3684 | */ | ||
3685 | 3850 | ||
3686 | /* move FCoE fp even NO_FCOE_FLAG is on */ | 3851 | /* move FCoE fp even NO_FCOE_FLAG is on */ |
3687 | bnx2x_move_fp(bp, FCOE_IDX(bp), FCOE_IDX(bp) - delta); | 3852 | bnx2x_move_fp(bp, FCOE_IDX(bp), FCOE_IDX(bp) - delta); |
3688 | #endif | 3853 | bp->num_ethernet_queues -= delta; |
3689 | bp->num_queues -= delta; | 3854 | bp->num_queues = bp->num_ethernet_queues + |
3855 | bp->num_cnic_queues; | ||
3690 | BNX2X_ERR("Adjusted num of queues from %d to %d\n", | 3856 | BNX2X_ERR("Adjusted num of queues from %d to %d\n", |
3691 | bp->num_queues + delta, bp->num_queues); | 3857 | bp->num_queues + delta, bp->num_queues); |
3692 | } | 3858 | } |
@@ -3711,7 +3877,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) | |||
3711 | struct msix_entry *tbl; | 3877 | struct msix_entry *tbl; |
3712 | struct bnx2x_ilt *ilt; | 3878 | struct bnx2x_ilt *ilt; |
3713 | int msix_table_size = 0; | 3879 | int msix_table_size = 0; |
3714 | int fp_array_size; | 3880 | int fp_array_size, txq_array_size; |
3715 | int i; | 3881 | int i; |
3716 | 3882 | ||
3717 | /* | 3883 | /* |
@@ -3721,7 +3887,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) | |||
3721 | msix_table_size = bp->igu_sb_cnt + 1; | 3887 | msix_table_size = bp->igu_sb_cnt + 1; |
3722 | 3888 | ||
3723 | /* fp array: RSS plus CNIC related L2 queues */ | 3889 | /* fp array: RSS plus CNIC related L2 queues */ |
3724 | fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + NON_ETH_CONTEXT_USE; | 3890 | fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + CNIC_SUPPORT(bp); |
3725 | BNX2X_DEV_INFO("fp_array_size %d", fp_array_size); | 3891 | BNX2X_DEV_INFO("fp_array_size %d", fp_array_size); |
3726 | 3892 | ||
3727 | fp = kcalloc(fp_array_size, sizeof(*fp), GFP_KERNEL); | 3893 | fp = kcalloc(fp_array_size, sizeof(*fp), GFP_KERNEL); |
@@ -3750,12 +3916,12 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) | |||
3750 | goto alloc_err; | 3916 | goto alloc_err; |
3751 | 3917 | ||
3752 | /* Allocate memory for the transmission queues array */ | 3918 | /* Allocate memory for the transmission queues array */ |
3753 | bp->bnx2x_txq_size = BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS; | 3919 | txq_array_size = |
3754 | #ifdef BCM_CNIC | 3920 | BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS + CNIC_SUPPORT(bp); |
3755 | bp->bnx2x_txq_size++; | 3921 | BNX2X_DEV_INFO("txq_array_size %d", txq_array_size); |
3756 | #endif | 3922 | |
3757 | bp->bnx2x_txq = kcalloc(bp->bnx2x_txq_size, | 3923 | bp->bnx2x_txq = kcalloc(txq_array_size, sizeof(struct bnx2x_fp_txdata), |
3758 | sizeof(struct bnx2x_fp_txdata), GFP_KERNEL); | 3924 | GFP_KERNEL); |
3759 | if (!bp->bnx2x_txq) | 3925 | if (!bp->bnx2x_txq) |
3760 | goto alloc_err; | 3926 | goto alloc_err; |
3761 | 3927 | ||
@@ -3838,7 +4004,7 @@ int bnx2x_get_link_cfg_idx(struct bnx2x *bp) | |||
3838 | return LINK_CONFIG_IDX(sel_phy_idx); | 4004 | return LINK_CONFIG_IDX(sel_phy_idx); |
3839 | } | 4005 | } |
3840 | 4006 | ||
3841 | #if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) | 4007 | #ifdef NETDEV_FCOE_WWNN |
3842 | int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) | 4008 | int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) |
3843 | { | 4009 | { |
3844 | struct bnx2x *bp = netdev_priv(dev); | 4010 | struct bnx2x *bp = netdev_priv(dev); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 9c5ea6c5b4c7..ad280740b134 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -238,7 +238,6 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance); | |||
238 | * @dev_instance: private instance | 238 | * @dev_instance: private instance |
239 | */ | 239 | */ |
240 | irqreturn_t bnx2x_interrupt(int irq, void *dev_instance); | 240 | irqreturn_t bnx2x_interrupt(int irq, void *dev_instance); |
241 | #ifdef BCM_CNIC | ||
242 | 241 | ||
243 | /** | 242 | /** |
244 | * bnx2x_cnic_notify - send command to cnic driver | 243 | * bnx2x_cnic_notify - send command to cnic driver |
@@ -262,8 +261,6 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); | |||
262 | */ | 261 | */ |
263 | void bnx2x_setup_cnic_info(struct bnx2x *bp); | 262 | void bnx2x_setup_cnic_info(struct bnx2x *bp); |
264 | 263 | ||
265 | #endif | ||
266 | |||
267 | /** | 264 | /** |
268 | * bnx2x_int_enable - enable HW interrupts. | 265 | * bnx2x_int_enable - enable HW interrupts. |
269 | * | 266 | * |
@@ -283,7 +280,7 @@ void bnx2x_int_enable(struct bnx2x *bp); | |||
283 | void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); | 280 | void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); |
284 | 281 | ||
285 | /** | 282 | /** |
286 | * bnx2x_nic_init - init driver internals. | 283 | * bnx2x_nic_init_cnic - init driver internals for cnic. |
287 | * | 284 | * |
288 | * @bp: driver handle | 285 | * @bp: driver handle |
289 | * @load_code: COMMON, PORT or FUNCTION | 286 | * @load_code: COMMON, PORT or FUNCTION |
@@ -293,9 +290,26 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); | |||
293 | * - status blocks | 290 | * - status blocks |
294 | * - etc. | 291 | * - etc. |
295 | */ | 292 | */ |
296 | void bnx2x_nic_init(struct bnx2x *bp, u32 load_code); | 293 | void bnx2x_nic_init_cnic(struct bnx2x *bp); |
297 | 294 | ||
298 | /** | 295 | /** |
296 | * bnx2x_nic_init - init driver internals. | ||
297 | * | ||
298 | * @bp: driver handle | ||
299 | * | ||
300 | * Initializes: | ||
301 | * - rings | ||
302 | * - status blocks | ||
303 | * - etc. | ||
304 | */ | ||
305 | void bnx2x_nic_init(struct bnx2x *bp, u32 load_code); | ||
306 | /** | ||
307 | * bnx2x_alloc_mem_cnic - allocate driver's memory for cnic. | ||
308 | * | ||
309 | * @bp: driver handle | ||
310 | */ | ||
311 | int bnx2x_alloc_mem_cnic(struct bnx2x *bp); | ||
312 | /** | ||
299 | * bnx2x_alloc_mem - allocate driver's memory. | 313 | * bnx2x_alloc_mem - allocate driver's memory. |
300 | * | 314 | * |
301 | * @bp: driver handle | 315 | * @bp: driver handle |
@@ -303,6 +317,12 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code); | |||
303 | int bnx2x_alloc_mem(struct bnx2x *bp); | 317 | int bnx2x_alloc_mem(struct bnx2x *bp); |
304 | 318 | ||
305 | /** | 319 | /** |
320 | * bnx2x_free_mem_cnic - release driver's memory for cnic. | ||
321 | * | ||
322 | * @bp: driver handle | ||
323 | */ | ||
324 | void bnx2x_free_mem_cnic(struct bnx2x *bp); | ||
325 | /** | ||
306 | * bnx2x_free_mem - release driver's memory. | 326 | * bnx2x_free_mem - release driver's memory. |
307 | * | 327 | * |
308 | * @bp: driver handle | 328 | * @bp: driver handle |
@@ -407,6 +427,7 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine); | |||
407 | void bnx2x_set_reset_in_progress(struct bnx2x *bp); | 427 | void bnx2x_set_reset_in_progress(struct bnx2x *bp); |
408 | void bnx2x_set_reset_global(struct bnx2x *bp); | 428 | void bnx2x_set_reset_global(struct bnx2x *bp); |
409 | void bnx2x_disable_close_the_gate(struct bnx2x *bp); | 429 | void bnx2x_disable_close_the_gate(struct bnx2x *bp); |
430 | int bnx2x_init_hw_func_cnic(struct bnx2x *bp); | ||
410 | 431 | ||
411 | /** | 432 | /** |
412 | * bnx2x_sp_event - handle ramrods completion. | 433 | * bnx2x_sp_event - handle ramrods completion. |
@@ -424,6 +445,14 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); | |||
424 | void bnx2x_ilt_set_info(struct bnx2x *bp); | 445 | void bnx2x_ilt_set_info(struct bnx2x *bp); |
425 | 446 | ||
426 | /** | 447 | /** |
448 | * bnx2x_ilt_set_cnic_info - prepare ILT configurations for SRC | ||
449 | * and TM. | ||
450 | * | ||
451 | * @bp: driver handle | ||
452 | */ | ||
453 | void bnx2x_ilt_set_info_cnic(struct bnx2x *bp); | ||
454 | |||
455 | /** | ||
427 | * bnx2x_dcbx_init - initialize dcbx protocol. | 456 | * bnx2x_dcbx_init - initialize dcbx protocol. |
428 | * | 457 | * |
429 | * @bp: driver handle | 458 | * @bp: driver handle |
@@ -491,12 +520,17 @@ int bnx2x_resume(struct pci_dev *pdev); | |||
491 | /* Release IRQ vectors */ | 520 | /* Release IRQ vectors */ |
492 | void bnx2x_free_irq(struct bnx2x *bp); | 521 | void bnx2x_free_irq(struct bnx2x *bp); |
493 | 522 | ||
523 | void bnx2x_free_fp_mem_cnic(struct bnx2x *bp); | ||
494 | void bnx2x_free_fp_mem(struct bnx2x *bp); | 524 | void bnx2x_free_fp_mem(struct bnx2x *bp); |
525 | int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp); | ||
495 | int bnx2x_alloc_fp_mem(struct bnx2x *bp); | 526 | int bnx2x_alloc_fp_mem(struct bnx2x *bp); |
496 | void bnx2x_init_rx_rings(struct bnx2x *bp); | 527 | void bnx2x_init_rx_rings(struct bnx2x *bp); |
528 | void bnx2x_init_rx_rings_cnic(struct bnx2x *bp); | ||
529 | void bnx2x_free_skbs_cnic(struct bnx2x *bp); | ||
497 | void bnx2x_free_skbs(struct bnx2x *bp); | 530 | void bnx2x_free_skbs(struct bnx2x *bp); |
498 | void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); | 531 | void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); |
499 | void bnx2x_netif_start(struct bnx2x *bp); | 532 | void bnx2x_netif_start(struct bnx2x *bp); |
533 | int bnx2x_load_cnic(struct bnx2x *bp); | ||
500 | 534 | ||
501 | /** | 535 | /** |
502 | * bnx2x_enable_msix - set msix configuration. | 536 | * bnx2x_enable_msix - set msix configuration. |
@@ -547,7 +581,7 @@ void bnx2x_free_mem_bp(struct bnx2x *bp); | |||
547 | */ | 581 | */ |
548 | int bnx2x_change_mtu(struct net_device *dev, int new_mtu); | 582 | int bnx2x_change_mtu(struct net_device *dev, int new_mtu); |
549 | 583 | ||
550 | #if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) | 584 | #ifdef NETDEV_FCOE_WWNN |
551 | /** | 585 | /** |
552 | * bnx2x_fcoe_get_wwn - return the requested WWN value for this port | 586 | * bnx2x_fcoe_get_wwn - return the requested WWN value for this port |
553 | * | 587 | * |
@@ -793,23 +827,39 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, | |||
793 | sge->addr_lo = 0; | 827 | sge->addr_lo = 0; |
794 | } | 828 | } |
795 | 829 | ||
796 | static inline void bnx2x_add_all_napi(struct bnx2x *bp) | 830 | static inline void bnx2x_add_all_napi_cnic(struct bnx2x *bp) |
797 | { | 831 | { |
798 | int i; | 832 | int i; |
799 | 833 | ||
800 | bp->num_napi_queues = bp->num_queues; | 834 | /* Add NAPI objects */ |
835 | for_each_rx_queue_cnic(bp, i) | ||
836 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | ||
837 | bnx2x_poll, BNX2X_NAPI_WEIGHT); | ||
838 | } | ||
839 | |||
840 | static inline void bnx2x_add_all_napi(struct bnx2x *bp) | ||
841 | { | ||
842 | int i; | ||
801 | 843 | ||
802 | /* Add NAPI objects */ | 844 | /* Add NAPI objects */ |
803 | for_each_rx_queue(bp, i) | 845 | for_each_eth_queue(bp, i) |
804 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | 846 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), |
805 | bnx2x_poll, BNX2X_NAPI_WEIGHT); | 847 | bnx2x_poll, BNX2X_NAPI_WEIGHT); |
806 | } | 848 | } |
807 | 849 | ||
850 | static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp) | ||
851 | { | ||
852 | int i; | ||
853 | |||
854 | for_each_rx_queue_cnic(bp, i) | ||
855 | netif_napi_del(&bnx2x_fp(bp, i, napi)); | ||
856 | } | ||
857 | |||
808 | static inline void bnx2x_del_all_napi(struct bnx2x *bp) | 858 | static inline void bnx2x_del_all_napi(struct bnx2x *bp) |
809 | { | 859 | { |
810 | int i; | 860 | int i; |
811 | 861 | ||
812 | for_each_rx_queue(bp, i) | 862 | for_each_eth_queue(bp, i) |
813 | netif_napi_del(&bnx2x_fp(bp, i, napi)); | 863 | netif_napi_del(&bnx2x_fp(bp, i, napi)); |
814 | } | 864 | } |
815 | 865 | ||
@@ -979,11 +1029,9 @@ static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) | |||
979 | { | 1029 | { |
980 | struct bnx2x *bp = fp->bp; | 1030 | struct bnx2x *bp = fp->bp; |
981 | if (!CHIP_IS_E1x(bp)) { | 1031 | if (!CHIP_IS_E1x(bp)) { |
982 | #ifdef BCM_CNIC | ||
983 | /* there are special statistics counters for FCoE 136..140 */ | 1032 | /* there are special statistics counters for FCoE 136..140 */ |
984 | if (IS_FCOE_FP(fp)) | 1033 | if (IS_FCOE_FP(fp)) |
985 | return bp->cnic_base_cl_id + (bp->pf_num >> 1); | 1034 | return bp->cnic_base_cl_id + (bp->pf_num >> 1); |
986 | #endif | ||
987 | return fp->cl_id; | 1035 | return fp->cl_id; |
988 | } | 1036 | } |
989 | return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x; | 1037 | return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x; |
@@ -1102,7 +1150,6 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, | |||
1102 | txdata->cid, txdata->txq_index); | 1150 | txdata->cid, txdata->txq_index); |
1103 | } | 1151 | } |
1104 | 1152 | ||
1105 | #ifdef BCM_CNIC | ||
1106 | static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) | 1153 | static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx) |
1107 | { | 1154 | { |
1108 | return bp->cnic_base_cl_id + cl_idx + | 1155 | return bp->cnic_base_cl_id + cl_idx + |
@@ -1162,7 +1209,6 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) | |||
1162 | fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, | 1209 | fp->index, bp, fp->status_blk.e2_sb, fp->cl_id, fp->fw_sb_id, |
1163 | fp->igu_sb_id); | 1210 | fp->igu_sb_id); |
1164 | } | 1211 | } |
1165 | #endif | ||
1166 | 1212 | ||
1167 | static inline int bnx2x_clean_tx_queue(struct bnx2x *bp, | 1213 | static inline int bnx2x_clean_tx_queue(struct bnx2x *bp, |
1168 | struct bnx2x_fp_txdata *txdata) | 1214 | struct bnx2x_fp_txdata *txdata) |
@@ -1280,7 +1326,7 @@ static inline bool bnx2x_mtu_allows_gro(int mtu) | |||
1280 | */ | 1326 | */ |
1281 | return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS; | 1327 | return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS; |
1282 | } | 1328 | } |
1283 | #ifdef BCM_CNIC | 1329 | |
1284 | /** | 1330 | /** |
1285 | * bnx2x_get_iscsi_info - update iSCSI params according to licensing info. | 1331 | * bnx2x_get_iscsi_info - update iSCSI params according to licensing info. |
1286 | * | 1332 | * |
@@ -1288,7 +1334,6 @@ static inline bool bnx2x_mtu_allows_gro(int mtu) | |||
1288 | * | 1334 | * |
1289 | */ | 1335 | */ |
1290 | void bnx2x_get_iscsi_info(struct bnx2x *bp); | 1336 | void bnx2x_get_iscsi_info(struct bnx2x *bp); |
1291 | #endif | ||
1292 | 1337 | ||
1293 | /** | 1338 | /** |
1294 | * bnx2x_link_sync_notify - send notification to other functions. | 1339 | * bnx2x_link_sync_notify - send notification to other functions. |
@@ -1340,13 +1385,11 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) | |||
1340 | 1385 | ||
1341 | static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr) | 1386 | static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr) |
1342 | { | 1387 | { |
1343 | if (is_valid_ether_addr(addr)) | 1388 | if (is_valid_ether_addr(addr) || |
1389 | (is_zero_ether_addr(addr) && | ||
1390 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)))) | ||
1344 | return true; | 1391 | return true; |
1345 | #ifdef BCM_CNIC | 1392 | |
1346 | if (is_zero_ether_addr(addr) && | ||
1347 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) | ||
1348 | return true; | ||
1349 | #endif | ||
1350 | return false; | 1393 | return false; |
1351 | } | 1394 | } |
1352 | 1395 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 2245c3895409..cba4a16ab86a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | |||
@@ -1908,10 +1908,10 @@ static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev, | |||
1908 | /* first the HW mac address */ | 1908 | /* first the HW mac address */ |
1909 | memcpy(perm_addr, netdev->dev_addr, netdev->addr_len); | 1909 | memcpy(perm_addr, netdev->dev_addr, netdev->addr_len); |
1910 | 1910 | ||
1911 | #ifdef BCM_CNIC | 1911 | if (CNIC_LOADED(bp)) |
1912 | /* second SAN address */ | 1912 | /* second SAN address */ |
1913 | memcpy(perm_addr+netdev->addr_len, bp->fip_mac, netdev->addr_len); | 1913 | memcpy(perm_addr+netdev->addr_len, bp->fip_mac, |
1914 | #endif | 1914 | netdev->addr_len); |
1915 | } | 1915 | } |
1916 | 1916 | ||
1917 | static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio, | 1917 | static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 6e5bdd1a31d9..c40c0253e105 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -2901,7 +2901,9 @@ static void bnx2x_get_channels(struct net_device *dev, | |||
2901 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) | 2901 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) |
2902 | { | 2902 | { |
2903 | bnx2x_disable_msi(bp); | 2903 | bnx2x_disable_msi(bp); |
2904 | BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; | 2904 | bp->num_ethernet_queues = num_rss; |
2905 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
2906 | BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues); | ||
2905 | bnx2x_set_int_mode(bp); | 2907 | bnx2x_set_int_mode(bp); |
2906 | } | 2908 | } |
2907 | 2909 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 18704929e642..7eaa74b78a5b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | |||
@@ -4845,9 +4845,17 @@ struct vif_list_event_data { | |||
4845 | __le32 reserved2; | 4845 | __le32 reserved2; |
4846 | }; | 4846 | }; |
4847 | 4847 | ||
4848 | /* | 4848 | /* function update event data */ |
4849 | * union for all event ring message types | 4849 | struct function_update_event_data { |
4850 | */ | 4850 | u8 echo; |
4851 | u8 reserved; | ||
4852 | __le16 reserved0; | ||
4853 | __le32 reserved1; | ||
4854 | __le32 reserved2; | ||
4855 | }; | ||
4856 | |||
4857 | |||
4858 | /* union for all event ring message types */ | ||
4851 | union event_data { | 4859 | union event_data { |
4852 | struct vf_pf_event_data vf_pf_event; | 4860 | struct vf_pf_event_data vf_pf_event; |
4853 | struct eth_event_data eth_event; | 4861 | struct eth_event_data eth_event; |
@@ -4855,6 +4863,7 @@ union event_data { | |||
4855 | struct vf_flr_event_data vf_flr_event; | 4863 | struct vf_flr_event_data vf_flr_event; |
4856 | struct malicious_vf_event_data malicious_vf_event; | 4864 | struct malicious_vf_event_data malicious_vf_event; |
4857 | struct vif_list_event_data vif_list_event; | 4865 | struct vif_list_event_data vif_list_event; |
4866 | struct function_update_event_data function_update_event; | ||
4858 | }; | 4867 | }; |
4859 | 4868 | ||
4860 | 4869 | ||
@@ -4984,8 +4993,10 @@ struct function_update_data { | |||
4984 | u8 allowed_priorities; | 4993 | u8 allowed_priorities; |
4985 | u8 network_cos_mode; | 4994 | u8 network_cos_mode; |
4986 | u8 lb_mode_en; | 4995 | u8 lb_mode_en; |
4987 | u8 reserved0; | 4996 | u8 tx_switch_suspend_change_flg; |
4988 | __le32 reserved1; | 4997 | u8 tx_switch_suspend; |
4998 | u8 echo; | ||
4999 | __le16 reserved1; | ||
4989 | }; | 5000 | }; |
4990 | 5001 | ||
4991 | 5002 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index fe66d902dc62..d755acfe7a40 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | |||
@@ -648,15 +648,25 @@ static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, | |||
648 | return rc; | 648 | return rc; |
649 | } | 649 | } |
650 | 650 | ||
651 | static int bnx2x_ilt_mem_op_cnic(struct bnx2x *bp, u8 memop) | ||
652 | { | ||
653 | int rc = 0; | ||
654 | |||
655 | if (CONFIGURE_NIC_MODE(bp)) | ||
656 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); | ||
657 | if (!rc) | ||
658 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop); | ||
659 | |||
660 | return rc; | ||
661 | } | ||
662 | |||
651 | static int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop) | 663 | static int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop) |
652 | { | 664 | { |
653 | int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop); | 665 | int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop); |
654 | if (!rc) | 666 | if (!rc) |
655 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop); | 667 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop); |
656 | if (!rc) | 668 | if (!rc && CNIC_SUPPORT(bp) && !CONFIGURE_NIC_MODE(bp)) |
657 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); | 669 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); |
658 | if (!rc) | ||
659 | rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop); | ||
660 | 670 | ||
661 | return rc; | 671 | return rc; |
662 | } | 672 | } |
@@ -781,12 +791,19 @@ static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp, | |||
781 | bnx2x_ilt_client_init_op(bp, ilt_cli, initop); | 791 | bnx2x_ilt_client_init_op(bp, ilt_cli, initop); |
782 | } | 792 | } |
783 | 793 | ||
794 | static void bnx2x_ilt_init_op_cnic(struct bnx2x *bp, u8 initop) | ||
795 | { | ||
796 | if (CONFIGURE_NIC_MODE(bp)) | ||
797 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); | ||
798 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop); | ||
799 | } | ||
800 | |||
784 | static void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) | 801 | static void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) |
785 | { | 802 | { |
786 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop); | 803 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop); |
787 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop); | 804 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop); |
788 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); | 805 | if (CNIC_SUPPORT(bp) && !CONFIGURE_NIC_MODE(bp)) |
789 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop); | 806 | bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); |
790 | } | 807 | } |
791 | 808 | ||
792 | static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, | 809 | static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, |
@@ -890,7 +907,6 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, | |||
890 | /**************************************************************************** | 907 | /**************************************************************************** |
891 | * SRC initializations | 908 | * SRC initializations |
892 | ****************************************************************************/ | 909 | ****************************************************************************/ |
893 | #ifdef BCM_CNIC | ||
894 | /* called during init func stage */ | 910 | /* called during init func stage */ |
895 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | 911 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, |
896 | dma_addr_t t2_mapping, int src_cid_count) | 912 | dma_addr_t t2_mapping, int src_cid_count) |
@@ -915,5 +931,4 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | |||
915 | U64_HI((u64)t2_mapping + | 931 | U64_HI((u64)t2_mapping + |
916 | (src_cid_count-1) * sizeof(struct src_ent))); | 932 | (src_cid_count-1) * sizeof(struct src_ent))); |
917 | } | 933 | } |
918 | #endif | ||
919 | #endif /* BNX2X_INIT_OPS_H */ | 934 | #endif /* BNX2X_INIT_OPS_H */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f6cfdc6cf20f..cd002943fac8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -12066,7 +12066,7 @@ void bnx2x_init_xgxs_loopback(struct link_params *params, | |||
12066 | bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); | 12066 | bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); |
12067 | } | 12067 | } |
12068 | 12068 | ||
12069 | static void bnx2x_set_rx_filter(struct link_params *params, u8 en) | 12069 | void bnx2x_set_rx_filter(struct link_params *params, u8 en) |
12070 | { | 12070 | { |
12071 | struct bnx2x *bp = params->bp; | 12071 | struct bnx2x *bp = params->bp; |
12072 | u8 val = en * 0x1F; | 12072 | u8 val = en * 0x1F; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 9165b89a4b19..ba981ced628b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | |||
@@ -432,7 +432,8 @@ int bnx2x_phy_probe(struct link_params *params); | |||
432 | u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, | 432 | u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, |
433 | u32 shmem2_base, u8 port); | 433 | u32 shmem2_base, u8 port); |
434 | 434 | ||
435 | 435 | /* Open / close the gate between the NIG and the BRB */ | |
436 | void bnx2x_set_rx_filter(struct link_params *params, u8 en); | ||
436 | 437 | ||
437 | /* DCBX structs */ | 438 | /* DCBX structs */ |
438 | 439 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bd1fd3d87c24..04b9f0ab183b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -791,10 +791,9 @@ void bnx2x_panic_dump(struct bnx2x *bp) | |||
791 | 791 | ||
792 | /* host sb data */ | 792 | /* host sb data */ |
793 | 793 | ||
794 | #ifdef BCM_CNIC | ||
795 | if (IS_FCOE_FP(fp)) | 794 | if (IS_FCOE_FP(fp)) |
796 | continue; | 795 | continue; |
797 | #endif | 796 | |
798 | BNX2X_ERR(" run indexes ("); | 797 | BNX2X_ERR(" run indexes ("); |
799 | for (j = 0; j < HC_SB_MAX_SM; j++) | 798 | for (j = 0; j < HC_SB_MAX_SM; j++) |
800 | pr_cont("0x%x%s", | 799 | pr_cont("0x%x%s", |
@@ -859,7 +858,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) | |||
859 | #ifdef BNX2X_STOP_ON_ERROR | 858 | #ifdef BNX2X_STOP_ON_ERROR |
860 | /* Rings */ | 859 | /* Rings */ |
861 | /* Rx */ | 860 | /* Rx */ |
862 | for_each_rx_queue(bp, i) { | 861 | for_each_valid_rx_queue(bp, i) { |
863 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 862 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
864 | 863 | ||
865 | start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10); | 864 | start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10); |
@@ -893,7 +892,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) | |||
893 | } | 892 | } |
894 | 893 | ||
895 | /* Tx */ | 894 | /* Tx */ |
896 | for_each_tx_queue(bp, i) { | 895 | for_each_valid_tx_queue(bp, i) { |
897 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 896 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
898 | for_each_cos_in_tx_queue(fp, cos) { | 897 | for_each_cos_in_tx_queue(fp, cos) { |
899 | struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; | 898 | struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos]; |
@@ -1504,9 +1503,8 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) | |||
1504 | if (msix) { | 1503 | if (msix) { |
1505 | synchronize_irq(bp->msix_table[0].vector); | 1504 | synchronize_irq(bp->msix_table[0].vector); |
1506 | offset = 1; | 1505 | offset = 1; |
1507 | #ifdef BCM_CNIC | 1506 | if (CNIC_SUPPORT(bp)) |
1508 | offset++; | 1507 | offset++; |
1509 | #endif | ||
1510 | for_each_eth_queue(bp, i) | 1508 | for_each_eth_queue(bp, i) |
1511 | synchronize_irq(bp->msix_table[offset++].vector); | 1509 | synchronize_irq(bp->msix_table[offset++].vector); |
1512 | } else | 1510 | } else |
@@ -1588,9 +1586,8 @@ static bool bnx2x_trylock_leader_lock(struct bnx2x *bp) | |||
1588 | return bnx2x_trylock_hw_lock(bp, bnx2x_get_leader_lock_resource(bp)); | 1586 | return bnx2x_trylock_hw_lock(bp, bnx2x_get_leader_lock_resource(bp)); |
1589 | } | 1587 | } |
1590 | 1588 | ||
1591 | #ifdef BCM_CNIC | ||
1592 | static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err); | 1589 | static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid, u8 err); |
1593 | #endif | 1590 | |
1594 | 1591 | ||
1595 | void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) | 1592 | void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) |
1596 | { | 1593 | { |
@@ -1720,7 +1717,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) | |||
1720 | for_each_eth_queue(bp, i) { | 1717 | for_each_eth_queue(bp, i) { |
1721 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1718 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
1722 | 1719 | ||
1723 | mask = 0x2 << (fp->index + CNIC_PRESENT); | 1720 | mask = 0x2 << (fp->index + CNIC_SUPPORT(bp)); |
1724 | if (status & mask) { | 1721 | if (status & mask) { |
1725 | /* Handle Rx or Tx according to SB id */ | 1722 | /* Handle Rx or Tx according to SB id */ |
1726 | prefetch(fp->rx_cons_sb); | 1723 | prefetch(fp->rx_cons_sb); |
@@ -1732,22 +1729,23 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) | |||
1732 | } | 1729 | } |
1733 | } | 1730 | } |
1734 | 1731 | ||
1735 | #ifdef BCM_CNIC | 1732 | if (CNIC_SUPPORT(bp)) { |
1736 | mask = 0x2; | 1733 | mask = 0x2; |
1737 | if (status & (mask | 0x1)) { | 1734 | if (status & (mask | 0x1)) { |
1738 | struct cnic_ops *c_ops = NULL; | 1735 | struct cnic_ops *c_ops = NULL; |
1739 | 1736 | ||
1740 | if (likely(bp->state == BNX2X_STATE_OPEN)) { | 1737 | if (likely(bp->state == BNX2X_STATE_OPEN)) { |
1741 | rcu_read_lock(); | 1738 | rcu_read_lock(); |
1742 | c_ops = rcu_dereference(bp->cnic_ops); | 1739 | c_ops = rcu_dereference(bp->cnic_ops); |
1743 | if (c_ops) | 1740 | if (c_ops) |
1744 | c_ops->cnic_handler(bp->cnic_data, NULL); | 1741 | c_ops->cnic_handler(bp->cnic_data, |
1745 | rcu_read_unlock(); | 1742 | NULL); |
1746 | } | 1743 | rcu_read_unlock(); |
1744 | } | ||
1747 | 1745 | ||
1748 | status &= ~mask; | 1746 | status &= ~mask; |
1747 | } | ||
1749 | } | 1748 | } |
1750 | #endif | ||
1751 | 1749 | ||
1752 | if (unlikely(status & 0x1)) { | 1750 | if (unlikely(status & 0x1)) { |
1753 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); | 1751 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); |
@@ -3075,11 +3073,13 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp) | |||
3075 | 3073 | ||
3076 | static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) | 3074 | static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) |
3077 | { | 3075 | { |
3078 | #ifdef BCM_CNIC | ||
3079 | struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app; | 3076 | struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app; |
3080 | struct fcoe_stats_info *fcoe_stat = | 3077 | struct fcoe_stats_info *fcoe_stat = |
3081 | &bp->slowpath->drv_info_to_mcp.fcoe_stat; | 3078 | &bp->slowpath->drv_info_to_mcp.fcoe_stat; |
3082 | 3079 | ||
3080 | if (!CNIC_LOADED(bp)) | ||
3081 | return; | ||
3082 | |||
3083 | memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT, | 3083 | memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT, |
3084 | bp->fip_mac, ETH_ALEN); | 3084 | bp->fip_mac, ETH_ALEN); |
3085 | 3085 | ||
@@ -3162,16 +3162,17 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp) | |||
3162 | 3162 | ||
3163 | /* ask L5 driver to add data to the struct */ | 3163 | /* ask L5 driver to add data to the struct */ |
3164 | bnx2x_cnic_notify(bp, CNIC_CTL_FCOE_STATS_GET_CMD); | 3164 | bnx2x_cnic_notify(bp, CNIC_CTL_FCOE_STATS_GET_CMD); |
3165 | #endif | ||
3166 | } | 3165 | } |
3167 | 3166 | ||
3168 | static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp) | 3167 | static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp) |
3169 | { | 3168 | { |
3170 | #ifdef BCM_CNIC | ||
3171 | struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app; | 3169 | struct bnx2x_dcbx_app_params *app = &bp->dcbx_port_params.app; |
3172 | struct iscsi_stats_info *iscsi_stat = | 3170 | struct iscsi_stats_info *iscsi_stat = |
3173 | &bp->slowpath->drv_info_to_mcp.iscsi_stat; | 3171 | &bp->slowpath->drv_info_to_mcp.iscsi_stat; |
3174 | 3172 | ||
3173 | if (!CNIC_LOADED(bp)) | ||
3174 | return; | ||
3175 | |||
3175 | memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT, | 3176 | memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT, |
3176 | bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); | 3177 | bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); |
3177 | 3178 | ||
@@ -3180,7 +3181,6 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp) | |||
3180 | 3181 | ||
3181 | /* ask L5 driver to add data to the struct */ | 3182 | /* ask L5 driver to add data to the struct */ |
3182 | bnx2x_cnic_notify(bp, CNIC_CTL_ISCSI_STATS_GET_CMD); | 3183 | bnx2x_cnic_notify(bp, CNIC_CTL_ISCSI_STATS_GET_CMD); |
3183 | #endif | ||
3184 | } | 3184 | } |
3185 | 3185 | ||
3186 | /* called due to MCP event (on pmf): | 3186 | /* called due to MCP event (on pmf): |
@@ -4572,7 +4572,6 @@ static void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) | |||
4572 | mmiowb(); /* keep prod updates ordered */ | 4572 | mmiowb(); /* keep prod updates ordered */ |
4573 | } | 4573 | } |
4574 | 4574 | ||
4575 | #ifdef BCM_CNIC | ||
4576 | static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, | 4575 | static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, |
4577 | union event_ring_elem *elem) | 4576 | union event_ring_elem *elem) |
4578 | { | 4577 | { |
@@ -4594,7 +4593,6 @@ static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, | |||
4594 | bnx2x_cnic_cfc_comp(bp, cid, err); | 4593 | bnx2x_cnic_cfc_comp(bp, cid, err); |
4595 | return 0; | 4594 | return 0; |
4596 | } | 4595 | } |
4597 | #endif | ||
4598 | 4596 | ||
4599 | static void bnx2x_handle_mcast_eqe(struct bnx2x *bp) | 4597 | static void bnx2x_handle_mcast_eqe(struct bnx2x *bp) |
4600 | { | 4598 | { |
@@ -4635,11 +4633,9 @@ static void bnx2x_handle_classification_eqe(struct bnx2x *bp, | |||
4635 | switch (elem->message.data.eth_event.echo >> BNX2X_SWCID_SHIFT) { | 4633 | switch (elem->message.data.eth_event.echo >> BNX2X_SWCID_SHIFT) { |
4636 | case BNX2X_FILTER_MAC_PENDING: | 4634 | case BNX2X_FILTER_MAC_PENDING: |
4637 | DP(BNX2X_MSG_SP, "Got SETUP_MAC completions\n"); | 4635 | DP(BNX2X_MSG_SP, "Got SETUP_MAC completions\n"); |
4638 | #ifdef BCM_CNIC | 4636 | if (CNIC_LOADED(bp) && (cid == BNX2X_ISCSI_ETH_CID(bp))) |
4639 | if (cid == BNX2X_ISCSI_ETH_CID(bp)) | ||
4640 | vlan_mac_obj = &bp->iscsi_l2_mac_obj; | 4637 | vlan_mac_obj = &bp->iscsi_l2_mac_obj; |
4641 | else | 4638 | else |
4642 | #endif | ||
4643 | vlan_mac_obj = &bp->sp_objs[cid].mac_obj; | 4639 | vlan_mac_obj = &bp->sp_objs[cid].mac_obj; |
4644 | 4640 | ||
4645 | break; | 4641 | break; |
@@ -4665,9 +4661,7 @@ static void bnx2x_handle_classification_eqe(struct bnx2x *bp, | |||
4665 | 4661 | ||
4666 | } | 4662 | } |
4667 | 4663 | ||
4668 | #ifdef BCM_CNIC | ||
4669 | static void bnx2x_set_iscsi_eth_rx_mode(struct bnx2x *bp, bool start); | 4664 | static void bnx2x_set_iscsi_eth_rx_mode(struct bnx2x *bp, bool start); |
4670 | #endif | ||
4671 | 4665 | ||
4672 | static void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp) | 4666 | static void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp) |
4673 | { | 4667 | { |
@@ -4678,14 +4672,12 @@ static void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp) | |||
4678 | /* Send rx_mode command again if was requested */ | 4672 | /* Send rx_mode command again if was requested */ |
4679 | if (test_and_clear_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state)) | 4673 | if (test_and_clear_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state)) |
4680 | bnx2x_set_storm_rx_mode(bp); | 4674 | bnx2x_set_storm_rx_mode(bp); |
4681 | #ifdef BCM_CNIC | ||
4682 | else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_START_SCHED, | 4675 | else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_START_SCHED, |
4683 | &bp->sp_state)) | 4676 | &bp->sp_state)) |
4684 | bnx2x_set_iscsi_eth_rx_mode(bp, true); | 4677 | bnx2x_set_iscsi_eth_rx_mode(bp, true); |
4685 | else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, | 4678 | else if (test_and_clear_bit(BNX2X_FILTER_ISCSI_ETH_STOP_SCHED, |
4686 | &bp->sp_state)) | 4679 | &bp->sp_state)) |
4687 | bnx2x_set_iscsi_eth_rx_mode(bp, false); | 4680 | bnx2x_set_iscsi_eth_rx_mode(bp, false); |
4688 | #endif | ||
4689 | 4681 | ||
4690 | netif_addr_unlock_bh(bp->dev); | 4682 | netif_addr_unlock_bh(bp->dev); |
4691 | } | 4683 | } |
@@ -4747,7 +4739,6 @@ static void bnx2x_after_function_update(struct bnx2x *bp) | |||
4747 | q); | 4739 | q); |
4748 | } | 4740 | } |
4749 | 4741 | ||
4750 | #ifdef BCM_CNIC | ||
4751 | if (!NO_FCOE(bp)) { | 4742 | if (!NO_FCOE(bp)) { |
4752 | fp = &bp->fp[FCOE_IDX(bp)]; | 4743 | fp = &bp->fp[FCOE_IDX(bp)]; |
4753 | queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; | 4744 | queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; |
@@ -4770,22 +4761,16 @@ static void bnx2x_after_function_update(struct bnx2x *bp) | |||
4770 | bnx2x_link_report(bp); | 4761 | bnx2x_link_report(bp); |
4771 | bnx2x_fw_command(bp, DRV_MSG_CODE_AFEX_VIFSET_ACK, 0); | 4762 | bnx2x_fw_command(bp, DRV_MSG_CODE_AFEX_VIFSET_ACK, 0); |
4772 | } | 4763 | } |
4773 | #else | ||
4774 | /* If no FCoE ring - ACK MCP now */ | ||
4775 | bnx2x_link_report(bp); | ||
4776 | bnx2x_fw_command(bp, DRV_MSG_CODE_AFEX_VIFSET_ACK, 0); | ||
4777 | #endif /* BCM_CNIC */ | ||
4778 | } | 4764 | } |
4779 | 4765 | ||
4780 | static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( | 4766 | static struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj( |
4781 | struct bnx2x *bp, u32 cid) | 4767 | struct bnx2x *bp, u32 cid) |
4782 | { | 4768 | { |
4783 | DP(BNX2X_MSG_SP, "retrieving fp from cid %d\n", cid); | 4769 | DP(BNX2X_MSG_SP, "retrieving fp from cid %d\n", cid); |
4784 | #ifdef BCM_CNIC | 4770 | |
4785 | if (cid == BNX2X_FCOE_ETH_CID(bp)) | 4771 | if (CNIC_LOADED(bp) && (cid == BNX2X_FCOE_ETH_CID(bp))) |
4786 | return &bnx2x_fcoe_sp_obj(bp, q_obj); | 4772 | return &bnx2x_fcoe_sp_obj(bp, q_obj); |
4787 | else | 4773 | else |
4788 | #endif | ||
4789 | return &bp->sp_objs[CID_TO_FP(cid, bp)].q_obj; | 4774 | return &bp->sp_objs[CID_TO_FP(cid, bp)].q_obj; |
4790 | } | 4775 | } |
4791 | 4776 | ||
@@ -4793,6 +4778,7 @@ static void bnx2x_eq_int(struct bnx2x *bp) | |||
4793 | { | 4778 | { |
4794 | u16 hw_cons, sw_cons, sw_prod; | 4779 | u16 hw_cons, sw_cons, sw_prod; |
4795 | union event_ring_elem *elem; | 4780 | union event_ring_elem *elem; |
4781 | u8 echo; | ||
4796 | u32 cid; | 4782 | u32 cid; |
4797 | u8 opcode; | 4783 | u8 opcode; |
4798 | int spqe_cnt = 0; | 4784 | int spqe_cnt = 0; |
@@ -4847,10 +4833,11 @@ static void bnx2x_eq_int(struct bnx2x *bp) | |||
4847 | */ | 4833 | */ |
4848 | DP(BNX2X_MSG_SP, | 4834 | DP(BNX2X_MSG_SP, |
4849 | "got delete ramrod for MULTI[%d]\n", cid); | 4835 | "got delete ramrod for MULTI[%d]\n", cid); |
4850 | #ifdef BCM_CNIC | 4836 | |
4851 | if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) | 4837 | if (CNIC_LOADED(bp) && |
4838 | !bnx2x_cnic_handle_cfc_del(bp, cid, elem)) | ||
4852 | goto next_spqe; | 4839 | goto next_spqe; |
4853 | #endif | 4840 | |
4854 | q_obj = bnx2x_cid_to_q_obj(bp, cid); | 4841 | q_obj = bnx2x_cid_to_q_obj(bp, cid); |
4855 | 4842 | ||
4856 | if (q_obj->complete_cmd(bp, q_obj, BNX2X_Q_CMD_CFC_DEL)) | 4843 | if (q_obj->complete_cmd(bp, q_obj, BNX2X_Q_CMD_CFC_DEL)) |
@@ -4875,21 +4862,34 @@ static void bnx2x_eq_int(struct bnx2x *bp) | |||
4875 | break; | 4862 | break; |
4876 | bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); | 4863 | bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); |
4877 | goto next_spqe; | 4864 | goto next_spqe; |
4865 | |||
4878 | case EVENT_RING_OPCODE_FUNCTION_UPDATE: | 4866 | case EVENT_RING_OPCODE_FUNCTION_UPDATE: |
4879 | DP(BNX2X_MSG_SP | BNX2X_MSG_MCP, | 4867 | echo = elem->message.data.function_update_event.echo; |
4880 | "AFEX: ramrod completed FUNCTION_UPDATE\n"); | 4868 | if (echo == SWITCH_UPDATE) { |
4881 | f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_AFEX_UPDATE); | 4869 | DP(BNX2X_MSG_SP | NETIF_MSG_IFUP, |
4870 | "got FUNC_SWITCH_UPDATE ramrod\n"); | ||
4871 | if (f_obj->complete_cmd( | ||
4872 | bp, f_obj, BNX2X_F_CMD_SWITCH_UPDATE)) | ||
4873 | break; | ||
4882 | 4874 | ||
4883 | /* We will perform the Queues update from sp_rtnl task | 4875 | } else { |
4884 | * as all Queue SP operations should run under | 4876 | DP(BNX2X_MSG_SP | BNX2X_MSG_MCP, |
4885 | * rtnl_lock. | 4877 | "AFEX: ramrod completed FUNCTION_UPDATE\n"); |
4886 | */ | 4878 | f_obj->complete_cmd(bp, f_obj, |
4887 | smp_mb__before_clear_bit(); | 4879 | BNX2X_F_CMD_AFEX_UPDATE); |
4888 | set_bit(BNX2X_SP_RTNL_AFEX_F_UPDATE, | 4880 | |
4889 | &bp->sp_rtnl_state); | 4881 | /* We will perform the Queues update from |
4890 | smp_mb__after_clear_bit(); | 4882 | * sp_rtnl task as all Queue SP operations |
4883 | * should run under rtnl_lock. | ||
4884 | */ | ||
4885 | smp_mb__before_clear_bit(); | ||
4886 | set_bit(BNX2X_SP_RTNL_AFEX_F_UPDATE, | ||
4887 | &bp->sp_rtnl_state); | ||
4888 | smp_mb__after_clear_bit(); | ||
4889 | |||
4890 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
4891 | } | ||
4891 | 4892 | ||
4892 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
4893 | goto next_spqe; | 4893 | goto next_spqe; |
4894 | 4894 | ||
4895 | case EVENT_RING_OPCODE_AFEX_VIF_LISTS: | 4895 | case EVENT_RING_OPCODE_AFEX_VIF_LISTS: |
@@ -4999,11 +4999,10 @@ static void bnx2x_sp_task(struct work_struct *work) | |||
4999 | 4999 | ||
5000 | /* SP events: STAT_QUERY and others */ | 5000 | /* SP events: STAT_QUERY and others */ |
5001 | if (status & BNX2X_DEF_SB_IDX) { | 5001 | if (status & BNX2X_DEF_SB_IDX) { |
5002 | #ifdef BCM_CNIC | ||
5003 | struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); | 5002 | struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); |
5004 | 5003 | ||
5005 | if ((!NO_FCOE(bp)) && | 5004 | if (FCOE_INIT(bp) && |
5006 | (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { | 5005 | (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { |
5007 | /* | 5006 | /* |
5008 | * Prevent local bottom-halves from running as | 5007 | * Prevent local bottom-halves from running as |
5009 | * we are going to change the local NAPI list. | 5008 | * we are going to change the local NAPI list. |
@@ -5012,7 +5011,7 @@ static void bnx2x_sp_task(struct work_struct *work) | |||
5012 | napi_schedule(&bnx2x_fcoe(bp, napi)); | 5011 | napi_schedule(&bnx2x_fcoe(bp, napi)); |
5013 | local_bh_enable(); | 5012 | local_bh_enable(); |
5014 | } | 5013 | } |
5015 | #endif | 5014 | |
5016 | /* Handle EQ completions */ | 5015 | /* Handle EQ completions */ |
5017 | bnx2x_eq_int(bp); | 5016 | bnx2x_eq_int(bp); |
5018 | 5017 | ||
@@ -5050,8 +5049,7 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) | |||
5050 | return IRQ_HANDLED; | 5049 | return IRQ_HANDLED; |
5051 | #endif | 5050 | #endif |
5052 | 5051 | ||
5053 | #ifdef BCM_CNIC | 5052 | if (CNIC_LOADED(bp)) { |
5054 | { | ||
5055 | struct cnic_ops *c_ops; | 5053 | struct cnic_ops *c_ops; |
5056 | 5054 | ||
5057 | rcu_read_lock(); | 5055 | rcu_read_lock(); |
@@ -5060,7 +5058,7 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) | |||
5060 | c_ops->cnic_handler(bp->cnic_data, NULL); | 5058 | c_ops->cnic_handler(bp->cnic_data, NULL); |
5061 | rcu_read_unlock(); | 5059 | rcu_read_unlock(); |
5062 | } | 5060 | } |
5063 | #endif | 5061 | |
5064 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); | 5062 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); |
5065 | 5063 | ||
5066 | return IRQ_HANDLED; | 5064 | return IRQ_HANDLED; |
@@ -5498,12 +5496,10 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | |||
5498 | unsigned long rx_mode_flags = 0, ramrod_flags = 0; | 5496 | unsigned long rx_mode_flags = 0, ramrod_flags = 0; |
5499 | unsigned long rx_accept_flags = 0, tx_accept_flags = 0; | 5497 | unsigned long rx_accept_flags = 0, tx_accept_flags = 0; |
5500 | 5498 | ||
5501 | #ifdef BCM_CNIC | ||
5502 | if (!NO_FCOE(bp)) | 5499 | if (!NO_FCOE(bp)) |
5503 | 5500 | ||
5504 | /* Configure rx_mode of FCoE Queue */ | 5501 | /* Configure rx_mode of FCoE Queue */ |
5505 | __set_bit(BNX2X_RX_MODE_FCOE_ETH, &rx_mode_flags); | 5502 | __set_bit(BNX2X_RX_MODE_FCOE_ETH, &rx_mode_flags); |
5506 | #endif | ||
5507 | 5503 | ||
5508 | switch (bp->rx_mode) { | 5504 | switch (bp->rx_mode) { |
5509 | case BNX2X_RX_MODE_NONE: | 5505 | case BNX2X_RX_MODE_NONE: |
@@ -5624,12 +5620,12 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) | |||
5624 | 5620 | ||
5625 | static inline u8 bnx2x_fp_igu_sb_id(struct bnx2x_fastpath *fp) | 5621 | static inline u8 bnx2x_fp_igu_sb_id(struct bnx2x_fastpath *fp) |
5626 | { | 5622 | { |
5627 | return fp->bp->igu_base_sb + fp->index + CNIC_PRESENT; | 5623 | return fp->bp->igu_base_sb + fp->index + CNIC_SUPPORT(fp->bp); |
5628 | } | 5624 | } |
5629 | 5625 | ||
5630 | static inline u8 bnx2x_fp_fw_sb_id(struct bnx2x_fastpath *fp) | 5626 | static inline u8 bnx2x_fp_fw_sb_id(struct bnx2x_fastpath *fp) |
5631 | { | 5627 | { |
5632 | return fp->bp->base_fw_ndsb + fp->index + CNIC_PRESENT; | 5628 | return fp->bp->base_fw_ndsb + fp->index + CNIC_SUPPORT(fp->bp); |
5633 | } | 5629 | } |
5634 | 5630 | ||
5635 | static u8 bnx2x_fp_cl_id(struct bnx2x_fastpath *fp) | 5631 | static u8 bnx2x_fp_cl_id(struct bnx2x_fastpath *fp) |
@@ -5720,23 +5716,25 @@ static void bnx2x_init_tx_ring_one(struct bnx2x_fp_txdata *txdata) | |||
5720 | txdata->tx_pkt = 0; | 5716 | txdata->tx_pkt = 0; |
5721 | } | 5717 | } |
5722 | 5718 | ||
5719 | static void bnx2x_init_tx_rings_cnic(struct bnx2x *bp) | ||
5720 | { | ||
5721 | int i; | ||
5722 | |||
5723 | for_each_tx_queue_cnic(bp, i) | ||
5724 | bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[0]); | ||
5725 | } | ||
5723 | static void bnx2x_init_tx_rings(struct bnx2x *bp) | 5726 | static void bnx2x_init_tx_rings(struct bnx2x *bp) |
5724 | { | 5727 | { |
5725 | int i; | 5728 | int i; |
5726 | u8 cos; | 5729 | u8 cos; |
5727 | 5730 | ||
5728 | for_each_tx_queue(bp, i) | 5731 | for_each_eth_queue(bp, i) |
5729 | for_each_cos_in_tx_queue(&bp->fp[i], cos) | 5732 | for_each_cos_in_tx_queue(&bp->fp[i], cos) |
5730 | bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[cos]); | 5733 | bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[cos]); |
5731 | } | 5734 | } |
5732 | 5735 | ||
5733 | void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) | 5736 | void bnx2x_nic_init_cnic(struct bnx2x *bp) |
5734 | { | 5737 | { |
5735 | int i; | ||
5736 | |||
5737 | for_each_eth_queue(bp, i) | ||
5738 | bnx2x_init_eth_fp(bp, i); | ||
5739 | #ifdef BCM_CNIC | ||
5740 | if (!NO_FCOE(bp)) | 5738 | if (!NO_FCOE(bp)) |
5741 | bnx2x_init_fcoe_fp(bp); | 5739 | bnx2x_init_fcoe_fp(bp); |
5742 | 5740 | ||
@@ -5744,8 +5742,22 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) | |||
5744 | BNX2X_VF_ID_INVALID, false, | 5742 | BNX2X_VF_ID_INVALID, false, |
5745 | bnx2x_cnic_fw_sb_id(bp), bnx2x_cnic_igu_sb_id(bp)); | 5743 | bnx2x_cnic_fw_sb_id(bp), bnx2x_cnic_igu_sb_id(bp)); |
5746 | 5744 | ||
5747 | #endif | 5745 | /* ensure status block indices were read */ |
5746 | rmb(); | ||
5747 | bnx2x_init_rx_rings_cnic(bp); | ||
5748 | bnx2x_init_tx_rings_cnic(bp); | ||
5749 | |||
5750 | /* flush all */ | ||
5751 | mb(); | ||
5752 | mmiowb(); | ||
5753 | } | ||
5748 | 5754 | ||
5755 | void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) | ||
5756 | { | ||
5757 | int i; | ||
5758 | |||
5759 | for_each_eth_queue(bp, i) | ||
5760 | bnx2x_init_eth_fp(bp, i); | ||
5749 | /* Initialize MOD_ABS interrupts */ | 5761 | /* Initialize MOD_ABS interrupts */ |
5750 | bnx2x_init_mod_abs_int(bp, &bp->link_vars, bp->common.chip_id, | 5762 | bnx2x_init_mod_abs_int(bp, &bp->link_vars, bp->common.chip_id, |
5751 | bp->common.shmem_base, bp->common.shmem2_base, | 5763 | bp->common.shmem_base, bp->common.shmem2_base, |
@@ -6031,10 +6043,9 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) | |||
6031 | msleep(50); | 6043 | msleep(50); |
6032 | bnx2x_init_block(bp, BLOCK_BRB1, PHASE_COMMON); | 6044 | bnx2x_init_block(bp, BLOCK_BRB1, PHASE_COMMON); |
6033 | bnx2x_init_block(bp, BLOCK_PRS, PHASE_COMMON); | 6045 | bnx2x_init_block(bp, BLOCK_PRS, PHASE_COMMON); |
6034 | #ifndef BCM_CNIC | 6046 | if (!CNIC_SUPPORT(bp)) |
6035 | /* set NIC mode */ | 6047 | /* set NIC mode */ |
6036 | REG_WR(bp, PRS_REG_NIC_MODE, 1); | 6048 | REG_WR(bp, PRS_REG_NIC_MODE, 1); |
6037 | #endif | ||
6038 | 6049 | ||
6039 | /* Enable inputs of parser neighbor blocks */ | 6050 | /* Enable inputs of parser neighbor blocks */ |
6040 | REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); | 6051 | REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); |
@@ -6522,9 +6533,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) | |||
6522 | REG_WR(bp, QM_REG_SOFT_RESET, 1); | 6533 | REG_WR(bp, QM_REG_SOFT_RESET, 1); |
6523 | REG_WR(bp, QM_REG_SOFT_RESET, 0); | 6534 | REG_WR(bp, QM_REG_SOFT_RESET, 0); |
6524 | 6535 | ||
6525 | #ifdef BCM_CNIC | 6536 | if (CNIC_SUPPORT(bp)) |
6526 | bnx2x_init_block(bp, BLOCK_TM, PHASE_COMMON); | 6537 | bnx2x_init_block(bp, BLOCK_TM, PHASE_COMMON); |
6527 | #endif | ||
6528 | 6538 | ||
6529 | bnx2x_init_block(bp, BLOCK_DORQ, PHASE_COMMON); | 6539 | bnx2x_init_block(bp, BLOCK_DORQ, PHASE_COMMON); |
6530 | REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); | 6540 | REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); |
@@ -6611,18 +6621,18 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) | |||
6611 | 6621 | ||
6612 | bnx2x_init_block(bp, BLOCK_SRC, PHASE_COMMON); | 6622 | bnx2x_init_block(bp, BLOCK_SRC, PHASE_COMMON); |
6613 | 6623 | ||
6614 | #ifdef BCM_CNIC | 6624 | if (CNIC_SUPPORT(bp)) { |
6615 | REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); | 6625 | REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); |
6616 | REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc); | 6626 | REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc); |
6617 | REG_WR(bp, SRC_REG_KEYSEARCH_2, 0x223aef9b); | 6627 | REG_WR(bp, SRC_REG_KEYSEARCH_2, 0x223aef9b); |
6618 | REG_WR(bp, SRC_REG_KEYSEARCH_3, 0x26001e3a); | 6628 | REG_WR(bp, SRC_REG_KEYSEARCH_3, 0x26001e3a); |
6619 | REG_WR(bp, SRC_REG_KEYSEARCH_4, 0x7ae91116); | 6629 | REG_WR(bp, SRC_REG_KEYSEARCH_4, 0x7ae91116); |
6620 | REG_WR(bp, SRC_REG_KEYSEARCH_5, 0x5ce5230b); | 6630 | REG_WR(bp, SRC_REG_KEYSEARCH_5, 0x5ce5230b); |
6621 | REG_WR(bp, SRC_REG_KEYSEARCH_6, 0x298d8adf); | 6631 | REG_WR(bp, SRC_REG_KEYSEARCH_6, 0x298d8adf); |
6622 | REG_WR(bp, SRC_REG_KEYSEARCH_7, 0x6eb0ff09); | 6632 | REG_WR(bp, SRC_REG_KEYSEARCH_7, 0x6eb0ff09); |
6623 | REG_WR(bp, SRC_REG_KEYSEARCH_8, 0x1830f82f); | 6633 | REG_WR(bp, SRC_REG_KEYSEARCH_8, 0x1830f82f); |
6624 | REG_WR(bp, SRC_REG_KEYSEARCH_9, 0x01e46be7); | 6634 | REG_WR(bp, SRC_REG_KEYSEARCH_9, 0x01e46be7); |
6625 | #endif | 6635 | } |
6626 | REG_WR(bp, SRC_REG_SOFT_RST, 0); | 6636 | REG_WR(bp, SRC_REG_SOFT_RST, 0); |
6627 | 6637 | ||
6628 | if (sizeof(union cdu_context) != 1024) | 6638 | if (sizeof(union cdu_context) != 1024) |
@@ -6786,11 +6796,11 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
6786 | /* QM cid (connection) count */ | 6796 | /* QM cid (connection) count */ |
6787 | bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); | 6797 | bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); |
6788 | 6798 | ||
6789 | #ifdef BCM_CNIC | 6799 | if (CNIC_SUPPORT(bp)) { |
6790 | bnx2x_init_block(bp, BLOCK_TM, init_phase); | 6800 | bnx2x_init_block(bp, BLOCK_TM, init_phase); |
6791 | REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); | 6801 | REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); |
6792 | REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); | 6802 | REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); |
6793 | #endif | 6803 | } |
6794 | 6804 | ||
6795 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); | 6805 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); |
6796 | 6806 | ||
@@ -6877,9 +6887,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
6877 | REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); | 6887 | REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); |
6878 | } | 6888 | } |
6879 | 6889 | ||
6880 | #ifdef BCM_CNIC | 6890 | if (CNIC_SUPPORT(bp)) |
6881 | bnx2x_init_block(bp, BLOCK_SRC, init_phase); | 6891 | bnx2x_init_block(bp, BLOCK_SRC, init_phase); |
6882 | #endif | 6892 | |
6883 | bnx2x_init_block(bp, BLOCK_CDU, init_phase); | 6893 | bnx2x_init_block(bp, BLOCK_CDU, init_phase); |
6884 | bnx2x_init_block(bp, BLOCK_CFC, init_phase); | 6894 | bnx2x_init_block(bp, BLOCK_CFC, init_phase); |
6885 | 6895 | ||
@@ -7040,6 +7050,130 @@ static void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func) | |||
7040 | bnx2x_ilt_wr(bp, i, 0); | 7050 | bnx2x_ilt_wr(bp, i, 0); |
7041 | } | 7051 | } |
7042 | 7052 | ||
7053 | |||
7054 | void bnx2x_init_searcher(struct bnx2x *bp) | ||
7055 | { | ||
7056 | int port = BP_PORT(bp); | ||
7057 | bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); | ||
7058 | /* T1 hash bits value determines the T1 number of entries */ | ||
7059 | REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS); | ||
7060 | } | ||
7061 | |||
7062 | static inline int bnx2x_func_switch_update(struct bnx2x *bp, int suspend) | ||
7063 | { | ||
7064 | int rc; | ||
7065 | struct bnx2x_func_state_params func_params = {NULL}; | ||
7066 | struct bnx2x_func_switch_update_params *switch_update_params = | ||
7067 | &func_params.params.switch_update; | ||
7068 | |||
7069 | /* Prepare parameters for function state transitions */ | ||
7070 | __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags); | ||
7071 | __set_bit(RAMROD_RETRY, &func_params.ramrod_flags); | ||
7072 | |||
7073 | func_params.f_obj = &bp->func_obj; | ||
7074 | func_params.cmd = BNX2X_F_CMD_SWITCH_UPDATE; | ||
7075 | |||
7076 | /* Function parameters */ | ||
7077 | switch_update_params->suspend = suspend; | ||
7078 | |||
7079 | rc = bnx2x_func_state_change(bp, &func_params); | ||
7080 | |||
7081 | return rc; | ||
7082 | } | ||
7083 | |||
7084 | int bnx2x_reset_nic_mode(struct bnx2x *bp) | ||
7085 | { | ||
7086 | int rc, i, port = BP_PORT(bp); | ||
7087 | int vlan_en = 0, mac_en[NUM_MACS]; | ||
7088 | |||
7089 | |||
7090 | /* Close input from network */ | ||
7091 | if (bp->mf_mode == SINGLE_FUNCTION) { | ||
7092 | bnx2x_set_rx_filter(&bp->link_params, 0); | ||
7093 | } else { | ||
7094 | vlan_en = REG_RD(bp, port ? NIG_REG_LLH1_FUNC_EN : | ||
7095 | NIG_REG_LLH0_FUNC_EN); | ||
7096 | REG_WR(bp, port ? NIG_REG_LLH1_FUNC_EN : | ||
7097 | NIG_REG_LLH0_FUNC_EN, 0); | ||
7098 | for (i = 0; i < NUM_MACS; i++) { | ||
7099 | mac_en[i] = REG_RD(bp, port ? | ||
7100 | (NIG_REG_LLH1_FUNC_MEM_ENABLE + | ||
7101 | 4 * i) : | ||
7102 | (NIG_REG_LLH0_FUNC_MEM_ENABLE + | ||
7103 | 4 * i)); | ||
7104 | REG_WR(bp, port ? (NIG_REG_LLH1_FUNC_MEM_ENABLE + | ||
7105 | 4 * i) : | ||
7106 | (NIG_REG_LLH0_FUNC_MEM_ENABLE + 4 * i), 0); | ||
7107 | } | ||
7108 | } | ||
7109 | |||
7110 | /* Close BMC to host */ | ||
7111 | REG_WR(bp, port ? NIG_REG_P0_TX_MNG_HOST_ENABLE : | ||
7112 | NIG_REG_P1_TX_MNG_HOST_ENABLE, 0); | ||
7113 | |||
7114 | /* Suspend Tx switching to the PF. Completion of this ramrod | ||
7115 | * further guarantees that all the packets of that PF / child | ||
7116 | * VFs in BRB were processed by the Parser, so it is safe to | ||
7117 | * change the NIC_MODE register. | ||
7118 | */ | ||
7119 | rc = bnx2x_func_switch_update(bp, 1); | ||
7120 | if (rc) { | ||
7121 | BNX2X_ERR("Can't suspend tx-switching!\n"); | ||
7122 | return rc; | ||
7123 | } | ||
7124 | |||
7125 | /* Change NIC_MODE register */ | ||
7126 | REG_WR(bp, PRS_REG_NIC_MODE, 0); | ||
7127 | |||
7128 | /* Open input from network */ | ||
7129 | if (bp->mf_mode == SINGLE_FUNCTION) { | ||
7130 | bnx2x_set_rx_filter(&bp->link_params, 1); | ||
7131 | } else { | ||
7132 | REG_WR(bp, port ? NIG_REG_LLH1_FUNC_EN : | ||
7133 | NIG_REG_LLH0_FUNC_EN, vlan_en); | ||
7134 | for (i = 0; i < NUM_MACS; i++) { | ||
7135 | REG_WR(bp, port ? (NIG_REG_LLH1_FUNC_MEM_ENABLE + | ||
7136 | 4 * i) : | ||
7137 | (NIG_REG_LLH0_FUNC_MEM_ENABLE + 4 * i), | ||
7138 | mac_en[i]); | ||
7139 | } | ||
7140 | } | ||
7141 | |||
7142 | /* Enable BMC to host */ | ||
7143 | REG_WR(bp, port ? NIG_REG_P0_TX_MNG_HOST_ENABLE : | ||
7144 | NIG_REG_P1_TX_MNG_HOST_ENABLE, 1); | ||
7145 | |||
7146 | /* Resume Tx switching to the PF */ | ||
7147 | rc = bnx2x_func_switch_update(bp, 0); | ||
7148 | if (rc) { | ||
7149 | BNX2X_ERR("Can't resume tx-switching!\n"); | ||
7150 | return rc; | ||
7151 | } | ||
7152 | |||
7153 | DP(NETIF_MSG_IFUP, "NIC MODE disabled\n"); | ||
7154 | return 0; | ||
7155 | } | ||
7156 | |||
7157 | int bnx2x_init_hw_func_cnic(struct bnx2x *bp) | ||
7158 | { | ||
7159 | int rc; | ||
7160 | |||
7161 | bnx2x_ilt_init_op_cnic(bp, INITOP_SET); | ||
7162 | |||
7163 | if (CONFIGURE_NIC_MODE(bp)) { | ||
7164 | /* Configrue searcher as part of function hw init */ | ||
7165 | bnx2x_init_searcher(bp); | ||
7166 | |||
7167 | /* Reset NIC mode */ | ||
7168 | rc = bnx2x_reset_nic_mode(bp); | ||
7169 | if (rc) | ||
7170 | BNX2X_ERR("Can't change NIC mode!\n"); | ||
7171 | return rc; | ||
7172 | } | ||
7173 | |||
7174 | return 0; | ||
7175 | } | ||
7176 | |||
7043 | static int bnx2x_init_hw_func(struct bnx2x *bp) | 7177 | static int bnx2x_init_hw_func(struct bnx2x *bp) |
7044 | { | 7178 | { |
7045 | int port = BP_PORT(bp); | 7179 | int port = BP_PORT(bp); |
@@ -7082,17 +7216,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) | |||
7082 | } | 7216 | } |
7083 | bnx2x_ilt_init_op(bp, INITOP_SET); | 7217 | bnx2x_ilt_init_op(bp, INITOP_SET); |
7084 | 7218 | ||
7085 | #ifdef BCM_CNIC | 7219 | if (!CONFIGURE_NIC_MODE(bp)) { |
7086 | bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); | 7220 | bnx2x_init_searcher(bp); |
7087 | 7221 | REG_WR(bp, PRS_REG_NIC_MODE, 0); | |
7088 | /* T1 hash bits value determines the T1 number of entries */ | 7222 | DP(NETIF_MSG_IFUP, "NIC MODE disabled\n"); |
7089 | REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS); | 7223 | } else { |
7090 | #endif | 7224 | /* Set NIC mode */ |
7225 | REG_WR(bp, PRS_REG_NIC_MODE, 1); | ||
7226 | DP(NETIF_MSG_IFUP, "NIC MODE configrued\n"); | ||
7091 | 7227 | ||
7092 | #ifndef BCM_CNIC | 7228 | } |
7093 | /* set NIC mode */ | ||
7094 | REG_WR(bp, PRS_REG_NIC_MODE, 1); | ||
7095 | #endif /* BCM_CNIC */ | ||
7096 | 7229 | ||
7097 | if (!CHIP_IS_E1x(bp)) { | 7230 | if (!CHIP_IS_E1x(bp)) { |
7098 | u32 pf_conf = IGU_PF_CONF_FUNC_EN; | 7231 | u32 pf_conf = IGU_PF_CONF_FUNC_EN; |
@@ -7343,6 +7476,20 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) | |||
7343 | } | 7476 | } |
7344 | 7477 | ||
7345 | 7478 | ||
7479 | void bnx2x_free_mem_cnic(struct bnx2x *bp) | ||
7480 | { | ||
7481 | bnx2x_ilt_mem_op_cnic(bp, ILT_MEMOP_FREE); | ||
7482 | |||
7483 | if (!CHIP_IS_E1x(bp)) | ||
7484 | BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, | ||
7485 | sizeof(struct host_hc_status_block_e2)); | ||
7486 | else | ||
7487 | BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, | ||
7488 | sizeof(struct host_hc_status_block_e1x)); | ||
7489 | |||
7490 | BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); | ||
7491 | } | ||
7492 | |||
7346 | void bnx2x_free_mem(struct bnx2x *bp) | 7493 | void bnx2x_free_mem(struct bnx2x *bp) |
7347 | { | 7494 | { |
7348 | int i; | 7495 | int i; |
@@ -7367,17 +7514,6 @@ void bnx2x_free_mem(struct bnx2x *bp) | |||
7367 | 7514 | ||
7368 | BNX2X_FREE(bp->ilt->lines); | 7515 | BNX2X_FREE(bp->ilt->lines); |
7369 | 7516 | ||
7370 | #ifdef BCM_CNIC | ||
7371 | if (!CHIP_IS_E1x(bp)) | ||
7372 | BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, | ||
7373 | sizeof(struct host_hc_status_block_e2)); | ||
7374 | else | ||
7375 | BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, | ||
7376 | sizeof(struct host_hc_status_block_e1x)); | ||
7377 | |||
7378 | BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); | ||
7379 | #endif | ||
7380 | |||
7381 | BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); | 7517 | BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); |
7382 | 7518 | ||
7383 | BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, | 7519 | BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, |
@@ -7445,24 +7581,44 @@ alloc_mem_err: | |||
7445 | return -ENOMEM; | 7581 | return -ENOMEM; |
7446 | } | 7582 | } |
7447 | 7583 | ||
7448 | 7584 | int bnx2x_alloc_mem_cnic(struct bnx2x *bp) | |
7449 | int bnx2x_alloc_mem(struct bnx2x *bp) | ||
7450 | { | 7585 | { |
7451 | int i, allocated, context_size; | ||
7452 | |||
7453 | #ifdef BCM_CNIC | ||
7454 | if (!CHIP_IS_E1x(bp)) | 7586 | if (!CHIP_IS_E1x(bp)) |
7455 | /* size = the status block + ramrod buffers */ | 7587 | /* size = the status block + ramrod buffers */ |
7456 | BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, | 7588 | BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, |
7457 | sizeof(struct host_hc_status_block_e2)); | 7589 | sizeof(struct host_hc_status_block_e2)); |
7458 | else | 7590 | else |
7459 | BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, | 7591 | BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, |
7460 | sizeof(struct host_hc_status_block_e1x)); | 7592 | &bp->cnic_sb_mapping, |
7593 | sizeof(struct | ||
7594 | host_hc_status_block_e1x)); | ||
7461 | 7595 | ||
7462 | /* allocate searcher T2 table */ | 7596 | if (CONFIGURE_NIC_MODE(bp)) |
7463 | BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); | 7597 | /* allocate searcher T2 table, as it wan't allocated before */ |
7464 | #endif | 7598 | BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); |
7599 | |||
7600 | /* write address to which L5 should insert its values */ | ||
7601 | bp->cnic_eth_dev.addr_drv_info_to_mcp = | ||
7602 | &bp->slowpath->drv_info_to_mcp; | ||
7603 | |||
7604 | if (bnx2x_ilt_mem_op_cnic(bp, ILT_MEMOP_ALLOC)) | ||
7605 | goto alloc_mem_err; | ||
7606 | |||
7607 | return 0; | ||
7608 | |||
7609 | alloc_mem_err: | ||
7610 | bnx2x_free_mem_cnic(bp); | ||
7611 | BNX2X_ERR("Can't allocate memory\n"); | ||
7612 | return -ENOMEM; | ||
7613 | } | ||
7614 | |||
7615 | int bnx2x_alloc_mem(struct bnx2x *bp) | ||
7616 | { | ||
7617 | int i, allocated, context_size; | ||
7465 | 7618 | ||
7619 | if (!CONFIGURE_NIC_MODE(bp)) | ||
7620 | /* allocate searcher T2 table */ | ||
7621 | BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); | ||
7466 | 7622 | ||
7467 | BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, | 7623 | BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, |
7468 | sizeof(struct host_sp_status_block)); | 7624 | sizeof(struct host_sp_status_block)); |
@@ -7470,11 +7626,6 @@ int bnx2x_alloc_mem(struct bnx2x *bp) | |||
7470 | BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, | 7626 | BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, |
7471 | sizeof(struct bnx2x_slowpath)); | 7627 | sizeof(struct bnx2x_slowpath)); |
7472 | 7628 | ||
7473 | #ifdef BCM_CNIC | ||
7474 | /* write address to which L5 should insert its values */ | ||
7475 | bp->cnic_eth_dev.addr_drv_info_to_mcp = &bp->slowpath->drv_info_to_mcp; | ||
7476 | #endif | ||
7477 | |||
7478 | /* Allocated memory for FW statistics */ | 7629 | /* Allocated memory for FW statistics */ |
7479 | if (bnx2x_alloc_fw_stats_mem(bp)) | 7630 | if (bnx2x_alloc_fw_stats_mem(bp)) |
7480 | goto alloc_mem_err; | 7631 | goto alloc_mem_err; |
@@ -7596,14 +7747,12 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set) | |||
7596 | { | 7747 | { |
7597 | unsigned long ramrod_flags = 0; | 7748 | unsigned long ramrod_flags = 0; |
7598 | 7749 | ||
7599 | #ifdef BCM_CNIC | ||
7600 | if (is_zero_ether_addr(bp->dev->dev_addr) && | 7750 | if (is_zero_ether_addr(bp->dev->dev_addr) && |
7601 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) { | 7751 | (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) { |
7602 | DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN, | 7752 | DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN, |
7603 | "Ignoring Zero MAC for STORAGE SD mode\n"); | 7753 | "Ignoring Zero MAC for STORAGE SD mode\n"); |
7604 | return 0; | 7754 | return 0; |
7605 | } | 7755 | } |
7606 | #endif | ||
7607 | 7756 | ||
7608 | DP(NETIF_MSG_IFUP, "Adding Eth MAC\n"); | 7757 | DP(NETIF_MSG_IFUP, "Adding Eth MAC\n"); |
7609 | 7758 | ||
@@ -7632,7 +7781,8 @@ void bnx2x_set_int_mode(struct bnx2x *bp) | |||
7632 | bnx2x_enable_msi(bp); | 7781 | bnx2x_enable_msi(bp); |
7633 | /* falling through... */ | 7782 | /* falling through... */ |
7634 | case INT_MODE_INTx: | 7783 | case INT_MODE_INTx: |
7635 | bp->num_queues = 1 + NON_ETH_CONTEXT_USE; | 7784 | bp->num_ethernet_queues = 1; |
7785 | bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues; | ||
7636 | BNX2X_DEV_INFO("set number of queues to 1\n"); | 7786 | BNX2X_DEV_INFO("set number of queues to 1\n"); |
7637 | break; | 7787 | break; |
7638 | default: | 7788 | default: |
@@ -7644,9 +7794,10 @@ void bnx2x_set_int_mode(struct bnx2x *bp) | |||
7644 | bp->flags & USING_SINGLE_MSIX_FLAG) { | 7794 | bp->flags & USING_SINGLE_MSIX_FLAG) { |
7645 | /* failed to enable multiple MSI-X */ | 7795 | /* failed to enable multiple MSI-X */ |
7646 | BNX2X_DEV_INFO("Failed to enable multiple MSI-X (%d), set number of queues to %d\n", | 7796 | BNX2X_DEV_INFO("Failed to enable multiple MSI-X (%d), set number of queues to %d\n", |
7647 | bp->num_queues, 1 + NON_ETH_CONTEXT_USE); | 7797 | bp->num_queues, |
7798 | 1 + bp->num_cnic_queues); | ||
7648 | 7799 | ||
7649 | bp->num_queues = 1 + NON_ETH_CONTEXT_USE; | 7800 | bp->num_queues = 1 + bp->num_cnic_queues; |
7650 | 7801 | ||
7651 | /* Try to enable MSI */ | 7802 | /* Try to enable MSI */ |
7652 | if (!(bp->flags & USING_SINGLE_MSIX_FLAG) && | 7803 | if (!(bp->flags & USING_SINGLE_MSIX_FLAG) && |
@@ -7679,9 +7830,9 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) | |||
7679 | ilt_client->flags = ILT_CLIENT_SKIP_MEM; | 7830 | ilt_client->flags = ILT_CLIENT_SKIP_MEM; |
7680 | ilt_client->start = line; | 7831 | ilt_client->start = line; |
7681 | line += bnx2x_cid_ilt_lines(bp); | 7832 | line += bnx2x_cid_ilt_lines(bp); |
7682 | #ifdef BCM_CNIC | 7833 | |
7683 | line += CNIC_ILT_LINES; | 7834 | if (CNIC_SUPPORT(bp)) |
7684 | #endif | 7835 | line += CNIC_ILT_LINES; |
7685 | ilt_client->end = line - 1; | 7836 | ilt_client->end = line - 1; |
7686 | 7837 | ||
7687 | DP(NETIF_MSG_IFUP, "ilt client[CDU]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", | 7838 | DP(NETIF_MSG_IFUP, "ilt client[CDU]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", |
@@ -7714,49 +7865,43 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) | |||
7714 | ilog2(ilt_client->page_size >> 12)); | 7865 | ilog2(ilt_client->page_size >> 12)); |
7715 | 7866 | ||
7716 | } | 7867 | } |
7717 | /* SRC */ | ||
7718 | ilt_client = &ilt->clients[ILT_CLIENT_SRC]; | ||
7719 | #ifdef BCM_CNIC | ||
7720 | ilt_client->client_num = ILT_CLIENT_SRC; | ||
7721 | ilt_client->page_size = SRC_ILT_PAGE_SZ; | ||
7722 | ilt_client->flags = 0; | ||
7723 | ilt_client->start = line; | ||
7724 | line += SRC_ILT_LINES; | ||
7725 | ilt_client->end = line - 1; | ||
7726 | 7868 | ||
7727 | DP(NETIF_MSG_IFUP, | 7869 | if (CNIC_SUPPORT(bp)) { |
7728 | "ilt client[SRC]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", | 7870 | /* SRC */ |
7729 | ilt_client->start, | 7871 | ilt_client = &ilt->clients[ILT_CLIENT_SRC]; |
7730 | ilt_client->end, | 7872 | ilt_client->client_num = ILT_CLIENT_SRC; |
7731 | ilt_client->page_size, | 7873 | ilt_client->page_size = SRC_ILT_PAGE_SZ; |
7732 | ilt_client->flags, | 7874 | ilt_client->flags = 0; |
7733 | ilog2(ilt_client->page_size >> 12)); | 7875 | ilt_client->start = line; |
7876 | line += SRC_ILT_LINES; | ||
7877 | ilt_client->end = line - 1; | ||
7734 | 7878 | ||
7735 | #else | 7879 | DP(NETIF_MSG_IFUP, |
7736 | ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); | 7880 | "ilt client[SRC]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", |
7737 | #endif | 7881 | ilt_client->start, |
7882 | ilt_client->end, | ||
7883 | ilt_client->page_size, | ||
7884 | ilt_client->flags, | ||
7885 | ilog2(ilt_client->page_size >> 12)); | ||
7738 | 7886 | ||
7739 | /* TM */ | 7887 | /* TM */ |
7740 | ilt_client = &ilt->clients[ILT_CLIENT_TM]; | 7888 | ilt_client = &ilt->clients[ILT_CLIENT_TM]; |
7741 | #ifdef BCM_CNIC | 7889 | ilt_client->client_num = ILT_CLIENT_TM; |
7742 | ilt_client->client_num = ILT_CLIENT_TM; | 7890 | ilt_client->page_size = TM_ILT_PAGE_SZ; |
7743 | ilt_client->page_size = TM_ILT_PAGE_SZ; | 7891 | ilt_client->flags = 0; |
7744 | ilt_client->flags = 0; | 7892 | ilt_client->start = line; |
7745 | ilt_client->start = line; | 7893 | line += TM_ILT_LINES; |
7746 | line += TM_ILT_LINES; | 7894 | ilt_client->end = line - 1; |
7747 | ilt_client->end = line - 1; | ||
7748 | 7895 | ||
7749 | DP(NETIF_MSG_IFUP, | 7896 | DP(NETIF_MSG_IFUP, |
7750 | "ilt client[TM]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", | 7897 | "ilt client[TM]: start %d, end %d, psz 0x%x, flags 0x%x, hw psz %d\n", |
7751 | ilt_client->start, | 7898 | ilt_client->start, |
7752 | ilt_client->end, | 7899 | ilt_client->end, |
7753 | ilt_client->page_size, | 7900 | ilt_client->page_size, |
7754 | ilt_client->flags, | 7901 | ilt_client->flags, |
7755 | ilog2(ilt_client->page_size >> 12)); | 7902 | ilog2(ilt_client->page_size >> 12)); |
7903 | } | ||
7756 | 7904 | ||
7757 | #else | ||
7758 | ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); | ||
7759 | #endif | ||
7760 | BUG_ON(line > ILT_MAX_LINES); | 7905 | BUG_ON(line > ILT_MAX_LINES); |
7761 | } | 7906 | } |
7762 | 7907 | ||
@@ -7924,6 +8069,9 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
7924 | /* Set the command */ | 8069 | /* Set the command */ |
7925 | q_params.cmd = BNX2X_Q_CMD_SETUP; | 8070 | q_params.cmd = BNX2X_Q_CMD_SETUP; |
7926 | 8071 | ||
8072 | if (IS_FCOE_FP(fp)) | ||
8073 | bp->fcoe_init = true; | ||
8074 | |||
7927 | /* Change the state to SETUP */ | 8075 | /* Change the state to SETUP */ |
7928 | rc = bnx2x_queue_state_change(bp, &q_params); | 8076 | rc = bnx2x_queue_state_change(bp, &q_params); |
7929 | if (rc) { | 8077 | if (rc) { |
@@ -8037,12 +8185,12 @@ static void bnx2x_reset_func(struct bnx2x *bp) | |||
8037 | SB_DISABLED); | 8185 | SB_DISABLED); |
8038 | } | 8186 | } |
8039 | 8187 | ||
8040 | #ifdef BCM_CNIC | 8188 | if (CNIC_LOADED(bp)) |
8041 | /* CNIC SB */ | 8189 | /* CNIC SB */ |
8042 | REG_WR8(bp, BAR_CSTRORM_INTMEM + | 8190 | REG_WR8(bp, BAR_CSTRORM_INTMEM + |
8043 | CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(bnx2x_cnic_fw_sb_id(bp)), | 8191 | CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET |
8044 | SB_DISABLED); | 8192 | (bnx2x_cnic_fw_sb_id(bp)), SB_DISABLED); |
8045 | #endif | 8193 | |
8046 | /* SP SB */ | 8194 | /* SP SB */ |
8047 | REG_WR8(bp, BAR_CSTRORM_INTMEM + | 8195 | REG_WR8(bp, BAR_CSTRORM_INTMEM + |
8048 | CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(func), | 8196 | CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(func), |
@@ -8061,19 +8209,19 @@ static void bnx2x_reset_func(struct bnx2x *bp) | |||
8061 | REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); | 8209 | REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); |
8062 | } | 8210 | } |
8063 | 8211 | ||
8064 | #ifdef BCM_CNIC | 8212 | if (CNIC_LOADED(bp)) { |
8065 | /* Disable Timer scan */ | 8213 | /* Disable Timer scan */ |
8066 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); | 8214 | REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); |
8067 | /* | 8215 | /* |
8068 | * Wait for at least 10ms and up to 2 second for the timers scan to | 8216 | * Wait for at least 10ms and up to 2 second for the timers |
8069 | * complete | 8217 | * scan to complete |
8070 | */ | 8218 | */ |
8071 | for (i = 0; i < 200; i++) { | 8219 | for (i = 0; i < 200; i++) { |
8072 | msleep(10); | 8220 | msleep(10); |
8073 | if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4)) | 8221 | if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4)) |
8074 | break; | 8222 | break; |
8223 | } | ||
8075 | } | 8224 | } |
8076 | #endif | ||
8077 | /* Clear ILT */ | 8225 | /* Clear ILT */ |
8078 | bnx2x_clear_func_ilt(bp, func); | 8226 | bnx2x_clear_func_ilt(bp, func); |
8079 | 8227 | ||
@@ -8409,13 +8557,24 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
8409 | /* Close multi and leading connections | 8557 | /* Close multi and leading connections |
8410 | * Completions for ramrods are collected in a synchronous way | 8558 | * Completions for ramrods are collected in a synchronous way |
8411 | */ | 8559 | */ |
8412 | for_each_queue(bp, i) | 8560 | for_each_eth_queue(bp, i) |
8413 | if (bnx2x_stop_queue(bp, i)) | 8561 | if (bnx2x_stop_queue(bp, i)) |
8414 | #ifdef BNX2X_STOP_ON_ERROR | 8562 | #ifdef BNX2X_STOP_ON_ERROR |
8415 | return; | 8563 | return; |
8416 | #else | 8564 | #else |
8417 | goto unload_error; | 8565 | goto unload_error; |
8418 | #endif | 8566 | #endif |
8567 | |||
8568 | if (CNIC_LOADED(bp)) { | ||
8569 | for_each_cnic_queue(bp, i) | ||
8570 | if (bnx2x_stop_queue(bp, i)) | ||
8571 | #ifdef BNX2X_STOP_ON_ERROR | ||
8572 | return; | ||
8573 | #else | ||
8574 | goto unload_error; | ||
8575 | #endif | ||
8576 | } | ||
8577 | |||
8419 | /* If SP settings didn't get completed so far - something | 8578 | /* If SP settings didn't get completed so far - something |
8420 | * very wrong has happen. | 8579 | * very wrong has happen. |
8421 | */ | 8580 | */ |
@@ -8437,6 +8596,8 @@ unload_error: | |||
8437 | bnx2x_netif_stop(bp, 1); | 8596 | bnx2x_netif_stop(bp, 1); |
8438 | /* Delete all NAPI objects */ | 8597 | /* Delete all NAPI objects */ |
8439 | bnx2x_del_all_napi(bp); | 8598 | bnx2x_del_all_napi(bp); |
8599 | if (CNIC_LOADED(bp)) | ||
8600 | bnx2x_del_all_napi_cnic(bp); | ||
8440 | 8601 | ||
8441 | /* Release IRQs */ | 8602 | /* Release IRQs */ |
8442 | bnx2x_free_irq(bp); | 8603 | bnx2x_free_irq(bp); |
@@ -10224,12 +10385,15 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
10224 | void bnx2x_get_iscsi_info(struct bnx2x *bp) | 10385 | void bnx2x_get_iscsi_info(struct bnx2x *bp) |
10225 | { | 10386 | { |
10226 | u32 no_flags = NO_ISCSI_FLAG; | 10387 | u32 no_flags = NO_ISCSI_FLAG; |
10227 | #ifdef BCM_CNIC | ||
10228 | int port = BP_PORT(bp); | 10388 | int port = BP_PORT(bp); |
10229 | |||
10230 | u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, | 10389 | u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, |
10231 | drv_lic_key[port].max_iscsi_conn); | 10390 | drv_lic_key[port].max_iscsi_conn); |
10232 | 10391 | ||
10392 | if (!CNIC_SUPPORT(bp)) { | ||
10393 | bp->flags |= no_flags; | ||
10394 | return; | ||
10395 | } | ||
10396 | |||
10233 | /* Get the number of maximum allowed iSCSI connections */ | 10397 | /* Get the number of maximum allowed iSCSI connections */ |
10234 | bp->cnic_eth_dev.max_iscsi_conn = | 10398 | bp->cnic_eth_dev.max_iscsi_conn = |
10235 | (max_iscsi_conn & BNX2X_MAX_ISCSI_INIT_CONN_MASK) >> | 10399 | (max_iscsi_conn & BNX2X_MAX_ISCSI_INIT_CONN_MASK) >> |
@@ -10244,12 +10408,9 @@ void bnx2x_get_iscsi_info(struct bnx2x *bp) | |||
10244 | */ | 10408 | */ |
10245 | if (!bp->cnic_eth_dev.max_iscsi_conn) | 10409 | if (!bp->cnic_eth_dev.max_iscsi_conn) |
10246 | bp->flags |= no_flags; | 10410 | bp->flags |= no_flags; |
10247 | #else | 10411 | |
10248 | bp->flags |= no_flags; | ||
10249 | #endif | ||
10250 | } | 10412 | } |
10251 | 10413 | ||
10252 | #ifdef BCM_CNIC | ||
10253 | static void __devinit bnx2x_get_ext_wwn_info(struct bnx2x *bp, int func) | 10414 | static void __devinit bnx2x_get_ext_wwn_info(struct bnx2x *bp, int func) |
10254 | { | 10415 | { |
10255 | /* Port info */ | 10416 | /* Port info */ |
@@ -10264,16 +10425,18 @@ static void __devinit bnx2x_get_ext_wwn_info(struct bnx2x *bp, int func) | |||
10264 | bp->cnic_eth_dev.fcoe_wwn_node_name_lo = | 10425 | bp->cnic_eth_dev.fcoe_wwn_node_name_lo = |
10265 | MF_CFG_RD(bp, func_ext_config[func].fcoe_wwn_node_name_lower); | 10426 | MF_CFG_RD(bp, func_ext_config[func].fcoe_wwn_node_name_lower); |
10266 | } | 10427 | } |
10267 | #endif | ||
10268 | static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | 10428 | static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) |
10269 | { | 10429 | { |
10270 | #ifdef BCM_CNIC | ||
10271 | int port = BP_PORT(bp); | 10430 | int port = BP_PORT(bp); |
10272 | int func = BP_ABS_FUNC(bp); | 10431 | int func = BP_ABS_FUNC(bp); |
10273 | |||
10274 | u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, | 10432 | u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, |
10275 | drv_lic_key[port].max_fcoe_conn); | 10433 | drv_lic_key[port].max_fcoe_conn); |
10276 | 10434 | ||
10435 | if (!CNIC_SUPPORT(bp)) { | ||
10436 | bp->flags |= NO_FCOE_FLAG; | ||
10437 | return; | ||
10438 | } | ||
10439 | |||
10277 | /* Get the number of maximum allowed FCoE connections */ | 10440 | /* Get the number of maximum allowed FCoE connections */ |
10278 | bp->cnic_eth_dev.max_fcoe_conn = | 10441 | bp->cnic_eth_dev.max_fcoe_conn = |
10279 | (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> | 10442 | (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> |
@@ -10319,9 +10482,6 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | |||
10319 | */ | 10482 | */ |
10320 | if (!bp->cnic_eth_dev.max_fcoe_conn) | 10483 | if (!bp->cnic_eth_dev.max_fcoe_conn) |
10321 | bp->flags |= NO_FCOE_FLAG; | 10484 | bp->flags |= NO_FCOE_FLAG; |
10322 | #else | ||
10323 | bp->flags |= NO_FCOE_FLAG; | ||
10324 | #endif | ||
10325 | } | 10485 | } |
10326 | 10486 | ||
10327 | static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) | 10487 | static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) |
@@ -10335,132 +10495,133 @@ static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) | |||
10335 | bnx2x_get_fcoe_info(bp); | 10495 | bnx2x_get_fcoe_info(bp); |
10336 | } | 10496 | } |
10337 | 10497 | ||
10338 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) | 10498 | static void __devinit bnx2x_get_cnic_mac_hwinfo(struct bnx2x *bp) |
10339 | { | 10499 | { |
10340 | u32 val, val2; | 10500 | u32 val, val2; |
10341 | int func = BP_ABS_FUNC(bp); | 10501 | int func = BP_ABS_FUNC(bp); |
10342 | int port = BP_PORT(bp); | 10502 | int port = BP_PORT(bp); |
10343 | #ifdef BCM_CNIC | ||
10344 | u8 *iscsi_mac = bp->cnic_eth_dev.iscsi_mac; | 10503 | u8 *iscsi_mac = bp->cnic_eth_dev.iscsi_mac; |
10345 | u8 *fip_mac = bp->fip_mac; | 10504 | u8 *fip_mac = bp->fip_mac; |
10346 | #endif | ||
10347 | 10505 | ||
10348 | /* Zero primary MAC configuration */ | 10506 | if (IS_MF(bp)) { |
10349 | memset(bp->dev->dev_addr, 0, ETH_ALEN); | 10507 | /* iSCSI and FCoE NPAR MACs: if there is no either iSCSI or |
10350 | |||
10351 | if (BP_NOMCP(bp)) { | ||
10352 | BNX2X_ERROR("warning: random MAC workaround active\n"); | ||
10353 | eth_hw_addr_random(bp->dev); | ||
10354 | } else if (IS_MF(bp)) { | ||
10355 | val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); | ||
10356 | val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); | ||
10357 | if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && | ||
10358 | (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) | ||
10359 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
10360 | |||
10361 | #ifdef BCM_CNIC | ||
10362 | /* | ||
10363 | * iSCSI and FCoE NPAR MACs: if there is no either iSCSI or | ||
10364 | * FCoE MAC then the appropriate feature should be disabled. | 10508 | * FCoE MAC then the appropriate feature should be disabled. |
10365 | * | 10509 | * In non SD mode features configuration comes from struct |
10366 | * In non SD mode features configuration comes from | 10510 | * func_ext_config. |
10367 | * struct func_ext_config. | ||
10368 | */ | 10511 | */ |
10369 | if (!IS_MF_SD(bp)) { | 10512 | if (!IS_MF_SD(bp) && !CHIP_IS_E1x(bp)) { |
10370 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); | 10513 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); |
10371 | if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { | 10514 | if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { |
10372 | val2 = MF_CFG_RD(bp, func_ext_config[func]. | 10515 | val2 = MF_CFG_RD(bp, func_ext_config[func]. |
10373 | iscsi_mac_addr_upper); | 10516 | iscsi_mac_addr_upper); |
10374 | val = MF_CFG_RD(bp, func_ext_config[func]. | 10517 | val = MF_CFG_RD(bp, func_ext_config[func]. |
10375 | iscsi_mac_addr_lower); | 10518 | iscsi_mac_addr_lower); |
10376 | bnx2x_set_mac_buf(iscsi_mac, val, val2); | 10519 | bnx2x_set_mac_buf(iscsi_mac, val, val2); |
10377 | BNX2X_DEV_INFO("Read iSCSI MAC: %pM\n", | 10520 | BNX2X_DEV_INFO |
10378 | iscsi_mac); | 10521 | ("Read iSCSI MAC: %pM\n", iscsi_mac); |
10379 | } else | 10522 | } else { |
10380 | bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; | 10523 | bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; |
10524 | } | ||
10381 | 10525 | ||
10382 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) { | 10526 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) { |
10383 | val2 = MF_CFG_RD(bp, func_ext_config[func]. | 10527 | val2 = MF_CFG_RD(bp, func_ext_config[func]. |
10384 | fcoe_mac_addr_upper); | 10528 | fcoe_mac_addr_upper); |
10385 | val = MF_CFG_RD(bp, func_ext_config[func]. | 10529 | val = MF_CFG_RD(bp, func_ext_config[func]. |
10386 | fcoe_mac_addr_lower); | 10530 | fcoe_mac_addr_lower); |
10387 | bnx2x_set_mac_buf(fip_mac, val, val2); | 10531 | bnx2x_set_mac_buf(fip_mac, val, val2); |
10388 | BNX2X_DEV_INFO("Read FCoE L2 MAC: %pM\n", | 10532 | BNX2X_DEV_INFO |
10389 | fip_mac); | 10533 | ("Read FCoE L2 MAC: %pM\n", fip_mac); |
10390 | 10534 | } else { | |
10391 | } else | ||
10392 | bp->flags |= NO_FCOE_FLAG; | 10535 | bp->flags |= NO_FCOE_FLAG; |
10536 | } | ||
10393 | 10537 | ||
10394 | bp->mf_ext_config = cfg; | 10538 | bp->mf_ext_config = cfg; |
10395 | 10539 | ||
10396 | } else { /* SD MODE */ | 10540 | } else { /* SD MODE */ |
10397 | if (IS_MF_STORAGE_SD(bp)) { | 10541 | if (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp)) { |
10398 | if (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp)) { | 10542 | /* use primary mac as iscsi mac */ |
10399 | /* use primary mac as iscsi mac */ | 10543 | memcpy(iscsi_mac, bp->dev->dev_addr, ETH_ALEN); |
10400 | memcpy(iscsi_mac, bp->dev->dev_addr, | 10544 | |
10401 | ETH_ALEN); | 10545 | BNX2X_DEV_INFO("SD ISCSI MODE\n"); |
10402 | 10546 | BNX2X_DEV_INFO | |
10403 | BNX2X_DEV_INFO("SD ISCSI MODE\n"); | 10547 | ("Read iSCSI MAC: %pM\n", iscsi_mac); |
10404 | BNX2X_DEV_INFO("Read iSCSI MAC: %pM\n", | 10548 | } else if (BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)) { |
10405 | iscsi_mac); | 10549 | /* use primary mac as fip mac */ |
10406 | } else { /* FCoE */ | 10550 | memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); |
10407 | memcpy(fip_mac, bp->dev->dev_addr, | 10551 | BNX2X_DEV_INFO("SD FCoE MODE\n"); |
10408 | ETH_ALEN); | 10552 | BNX2X_DEV_INFO |
10409 | BNX2X_DEV_INFO("SD FCoE MODE\n"); | 10553 | ("Read FIP MAC: %pM\n", fip_mac); |
10410 | BNX2X_DEV_INFO("Read FIP MAC: %pM\n", | ||
10411 | fip_mac); | ||
10412 | } | ||
10413 | /* Zero primary MAC configuration */ | ||
10414 | memset(bp->dev->dev_addr, 0, ETH_ALEN); | ||
10415 | } | 10554 | } |
10416 | } | 10555 | } |
10417 | 10556 | ||
10557 | if (IS_MF_STORAGE_SD(bp)) | ||
10558 | /* Zero primary MAC configuration */ | ||
10559 | memset(bp->dev->dev_addr, 0, ETH_ALEN); | ||
10560 | |||
10418 | if (IS_MF_FCOE_AFEX(bp)) | 10561 | if (IS_MF_FCOE_AFEX(bp)) |
10419 | /* use FIP MAC as primary MAC */ | 10562 | /* use FIP MAC as primary MAC */ |
10420 | memcpy(bp->dev->dev_addr, fip_mac, ETH_ALEN); | 10563 | memcpy(bp->dev->dev_addr, fip_mac, ETH_ALEN); |
10421 | 10564 | ||
10422 | #endif | ||
10423 | } else { | 10565 | } else { |
10424 | /* in SF read MACs from port configuration */ | ||
10425 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); | ||
10426 | val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); | ||
10427 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
10428 | |||
10429 | #ifdef BCM_CNIC | ||
10430 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. | 10566 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. |
10431 | iscsi_mac_upper); | 10567 | iscsi_mac_upper); |
10432 | val = SHMEM_RD(bp, dev_info.port_hw_config[port]. | 10568 | val = SHMEM_RD(bp, dev_info.port_hw_config[port]. |
10433 | iscsi_mac_lower); | 10569 | iscsi_mac_lower); |
10434 | bnx2x_set_mac_buf(iscsi_mac, val, val2); | 10570 | bnx2x_set_mac_buf(iscsi_mac, val, val2); |
10435 | 10571 | ||
10436 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. | 10572 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. |
10437 | fcoe_fip_mac_upper); | 10573 | fcoe_fip_mac_upper); |
10438 | val = SHMEM_RD(bp, dev_info.port_hw_config[port]. | 10574 | val = SHMEM_RD(bp, dev_info.port_hw_config[port]. |
10439 | fcoe_fip_mac_lower); | 10575 | fcoe_fip_mac_lower); |
10440 | bnx2x_set_mac_buf(fip_mac, val, val2); | 10576 | bnx2x_set_mac_buf(fip_mac, val, val2); |
10441 | #endif | ||
10442 | } | 10577 | } |
10443 | 10578 | ||
10444 | memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); | 10579 | /* Disable iSCSI OOO if MAC configuration is invalid. */ |
10445 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); | ||
10446 | |||
10447 | #ifdef BCM_CNIC | ||
10448 | /* Disable iSCSI if MAC configuration is | ||
10449 | * invalid. | ||
10450 | */ | ||
10451 | if (!is_valid_ether_addr(iscsi_mac)) { | 10580 | if (!is_valid_ether_addr(iscsi_mac)) { |
10452 | bp->flags |= NO_ISCSI_FLAG; | 10581 | bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; |
10453 | memset(iscsi_mac, 0, ETH_ALEN); | 10582 | memset(iscsi_mac, 0, ETH_ALEN); |
10454 | } | 10583 | } |
10455 | 10584 | ||
10456 | /* Disable FCoE if MAC configuration is | 10585 | /* Disable FCoE if MAC configuration is invalid. */ |
10457 | * invalid. | ||
10458 | */ | ||
10459 | if (!is_valid_ether_addr(fip_mac)) { | 10586 | if (!is_valid_ether_addr(fip_mac)) { |
10460 | bp->flags |= NO_FCOE_FLAG; | 10587 | bp->flags |= NO_FCOE_FLAG; |
10461 | memset(bp->fip_mac, 0, ETH_ALEN); | 10588 | memset(bp->fip_mac, 0, ETH_ALEN); |
10462 | } | 10589 | } |
10463 | #endif | 10590 | } |
10591 | |||
10592 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) | ||
10593 | { | ||
10594 | u32 val, val2; | ||
10595 | int func = BP_ABS_FUNC(bp); | ||
10596 | int port = BP_PORT(bp); | ||
10597 | |||
10598 | /* Zero primary MAC configuration */ | ||
10599 | memset(bp->dev->dev_addr, 0, ETH_ALEN); | ||
10600 | |||
10601 | if (BP_NOMCP(bp)) { | ||
10602 | BNX2X_ERROR("warning: random MAC workaround active\n"); | ||
10603 | eth_hw_addr_random(bp->dev); | ||
10604 | } else if (IS_MF(bp)) { | ||
10605 | val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); | ||
10606 | val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); | ||
10607 | if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && | ||
10608 | (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) | ||
10609 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
10610 | |||
10611 | if (CNIC_SUPPORT(bp)) | ||
10612 | bnx2x_get_cnic_mac_hwinfo(bp); | ||
10613 | } else { | ||
10614 | /* in SF read MACs from port configuration */ | ||
10615 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); | ||
10616 | val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); | ||
10617 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
10618 | |||
10619 | if (CNIC_SUPPORT(bp)) | ||
10620 | bnx2x_get_cnic_mac_hwinfo(bp); | ||
10621 | } | ||
10622 | |||
10623 | memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); | ||
10624 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); | ||
10464 | 10625 | ||
10465 | if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr)) | 10626 | if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr)) |
10466 | dev_err(&bp->pdev->dev, | 10627 | dev_err(&bp->pdev->dev, |
@@ -10837,9 +10998,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
10837 | mutex_init(&bp->port.phy_mutex); | 10998 | mutex_init(&bp->port.phy_mutex); |
10838 | mutex_init(&bp->fw_mb_mutex); | 10999 | mutex_init(&bp->fw_mb_mutex); |
10839 | spin_lock_init(&bp->stats_lock); | 11000 | spin_lock_init(&bp->stats_lock); |
10840 | #ifdef BCM_CNIC | 11001 | |
10841 | mutex_init(&bp->cnic_mutex); | ||
10842 | #endif | ||
10843 | 11002 | ||
10844 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); | 11003 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); |
10845 | INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); | 11004 | INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); |
@@ -10877,10 +11036,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
10877 | dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n"); | 11036 | dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n"); |
10878 | 11037 | ||
10879 | bp->disable_tpa = disable_tpa; | 11038 | bp->disable_tpa = disable_tpa; |
10880 | |||
10881 | #ifdef BCM_CNIC | ||
10882 | bp->disable_tpa |= IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp); | 11039 | bp->disable_tpa |= IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp); |
10883 | #endif | ||
10884 | 11040 | ||
10885 | /* Set TPA flags */ | 11041 | /* Set TPA flags */ |
10886 | if (bp->disable_tpa) { | 11042 | if (bp->disable_tpa) { |
@@ -10914,12 +11070,10 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
10914 | bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); | 11070 | bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); |
10915 | bnx2x_dcbx_init_params(bp); | 11071 | bnx2x_dcbx_init_params(bp); |
10916 | 11072 | ||
10917 | #ifdef BCM_CNIC | ||
10918 | if (CHIP_IS_E1x(bp)) | 11073 | if (CHIP_IS_E1x(bp)) |
10919 | bp->cnic_base_cl_id = FP_SB_MAX_E1x; | 11074 | bp->cnic_base_cl_id = FP_SB_MAX_E1x; |
10920 | else | 11075 | else |
10921 | bp->cnic_base_cl_id = FP_SB_MAX_E2; | 11076 | bp->cnic_base_cl_id = FP_SB_MAX_E2; |
10922 | #endif | ||
10923 | 11077 | ||
10924 | /* multiple tx priority */ | 11078 | /* multiple tx priority */ |
10925 | if (CHIP_IS_E1x(bp)) | 11079 | if (CHIP_IS_E1x(bp)) |
@@ -10929,6 +11083,16 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
10929 | if (CHIP_IS_E3B0(bp)) | 11083 | if (CHIP_IS_E3B0(bp)) |
10930 | bp->max_cos = BNX2X_MULTI_TX_COS_E3B0; | 11084 | bp->max_cos = BNX2X_MULTI_TX_COS_E3B0; |
10931 | 11085 | ||
11086 | /* We need at least one default status block for slow-path events, | ||
11087 | * second status block for the L2 queue, and a third status block for | ||
11088 | * CNIC if supproted. | ||
11089 | */ | ||
11090 | if (CNIC_SUPPORT(bp)) | ||
11091 | bp->min_msix_vec_cnt = 3; | ||
11092 | else | ||
11093 | bp->min_msix_vec_cnt = 2; | ||
11094 | BNX2X_DEV_INFO("bp->min_msix_vec_cnt %d", bp->min_msix_vec_cnt); | ||
11095 | |||
10932 | return rc; | 11096 | return rc; |
10933 | } | 11097 | } |
10934 | 11098 | ||
@@ -11165,11 +11329,9 @@ void bnx2x_set_rx_mode(struct net_device *dev) | |||
11165 | } | 11329 | } |
11166 | 11330 | ||
11167 | bp->rx_mode = rx_mode; | 11331 | bp->rx_mode = rx_mode; |
11168 | #ifdef BCM_CNIC | ||
11169 | /* handle ISCSI SD mode */ | 11332 | /* handle ISCSI SD mode */ |
11170 | if (IS_MF_ISCSI_SD(bp)) | 11333 | if (IS_MF_ISCSI_SD(bp)) |
11171 | bp->rx_mode = BNX2X_RX_MODE_NONE; | 11334 | bp->rx_mode = BNX2X_RX_MODE_NONE; |
11172 | #endif | ||
11173 | 11335 | ||
11174 | /* Schedule the rx_mode command */ | 11336 | /* Schedule the rx_mode command */ |
11175 | if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) { | 11337 | if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) { |
@@ -11281,7 +11443,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { | |||
11281 | #endif | 11443 | #endif |
11282 | .ndo_setup_tc = bnx2x_setup_tc, | 11444 | .ndo_setup_tc = bnx2x_setup_tc, |
11283 | 11445 | ||
11284 | #if defined(NETDEV_FCOE_WWNN) && defined(BCM_CNIC) | 11446 | #ifdef NETDEV_FCOE_WWNN |
11285 | .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, | 11447 | .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, |
11286 | #endif | 11448 | #endif |
11287 | }; | 11449 | }; |
@@ -11747,9 +11909,8 @@ static int bnx2x_set_qm_cid_count(struct bnx2x *bp) | |||
11747 | { | 11909 | { |
11748 | int cid_count = BNX2X_L2_MAX_CID(bp); | 11910 | int cid_count = BNX2X_L2_MAX_CID(bp); |
11749 | 11911 | ||
11750 | #ifdef BCM_CNIC | 11912 | if (CNIC_SUPPORT(bp)) |
11751 | cid_count += CNIC_CID_MAX; | 11913 | cid_count += CNIC_CID_MAX; |
11752 | #endif | ||
11753 | return roundup(cid_count, QM_CID_ROUND); | 11914 | return roundup(cid_count, QM_CID_ROUND); |
11754 | } | 11915 | } |
11755 | 11916 | ||
@@ -11759,7 +11920,8 @@ static int bnx2x_set_qm_cid_count(struct bnx2x *bp) | |||
11759 | * @dev: pci device | 11920 | * @dev: pci device |
11760 | * | 11921 | * |
11761 | */ | 11922 | */ |
11762 | static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev) | 11923 | static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev, |
11924 | int cnic_cnt) | ||
11763 | { | 11925 | { |
11764 | int pos; | 11926 | int pos; |
11765 | u16 control; | 11927 | u16 control; |
@@ -11771,7 +11933,7 @@ static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev) | |||
11771 | * one fast path queue: one FP queue + SB for CNIC | 11933 | * one fast path queue: one FP queue + SB for CNIC |
11772 | */ | 11934 | */ |
11773 | if (!pos) | 11935 | if (!pos) |
11774 | return 1 + CNIC_PRESENT; | 11936 | return 1 + cnic_cnt; |
11775 | 11937 | ||
11776 | /* | 11938 | /* |
11777 | * The value in the PCI configuration space is the index of the last | 11939 | * The value in the PCI configuration space is the index of the last |
@@ -11791,6 +11953,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11791 | int pcie_width, pcie_speed; | 11953 | int pcie_width, pcie_speed; |
11792 | int rc, max_non_def_sbs; | 11954 | int rc, max_non_def_sbs; |
11793 | int rx_count, tx_count, rss_count, doorbell_size; | 11955 | int rx_count, tx_count, rss_count, doorbell_size; |
11956 | int cnic_cnt; | ||
11794 | /* | 11957 | /* |
11795 | * An estimated maximum supported CoS number according to the chip | 11958 | * An estimated maximum supported CoS number according to the chip |
11796 | * version. | 11959 | * version. |
@@ -11834,21 +11997,22 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11834 | return -ENODEV; | 11997 | return -ENODEV; |
11835 | } | 11998 | } |
11836 | 11999 | ||
11837 | max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev); | 12000 | cnic_cnt = 1; |
12001 | max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev, cnic_cnt); | ||
11838 | 12002 | ||
11839 | WARN_ON(!max_non_def_sbs); | 12003 | WARN_ON(!max_non_def_sbs); |
11840 | 12004 | ||
11841 | /* Maximum number of RSS queues: one IGU SB goes to CNIC */ | 12005 | /* Maximum number of RSS queues: one IGU SB goes to CNIC */ |
11842 | rss_count = max_non_def_sbs - CNIC_PRESENT; | 12006 | rss_count = max_non_def_sbs - cnic_cnt; |
11843 | 12007 | ||
11844 | /* Maximum number of netdev Rx queues: RSS + FCoE L2 */ | 12008 | /* Maximum number of netdev Rx queues: RSS + FCoE L2 */ |
11845 | rx_count = rss_count + FCOE_PRESENT; | 12009 | rx_count = rss_count + cnic_cnt; |
11846 | 12010 | ||
11847 | /* | 12011 | /* |
11848 | * Maximum number of netdev Tx queues: | 12012 | * Maximum number of netdev Tx queues: |
11849 | * Maximum TSS queues * Maximum supported number of CoS + FCoE L2 | 12013 | * Maximum TSS queues * Maximum supported number of CoS + FCoE L2 |
11850 | */ | 12014 | */ |
11851 | tx_count = rss_count * max_cos_est + FCOE_PRESENT; | 12015 | tx_count = rss_count * max_cos_est + cnic_cnt; |
11852 | 12016 | ||
11853 | /* dev zeroed in init_etherdev */ | 12017 | /* dev zeroed in init_etherdev */ |
11854 | dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); | 12018 | dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); |
@@ -11859,6 +12023,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11859 | 12023 | ||
11860 | bp->igu_sb_cnt = max_non_def_sbs; | 12024 | bp->igu_sb_cnt = max_non_def_sbs; |
11861 | bp->msg_enable = debug; | 12025 | bp->msg_enable = debug; |
12026 | bp->cnic_support = cnic_cnt; | ||
12027 | |||
11862 | pci_set_drvdata(pdev, dev); | 12028 | pci_set_drvdata(pdev, dev); |
11863 | 12029 | ||
11864 | rc = bnx2x_init_dev(pdev, dev, ent->driver_data); | 12030 | rc = bnx2x_init_dev(pdev, dev, ent->driver_data); |
@@ -11867,6 +12033,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11867 | return rc; | 12033 | return rc; |
11868 | } | 12034 | } |
11869 | 12035 | ||
12036 | BNX2X_DEV_INFO("Cnic support is %s\n", CNIC_SUPPORT(bp) ? "on" : "off"); | ||
11870 | BNX2X_DEV_INFO("max_non_def_sbs %d\n", max_non_def_sbs); | 12037 | BNX2X_DEV_INFO("max_non_def_sbs %d\n", max_non_def_sbs); |
11871 | 12038 | ||
11872 | BNX2X_DEV_INFO("Allocated netdev with %d tx and %d rx queues\n", | 12039 | BNX2X_DEV_INFO("Allocated netdev with %d tx and %d rx queues\n", |
@@ -11899,10 +12066,10 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11899 | /* calc qm_cid_count */ | 12066 | /* calc qm_cid_count */ |
11900 | bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); | 12067 | bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); |
11901 | 12068 | ||
11902 | #ifdef BCM_CNIC | 12069 | /* disable FCOE L2 queue for E1x*/ |
11903 | /* disable FCOE L2 queue for E1x */ | ||
11904 | if (CHIP_IS_E1x(bp)) | 12070 | if (CHIP_IS_E1x(bp)) |
11905 | bp->flags |= NO_FCOE_FLAG; | 12071 | bp->flags |= NO_FCOE_FLAG; |
12072 | |||
11906 | /* disable FCOE for 57840 device, until FW supports it */ | 12073 | /* disable FCOE for 57840 device, until FW supports it */ |
11907 | switch (ent->driver_data) { | 12074 | switch (ent->driver_data) { |
11908 | case BCM57840_O: | 12075 | case BCM57840_O: |
@@ -11912,8 +12079,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11912 | case BCM57840_MF: | 12079 | case BCM57840_MF: |
11913 | bp->flags |= NO_FCOE_FLAG; | 12080 | bp->flags |= NO_FCOE_FLAG; |
11914 | } | 12081 | } |
11915 | #endif | ||
11916 | |||
11917 | 12082 | ||
11918 | /* Set bp->num_queues for MSI-X mode*/ | 12083 | /* Set bp->num_queues for MSI-X mode*/ |
11919 | bnx2x_set_num_queues(bp); | 12084 | bnx2x_set_num_queues(bp); |
@@ -11929,14 +12094,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11929 | goto init_one_exit; | 12094 | goto init_one_exit; |
11930 | } | 12095 | } |
11931 | 12096 | ||
11932 | #ifdef BCM_CNIC | 12097 | |
11933 | if (!NO_FCOE(bp)) { | 12098 | if (!NO_FCOE(bp)) { |
11934 | /* Add storage MAC address */ | 12099 | /* Add storage MAC address */ |
11935 | rtnl_lock(); | 12100 | rtnl_lock(); |
11936 | dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); | 12101 | dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); |
11937 | rtnl_unlock(); | 12102 | rtnl_unlock(); |
11938 | } | 12103 | } |
11939 | #endif | ||
11940 | 12104 | ||
11941 | bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); | 12105 | bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); |
11942 | 12106 | ||
@@ -11981,14 +12145,12 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) | |||
11981 | } | 12145 | } |
11982 | bp = netdev_priv(dev); | 12146 | bp = netdev_priv(dev); |
11983 | 12147 | ||
11984 | #ifdef BCM_CNIC | ||
11985 | /* Delete storage MAC address */ | 12148 | /* Delete storage MAC address */ |
11986 | if (!NO_FCOE(bp)) { | 12149 | if (!NO_FCOE(bp)) { |
11987 | rtnl_lock(); | 12150 | rtnl_lock(); |
11988 | dev_addr_del(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); | 12151 | dev_addr_del(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); |
11989 | rtnl_unlock(); | 12152 | rtnl_unlock(); |
11990 | } | 12153 | } |
11991 | #endif | ||
11992 | 12154 | ||
11993 | #ifdef BCM_DCBNL | 12155 | #ifdef BCM_DCBNL |
11994 | /* Delete app tlvs from dcbnl */ | 12156 | /* Delete app tlvs from dcbnl */ |
@@ -12036,15 +12198,17 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) | |||
12036 | 12198 | ||
12037 | bp->rx_mode = BNX2X_RX_MODE_NONE; | 12199 | bp->rx_mode = BNX2X_RX_MODE_NONE; |
12038 | 12200 | ||
12039 | #ifdef BCM_CNIC | 12201 | if (CNIC_LOADED(bp)) |
12040 | bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); | 12202 | bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); |
12041 | #endif | 12203 | |
12042 | /* Stop Tx */ | 12204 | /* Stop Tx */ |
12043 | bnx2x_tx_disable(bp); | 12205 | bnx2x_tx_disable(bp); |
12044 | 12206 | ||
12045 | bnx2x_netif_stop(bp, 0); | 12207 | bnx2x_netif_stop(bp, 0); |
12046 | /* Delete all NAPI objects */ | 12208 | /* Delete all NAPI objects */ |
12047 | bnx2x_del_all_napi(bp); | 12209 | bnx2x_del_all_napi(bp); |
12210 | if (CNIC_LOADED(bp)) | ||
12211 | bnx2x_del_all_napi_cnic(bp); | ||
12048 | 12212 | ||
12049 | del_timer_sync(&bp->timer); | 12213 | del_timer_sync(&bp->timer); |
12050 | 12214 | ||
@@ -12235,7 +12399,6 @@ void bnx2x_notify_link_changed(struct bnx2x *bp) | |||
12235 | module_init(bnx2x_init); | 12399 | module_init(bnx2x_init); |
12236 | module_exit(bnx2x_cleanup); | 12400 | module_exit(bnx2x_cleanup); |
12237 | 12401 | ||
12238 | #ifdef BCM_CNIC | ||
12239 | /** | 12402 | /** |
12240 | * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). | 12403 | * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). |
12241 | * | 12404 | * |
@@ -12688,12 +12851,31 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, | |||
12688 | { | 12851 | { |
12689 | struct bnx2x *bp = netdev_priv(dev); | 12852 | struct bnx2x *bp = netdev_priv(dev); |
12690 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; | 12853 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; |
12854 | int rc; | ||
12855 | |||
12856 | DP(NETIF_MSG_IFUP, "Register_cnic called\n"); | ||
12691 | 12857 | ||
12692 | if (ops == NULL) { | 12858 | if (ops == NULL) { |
12693 | BNX2X_ERR("NULL ops received\n"); | 12859 | BNX2X_ERR("NULL ops received\n"); |
12694 | return -EINVAL; | 12860 | return -EINVAL; |
12695 | } | 12861 | } |
12696 | 12862 | ||
12863 | if (!CNIC_SUPPORT(bp)) { | ||
12864 | BNX2X_ERR("Can't register CNIC when not supported\n"); | ||
12865 | return -EOPNOTSUPP; | ||
12866 | } | ||
12867 | |||
12868 | if (!CNIC_LOADED(bp)) { | ||
12869 | rc = bnx2x_load_cnic(bp); | ||
12870 | if (rc) { | ||
12871 | BNX2X_ERR("CNIC-related load failed\n"); | ||
12872 | return rc; | ||
12873 | } | ||
12874 | |||
12875 | } | ||
12876 | |||
12877 | bp->cnic_enabled = true; | ||
12878 | |||
12697 | bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL); | 12879 | bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL); |
12698 | if (!bp->cnic_kwq) | 12880 | if (!bp->cnic_kwq) |
12699 | return -ENOMEM; | 12881 | return -ENOMEM; |
@@ -12785,5 +12967,4 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) | |||
12785 | } | 12967 | } |
12786 | EXPORT_SYMBOL(bnx2x_cnic_probe); | 12968 | EXPORT_SYMBOL(bnx2x_cnic_probe); |
12787 | 12969 | ||
12788 | #endif /* BCM_CNIC */ | ||
12789 | 12970 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 1b1999d34c71..7d93adb57f31 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -2107,6 +2107,7 @@ | |||
2107 | #define NIG_REG_LLH1_ERROR_MASK 0x10090 | 2107 | #define NIG_REG_LLH1_ERROR_MASK 0x10090 |
2108 | /* [RW 8] event id for llh1 */ | 2108 | /* [RW 8] event id for llh1 */ |
2109 | #define NIG_REG_LLH1_EVENT_ID 0x10088 | 2109 | #define NIG_REG_LLH1_EVENT_ID 0x10088 |
2110 | #define NIG_REG_LLH1_FUNC_EN 0x16104 | ||
2110 | #define NIG_REG_LLH1_FUNC_MEM 0x161c0 | 2111 | #define NIG_REG_LLH1_FUNC_MEM 0x161c0 |
2111 | #define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 | 2112 | #define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 |
2112 | #define NIG_REG_LLH1_FUNC_MEM_SIZE 16 | 2113 | #define NIG_REG_LLH1_FUNC_MEM_SIZE 16 |
@@ -2302,6 +2303,15 @@ | |||
2302 | * set to 0x345678021. This is a new register (with 2_) added in E3 B0 to | 2303 | * set to 0x345678021. This is a new register (with 2_) added in E3 B0 to |
2303 | * accommodate the 9 input clients to ETS arbiter. */ | 2304 | * accommodate the 9 input clients to ETS arbiter. */ |
2304 | #define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB 0x18684 | 2305 | #define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB 0x18684 |
2306 | /* [RW 1] MCP-to-host path enable. Set this bit to enable the routing of MCP | ||
2307 | * packets to BRB LB interface to forward the packet to the host. All | ||
2308 | * packets from MCP are forwarded to the network when this bit is cleared - | ||
2309 | * regardless of the configured destination in tx_mng_destination register. | ||
2310 | * When MCP-to-host paths for both ports 0 and 1 are disabled - the arbiter | ||
2311 | * for BRB LB interface is bypassed and PBF LB traffic is always selected to | ||
2312 | * send to BRB LB. | ||
2313 | */ | ||
2314 | #define NIG_REG_P0_TX_MNG_HOST_ENABLE 0x182f4 | ||
2305 | #define NIG_REG_P1_HWPFC_ENABLE 0x181d0 | 2315 | #define NIG_REG_P1_HWPFC_ENABLE 0x181d0 |
2306 | #define NIG_REG_P1_MAC_IN_EN 0x185c0 | 2316 | #define NIG_REG_P1_MAC_IN_EN 0x185c0 |
2307 | /* [RW 1] Output enable for TX MAC interface */ | 2317 | /* [RW 1] Output enable for TX MAC interface */ |
@@ -2418,6 +2428,12 @@ | |||
2418 | #define NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB 0x186e4 | 2428 | #define NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB 0x186e4 |
2419 | /* [R 1] TX FIFO for transmitting data to MAC is empty. */ | 2429 | /* [R 1] TX FIFO for transmitting data to MAC is empty. */ |
2420 | #define NIG_REG_P1_TX_MACFIFO_EMPTY 0x18594 | 2430 | #define NIG_REG_P1_TX_MACFIFO_EMPTY 0x18594 |
2431 | /* [RW 1] MCP-to-host path enable. Set this bit to enable the routing of MCP | ||
2432 | * packets to BRB LB interface to forward the packet to the host. All | ||
2433 | * packets from MCP are forwarded to the network when this bit is cleared - | ||
2434 | * regardless of the configured destination in tx_mng_destination register. | ||
2435 | */ | ||
2436 | #define NIG_REG_P1_TX_MNG_HOST_ENABLE 0x182f8 | ||
2421 | /* [R 1] FIFO empty status of the MCP TX FIFO used for storing MCP packets | 2437 | /* [R 1] FIFO empty status of the MCP TX FIFO used for storing MCP packets |
2422 | forwarded to the host. */ | 2438 | forwarded to the host. */ |
2423 | #define NIG_REG_P1_TX_MNG_HOST_FIFO_EMPTY 0x182b8 | 2439 | #define NIG_REG_P1_TX_MNG_HOST_FIFO_EMPTY 0x182b8 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 614981c02264..b8b4b749daab 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -5350,12 +5350,24 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, | |||
5350 | else if ((cmd == BNX2X_F_CMD_AFEX_VIFLISTS) && | 5350 | else if ((cmd == BNX2X_F_CMD_AFEX_VIFLISTS) && |
5351 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | 5351 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) |
5352 | next_state = BNX2X_F_STATE_STARTED; | 5352 | next_state = BNX2X_F_STATE_STARTED; |
5353 | |||
5354 | /* Switch_update ramrod can be sent in either started or | ||
5355 | * tx_stopped state, and it doesn't change the state. | ||
5356 | */ | ||
5357 | else if ((cmd == BNX2X_F_CMD_SWITCH_UPDATE) && | ||
5358 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5359 | next_state = BNX2X_F_STATE_STARTED; | ||
5360 | |||
5353 | else if (cmd == BNX2X_F_CMD_TX_STOP) | 5361 | else if (cmd == BNX2X_F_CMD_TX_STOP) |
5354 | next_state = BNX2X_F_STATE_TX_STOPPED; | 5362 | next_state = BNX2X_F_STATE_TX_STOPPED; |
5355 | 5363 | ||
5356 | break; | 5364 | break; |
5357 | case BNX2X_F_STATE_TX_STOPPED: | 5365 | case BNX2X_F_STATE_TX_STOPPED: |
5358 | if (cmd == BNX2X_F_CMD_TX_START) | 5366 | if ((cmd == BNX2X_F_CMD_SWITCH_UPDATE) && |
5367 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5368 | next_state = BNX2X_F_STATE_TX_STOPPED; | ||
5369 | |||
5370 | else if (cmd == BNX2X_F_CMD_TX_START) | ||
5359 | next_state = BNX2X_F_STATE_STARTED; | 5371 | next_state = BNX2X_F_STATE_STARTED; |
5360 | 5372 | ||
5361 | break; | 5373 | break; |
@@ -5637,6 +5649,28 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, | |||
5637 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | 5649 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); |
5638 | } | 5650 | } |
5639 | 5651 | ||
5652 | static inline int bnx2x_func_send_switch_update(struct bnx2x *bp, | ||
5653 | struct bnx2x_func_state_params *params) | ||
5654 | { | ||
5655 | struct bnx2x_func_sp_obj *o = params->f_obj; | ||
5656 | struct function_update_data *rdata = | ||
5657 | (struct function_update_data *)o->rdata; | ||
5658 | dma_addr_t data_mapping = o->rdata_mapping; | ||
5659 | struct bnx2x_func_switch_update_params *switch_update_params = | ||
5660 | ¶ms->params.switch_update; | ||
5661 | |||
5662 | memset(rdata, 0, sizeof(*rdata)); | ||
5663 | |||
5664 | /* Fill the ramrod data with provided parameters */ | ||
5665 | rdata->tx_switch_suspend_change_flg = 1; | ||
5666 | rdata->tx_switch_suspend = switch_update_params->suspend; | ||
5667 | rdata->echo = SWITCH_UPDATE; | ||
5668 | |||
5669 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0, | ||
5670 | U64_HI(data_mapping), | ||
5671 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | ||
5672 | } | ||
5673 | |||
5640 | static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, | 5674 | static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, |
5641 | struct bnx2x_func_state_params *params) | 5675 | struct bnx2x_func_state_params *params) |
5642 | { | 5676 | { |
@@ -5657,6 +5691,7 @@ static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, | |||
5657 | cpu_to_le16(afex_update_params->afex_default_vlan); | 5691 | cpu_to_le16(afex_update_params->afex_default_vlan); |
5658 | rdata->allowed_priorities_change_flg = 1; | 5692 | rdata->allowed_priorities_change_flg = 1; |
5659 | rdata->allowed_priorities = afex_update_params->allowed_priorities; | 5693 | rdata->allowed_priorities = afex_update_params->allowed_priorities; |
5694 | rdata->echo = AFEX_UPDATE; | ||
5660 | 5695 | ||
5661 | /* No need for an explicit memory barrier here as long we would | 5696 | /* No need for an explicit memory barrier here as long we would |
5662 | * need to ensure the ordering of writing to the SPQ element | 5697 | * need to ensure the ordering of writing to the SPQ element |
@@ -5773,6 +5808,8 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp, | |||
5773 | return bnx2x_func_send_tx_stop(bp, params); | 5808 | return bnx2x_func_send_tx_stop(bp, params); |
5774 | case BNX2X_F_CMD_TX_START: | 5809 | case BNX2X_F_CMD_TX_START: |
5775 | return bnx2x_func_send_tx_start(bp, params); | 5810 | return bnx2x_func_send_tx_start(bp, params); |
5811 | case BNX2X_F_CMD_SWITCH_UPDATE: | ||
5812 | return bnx2x_func_send_switch_update(bp, params); | ||
5776 | default: | 5813 | default: |
5777 | BNX2X_ERR("Unknown command: %d\n", params->cmd); | 5814 | BNX2X_ERR("Unknown command: %d\n", params->cmd); |
5778 | return -EINVAL; | 5815 | return -EINVAL; |
@@ -5818,16 +5855,30 @@ int bnx2x_func_state_change(struct bnx2x *bp, | |||
5818 | struct bnx2x_func_state_params *params) | 5855 | struct bnx2x_func_state_params *params) |
5819 | { | 5856 | { |
5820 | struct bnx2x_func_sp_obj *o = params->f_obj; | 5857 | struct bnx2x_func_sp_obj *o = params->f_obj; |
5821 | int rc; | 5858 | int rc, cnt = 300; |
5822 | enum bnx2x_func_cmd cmd = params->cmd; | 5859 | enum bnx2x_func_cmd cmd = params->cmd; |
5823 | unsigned long *pending = &o->pending; | 5860 | unsigned long *pending = &o->pending; |
5824 | 5861 | ||
5825 | mutex_lock(&o->one_pending_mutex); | 5862 | mutex_lock(&o->one_pending_mutex); |
5826 | 5863 | ||
5827 | /* Check that the requested transition is legal */ | 5864 | /* Check that the requested transition is legal */ |
5828 | if (o->check_transition(bp, o, params)) { | 5865 | rc = o->check_transition(bp, o, params); |
5866 | if ((rc == -EBUSY) && | ||
5867 | (test_bit(RAMROD_RETRY, ¶ms->ramrod_flags))) { | ||
5868 | while ((rc == -EBUSY) && (--cnt > 0)) { | ||
5869 | mutex_unlock(&o->one_pending_mutex); | ||
5870 | msleep(10); | ||
5871 | mutex_lock(&o->one_pending_mutex); | ||
5872 | rc = o->check_transition(bp, o, params); | ||
5873 | } | ||
5874 | if (rc == -EBUSY) { | ||
5875 | mutex_unlock(&o->one_pending_mutex); | ||
5876 | BNX2X_ERR("timeout waiting for previous ramrod completion\n"); | ||
5877 | return rc; | ||
5878 | } | ||
5879 | } else if (rc) { | ||
5829 | mutex_unlock(&o->one_pending_mutex); | 5880 | mutex_unlock(&o->one_pending_mutex); |
5830 | return -EINVAL; | 5881 | return rc; |
5831 | } | 5882 | } |
5832 | 5883 | ||
5833 | /* Set "pending" bit */ | 5884 | /* Set "pending" bit */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index acf2fe4ca608..adbd91b1bdfc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | |||
@@ -40,6 +40,12 @@ enum { | |||
40 | * pending commands list. | 40 | * pending commands list. |
41 | */ | 41 | */ |
42 | RAMROD_CONT, | 42 | RAMROD_CONT, |
43 | /* If there is another pending ramrod, wait until it finishes and | ||
44 | * re-try to submit this one. This flag can be set only in sleepable | ||
45 | * context, and should not be set from the context that completes the | ||
46 | * ramrods as deadlock will occur. | ||
47 | */ | ||
48 | RAMROD_RETRY, | ||
43 | }; | 49 | }; |
44 | 50 | ||
45 | typedef enum { | 51 | typedef enum { |
@@ -1061,6 +1067,7 @@ enum bnx2x_func_cmd { | |||
1061 | BNX2X_F_CMD_AFEX_VIFLISTS, | 1067 | BNX2X_F_CMD_AFEX_VIFLISTS, |
1062 | BNX2X_F_CMD_TX_STOP, | 1068 | BNX2X_F_CMD_TX_STOP, |
1063 | BNX2X_F_CMD_TX_START, | 1069 | BNX2X_F_CMD_TX_START, |
1070 | BNX2X_F_CMD_SWITCH_UPDATE, | ||
1064 | BNX2X_F_CMD_MAX, | 1071 | BNX2X_F_CMD_MAX, |
1065 | }; | 1072 | }; |
1066 | 1073 | ||
@@ -1103,6 +1110,10 @@ struct bnx2x_func_start_params { | |||
1103 | u8 network_cos_mode; | 1110 | u8 network_cos_mode; |
1104 | }; | 1111 | }; |
1105 | 1112 | ||
1113 | struct bnx2x_func_switch_update_params { | ||
1114 | u8 suspend; | ||
1115 | }; | ||
1116 | |||
1106 | struct bnx2x_func_afex_update_params { | 1117 | struct bnx2x_func_afex_update_params { |
1107 | u16 vif_id; | 1118 | u16 vif_id; |
1108 | u16 afex_default_vlan; | 1119 | u16 afex_default_vlan; |
@@ -1136,6 +1147,7 @@ struct bnx2x_func_state_params { | |||
1136 | struct bnx2x_func_hw_init_params hw_init; | 1147 | struct bnx2x_func_hw_init_params hw_init; |
1137 | struct bnx2x_func_hw_reset_params hw_reset; | 1148 | struct bnx2x_func_hw_reset_params hw_reset; |
1138 | struct bnx2x_func_start_params start; | 1149 | struct bnx2x_func_start_params start; |
1150 | struct bnx2x_func_switch_update_params switch_update; | ||
1139 | struct bnx2x_func_afex_update_params afex_update; | 1151 | struct bnx2x_func_afex_update_params afex_update; |
1140 | struct bnx2x_func_afex_viflists_params afex_viflists; | 1152 | struct bnx2x_func_afex_viflists_params afex_viflists; |
1141 | struct bnx2x_func_tx_start_params tx_start; | 1153 | struct bnx2x_func_tx_start_params tx_start; |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a8800ac10df9..038ce0215e3e 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -90,10 +90,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
90 | 90 | ||
91 | #define DRV_MODULE_NAME "tg3" | 91 | #define DRV_MODULE_NAME "tg3" |
92 | #define TG3_MAJ_NUM 3 | 92 | #define TG3_MAJ_NUM 3 |
93 | #define TG3_MIN_NUM 125 | 93 | #define TG3_MIN_NUM 126 |
94 | #define DRV_MODULE_VERSION \ | 94 | #define DRV_MODULE_VERSION \ |
95 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) | 95 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) |
96 | #define DRV_MODULE_RELDATE "September 26, 2012" | 96 | #define DRV_MODULE_RELDATE "November 05, 2012" |
97 | 97 | ||
98 | #define RESET_KIND_SHUTDOWN 0 | 98 | #define RESET_KIND_SHUTDOWN 0 |
99 | #define RESET_KIND_INIT 1 | 99 | #define RESET_KIND_INIT 1 |
@@ -291,6 +291,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { | |||
291 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)}, | 291 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)}, |
292 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)}, | 292 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)}, |
293 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)}, | 293 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)}, |
294 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717_C)}, | ||
294 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)}, | 295 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)}, |
295 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)}, | 296 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)}, |
296 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)}, | 297 | {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)}, |
@@ -10429,10 +10430,8 @@ static void tg3_stop(struct tg3 *tp) | |||
10429 | { | 10430 | { |
10430 | int i; | 10431 | int i; |
10431 | 10432 | ||
10432 | tg3_napi_disable(tp); | ||
10433 | tg3_reset_task_cancel(tp); | 10433 | tg3_reset_task_cancel(tp); |
10434 | 10434 | tg3_netif_stop(tp); | |
10435 | netif_tx_disable(tp->dev); | ||
10436 | 10435 | ||
10437 | tg3_timer_stop(tp); | 10436 | tg3_timer_stop(tp); |
10438 | 10437 | ||
@@ -14026,7 +14025,8 @@ out_not_found: | |||
14026 | 14025 | ||
14027 | out_no_vpd: | 14026 | out_no_vpd: |
14028 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { | 14027 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { |
14029 | if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717) | 14028 | if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || |
14029 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C) | ||
14030 | strcpy(tp->board_part_number, "BCM5717"); | 14030 | strcpy(tp->board_part_number, "BCM5717"); |
14031 | else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718) | 14031 | else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718) |
14032 | strcpy(tp->board_part_number, "BCM5718"); | 14032 | strcpy(tp->board_part_number, "BCM5718"); |
@@ -14397,6 +14397,7 @@ static void __devinit tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) | |||
14397 | tg3_flag_set(tp, CPMU_PRESENT); | 14397 | tg3_flag_set(tp, CPMU_PRESENT); |
14398 | 14398 | ||
14399 | if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || | 14399 | if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || |
14400 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C || | ||
14400 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || | 14401 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || |
14401 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || | 14402 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || |
14402 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) | 14403 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) |
@@ -14424,6 +14425,9 @@ static void __devinit tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) | |||
14424 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) | 14425 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) |
14425 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; | 14426 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; |
14426 | 14427 | ||
14428 | if (tp->pci_chip_rev_id == CHIPREV_ID_5717_C0) | ||
14429 | tp->pci_chip_rev_id = CHIPREV_ID_5720_A0; | ||
14430 | |||
14427 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || | 14431 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || |
14428 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | 14432 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || |
14429 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) | 14433 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) |
@@ -16013,6 +16017,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
16013 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S || | 16017 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S || |
16014 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761SE || | 16018 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761SE || |
16015 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || | 16019 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || |
16020 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717_C || | ||
16016 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || | 16021 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || |
16017 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || | 16022 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || |
16018 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) { | 16023 | tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) { |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index d9308c32102e..b3c2bf2c082f 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -50,6 +50,7 @@ | |||
50 | #define TG3PCI_DEVICE_TIGON3_5785_G 0x1699 /* GPHY */ | 50 | #define TG3PCI_DEVICE_TIGON3_5785_G 0x1699 /* GPHY */ |
51 | #define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */ | 51 | #define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */ |
52 | #define TG3PCI_DEVICE_TIGON3_5717 0x1655 | 52 | #define TG3PCI_DEVICE_TIGON3_5717 0x1655 |
53 | #define TG3PCI_DEVICE_TIGON3_5717_C 0x1665 | ||
53 | #define TG3PCI_DEVICE_TIGON3_5718 0x1656 | 54 | #define TG3PCI_DEVICE_TIGON3_5718 0x1656 |
54 | #define TG3PCI_DEVICE_TIGON3_57781 0x16b1 | 55 | #define TG3PCI_DEVICE_TIGON3_57781 0x16b1 |
55 | #define TG3PCI_DEVICE_TIGON3_57785 0x16b5 | 56 | #define TG3PCI_DEVICE_TIGON3_57785 0x16b5 |
@@ -149,6 +150,7 @@ | |||
149 | #define CHIPREV_ID_57780_A0 0x57780000 | 150 | #define CHIPREV_ID_57780_A0 0x57780000 |
150 | #define CHIPREV_ID_57780_A1 0x57780001 | 151 | #define CHIPREV_ID_57780_A1 0x57780001 |
151 | #define CHIPREV_ID_5717_A0 0x05717000 | 152 | #define CHIPREV_ID_5717_A0 0x05717000 |
153 | #define CHIPREV_ID_5717_C0 0x05717200 | ||
152 | #define CHIPREV_ID_57765_A0 0x57785000 | 154 | #define CHIPREV_ID_57765_A0 0x57785000 |
153 | #define CHIPREV_ID_5719_A0 0x05719000 | 155 | #define CHIPREV_ID_5719_A0 0x05719000 |
154 | #define CHIPREV_ID_5720_A0 0x05720000 | 156 | #define CHIPREV_ID_5720_A0 0x05720000 |
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index db931916da08..ceb0de0cf62c 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig | |||
@@ -2,13 +2,10 @@ | |||
2 | # Atmel device configuration | 2 | # Atmel device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | config HAVE_NET_MACB | ||
6 | bool | ||
7 | |||
8 | config NET_CADENCE | 5 | config NET_CADENCE |
9 | bool "Cadence devices" | 6 | bool "Cadence devices" |
7 | depends on HAS_IOMEM | ||
10 | default y | 8 | default y |
11 | depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200) | ||
12 | ---help--- | 9 | ---help--- |
13 | If you have a network (Ethernet) card belonging to this class, say Y. | 10 | If you have a network (Ethernet) card belonging to this class, say Y. |
14 | Make sure you know the name of your card. Read the Ethernet-HOWTO, | 11 | Make sure you know the name of your card. Read the Ethernet-HOWTO, |
@@ -25,16 +22,14 @@ if NET_CADENCE | |||
25 | 22 | ||
26 | config ARM_AT91_ETHER | 23 | config ARM_AT91_ETHER |
27 | tristate "AT91RM9200 Ethernet support" | 24 | tristate "AT91RM9200 Ethernet support" |
28 | depends on ARM && ARCH_AT91RM9200 | ||
29 | select NET_CORE | 25 | select NET_CORE |
30 | select MII | 26 | select MACB |
31 | ---help--- | 27 | ---help--- |
32 | If you wish to compile a kernel for the AT91RM9200 and enable | 28 | If you wish to compile a kernel for the AT91RM9200 and enable |
33 | ethernet support, then you should always answer Y to this. | 29 | ethernet support, then you should always answer Y to this. |
34 | 30 | ||
35 | config MACB | 31 | config MACB |
36 | tristate "Cadence MACB/GEM support" | 32 | tristate "Cadence MACB/GEM support" |
37 | depends on HAVE_NET_MACB | ||
38 | select PHYLIB | 33 | select PHYLIB |
39 | ---help--- | 34 | ---help--- |
40 | The Cadence MACB ethernet interface is found on many Atmel AT32 and | 35 | The Cadence MACB ethernet interface is found on many Atmel AT32 and |
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 4e980a7886fb..e7a476cff6c5 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c | |||
@@ -6,11 +6,6 @@ | |||
6 | * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. | 6 | * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. |
7 | * Initial version by Rick Bronson 01/11/2003 | 7 | * Initial version by Rick Bronson 01/11/2003 |
8 | * | 8 | * |
9 | * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker | ||
10 | * (Polaroid Corporation) | ||
11 | * | ||
12 | * Realtek RTL8201(B)L PHY support by Roman Avramenko <roman@imsystems.ru> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
16 | * as published by the Free Software Foundation; either version | 11 | * as published by the Free Software Foundation; either version |
@@ -20,7 +15,6 @@ | |||
20 | #include <linux/module.h> | 15 | #include <linux/module.h> |
21 | #include <linux/init.h> | 16 | #include <linux/init.h> |
22 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
23 | #include <linux/mii.h> | ||
24 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
25 | #include <linux/etherdevice.h> | 19 | #include <linux/etherdevice.h> |
26 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> |
@@ -31,956 +25,251 @@ | |||
31 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
32 | #include <linux/gfp.h> | 26 | #include <linux/gfp.h> |
33 | #include <linux/phy.h> | 27 | #include <linux/phy.h> |
28 | #include <linux/io.h> | ||
29 | #include <linux/of.h> | ||
30 | #include <linux/of_device.h> | ||
31 | #include <linux/of_net.h> | ||
32 | #include <linux/pinctrl/consumer.h> | ||
34 | 33 | ||
35 | #include <asm/io.h> | 34 | #include "macb.h" |
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/mach-types.h> | ||
38 | |||
39 | #include <mach/at91rm9200_emac.h> | ||
40 | #include <asm/gpio.h> | ||
41 | #include <mach/board.h> | ||
42 | |||
43 | #include "at91_ether.h" | ||
44 | |||
45 | #define DRV_NAME "at91_ether" | ||
46 | #define DRV_VERSION "1.0" | ||
47 | |||
48 | #define LINK_POLL_INTERVAL (HZ) | ||
49 | |||
50 | /* ..................................................................... */ | ||
51 | |||
52 | /* | ||
53 | * Read from a EMAC register. | ||
54 | */ | ||
55 | static inline unsigned long at91_emac_read(struct at91_private *lp, unsigned int reg) | ||
56 | { | ||
57 | return __raw_readl(lp->emac_base + reg); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * Write to a EMAC register. | ||
62 | */ | ||
63 | static inline void at91_emac_write(struct at91_private *lp, unsigned int reg, unsigned long value) | ||
64 | { | ||
65 | __raw_writel(value, lp->emac_base + reg); | ||
66 | } | ||
67 | |||
68 | /* ........................... PHY INTERFACE ........................... */ | ||
69 | |||
70 | /* | ||
71 | * Enable the MDIO bit in MAC control register | ||
72 | * When not called from an interrupt-handler, access to the PHY must be | ||
73 | * protected by a spinlock. | ||
74 | */ | ||
75 | static void enable_mdi(struct at91_private *lp) | ||
76 | { | ||
77 | unsigned long ctl; | ||
78 | |||
79 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | ||
80 | at91_emac_write(lp, AT91_EMAC_CTL, ctl | AT91_EMAC_MPE); /* enable management port */ | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Disable the MDIO bit in the MAC control register | ||
85 | */ | ||
86 | static void disable_mdi(struct at91_private *lp) | ||
87 | { | ||
88 | unsigned long ctl; | ||
89 | |||
90 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | ||
91 | at91_emac_write(lp, AT91_EMAC_CTL, ctl & ~AT91_EMAC_MPE); /* disable management port */ | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Wait until the PHY operation is complete. | ||
96 | */ | ||
97 | static inline void at91_phy_wait(struct at91_private *lp) | ||
98 | { | ||
99 | unsigned long timeout = jiffies + 2; | ||
100 | |||
101 | while (!(at91_emac_read(lp, AT91_EMAC_SR) & AT91_EMAC_SR_IDLE)) { | ||
102 | if (time_after(jiffies, timeout)) { | ||
103 | printk("at91_ether: MIO timeout\n"); | ||
104 | break; | ||
105 | } | ||
106 | cpu_relax(); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Write value to the a PHY register | ||
112 | * Note: MDI interface is assumed to already have been enabled. | ||
113 | */ | ||
114 | static void write_phy(struct at91_private *lp, unsigned char phy_addr, unsigned char address, unsigned int value) | ||
115 | { | ||
116 | at91_emac_write(lp, AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_W | ||
117 | | ((phy_addr & 0x1f) << 23) | (address << 18) | (value & AT91_EMAC_DATA)); | ||
118 | |||
119 | /* Wait until IDLE bit in Network Status register is cleared */ | ||
120 | at91_phy_wait(lp); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Read value stored in a PHY register. | ||
125 | * Note: MDI interface is assumed to already have been enabled. | ||
126 | */ | ||
127 | static void read_phy(struct at91_private *lp, unsigned char phy_addr, unsigned char address, unsigned int *value) | ||
128 | { | ||
129 | at91_emac_write(lp, AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_R | ||
130 | | ((phy_addr & 0x1f) << 23) | (address << 18)); | ||
131 | |||
132 | /* Wait until IDLE bit in Network Status register is cleared */ | ||
133 | at91_phy_wait(lp); | ||
134 | |||
135 | *value = at91_emac_read(lp, AT91_EMAC_MAN) & AT91_EMAC_DATA; | ||
136 | } | ||
137 | |||
138 | /* ........................... PHY MANAGEMENT .......................... */ | ||
139 | |||
140 | /* | ||
141 | * Access the PHY to determine the current link speed and mode, and update the | ||
142 | * MAC accordingly. | ||
143 | * If no link or auto-negotiation is busy, then no changes are made. | ||
144 | */ | ||
145 | static void update_linkspeed(struct net_device *dev, int silent) | ||
146 | { | ||
147 | struct at91_private *lp = netdev_priv(dev); | ||
148 | unsigned int bmsr, bmcr, lpa, mac_cfg; | ||
149 | unsigned int speed, duplex; | ||
150 | |||
151 | if (!mii_link_ok(&lp->mii)) { /* no link */ | ||
152 | netif_carrier_off(dev); | ||
153 | if (!silent) | ||
154 | printk(KERN_INFO "%s: Link down.\n", dev->name); | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | /* Link up, or auto-negotiation still in progress */ | ||
159 | read_phy(lp, lp->phy_address, MII_BMSR, &bmsr); | ||
160 | read_phy(lp, lp->phy_address, MII_BMCR, &bmcr); | ||
161 | if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */ | ||
162 | if (!(bmsr & BMSR_ANEGCOMPLETE)) | ||
163 | return; /* Do nothing - another interrupt generated when negotiation complete */ | ||
164 | |||
165 | read_phy(lp, lp->phy_address, MII_LPA, &lpa); | ||
166 | if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100; | ||
167 | else speed = SPEED_10; | ||
168 | if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL; | ||
169 | else duplex = DUPLEX_HALF; | ||
170 | } else { | ||
171 | speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; | ||
172 | duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; | ||
173 | } | ||
174 | |||
175 | /* Update the MAC */ | ||
176 | mac_cfg = at91_emac_read(lp, AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD); | ||
177 | if (speed == SPEED_100) { | ||
178 | if (duplex == DUPLEX_FULL) /* 100 Full Duplex */ | ||
179 | mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD; | ||
180 | else /* 100 Half Duplex */ | ||
181 | mac_cfg |= AT91_EMAC_SPD; | ||
182 | } else { | ||
183 | if (duplex == DUPLEX_FULL) /* 10 Full Duplex */ | ||
184 | mac_cfg |= AT91_EMAC_FD; | ||
185 | else {} /* 10 Half Duplex */ | ||
186 | } | ||
187 | at91_emac_write(lp, AT91_EMAC_CFG, mac_cfg); | ||
188 | |||
189 | if (!silent) | ||
190 | printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | ||
191 | netif_carrier_on(dev); | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Handle interrupts from the PHY | ||
196 | */ | ||
197 | static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) | ||
198 | { | ||
199 | struct net_device *dev = (struct net_device *) dev_id; | ||
200 | struct at91_private *lp = netdev_priv(dev); | ||
201 | unsigned int phy; | ||
202 | |||
203 | /* | ||
204 | * This hander is triggered on both edges, but the PHY chips expect | ||
205 | * level-triggering. We therefore have to check if the PHY actually has | ||
206 | * an IRQ pending. | ||
207 | */ | ||
208 | enable_mdi(lp); | ||
209 | if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { | ||
210 | read_phy(lp, lp->phy_address, MII_DSINTR_REG, &phy); /* ack interrupt in Davicom PHY */ | ||
211 | if (!(phy & (1 << 0))) | ||
212 | goto done; | ||
213 | } | ||
214 | else if (lp->phy_type == MII_LXT971A_ID) { | ||
215 | read_phy(lp, lp->phy_address, MII_ISINTS_REG, &phy); /* ack interrupt in Intel PHY */ | ||
216 | if (!(phy & (1 << 2))) | ||
217 | goto done; | ||
218 | } | ||
219 | else if (lp->phy_type == MII_BCM5221_ID) { | ||
220 | read_phy(lp, lp->phy_address, MII_BCMINTR_REG, &phy); /* ack interrupt in Broadcom PHY */ | ||
221 | if (!(phy & (1 << 0))) | ||
222 | goto done; | ||
223 | } | ||
224 | else if (lp->phy_type == MII_KS8721_ID) { | ||
225 | read_phy(lp, lp->phy_address, MII_TPISTATUS, &phy); /* ack interrupt in Micrel PHY */ | ||
226 | if (!(phy & ((1 << 2) | 1))) | ||
227 | goto done; | ||
228 | } | ||
229 | else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */ | ||
230 | read_phy(lp, lp->phy_address, MII_T78Q21INT_REG, &phy); | ||
231 | if (!(phy & ((1 << 2) | 1))) | ||
232 | goto done; | ||
233 | } | ||
234 | else if (lp->phy_type == MII_DP83848_ID) { | ||
235 | read_phy(lp, lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */ | ||
236 | if (!(phy & (1 << 7))) | ||
237 | goto done; | ||
238 | } | ||
239 | |||
240 | update_linkspeed(dev, 0); | ||
241 | |||
242 | done: | ||
243 | disable_mdi(lp); | ||
244 | |||
245 | return IRQ_HANDLED; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * Initialize and enable the PHY interrupt for link-state changes | ||
250 | */ | ||
251 | static void enable_phyirq(struct net_device *dev) | ||
252 | { | ||
253 | struct at91_private *lp = netdev_priv(dev); | ||
254 | unsigned int dsintr, irq_number; | ||
255 | int status; | ||
256 | |||
257 | if (!gpio_is_valid(lp->board_data.phy_irq_pin)) { | ||
258 | /* | ||
259 | * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), | ||
260 | * or board does not have it connected. | ||
261 | */ | ||
262 | mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | irq_number = gpio_to_irq(lp->board_data.phy_irq_pin); | ||
267 | status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); | ||
268 | if (status) { | ||
269 | printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | spin_lock_irq(&lp->lock); | ||
274 | enable_mdi(lp); | ||
275 | |||
276 | if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */ | ||
277 | read_phy(lp, lp->phy_address, MII_DSINTR_REG, &dsintr); | ||
278 | dsintr = dsintr & ~0xf00; /* clear bits 8..11 */ | ||
279 | write_phy(lp, lp->phy_address, MII_DSINTR_REG, dsintr); | ||
280 | } | ||
281 | else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ | ||
282 | read_phy(lp, lp->phy_address, MII_ISINTE_REG, &dsintr); | ||
283 | dsintr = dsintr | 0xf2; /* set bits 1, 4..7 */ | ||
284 | write_phy(lp, lp->phy_address, MII_ISINTE_REG, dsintr); | ||
285 | } | ||
286 | else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */ | ||
287 | dsintr = (1 << 15) | ( 1 << 14); | ||
288 | write_phy(lp, lp->phy_address, MII_BCMINTR_REG, dsintr); | ||
289 | } | ||
290 | else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */ | ||
291 | dsintr = (1 << 10) | ( 1 << 8); | ||
292 | write_phy(lp, lp->phy_address, MII_TPISTATUS, dsintr); | ||
293 | } | ||
294 | else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ | ||
295 | read_phy(lp, lp->phy_address, MII_T78Q21INT_REG, &dsintr); | ||
296 | dsintr = dsintr | 0x500; /* set bits 8, 10 */ | ||
297 | write_phy(lp, lp->phy_address, MII_T78Q21INT_REG, dsintr); | ||
298 | } | ||
299 | else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ | ||
300 | read_phy(lp, lp->phy_address, MII_DPMISR_REG, &dsintr); | ||
301 | dsintr = dsintr | 0x3c; /* set bits 2..5 */ | ||
302 | write_phy(lp, lp->phy_address, MII_DPMISR_REG, dsintr); | ||
303 | read_phy(lp, lp->phy_address, MII_DPMICR_REG, &dsintr); | ||
304 | dsintr = dsintr | 0x3; /* set bits 0,1 */ | ||
305 | write_phy(lp, lp->phy_address, MII_DPMICR_REG, dsintr); | ||
306 | } | ||
307 | |||
308 | disable_mdi(lp); | ||
309 | spin_unlock_irq(&lp->lock); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Disable the PHY interrupt | ||
314 | */ | ||
315 | static void disable_phyirq(struct net_device *dev) | ||
316 | { | ||
317 | struct at91_private *lp = netdev_priv(dev); | ||
318 | unsigned int dsintr; | ||
319 | unsigned int irq_number; | ||
320 | |||
321 | if (!gpio_is_valid(lp->board_data.phy_irq_pin)) { | ||
322 | del_timer_sync(&lp->check_timer); | ||
323 | return; | ||
324 | } | ||
325 | |||
326 | spin_lock_irq(&lp->lock); | ||
327 | enable_mdi(lp); | ||
328 | |||
329 | if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */ | ||
330 | read_phy(lp, lp->phy_address, MII_DSINTR_REG, &dsintr); | ||
331 | dsintr = dsintr | 0xf00; /* set bits 8..11 */ | ||
332 | write_phy(lp, lp->phy_address, MII_DSINTR_REG, dsintr); | ||
333 | } | ||
334 | else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */ | ||
335 | read_phy(lp, lp->phy_address, MII_ISINTE_REG, &dsintr); | ||
336 | dsintr = dsintr & ~0xf2; /* clear bits 1, 4..7 */ | ||
337 | write_phy(lp, lp->phy_address, MII_ISINTE_REG, dsintr); | ||
338 | } | ||
339 | else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */ | ||
340 | read_phy(lp, lp->phy_address, MII_BCMINTR_REG, &dsintr); | ||
341 | dsintr = ~(1 << 14); | ||
342 | write_phy(lp, lp->phy_address, MII_BCMINTR_REG, dsintr); | ||
343 | } | ||
344 | else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */ | ||
345 | read_phy(lp, lp->phy_address, MII_TPISTATUS, &dsintr); | ||
346 | dsintr = ~((1 << 10) | (1 << 8)); | ||
347 | write_phy(lp, lp->phy_address, MII_TPISTATUS, dsintr); | ||
348 | } | ||
349 | else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ | ||
350 | read_phy(lp, lp->phy_address, MII_T78Q21INT_REG, &dsintr); | ||
351 | dsintr = dsintr & ~0x500; /* clear bits 8, 10 */ | ||
352 | write_phy(lp, lp->phy_address, MII_T78Q21INT_REG, dsintr); | ||
353 | } | ||
354 | else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ | ||
355 | read_phy(lp, lp->phy_address, MII_DPMICR_REG, &dsintr); | ||
356 | dsintr = dsintr & ~0x3; /* clear bits 0, 1 */ | ||
357 | write_phy(lp, lp->phy_address, MII_DPMICR_REG, dsintr); | ||
358 | read_phy(lp, lp->phy_address, MII_DPMISR_REG, &dsintr); | ||
359 | dsintr = dsintr & ~0x3c; /* clear bits 2..5 */ | ||
360 | write_phy(lp, lp->phy_address, MII_DPMISR_REG, dsintr); | ||
361 | } | ||
362 | |||
363 | disable_mdi(lp); | ||
364 | spin_unlock_irq(&lp->lock); | ||
365 | |||
366 | irq_number = gpio_to_irq(lp->board_data.phy_irq_pin); | ||
367 | free_irq(irq_number, dev); /* Free interrupt handler */ | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * Perform a software reset of the PHY. | ||
372 | */ | ||
373 | #if 0 | ||
374 | static void reset_phy(struct net_device *dev) | ||
375 | { | ||
376 | struct at91_private *lp = netdev_priv(dev); | ||
377 | unsigned int bmcr; | ||
378 | |||
379 | spin_lock_irq(&lp->lock); | ||
380 | enable_mdi(lp); | ||
381 | |||
382 | /* Perform PHY reset */ | ||
383 | write_phy(lp, lp->phy_address, MII_BMCR, BMCR_RESET); | ||
384 | |||
385 | /* Wait until PHY reset is complete */ | ||
386 | do { | ||
387 | read_phy(lp, lp->phy_address, MII_BMCR, &bmcr); | ||
388 | } while (!(bmcr & BMCR_RESET)); | ||
389 | |||
390 | disable_mdi(lp); | ||
391 | spin_unlock_irq(&lp->lock); | ||
392 | } | ||
393 | #endif | ||
394 | |||
395 | static void at91ether_check_link(unsigned long dev_id) | ||
396 | { | ||
397 | struct net_device *dev = (struct net_device *) dev_id; | ||
398 | struct at91_private *lp = netdev_priv(dev); | ||
399 | |||
400 | enable_mdi(lp); | ||
401 | update_linkspeed(dev, 1); | ||
402 | disable_mdi(lp); | ||
403 | |||
404 | mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL); | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * Perform any PHY-specific initialization. | ||
409 | */ | ||
410 | static void __init initialize_phy(struct at91_private *lp) | ||
411 | { | ||
412 | unsigned int val; | ||
413 | |||
414 | spin_lock_irq(&lp->lock); | ||
415 | enable_mdi(lp); | ||
416 | |||
417 | if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { | ||
418 | read_phy(lp, lp->phy_address, MII_DSCR_REG, &val); | ||
419 | if ((val & (1 << 10)) == 0) /* DSCR bit 10 is 0 -- fiber mode */ | ||
420 | lp->phy_media = PORT_FIBRE; | ||
421 | } else if (machine_is_csb337()) { | ||
422 | /* mix link activity status into LED2 link state */ | ||
423 | write_phy(lp, lp->phy_address, MII_LEDCTRL_REG, 0x0d22); | ||
424 | } else if (machine_is_ecbat91()) | ||
425 | write_phy(lp, lp->phy_address, MII_LEDCTRL_REG, 0x156A); | ||
426 | |||
427 | disable_mdi(lp); | ||
428 | spin_unlock_irq(&lp->lock); | ||
429 | } | ||
430 | |||
431 | /* ......................... ADDRESS MANAGEMENT ........................ */ | ||
432 | |||
433 | /* | ||
434 | * NOTE: Your bootloader must always set the MAC address correctly before | ||
435 | * booting into Linux. | ||
436 | * | ||
437 | * - It must always set the MAC address after reset, even if it doesn't | ||
438 | * happen to access the Ethernet while it's booting. Some versions of | ||
439 | * U-Boot on the AT91RM9200-DK do not do this. | ||
440 | * | ||
441 | * - Likewise it must store the addresses in the correct byte order. | ||
442 | * MicroMonitor (uMon) on the CSB337 does this incorrectly (and | ||
443 | * continues to do so, for bug-compatibility). | ||
444 | */ | ||
445 | |||
446 | static short __init unpack_mac_address(struct net_device *dev, unsigned int hi, unsigned int lo) | ||
447 | { | ||
448 | char addr[6]; | ||
449 | |||
450 | if (machine_is_csb337()) { | ||
451 | addr[5] = (lo & 0xff); /* The CSB337 bootloader stores the MAC the wrong-way around */ | ||
452 | addr[4] = (lo & 0xff00) >> 8; | ||
453 | addr[3] = (lo & 0xff0000) >> 16; | ||
454 | addr[2] = (lo & 0xff000000) >> 24; | ||
455 | addr[1] = (hi & 0xff); | ||
456 | addr[0] = (hi & 0xff00) >> 8; | ||
457 | } | ||
458 | else { | ||
459 | addr[0] = (lo & 0xff); | ||
460 | addr[1] = (lo & 0xff00) >> 8; | ||
461 | addr[2] = (lo & 0xff0000) >> 16; | ||
462 | addr[3] = (lo & 0xff000000) >> 24; | ||
463 | addr[4] = (hi & 0xff); | ||
464 | addr[5] = (hi & 0xff00) >> 8; | ||
465 | } | ||
466 | |||
467 | if (is_valid_ether_addr(addr)) { | ||
468 | memcpy(dev->dev_addr, &addr, 6); | ||
469 | return 1; | ||
470 | } | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Set the ethernet MAC address in dev->dev_addr | ||
476 | */ | ||
477 | static void __init get_mac_address(struct net_device *dev) | ||
478 | { | ||
479 | struct at91_private *lp = netdev_priv(dev); | ||
480 | |||
481 | /* Check Specific-Address 1 */ | ||
482 | if (unpack_mac_address(dev, at91_emac_read(lp, AT91_EMAC_SA1H), at91_emac_read(lp, AT91_EMAC_SA1L))) | ||
483 | return; | ||
484 | /* Check Specific-Address 2 */ | ||
485 | if (unpack_mac_address(dev, at91_emac_read(lp, AT91_EMAC_SA2H), at91_emac_read(lp, AT91_EMAC_SA2L))) | ||
486 | return; | ||
487 | /* Check Specific-Address 3 */ | ||
488 | if (unpack_mac_address(dev, at91_emac_read(lp, AT91_EMAC_SA3H), at91_emac_read(lp, AT91_EMAC_SA3L))) | ||
489 | return; | ||
490 | /* Check Specific-Address 4 */ | ||
491 | if (unpack_mac_address(dev, at91_emac_read(lp, AT91_EMAC_SA4H), at91_emac_read(lp, AT91_EMAC_SA4L))) | ||
492 | return; | ||
493 | |||
494 | printk(KERN_ERR "at91_ether: Your bootloader did not configure a MAC address.\n"); | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Program the hardware MAC address from dev->dev_addr. | ||
499 | */ | ||
500 | static void update_mac_address(struct net_device *dev) | ||
501 | { | ||
502 | struct at91_private *lp = netdev_priv(dev); | ||
503 | |||
504 | at91_emac_write(lp, AT91_EMAC_SA1L, (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0])); | ||
505 | at91_emac_write(lp, AT91_EMAC_SA1H, (dev->dev_addr[5] << 8) | (dev->dev_addr[4])); | ||
506 | |||
507 | at91_emac_write(lp, AT91_EMAC_SA2L, 0); | ||
508 | at91_emac_write(lp, AT91_EMAC_SA2H, 0); | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * Store the new hardware address in dev->dev_addr, and update the MAC. | ||
513 | */ | ||
514 | static int set_mac_address(struct net_device *dev, void* addr) | ||
515 | { | ||
516 | struct sockaddr *address = addr; | ||
517 | |||
518 | if (!is_valid_ether_addr(address->sa_data)) | ||
519 | return -EADDRNOTAVAIL; | ||
520 | |||
521 | memcpy(dev->dev_addr, address->sa_data, dev->addr_len); | ||
522 | update_mac_address(dev); | ||
523 | 35 | ||
524 | printk("%s: Setting MAC address to %pM\n", dev->name, | 36 | /* 1518 rounded up */ |
525 | dev->dev_addr); | 37 | #define MAX_RBUFF_SZ 0x600 |
38 | /* max number of receive buffers */ | ||
39 | #define MAX_RX_DESCR 9 | ||
526 | 40 | ||
527 | return 0; | 41 | /* Initialize and start the Receiver and Transmit subsystems */ |
528 | } | 42 | static int at91ether_start(struct net_device *dev) |
529 | |||
530 | static int inline hash_bit_value(int bitnr, __u8 *addr) | ||
531 | { | ||
532 | if (addr[bitnr / 8] & (1 << (bitnr % 8))) | ||
533 | return 1; | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | /* | ||
538 | * The hash address register is 64 bits long and takes up two locations in the memory map. | ||
539 | * The least significant bits are stored in EMAC_HSL and the most significant | ||
540 | * bits in EMAC_HSH. | ||
541 | * | ||
542 | * The unicast hash enable and the multicast hash enable bits in the network configuration | ||
543 | * register enable the reception of hash matched frames. The destination address is | ||
544 | * reduced to a 6 bit index into the 64 bit hash register using the following hash function. | ||
545 | * The hash function is an exclusive or of every sixth bit of the destination address. | ||
546 | * hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] | ||
547 | * hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] | ||
548 | * hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] | ||
549 | * hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] | ||
550 | * hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] | ||
551 | * hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] | ||
552 | * da[0] represents the least significant bit of the first byte received, that is, the multicast/ | ||
553 | * unicast indicator, and da[47] represents the most significant bit of the last byte | ||
554 | * received. | ||
555 | * If the hash index points to a bit that is set in the hash register then the frame will be | ||
556 | * matched according to whether the frame is multicast or unicast. | ||
557 | * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and | ||
558 | * the hash index points to a bit set in the hash register. | ||
559 | * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the | ||
560 | * hash index points to a bit set in the hash register. | ||
561 | * To receive all multicast frames, the hash register should be set with all ones and the | ||
562 | * multicast hash enable bit should be set in the network configuration register. | ||
563 | */ | ||
564 | |||
565 | /* | ||
566 | * Return the hash index value for the specified address. | ||
567 | */ | ||
568 | static int hash_get_index(__u8 *addr) | ||
569 | { | ||
570 | int i, j, bitval; | ||
571 | int hash_index = 0; | ||
572 | |||
573 | for (j = 0; j < 6; j++) { | ||
574 | for (i = 0, bitval = 0; i < 8; i++) | ||
575 | bitval ^= hash_bit_value(i*6 + j, addr); | ||
576 | |||
577 | hash_index |= (bitval << j); | ||
578 | } | ||
579 | |||
580 | return hash_index; | ||
581 | } | ||
582 | |||
583 | /* | ||
584 | * Add multicast addresses to the internal multicast-hash table. | ||
585 | */ | ||
586 | static void at91ether_sethashtable(struct net_device *dev) | ||
587 | { | 43 | { |
588 | struct at91_private *lp = netdev_priv(dev); | 44 | struct macb *lp = netdev_priv(dev); |
589 | struct netdev_hw_addr *ha; | 45 | dma_addr_t addr; |
590 | unsigned long mc_filter[2]; | 46 | u32 ctl; |
591 | unsigned int bitnr; | 47 | int i; |
592 | |||
593 | mc_filter[0] = mc_filter[1] = 0; | ||
594 | |||
595 | netdev_for_each_mc_addr(ha, dev) { | ||
596 | bitnr = hash_get_index(ha->addr); | ||
597 | mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); | ||
598 | } | ||
599 | |||
600 | at91_emac_write(lp, AT91_EMAC_HSL, mc_filter[0]); | ||
601 | at91_emac_write(lp, AT91_EMAC_HSH, mc_filter[1]); | ||
602 | } | ||
603 | 48 | ||
604 | /* | 49 | lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev, |
605 | * Enable/Disable promiscuous and multicast modes. | 50 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), |
606 | */ | 51 | &lp->rx_ring_dma, GFP_KERNEL); |
607 | static void at91ether_set_multicast_list(struct net_device *dev) | 52 | if (!lp->rx_ring) { |
608 | { | 53 | netdev_err(dev, "unable to alloc rx ring DMA buffer\n"); |
609 | struct at91_private *lp = netdev_priv(dev); | 54 | return -ENOMEM; |
610 | unsigned long cfg; | ||
611 | |||
612 | cfg = at91_emac_read(lp, AT91_EMAC_CFG); | ||
613 | |||
614 | if (dev->flags & IFF_PROMISC) /* Enable promiscuous mode */ | ||
615 | cfg |= AT91_EMAC_CAF; | ||
616 | else if (dev->flags & (~IFF_PROMISC)) /* Disable promiscuous mode */ | ||
617 | cfg &= ~AT91_EMAC_CAF; | ||
618 | |||
619 | if (dev->flags & IFF_ALLMULTI) { /* Enable all multicast mode */ | ||
620 | at91_emac_write(lp, AT91_EMAC_HSH, -1); | ||
621 | at91_emac_write(lp, AT91_EMAC_HSL, -1); | ||
622 | cfg |= AT91_EMAC_MTI; | ||
623 | } else if (!netdev_mc_empty(dev)) { /* Enable specific multicasts */ | ||
624 | at91ether_sethashtable(dev); | ||
625 | cfg |= AT91_EMAC_MTI; | ||
626 | } else if (dev->flags & (~IFF_ALLMULTI)) { /* Disable all multicast mode */ | ||
627 | at91_emac_write(lp, AT91_EMAC_HSH, 0); | ||
628 | at91_emac_write(lp, AT91_EMAC_HSL, 0); | ||
629 | cfg &= ~AT91_EMAC_MTI; | ||
630 | } | 55 | } |
631 | 56 | ||
632 | at91_emac_write(lp, AT91_EMAC_CFG, cfg); | 57 | lp->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, |
633 | } | 58 | MAX_RX_DESCR * MAX_RBUFF_SZ, |
634 | 59 | &lp->rx_buffers_dma, GFP_KERNEL); | |
635 | /* ......................... ETHTOOL SUPPORT ........................... */ | 60 | if (!lp->rx_buffers) { |
636 | 61 | netdev_err(dev, "unable to alloc rx data DMA buffer\n"); | |
637 | static int mdio_read(struct net_device *dev, int phy_id, int location) | ||
638 | { | ||
639 | struct at91_private *lp = netdev_priv(dev); | ||
640 | unsigned int value; | ||
641 | |||
642 | read_phy(lp, phy_id, location, &value); | ||
643 | return value; | ||
644 | } | ||
645 | |||
646 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value) | ||
647 | { | ||
648 | struct at91_private *lp = netdev_priv(dev); | ||
649 | |||
650 | write_phy(lp, phy_id, location, value); | ||
651 | } | ||
652 | |||
653 | static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
654 | { | ||
655 | struct at91_private *lp = netdev_priv(dev); | ||
656 | int ret; | ||
657 | |||
658 | spin_lock_irq(&lp->lock); | ||
659 | enable_mdi(lp); | ||
660 | |||
661 | ret = mii_ethtool_gset(&lp->mii, cmd); | ||
662 | |||
663 | disable_mdi(lp); | ||
664 | spin_unlock_irq(&lp->lock); | ||
665 | 62 | ||
666 | if (lp->phy_media == PORT_FIBRE) { /* override media type since mii.c doesn't know */ | 63 | dma_free_coherent(&lp->pdev->dev, |
667 | cmd->supported = SUPPORTED_FIBRE; | 64 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), |
668 | cmd->port = PORT_FIBRE; | 65 | lp->rx_ring, lp->rx_ring_dma); |
66 | lp->rx_ring = NULL; | ||
67 | return -ENOMEM; | ||
669 | } | 68 | } |
670 | 69 | ||
671 | return ret; | 70 | addr = lp->rx_buffers_dma; |
672 | } | ||
673 | |||
674 | static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
675 | { | ||
676 | struct at91_private *lp = netdev_priv(dev); | ||
677 | int ret; | ||
678 | |||
679 | spin_lock_irq(&lp->lock); | ||
680 | enable_mdi(lp); | ||
681 | |||
682 | ret = mii_ethtool_sset(&lp->mii, cmd); | ||
683 | |||
684 | disable_mdi(lp); | ||
685 | spin_unlock_irq(&lp->lock); | ||
686 | |||
687 | return ret; | ||
688 | } | ||
689 | |||
690 | static int at91ether_nwayreset(struct net_device *dev) | ||
691 | { | ||
692 | struct at91_private *lp = netdev_priv(dev); | ||
693 | int ret; | ||
694 | |||
695 | spin_lock_irq(&lp->lock); | ||
696 | enable_mdi(lp); | ||
697 | |||
698 | ret = mii_nway_restart(&lp->mii); | ||
699 | |||
700 | disable_mdi(lp); | ||
701 | spin_unlock_irq(&lp->lock); | ||
702 | |||
703 | return ret; | ||
704 | } | ||
705 | |||
706 | static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
707 | { | ||
708 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); | ||
709 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | ||
710 | strlcpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info)); | ||
711 | } | ||
712 | |||
713 | static const struct ethtool_ops at91ether_ethtool_ops = { | ||
714 | .get_settings = at91ether_get_settings, | ||
715 | .set_settings = at91ether_set_settings, | ||
716 | .get_drvinfo = at91ether_get_drvinfo, | ||
717 | .nway_reset = at91ether_nwayreset, | ||
718 | .get_link = ethtool_op_get_link, | ||
719 | }; | ||
720 | |||
721 | static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
722 | { | ||
723 | struct at91_private *lp = netdev_priv(dev); | ||
724 | int res; | ||
725 | |||
726 | if (!netif_running(dev)) | ||
727 | return -EINVAL; | ||
728 | |||
729 | spin_lock_irq(&lp->lock); | ||
730 | enable_mdi(lp); | ||
731 | res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL); | ||
732 | disable_mdi(lp); | ||
733 | spin_unlock_irq(&lp->lock); | ||
734 | |||
735 | return res; | ||
736 | } | ||
737 | |||
738 | /* ................................ MAC ................................ */ | ||
739 | |||
740 | /* | ||
741 | * Initialize and start the Receiver and Transmit subsystems | ||
742 | */ | ||
743 | static void at91ether_start(struct net_device *dev) | ||
744 | { | ||
745 | struct at91_private *lp = netdev_priv(dev); | ||
746 | struct recv_desc_bufs *dlist, *dlist_phys; | ||
747 | int i; | ||
748 | unsigned long ctl; | ||
749 | |||
750 | dlist = lp->dlist; | ||
751 | dlist_phys = lp->dlist_phys; | ||
752 | |||
753 | for (i = 0; i < MAX_RX_DESCR; i++) { | 71 | for (i = 0; i < MAX_RX_DESCR; i++) { |
754 | dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0]; | 72 | lp->rx_ring[i].addr = addr; |
755 | dlist->descriptors[i].size = 0; | 73 | lp->rx_ring[i].ctrl = 0; |
74 | addr += MAX_RBUFF_SZ; | ||
756 | } | 75 | } |
757 | 76 | ||
758 | /* Set the Wrap bit on the last descriptor */ | 77 | /* Set the Wrap bit on the last descriptor */ |
759 | dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP; | 78 | lp->rx_ring[MAX_RX_DESCR - 1].addr |= MACB_BIT(RX_WRAP); |
760 | 79 | ||
761 | /* Reset buffer index */ | 80 | /* Reset buffer index */ |
762 | lp->rxBuffIndex = 0; | 81 | lp->rx_tail = 0; |
763 | 82 | ||
764 | /* Program address of descriptor list in Rx Buffer Queue register */ | 83 | /* Program address of descriptor list in Rx Buffer Queue register */ |
765 | at91_emac_write(lp, AT91_EMAC_RBQP, (unsigned long) dlist_phys); | 84 | macb_writel(lp, RBQP, lp->rx_ring_dma); |
766 | 85 | ||
767 | /* Enable Receive and Transmit */ | 86 | /* Enable Receive and Transmit */ |
768 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | 87 | ctl = macb_readl(lp, NCR); |
769 | at91_emac_write(lp, AT91_EMAC_CTL, ctl | AT91_EMAC_RE | AT91_EMAC_TE); | 88 | macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); |
89 | |||
90 | return 0; | ||
770 | } | 91 | } |
771 | 92 | ||
772 | /* | 93 | /* Open the ethernet interface */ |
773 | * Open the ethernet interface | ||
774 | */ | ||
775 | static int at91ether_open(struct net_device *dev) | 94 | static int at91ether_open(struct net_device *dev) |
776 | { | 95 | { |
777 | struct at91_private *lp = netdev_priv(dev); | 96 | struct macb *lp = netdev_priv(dev); |
778 | unsigned long ctl; | 97 | u32 ctl; |
98 | int ret; | ||
779 | 99 | ||
780 | if (!is_valid_ether_addr(dev->dev_addr)) | 100 | if (!is_valid_ether_addr(dev->dev_addr)) |
781 | return -EADDRNOTAVAIL; | 101 | return -EADDRNOTAVAIL; |
782 | 102 | ||
783 | clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */ | ||
784 | |||
785 | /* Clear internal statistics */ | 103 | /* Clear internal statistics */ |
786 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | 104 | ctl = macb_readl(lp, NCR); |
787 | at91_emac_write(lp, AT91_EMAC_CTL, ctl | AT91_EMAC_CSR); | 105 | macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); |
788 | 106 | ||
789 | /* Update the MAC address (incase user has changed it) */ | 107 | macb_set_hwaddr(lp); |
790 | update_mac_address(dev); | ||
791 | 108 | ||
792 | /* Enable PHY interrupt */ | 109 | ret = at91ether_start(dev); |
793 | enable_phyirq(dev); | 110 | if (ret) |
111 | return ret; | ||
794 | 112 | ||
795 | /* Enable MAC interrupts */ | 113 | /* Enable MAC interrupts */ |
796 | at91_emac_write(lp, AT91_EMAC_IER, AT91_EMAC_RCOM | AT91_EMAC_RBNA | 114 | macb_writel(lp, IER, MACB_BIT(RCOMP) | |
797 | | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM | 115 | MACB_BIT(RXUBR) | |
798 | | AT91_EMAC_ROVR | AT91_EMAC_ABT); | 116 | MACB_BIT(ISR_TUND) | |
799 | 117 | MACB_BIT(ISR_RLE) | | |
800 | /* Determine current link speed */ | 118 | MACB_BIT(TCOMP) | |
801 | spin_lock_irq(&lp->lock); | 119 | MACB_BIT(ISR_ROVR) | |
802 | enable_mdi(lp); | 120 | MACB_BIT(HRESP)); |
803 | update_linkspeed(dev, 0); | 121 | |
804 | disable_mdi(lp); | 122 | /* schedule a link state check */ |
805 | spin_unlock_irq(&lp->lock); | 123 | phy_start(lp->phy_dev); |
806 | 124 | ||
807 | at91ether_start(dev); | ||
808 | netif_start_queue(dev); | 125 | netif_start_queue(dev); |
126 | |||
809 | return 0; | 127 | return 0; |
810 | } | 128 | } |
811 | 129 | ||
812 | /* | 130 | /* Close the interface */ |
813 | * Close the interface | ||
814 | */ | ||
815 | static int at91ether_close(struct net_device *dev) | 131 | static int at91ether_close(struct net_device *dev) |
816 | { | 132 | { |
817 | struct at91_private *lp = netdev_priv(dev); | 133 | struct macb *lp = netdev_priv(dev); |
818 | unsigned long ctl; | 134 | u32 ctl; |
819 | 135 | ||
820 | /* Disable Receiver and Transmitter */ | 136 | /* Disable Receiver and Transmitter */ |
821 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | 137 | ctl = macb_readl(lp, NCR); |
822 | at91_emac_write(lp, AT91_EMAC_CTL, ctl & ~(AT91_EMAC_TE | AT91_EMAC_RE)); | 138 | macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); |
823 | |||
824 | /* Disable PHY interrupt */ | ||
825 | disable_phyirq(dev); | ||
826 | 139 | ||
827 | /* Disable MAC interrupts */ | 140 | /* Disable MAC interrupts */ |
828 | at91_emac_write(lp, AT91_EMAC_IDR, AT91_EMAC_RCOM | AT91_EMAC_RBNA | 141 | macb_writel(lp, IDR, MACB_BIT(RCOMP) | |
829 | | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM | 142 | MACB_BIT(RXUBR) | |
830 | | AT91_EMAC_ROVR | AT91_EMAC_ABT); | 143 | MACB_BIT(ISR_TUND) | |
144 | MACB_BIT(ISR_RLE) | | ||
145 | MACB_BIT(TCOMP) | | ||
146 | MACB_BIT(ISR_ROVR) | | ||
147 | MACB_BIT(HRESP)); | ||
831 | 148 | ||
832 | netif_stop_queue(dev); | 149 | netif_stop_queue(dev); |
833 | 150 | ||
834 | clk_disable(lp->ether_clk); /* Disable Peripheral clock */ | 151 | dma_free_coherent(&lp->pdev->dev, |
152 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), | ||
153 | lp->rx_ring, lp->rx_ring_dma); | ||
154 | lp->rx_ring = NULL; | ||
155 | |||
156 | dma_free_coherent(&lp->pdev->dev, | ||
157 | MAX_RX_DESCR * MAX_RBUFF_SZ, | ||
158 | lp->rx_buffers, lp->rx_buffers_dma); | ||
159 | lp->rx_buffers = NULL; | ||
835 | 160 | ||
836 | return 0; | 161 | return 0; |
837 | } | 162 | } |
838 | 163 | ||
839 | /* | 164 | /* Transmit packet */ |
840 | * Transmit packet. | ||
841 | */ | ||
842 | static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) | 165 | static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) |
843 | { | 166 | { |
844 | struct at91_private *lp = netdev_priv(dev); | 167 | struct macb *lp = netdev_priv(dev); |
845 | 168 | ||
846 | if (at91_emac_read(lp, AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) { | 169 | if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { |
847 | netif_stop_queue(dev); | 170 | netif_stop_queue(dev); |
848 | 171 | ||
849 | /* Store packet information (to free when Tx completed) */ | 172 | /* Store packet information (to free when Tx completed) */ |
850 | lp->skb = skb; | 173 | lp->skb = skb; |
851 | lp->skb_length = skb->len; | 174 | lp->skb_length = skb->len; |
852 | lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE); | 175 | lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, |
853 | dev->stats.tx_bytes += skb->len; | 176 | DMA_TO_DEVICE); |
854 | 177 | ||
855 | /* Set address of the data in the Transmit Address register */ | 178 | /* Set address of the data in the Transmit Address register */ |
856 | at91_emac_write(lp, AT91_EMAC_TAR, lp->skb_physaddr); | 179 | macb_writel(lp, TAR, lp->skb_physaddr); |
857 | /* Set length of the packet in the Transmit Control register */ | 180 | /* Set length of the packet in the Transmit Control register */ |
858 | at91_emac_write(lp, AT91_EMAC_TCR, skb->len); | 181 | macb_writel(lp, TCR, skb->len); |
859 | 182 | ||
860 | } else { | 183 | } else { |
861 | printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n"); | 184 | netdev_err(dev, "%s called, but device is busy!\n", __func__); |
862 | return NETDEV_TX_BUSY; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb) | 185 | return NETDEV_TX_BUSY; |
863 | on this skb, he also reports -ENETDOWN and printk's, so either | ||
864 | we free and return(0) or don't free and return 1 */ | ||
865 | } | 186 | } |
866 | 187 | ||
867 | return NETDEV_TX_OK; | 188 | return NETDEV_TX_OK; |
868 | } | 189 | } |
869 | 190 | ||
870 | /* | 191 | /* Extract received frame from buffer descriptors and sent to upper layers. |
871 | * Update the current statistics from the internal statistics registers. | ||
872 | */ | ||
873 | static struct net_device_stats *at91ether_stats(struct net_device *dev) | ||
874 | { | ||
875 | struct at91_private *lp = netdev_priv(dev); | ||
876 | int ale, lenerr, seqe, lcol, ecol; | ||
877 | |||
878 | if (netif_running(dev)) { | ||
879 | dev->stats.rx_packets += at91_emac_read(lp, AT91_EMAC_OK); /* Good frames received */ | ||
880 | ale = at91_emac_read(lp, AT91_EMAC_ALE); | ||
881 | dev->stats.rx_frame_errors += ale; /* Alignment errors */ | ||
882 | lenerr = at91_emac_read(lp, AT91_EMAC_ELR) + at91_emac_read(lp, AT91_EMAC_USF); | ||
883 | dev->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */ | ||
884 | seqe = at91_emac_read(lp, AT91_EMAC_SEQE); | ||
885 | dev->stats.rx_crc_errors += seqe; /* CRC error */ | ||
886 | dev->stats.rx_fifo_errors += at91_emac_read(lp, AT91_EMAC_DRFC);/* Receive buffer not available */ | ||
887 | dev->stats.rx_errors += (ale + lenerr + seqe | ||
888 | + at91_emac_read(lp, AT91_EMAC_CDE) + at91_emac_read(lp, AT91_EMAC_RJB)); | ||
889 | |||
890 | dev->stats.tx_packets += at91_emac_read(lp, AT91_EMAC_FRA); /* Frames successfully transmitted */ | ||
891 | dev->stats.tx_fifo_errors += at91_emac_read(lp, AT91_EMAC_TUE); /* Transmit FIFO underruns */ | ||
892 | dev->stats.tx_carrier_errors += at91_emac_read(lp, AT91_EMAC_CSE); /* Carrier Sense errors */ | ||
893 | dev->stats.tx_heartbeat_errors += at91_emac_read(lp, AT91_EMAC_SQEE);/* Heartbeat error */ | ||
894 | |||
895 | lcol = at91_emac_read(lp, AT91_EMAC_LCOL); | ||
896 | ecol = at91_emac_read(lp, AT91_EMAC_ECOL); | ||
897 | dev->stats.tx_window_errors += lcol; /* Late collisions */ | ||
898 | dev->stats.tx_aborted_errors += ecol; /* 16 collisions */ | ||
899 | |||
900 | dev->stats.collisions += (at91_emac_read(lp, AT91_EMAC_SCOL) + at91_emac_read(lp, AT91_EMAC_MCOL) + lcol + ecol); | ||
901 | } | ||
902 | return &dev->stats; | ||
903 | } | ||
904 | |||
905 | /* | ||
906 | * Extract received frame from buffer descriptors and sent to upper layers. | ||
907 | * (Called from interrupt context) | 192 | * (Called from interrupt context) |
908 | */ | 193 | */ |
909 | static void at91ether_rx(struct net_device *dev) | 194 | static void at91ether_rx(struct net_device *dev) |
910 | { | 195 | { |
911 | struct at91_private *lp = netdev_priv(dev); | 196 | struct macb *lp = netdev_priv(dev); |
912 | struct recv_desc_bufs *dlist; | ||
913 | unsigned char *p_recv; | 197 | unsigned char *p_recv; |
914 | struct sk_buff *skb; | 198 | struct sk_buff *skb; |
915 | unsigned int pktlen; | 199 | unsigned int pktlen; |
916 | 200 | ||
917 | dlist = lp->dlist; | 201 | while (lp->rx_ring[lp->rx_tail].addr & MACB_BIT(RX_USED)) { |
918 | while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) { | 202 | p_recv = lp->rx_buffers + lp->rx_tail * MAX_RBUFF_SZ; |
919 | p_recv = dlist->recv_buf[lp->rxBuffIndex]; | 203 | pktlen = MACB_BF(RX_FRMLEN, lp->rx_ring[lp->rx_tail].ctrl); |
920 | pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */ | ||
921 | skb = netdev_alloc_skb(dev, pktlen + 2); | 204 | skb = netdev_alloc_skb(dev, pktlen + 2); |
922 | if (skb != NULL) { | 205 | if (skb) { |
923 | skb_reserve(skb, 2); | 206 | skb_reserve(skb, 2); |
924 | memcpy(skb_put(skb, pktlen), p_recv, pktlen); | 207 | memcpy(skb_put(skb, pktlen), p_recv, pktlen); |
925 | 208 | ||
926 | skb->protocol = eth_type_trans(skb, dev); | 209 | skb->protocol = eth_type_trans(skb, dev); |
927 | dev->stats.rx_bytes += pktlen; | 210 | lp->stats.rx_packets++; |
211 | lp->stats.rx_bytes += pktlen; | ||
928 | netif_rx(skb); | 212 | netif_rx(skb); |
213 | } else { | ||
214 | lp->stats.rx_dropped++; | ||
215 | netdev_notice(dev, "Memory squeeze, dropping packet.\n"); | ||
929 | } | 216 | } |
930 | else { | ||
931 | dev->stats.rx_dropped += 1; | ||
932 | printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); | ||
933 | } | ||
934 | 217 | ||
935 | if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST) | 218 | if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH)) |
936 | dev->stats.multicast++; | 219 | lp->stats.multicast++; |
220 | |||
221 | /* reset ownership bit */ | ||
222 | lp->rx_ring[lp->rx_tail].addr &= ~MACB_BIT(RX_USED); | ||
937 | 223 | ||
938 | dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */ | 224 | /* wrap after last buffer */ |
939 | if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */ | 225 | if (lp->rx_tail == MAX_RX_DESCR - 1) |
940 | lp->rxBuffIndex = 0; | 226 | lp->rx_tail = 0; |
941 | else | 227 | else |
942 | lp->rxBuffIndex++; | 228 | lp->rx_tail++; |
943 | } | 229 | } |
944 | } | 230 | } |
945 | 231 | ||
946 | /* | 232 | /* MAC interrupt handler */ |
947 | * MAC interrupt handler | ||
948 | */ | ||
949 | static irqreturn_t at91ether_interrupt(int irq, void *dev_id) | 233 | static irqreturn_t at91ether_interrupt(int irq, void *dev_id) |
950 | { | 234 | { |
951 | struct net_device *dev = (struct net_device *) dev_id; | 235 | struct net_device *dev = dev_id; |
952 | struct at91_private *lp = netdev_priv(dev); | 236 | struct macb *lp = netdev_priv(dev); |
953 | unsigned long intstatus, ctl; | 237 | u32 intstatus, ctl; |
954 | 238 | ||
955 | /* MAC Interrupt Status register indicates what interrupts are pending. | 239 | /* MAC Interrupt Status register indicates what interrupts are pending. |
956 | It is automatically cleared once read. */ | 240 | * It is automatically cleared once read. |
957 | intstatus = at91_emac_read(lp, AT91_EMAC_ISR); | 241 | */ |
242 | intstatus = macb_readl(lp, ISR); | ||
958 | 243 | ||
959 | if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ | 244 | /* Receive complete */ |
245 | if (intstatus & MACB_BIT(RCOMP)) | ||
960 | at91ether_rx(dev); | 246 | at91ether_rx(dev); |
961 | 247 | ||
962 | if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ | 248 | /* Transmit complete */ |
963 | /* The TCOM bit is set even if the transmission failed. */ | 249 | if (intstatus & MACB_BIT(TCOMP)) { |
964 | if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) | 250 | /* The TCOM bit is set even if the transmission failed */ |
965 | dev->stats.tx_errors += 1; | 251 | if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) |
252 | lp->stats.tx_errors++; | ||
966 | 253 | ||
967 | if (lp->skb) { | 254 | if (lp->skb) { |
968 | dev_kfree_skb_irq(lp->skb); | 255 | dev_kfree_skb_irq(lp->skb); |
969 | lp->skb = NULL; | 256 | lp->skb = NULL; |
970 | dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE); | 257 | dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE); |
258 | lp->stats.tx_packets++; | ||
259 | lp->stats.tx_bytes += lp->skb_length; | ||
971 | } | 260 | } |
972 | netif_wake_queue(dev); | 261 | netif_wake_queue(dev); |
973 | } | 262 | } |
974 | 263 | ||
975 | /* Work-around for Errata #11 */ | 264 | /* Work-around for EMAC Errata section 41.3.1 */ |
976 | if (intstatus & AT91_EMAC_RBNA) { | 265 | if (intstatus & MACB_BIT(RXUBR)) { |
977 | ctl = at91_emac_read(lp, AT91_EMAC_CTL); | 266 | ctl = macb_readl(lp, NCR); |
978 | at91_emac_write(lp, AT91_EMAC_CTL, ctl & ~AT91_EMAC_RE); | 267 | macb_writel(lp, NCR, ctl & ~MACB_BIT(RE)); |
979 | at91_emac_write(lp, AT91_EMAC_CTL, ctl | AT91_EMAC_RE); | 268 | macb_writel(lp, NCR, ctl | MACB_BIT(RE)); |
980 | } | 269 | } |
981 | 270 | ||
982 | if (intstatus & AT91_EMAC_ROVR) | 271 | if (intstatus & MACB_BIT(ISR_ROVR)) |
983 | printk("%s: ROVR error\n", dev->name); | 272 | netdev_err(dev, "ROVR error\n"); |
984 | 273 | ||
985 | return IRQ_HANDLED; | 274 | return IRQ_HANDLED; |
986 | } | 275 | } |
@@ -1000,10 +289,10 @@ static const struct net_device_ops at91ether_netdev_ops = { | |||
1000 | .ndo_open = at91ether_open, | 289 | .ndo_open = at91ether_open, |
1001 | .ndo_stop = at91ether_close, | 290 | .ndo_stop = at91ether_close, |
1002 | .ndo_start_xmit = at91ether_start_xmit, | 291 | .ndo_start_xmit = at91ether_start_xmit, |
1003 | .ndo_get_stats = at91ether_stats, | 292 | .ndo_get_stats = macb_get_stats, |
1004 | .ndo_set_rx_mode = at91ether_set_multicast_list, | 293 | .ndo_set_rx_mode = macb_set_rx_mode, |
1005 | .ndo_set_mac_address = set_mac_address, | 294 | .ndo_set_mac_address = eth_mac_addr, |
1006 | .ndo_do_ioctl = at91ether_ioctl, | 295 | .ndo_do_ioctl = macb_ioctl, |
1007 | .ndo_validate_addr = eth_validate_addr, | 296 | .ndo_validate_addr = eth_validate_addr, |
1008 | .ndo_change_mtu = eth_change_mtu, | 297 | .ndo_change_mtu = eth_change_mtu, |
1009 | #ifdef CONFIG_NET_POLL_CONTROLLER | 298 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -1011,197 +300,160 @@ static const struct net_device_ops at91ether_netdev_ops = { | |||
1011 | #endif | 300 | #endif |
1012 | }; | 301 | }; |
1013 | 302 | ||
1014 | /* | 303 | #if defined(CONFIG_OF) |
1015 | * Detect the PHY type, and its address. | 304 | static const struct of_device_id at91ether_dt_ids[] = { |
1016 | */ | 305 | { .compatible = "cdns,at91rm9200-emac" }, |
1017 | static int __init at91ether_phy_detect(struct at91_private *lp) | 306 | { .compatible = "cdns,emac" }, |
307 | { /* sentinel */ } | ||
308 | }; | ||
309 | |||
310 | MODULE_DEVICE_TABLE(of, at91ether_dt_ids); | ||
311 | |||
312 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) | ||
1018 | { | 313 | { |
1019 | unsigned int phyid1, phyid2; | 314 | struct device_node *np = pdev->dev.of_node; |
1020 | unsigned long phy_id; | ||
1021 | unsigned short phy_address = 0; | ||
1022 | |||
1023 | while (phy_address < PHY_MAX_ADDR) { | ||
1024 | /* Read the PHY ID registers */ | ||
1025 | enable_mdi(lp); | ||
1026 | read_phy(lp, phy_address, MII_PHYSID1, &phyid1); | ||
1027 | read_phy(lp, phy_address, MII_PHYSID2, &phyid2); | ||
1028 | disable_mdi(lp); | ||
1029 | |||
1030 | phy_id = (phyid1 << 16) | (phyid2 & 0xfff0); | ||
1031 | switch (phy_id) { | ||
1032 | case MII_DM9161_ID: /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */ | ||
1033 | case MII_DM9161A_ID: /* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */ | ||
1034 | case MII_LXT971A_ID: /* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */ | ||
1035 | case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */ | ||
1036 | case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */ | ||
1037 | case MII_DP83847_ID: /* National Semiconductor DP83847: */ | ||
1038 | case MII_DP83848_ID: /* National Semiconductor DP83848: */ | ||
1039 | case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ | ||
1040 | case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ | ||
1041 | case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */ | ||
1042 | case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */ | ||
1043 | /* store detected values */ | ||
1044 | lp->phy_type = phy_id; /* Type of PHY connected */ | ||
1045 | lp->phy_address = phy_address; /* MDI address of PHY */ | ||
1046 | return 1; | ||
1047 | } | ||
1048 | 315 | ||
1049 | phy_address++; | 316 | if (np) |
1050 | } | 317 | return of_get_phy_mode(np); |
1051 | 318 | ||
1052 | return 0; /* not detected */ | 319 | return -ENODEV; |
1053 | } | 320 | } |
1054 | 321 | ||
322 | static int at91ether_get_hwaddr_dt(struct macb *bp) | ||
323 | { | ||
324 | struct device_node *np = bp->pdev->dev.of_node; | ||
1055 | 325 | ||
1056 | /* | 326 | if (np) { |
1057 | * Detect MAC & PHY and perform ethernet interface initialization | 327 | const char *mac = of_get_mac_address(np); |
1058 | */ | 328 | if (mac) { |
329 | memcpy(bp->dev->dev_addr, mac, ETH_ALEN); | ||
330 | return 0; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return -ENODEV; | ||
335 | } | ||
336 | #else | ||
337 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) | ||
338 | { | ||
339 | return -ENODEV; | ||
340 | } | ||
341 | static int at91ether_get_hwaddr_dt(struct macb *bp) | ||
342 | { | ||
343 | return -ENODEV; | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | /* Detect MAC & PHY and perform ethernet interface initialization */ | ||
1059 | static int __init at91ether_probe(struct platform_device *pdev) | 348 | static int __init at91ether_probe(struct platform_device *pdev) |
1060 | { | 349 | { |
1061 | struct macb_platform_data *board_data = pdev->dev.platform_data; | 350 | struct macb_platform_data *board_data = pdev->dev.platform_data; |
1062 | struct resource *regs; | 351 | struct resource *regs; |
1063 | struct net_device *dev; | 352 | struct net_device *dev; |
1064 | struct at91_private *lp; | 353 | struct phy_device *phydev; |
354 | struct pinctrl *pinctrl; | ||
355 | struct macb *lp; | ||
1065 | int res; | 356 | int res; |
357 | u32 reg; | ||
1066 | 358 | ||
1067 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 359 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1068 | if (!regs) | 360 | if (!regs) |
1069 | return -ENOENT; | 361 | return -ENOENT; |
1070 | 362 | ||
1071 | dev = alloc_etherdev(sizeof(struct at91_private)); | 363 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
364 | if (IS_ERR(pinctrl)) { | ||
365 | res = PTR_ERR(pinctrl); | ||
366 | if (res == -EPROBE_DEFER) | ||
367 | return res; | ||
368 | |||
369 | dev_warn(&pdev->dev, "No pinctrl provided\n"); | ||
370 | } | ||
371 | |||
372 | dev = alloc_etherdev(sizeof(struct macb)); | ||
1072 | if (!dev) | 373 | if (!dev) |
1073 | return -ENOMEM; | 374 | return -ENOMEM; |
1074 | 375 | ||
1075 | lp = netdev_priv(dev); | 376 | lp = netdev_priv(dev); |
1076 | lp->board_data = *board_data; | 377 | lp->pdev = pdev; |
378 | lp->dev = dev; | ||
1077 | spin_lock_init(&lp->lock); | 379 | spin_lock_init(&lp->lock); |
1078 | 380 | ||
1079 | dev->base_addr = regs->start; /* physical base address */ | 381 | /* physical base address */ |
1080 | lp->emac_base = ioremap(regs->start, regs->end - regs->start + 1); | 382 | dev->base_addr = regs->start; |
1081 | if (!lp->emac_base) { | 383 | lp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); |
384 | if (!lp->regs) { | ||
1082 | res = -ENOMEM; | 385 | res = -ENOMEM; |
1083 | goto err_free_dev; | 386 | goto err_free_dev; |
1084 | } | 387 | } |
1085 | 388 | ||
1086 | /* Clock */ | 389 | /* Clock */ |
1087 | lp->ether_clk = clk_get(&pdev->dev, "ether_clk"); | 390 | lp->pclk = devm_clk_get(&pdev->dev, "ether_clk"); |
1088 | if (IS_ERR(lp->ether_clk)) { | 391 | if (IS_ERR(lp->pclk)) { |
1089 | res = PTR_ERR(lp->ether_clk); | 392 | res = PTR_ERR(lp->pclk); |
1090 | goto err_ioumap; | 393 | goto err_free_dev; |
1091 | } | 394 | } |
1092 | clk_enable(lp->ether_clk); | 395 | clk_enable(lp->pclk); |
1093 | 396 | ||
1094 | /* Install the interrupt handler */ | 397 | /* Install the interrupt handler */ |
1095 | dev->irq = platform_get_irq(pdev, 0); | 398 | dev->irq = platform_get_irq(pdev, 0); |
1096 | if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) { | 399 | res = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 0, dev->name, dev); |
1097 | res = -EBUSY; | 400 | if (res) |
1098 | goto err_disable_clock; | 401 | goto err_disable_clock; |
1099 | } | ||
1100 | |||
1101 | /* Allocate memory for DMA Receive descriptors */ | ||
1102 | lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL); | ||
1103 | if (lp->dlist == NULL) { | ||
1104 | res = -ENOMEM; | ||
1105 | goto err_free_irq; | ||
1106 | } | ||
1107 | 402 | ||
1108 | ether_setup(dev); | 403 | ether_setup(dev); |
1109 | dev->netdev_ops = &at91ether_netdev_ops; | 404 | dev->netdev_ops = &at91ether_netdev_ops; |
1110 | dev->ethtool_ops = &at91ether_ethtool_ops; | 405 | dev->ethtool_ops = &macb_ethtool_ops; |
1111 | platform_set_drvdata(pdev, dev); | 406 | platform_set_drvdata(pdev, dev); |
1112 | SET_NETDEV_DEV(dev, &pdev->dev); | 407 | SET_NETDEV_DEV(dev, &pdev->dev); |
1113 | 408 | ||
1114 | get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ | 409 | res = at91ether_get_hwaddr_dt(lp); |
1115 | update_mac_address(dev); /* Program ethernet address into MAC */ | 410 | if (res < 0) |
1116 | 411 | macb_get_hwaddr(lp); | |
1117 | at91_emac_write(lp, AT91_EMAC_CTL, 0); | ||
1118 | 412 | ||
1119 | if (board_data->is_rmii) | 413 | res = at91ether_get_phy_mode_dt(pdev); |
1120 | at91_emac_write(lp, AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG | AT91_EMAC_RMII); | 414 | if (res < 0) { |
1121 | else | 415 | if (board_data && board_data->is_rmii) |
1122 | at91_emac_write(lp, AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG); | 416 | lp->phy_interface = PHY_INTERFACE_MODE_RMII; |
1123 | 417 | else | |
1124 | /* Detect PHY */ | 418 | lp->phy_interface = PHY_INTERFACE_MODE_MII; |
1125 | if (!at91ether_phy_detect(lp)) { | 419 | } else { |
1126 | printk(KERN_ERR "at91_ether: Could not detect ethernet PHY\n"); | 420 | lp->phy_interface = res; |
1127 | res = -ENODEV; | ||
1128 | goto err_free_dmamem; | ||
1129 | } | 421 | } |
1130 | 422 | ||
1131 | initialize_phy(lp); | 423 | macb_writel(lp, NCR, 0); |
424 | |||
425 | reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); | ||
426 | if (lp->phy_interface == PHY_INTERFACE_MODE_RMII) | ||
427 | reg |= MACB_BIT(RM9200_RMII); | ||
1132 | 428 | ||
1133 | lp->mii.dev = dev; /* Support for ethtool */ | 429 | macb_writel(lp, NCFGR, reg); |
1134 | lp->mii.mdio_read = mdio_read; | ||
1135 | lp->mii.mdio_write = mdio_write; | ||
1136 | lp->mii.phy_id = lp->phy_address; | ||
1137 | lp->mii.phy_id_mask = 0x1f; | ||
1138 | lp->mii.reg_num_mask = 0x1f; | ||
1139 | 430 | ||
1140 | /* Register the network interface */ | 431 | /* Register the network interface */ |
1141 | res = register_netdev(dev); | 432 | res = register_netdev(dev); |
1142 | if (res) | 433 | if (res) |
1143 | goto err_free_dmamem; | 434 | goto err_disable_clock; |
1144 | 435 | ||
1145 | /* Determine current link speed */ | 436 | if (macb_mii_init(lp) != 0) |
1146 | spin_lock_irq(&lp->lock); | 437 | goto err_out_unregister_netdev; |
1147 | enable_mdi(lp); | 438 | |
1148 | update_linkspeed(dev, 0); | 439 | /* will be enabled in open() */ |
1149 | disable_mdi(lp); | 440 | netif_carrier_off(dev); |
1150 | spin_unlock_irq(&lp->lock); | 441 | |
1151 | netif_carrier_off(dev); /* will be enabled in open() */ | 442 | phydev = lp->phy_dev; |
1152 | 443 | netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | |
1153 | /* If board has no PHY IRQ, use a timer to poll the PHY */ | 444 | phydev->drv->name, dev_name(&phydev->dev), |
1154 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) { | 445 | phydev->irq); |
1155 | gpio_request(board_data->phy_irq_pin, "ethernet_phy"); | ||
1156 | } else { | ||
1157 | /* If board has no PHY IRQ, use a timer to poll the PHY */ | ||
1158 | init_timer(&lp->check_timer); | ||
1159 | lp->check_timer.data = (unsigned long)dev; | ||
1160 | lp->check_timer.function = at91ether_check_link; | ||
1161 | } | ||
1162 | 446 | ||
1163 | /* Display ethernet banner */ | 447 | /* Display ethernet banner */ |
1164 | printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%pM)\n", | 448 | netdev_info(dev, "AT91 ethernet at 0x%08lx int=%d (%pM)\n", |
1165 | dev->name, (uint) dev->base_addr, dev->irq, | 449 | dev->base_addr, dev->irq, dev->dev_addr); |
1166 | at91_emac_read(lp, AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-", | ||
1167 | at91_emac_read(lp, AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex", | ||
1168 | dev->dev_addr); | ||
1169 | if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) | ||
1170 | printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); | ||
1171 | else if (lp->phy_type == MII_LXT971A_ID) | ||
1172 | printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); | ||
1173 | else if (lp->phy_type == MII_RTL8201_ID) | ||
1174 | printk(KERN_INFO "%s: Realtek RTL8201(B)L PHY\n", dev->name); | ||
1175 | else if (lp->phy_type == MII_BCM5221_ID) | ||
1176 | printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name); | ||
1177 | else if (lp->phy_type == MII_DP83847_ID) | ||
1178 | printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name); | ||
1179 | else if (lp->phy_type == MII_DP83848_ID) | ||
1180 | printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name); | ||
1181 | else if (lp->phy_type == MII_AC101L_ID) | ||
1182 | printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name); | ||
1183 | else if (lp->phy_type == MII_KS8721_ID) | ||
1184 | printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name); | ||
1185 | else if (lp->phy_type == MII_T78Q21x3_ID) | ||
1186 | printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name); | ||
1187 | else if (lp->phy_type == MII_LAN83C185_ID) | ||
1188 | printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name); | ||
1189 | |||
1190 | clk_disable(lp->ether_clk); /* Disable Peripheral clock */ | ||
1191 | 450 | ||
1192 | return 0; | 451 | return 0; |
1193 | 452 | ||
1194 | 453 | err_out_unregister_netdev: | |
1195 | err_free_dmamem: | 454 | unregister_netdev(dev); |
1196 | platform_set_drvdata(pdev, NULL); | ||
1197 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); | ||
1198 | err_free_irq: | ||
1199 | free_irq(dev->irq, dev); | ||
1200 | err_disable_clock: | 455 | err_disable_clock: |
1201 | clk_disable(lp->ether_clk); | 456 | clk_disable(lp->pclk); |
1202 | clk_put(lp->ether_clk); | ||
1203 | err_ioumap: | ||
1204 | iounmap(lp->emac_base); | ||
1205 | err_free_dev: | 457 | err_free_dev: |
1206 | free_netdev(dev); | 458 | free_netdev(dev); |
1207 | return res; | 459 | return res; |
@@ -1210,38 +462,33 @@ err_free_dev: | |||
1210 | static int __devexit at91ether_remove(struct platform_device *pdev) | 462 | static int __devexit at91ether_remove(struct platform_device *pdev) |
1211 | { | 463 | { |
1212 | struct net_device *dev = platform_get_drvdata(pdev); | 464 | struct net_device *dev = platform_get_drvdata(pdev); |
1213 | struct at91_private *lp = netdev_priv(dev); | 465 | struct macb *lp = netdev_priv(dev); |
1214 | 466 | ||
1215 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) | 467 | if (lp->phy_dev) |
1216 | gpio_free(lp->board_data.phy_irq_pin); | 468 | phy_disconnect(lp->phy_dev); |
1217 | 469 | ||
470 | mdiobus_unregister(lp->mii_bus); | ||
471 | kfree(lp->mii_bus->irq); | ||
472 | mdiobus_free(lp->mii_bus); | ||
1218 | unregister_netdev(dev); | 473 | unregister_netdev(dev); |
1219 | free_irq(dev->irq, dev); | 474 | clk_disable(lp->pclk); |
1220 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); | ||
1221 | clk_put(lp->ether_clk); | ||
1222 | |||
1223 | platform_set_drvdata(pdev, NULL); | ||
1224 | free_netdev(dev); | 475 | free_netdev(dev); |
476 | platform_set_drvdata(pdev, NULL); | ||
477 | |||
1225 | return 0; | 478 | return 0; |
1226 | } | 479 | } |
1227 | 480 | ||
1228 | #ifdef CONFIG_PM | 481 | #ifdef CONFIG_PM |
1229 | |||
1230 | static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) | 482 | static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) |
1231 | { | 483 | { |
1232 | struct net_device *net_dev = platform_get_drvdata(pdev); | 484 | struct net_device *net_dev = platform_get_drvdata(pdev); |
1233 | struct at91_private *lp = netdev_priv(net_dev); | 485 | struct macb *lp = netdev_priv(net_dev); |
1234 | 486 | ||
1235 | if (netif_running(net_dev)) { | 487 | if (netif_running(net_dev)) { |
1236 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) { | ||
1237 | int phy_irq = gpio_to_irq(lp->board_data.phy_irq_pin); | ||
1238 | disable_irq(phy_irq); | ||
1239 | } | ||
1240 | |||
1241 | netif_stop_queue(net_dev); | 488 | netif_stop_queue(net_dev); |
1242 | netif_device_detach(net_dev); | 489 | netif_device_detach(net_dev); |
1243 | 490 | ||
1244 | clk_disable(lp->ether_clk); | 491 | clk_disable(lp->pclk); |
1245 | } | 492 | } |
1246 | return 0; | 493 | return 0; |
1247 | } | 494 | } |
@@ -1249,22 +496,16 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1249 | static int at91ether_resume(struct platform_device *pdev) | 496 | static int at91ether_resume(struct platform_device *pdev) |
1250 | { | 497 | { |
1251 | struct net_device *net_dev = platform_get_drvdata(pdev); | 498 | struct net_device *net_dev = platform_get_drvdata(pdev); |
1252 | struct at91_private *lp = netdev_priv(net_dev); | 499 | struct macb *lp = netdev_priv(net_dev); |
1253 | 500 | ||
1254 | if (netif_running(net_dev)) { | 501 | if (netif_running(net_dev)) { |
1255 | clk_enable(lp->ether_clk); | 502 | clk_enable(lp->pclk); |
1256 | 503 | ||
1257 | netif_device_attach(net_dev); | 504 | netif_device_attach(net_dev); |
1258 | netif_start_queue(net_dev); | 505 | netif_start_queue(net_dev); |
1259 | |||
1260 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) { | ||
1261 | int phy_irq = gpio_to_irq(lp->board_data.phy_irq_pin); | ||
1262 | enable_irq(phy_irq); | ||
1263 | } | ||
1264 | } | 506 | } |
1265 | return 0; | 507 | return 0; |
1266 | } | 508 | } |
1267 | |||
1268 | #else | 509 | #else |
1269 | #define at91ether_suspend NULL | 510 | #define at91ether_suspend NULL |
1270 | #define at91ether_resume NULL | 511 | #define at91ether_resume NULL |
@@ -1275,8 +516,9 @@ static struct platform_driver at91ether_driver = { | |||
1275 | .suspend = at91ether_suspend, | 516 | .suspend = at91ether_suspend, |
1276 | .resume = at91ether_resume, | 517 | .resume = at91ether_resume, |
1277 | .driver = { | 518 | .driver = { |
1278 | .name = DRV_NAME, | 519 | .name = "at91_ether", |
1279 | .owner = THIS_MODULE, | 520 | .owner = THIS_MODULE, |
521 | .of_match_table = of_match_ptr(at91ether_dt_ids), | ||
1280 | }, | 522 | }, |
1281 | }; | 523 | }; |
1282 | 524 | ||
@@ -1296,4 +538,4 @@ module_exit(at91ether_exit) | |||
1296 | MODULE_LICENSE("GPL"); | 538 | MODULE_LICENSE("GPL"); |
1297 | MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); | 539 | MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); |
1298 | MODULE_AUTHOR("Andrew Victor"); | 540 | MODULE_AUTHOR("Andrew Victor"); |
1299 | MODULE_ALIAS("platform:" DRV_NAME); | 541 | MODULE_ALIAS("platform:at91_ether"); |
diff --git a/drivers/net/ethernet/cadence/at91_ether.h b/drivers/net/ethernet/cadence/at91_ether.h deleted file mode 100644 index 0ef6328fa7f8..000000000000 --- a/drivers/net/ethernet/cadence/at91_ether.h +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | /* | ||
2 | * Ethernet driver for the Atmel AT91RM9200 (Thunder) | ||
3 | * | ||
4 | * Copyright (C) SAN People (Pty) Ltd | ||
5 | * | ||
6 | * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. | ||
7 | * Initial version by Rick Bronson. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #ifndef AT91_ETHERNET | ||
16 | #define AT91_ETHERNET | ||
17 | |||
18 | |||
19 | /* Davicom 9161 PHY */ | ||
20 | #define MII_DM9161_ID 0x0181b880 | ||
21 | #define MII_DM9161A_ID 0x0181b8a0 | ||
22 | #define MII_DSCR_REG 16 | ||
23 | #define MII_DSCSR_REG 17 | ||
24 | #define MII_DSINTR_REG 21 | ||
25 | |||
26 | /* Intel LXT971A PHY */ | ||
27 | #define MII_LXT971A_ID 0x001378E0 | ||
28 | #define MII_ISINTE_REG 18 | ||
29 | #define MII_ISINTS_REG 19 | ||
30 | #define MII_LEDCTRL_REG 20 | ||
31 | |||
32 | /* Realtek RTL8201 PHY */ | ||
33 | #define MII_RTL8201_ID 0x00008200 | ||
34 | |||
35 | /* Broadcom BCM5221 PHY */ | ||
36 | #define MII_BCM5221_ID 0x004061e0 | ||
37 | #define MII_BCMINTR_REG 26 | ||
38 | |||
39 | /* National Semiconductor DP83847 */ | ||
40 | #define MII_DP83847_ID 0x20005c30 | ||
41 | |||
42 | /* National Semiconductor DP83848 */ | ||
43 | #define MII_DP83848_ID 0x20005c90 | ||
44 | #define MII_DPPHYSTS_REG 16 | ||
45 | #define MII_DPMICR_REG 17 | ||
46 | #define MII_DPMISR_REG 18 | ||
47 | |||
48 | /* Altima AC101L PHY */ | ||
49 | #define MII_AC101L_ID 0x00225520 | ||
50 | |||
51 | /* Micrel KS8721 PHY */ | ||
52 | #define MII_KS8721_ID 0x00221610 | ||
53 | |||
54 | /* Teridian 78Q2123/78Q2133 */ | ||
55 | #define MII_T78Q21x3_ID 0x000e7230 | ||
56 | #define MII_T78Q21INT_REG 17 | ||
57 | |||
58 | /* SMSC LAN83C185 */ | ||
59 | #define MII_LAN83C185_ID 0x0007C0A0 | ||
60 | |||
61 | /* ........................................................................ */ | ||
62 | |||
63 | #define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */ | ||
64 | #define MAX_RX_DESCR 9 /* max number of receive buffers */ | ||
65 | |||
66 | #define EMAC_DESC_DONE 0x00000001 /* bit for if DMA is done */ | ||
67 | #define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */ | ||
68 | |||
69 | #define EMAC_BROADCAST 0x80000000 /* broadcast address */ | ||
70 | #define EMAC_MULTICAST 0x40000000 /* multicast address */ | ||
71 | #define EMAC_UNICAST 0x20000000 /* unicast address */ | ||
72 | |||
73 | struct rbf_t | ||
74 | { | ||
75 | unsigned int addr; | ||
76 | unsigned long size; | ||
77 | }; | ||
78 | |||
79 | struct recv_desc_bufs | ||
80 | { | ||
81 | struct rbf_t descriptors[MAX_RX_DESCR]; /* must be on sizeof (rbf_t) boundary */ | ||
82 | char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ]; /* must be on long boundary */ | ||
83 | }; | ||
84 | |||
85 | struct at91_private | ||
86 | { | ||
87 | struct mii_if_info mii; /* ethtool support */ | ||
88 | struct macb_platform_data board_data; /* board-specific | ||
89 | * configuration (shared with | ||
90 | * macb for common data */ | ||
91 | void __iomem *emac_base; /* base register address */ | ||
92 | struct clk *ether_clk; /* clock */ | ||
93 | |||
94 | /* PHY */ | ||
95 | unsigned long phy_type; /* type of PHY (PHY_ID) */ | ||
96 | spinlock_t lock; /* lock for MDI interface */ | ||
97 | short phy_media; /* media interface type */ | ||
98 | unsigned short phy_address; /* 5-bit MDI address of PHY (0..31) */ | ||
99 | struct timer_list check_timer; /* Poll link status */ | ||
100 | |||
101 | /* Transmit */ | ||
102 | struct sk_buff *skb; /* holds skb until xmit interrupt completes */ | ||
103 | dma_addr_t skb_physaddr; /* phys addr from pci_map_single */ | ||
104 | int skb_length; /* saved skb length for pci_unmap_single */ | ||
105 | |||
106 | /* Receive */ | ||
107 | int rxBuffIndex; /* index into receive descriptor list */ | ||
108 | struct recv_desc_bufs *dlist; /* descriptor list address */ | ||
109 | struct recv_desc_bufs *dlist_phys; /* descriptor list physical address */ | ||
110 | }; | ||
111 | |||
112 | #endif | ||
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 033064b7b576..1fac769989ad 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -26,37 +26,79 @@ | |||
26 | #include <linux/of.h> | 26 | #include <linux/of.h> |
27 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
28 | #include <linux/of_net.h> | 28 | #include <linux/of_net.h> |
29 | #include <linux/pinctrl/consumer.h> | ||
29 | 30 | ||
30 | #include "macb.h" | 31 | #include "macb.h" |
31 | 32 | ||
32 | #define RX_BUFFER_SIZE 128 | 33 | #define RX_BUFFER_SIZE 128 |
33 | #define RX_RING_SIZE 512 | 34 | #define RX_RING_SIZE 512 /* must be power of 2 */ |
34 | #define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE) | 35 | #define RX_RING_BYTES (sizeof(struct macb_dma_desc) * RX_RING_SIZE) |
35 | 36 | ||
36 | /* Make the IP header word-aligned (the ethernet header is 14 bytes) */ | 37 | #define TX_RING_SIZE 128 /* must be power of 2 */ |
37 | #define RX_OFFSET 2 | 38 | #define TX_RING_BYTES (sizeof(struct macb_dma_desc) * TX_RING_SIZE) |
38 | |||
39 | #define TX_RING_SIZE 128 | ||
40 | #define DEF_TX_RING_PENDING (TX_RING_SIZE - 1) | ||
41 | #define TX_RING_BYTES (sizeof(struct dma_desc) * TX_RING_SIZE) | ||
42 | |||
43 | #define TX_RING_GAP(bp) \ | ||
44 | (TX_RING_SIZE - (bp)->tx_pending) | ||
45 | #define TX_BUFFS_AVAIL(bp) \ | ||
46 | (((bp)->tx_tail <= (bp)->tx_head) ? \ | ||
47 | (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head : \ | ||
48 | (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp)) | ||
49 | #define NEXT_TX(n) (((n) + 1) & (TX_RING_SIZE - 1)) | ||
50 | |||
51 | #define NEXT_RX(n) (((n) + 1) & (RX_RING_SIZE - 1)) | ||
52 | 39 | ||
53 | /* minimum number of free TX descriptors before waking up TX process */ | 40 | /* minimum number of free TX descriptors before waking up TX process */ |
54 | #define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4) | 41 | #define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4) |
55 | 42 | ||
56 | #define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ | 43 | #define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ |
57 | | MACB_BIT(ISR_ROVR)) | 44 | | MACB_BIT(ISR_ROVR)) |
45 | #define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \ | ||
46 | | MACB_BIT(ISR_RLE) \ | ||
47 | | MACB_BIT(TXERR)) | ||
48 | #define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP)) | ||
49 | |||
50 | /* | ||
51 | * Graceful stop timeouts in us. We should allow up to | ||
52 | * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions) | ||
53 | */ | ||
54 | #define MACB_HALT_TIMEOUT 1230 | ||
55 | |||
56 | /* Ring buffer accessors */ | ||
57 | static unsigned int macb_tx_ring_wrap(unsigned int index) | ||
58 | { | ||
59 | return index & (TX_RING_SIZE - 1); | ||
60 | } | ||
61 | |||
62 | static unsigned int macb_tx_ring_avail(struct macb *bp) | ||
63 | { | ||
64 | return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1); | ||
65 | } | ||
66 | |||
67 | static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index) | ||
68 | { | ||
69 | return &bp->tx_ring[macb_tx_ring_wrap(index)]; | ||
70 | } | ||
71 | |||
72 | static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index) | ||
73 | { | ||
74 | return &bp->tx_skb[macb_tx_ring_wrap(index)]; | ||
75 | } | ||
76 | |||
77 | static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index) | ||
78 | { | ||
79 | dma_addr_t offset; | ||
80 | |||
81 | offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc); | ||
82 | |||
83 | return bp->tx_ring_dma + offset; | ||
84 | } | ||
85 | |||
86 | static unsigned int macb_rx_ring_wrap(unsigned int index) | ||
87 | { | ||
88 | return index & (RX_RING_SIZE - 1); | ||
89 | } | ||
90 | |||
91 | static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index) | ||
92 | { | ||
93 | return &bp->rx_ring[macb_rx_ring_wrap(index)]; | ||
94 | } | ||
58 | 95 | ||
59 | static void __macb_set_hwaddr(struct macb *bp) | 96 | static void *macb_rx_buffer(struct macb *bp, unsigned int index) |
97 | { | ||
98 | return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index); | ||
99 | } | ||
100 | |||
101 | void macb_set_hwaddr(struct macb *bp) | ||
60 | { | 102 | { |
61 | u32 bottom; | 103 | u32 bottom; |
62 | u16 top; | 104 | u16 top; |
@@ -66,30 +108,49 @@ static void __macb_set_hwaddr(struct macb *bp) | |||
66 | top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); | 108 | top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); |
67 | macb_or_gem_writel(bp, SA1T, top); | 109 | macb_or_gem_writel(bp, SA1T, top); |
68 | } | 110 | } |
111 | EXPORT_SYMBOL_GPL(macb_set_hwaddr); | ||
69 | 112 | ||
70 | static void __init macb_get_hwaddr(struct macb *bp) | 113 | void macb_get_hwaddr(struct macb *bp) |
71 | { | 114 | { |
115 | struct macb_platform_data *pdata; | ||
72 | u32 bottom; | 116 | u32 bottom; |
73 | u16 top; | 117 | u16 top; |
74 | u8 addr[6]; | 118 | u8 addr[6]; |
119 | int i; | ||
75 | 120 | ||
76 | bottom = macb_or_gem_readl(bp, SA1B); | 121 | pdata = bp->pdev->dev.platform_data; |
77 | top = macb_or_gem_readl(bp, SA1T); | ||
78 | 122 | ||
79 | addr[0] = bottom & 0xff; | 123 | /* Check all 4 address register for vaild address */ |
80 | addr[1] = (bottom >> 8) & 0xff; | 124 | for (i = 0; i < 4; i++) { |
81 | addr[2] = (bottom >> 16) & 0xff; | 125 | bottom = macb_or_gem_readl(bp, SA1B + i * 8); |
82 | addr[3] = (bottom >> 24) & 0xff; | 126 | top = macb_or_gem_readl(bp, SA1T + i * 8); |
83 | addr[4] = top & 0xff; | 127 | |
84 | addr[5] = (top >> 8) & 0xff; | 128 | if (pdata && pdata->rev_eth_addr) { |
129 | addr[5] = bottom & 0xff; | ||
130 | addr[4] = (bottom >> 8) & 0xff; | ||
131 | addr[3] = (bottom >> 16) & 0xff; | ||
132 | addr[2] = (bottom >> 24) & 0xff; | ||
133 | addr[1] = top & 0xff; | ||
134 | addr[0] = (top & 0xff00) >> 8; | ||
135 | } else { | ||
136 | addr[0] = bottom & 0xff; | ||
137 | addr[1] = (bottom >> 8) & 0xff; | ||
138 | addr[2] = (bottom >> 16) & 0xff; | ||
139 | addr[3] = (bottom >> 24) & 0xff; | ||
140 | addr[4] = top & 0xff; | ||
141 | addr[5] = (top >> 8) & 0xff; | ||
142 | } | ||
85 | 143 | ||
86 | if (is_valid_ether_addr(addr)) { | 144 | if (is_valid_ether_addr(addr)) { |
87 | memcpy(bp->dev->dev_addr, addr, sizeof(addr)); | 145 | memcpy(bp->dev->dev_addr, addr, sizeof(addr)); |
88 | } else { | 146 | return; |
89 | netdev_info(bp->dev, "invalid hw address, using random\n"); | 147 | } |
90 | eth_hw_addr_random(bp->dev); | ||
91 | } | 148 | } |
149 | |||
150 | netdev_info(bp->dev, "invalid hw address, using random\n"); | ||
151 | eth_hw_addr_random(bp->dev); | ||
92 | } | 152 | } |
153 | EXPORT_SYMBOL_GPL(macb_get_hwaddr); | ||
93 | 154 | ||
94 | static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | 155 | static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
95 | { | 156 | { |
@@ -152,13 +213,17 @@ static void macb_handle_link_change(struct net_device *dev) | |||
152 | 213 | ||
153 | reg = macb_readl(bp, NCFGR); | 214 | reg = macb_readl(bp, NCFGR); |
154 | reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); | 215 | reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); |
216 | if (macb_is_gem(bp)) | ||
217 | reg &= ~GEM_BIT(GBE); | ||
155 | 218 | ||
156 | if (phydev->duplex) | 219 | if (phydev->duplex) |
157 | reg |= MACB_BIT(FD); | 220 | reg |= MACB_BIT(FD); |
158 | if (phydev->speed == SPEED_100) | 221 | if (phydev->speed == SPEED_100) |
159 | reg |= MACB_BIT(SPD); | 222 | reg |= MACB_BIT(SPD); |
223 | if (phydev->speed == SPEED_1000) | ||
224 | reg |= GEM_BIT(GBE); | ||
160 | 225 | ||
161 | macb_writel(bp, NCFGR, reg); | 226 | macb_or_gem_writel(bp, NCFGR, reg); |
162 | 227 | ||
163 | bp->speed = phydev->speed; | 228 | bp->speed = phydev->speed; |
164 | bp->duplex = phydev->duplex; | 229 | bp->duplex = phydev->duplex; |
@@ -216,7 +281,10 @@ static int macb_mii_probe(struct net_device *dev) | |||
216 | } | 281 | } |
217 | 282 | ||
218 | /* mask with MAC supported features */ | 283 | /* mask with MAC supported features */ |
219 | phydev->supported &= PHY_BASIC_FEATURES; | 284 | if (macb_is_gem(bp)) |
285 | phydev->supported &= PHY_GBIT_FEATURES; | ||
286 | else | ||
287 | phydev->supported &= PHY_BASIC_FEATURES; | ||
220 | 288 | ||
221 | phydev->advertising = phydev->supported; | 289 | phydev->advertising = phydev->supported; |
222 | 290 | ||
@@ -228,7 +296,7 @@ static int macb_mii_probe(struct net_device *dev) | |||
228 | return 0; | 296 | return 0; |
229 | } | 297 | } |
230 | 298 | ||
231 | static int macb_mii_init(struct macb *bp) | 299 | int macb_mii_init(struct macb *bp) |
232 | { | 300 | { |
233 | struct macb_platform_data *pdata; | 301 | struct macb_platform_data *pdata; |
234 | int err = -ENXIO, i; | 302 | int err = -ENXIO, i; |
@@ -284,6 +352,7 @@ err_out_free_mdiobus: | |||
284 | err_out: | 352 | err_out: |
285 | return err; | 353 | return err; |
286 | } | 354 | } |
355 | EXPORT_SYMBOL_GPL(macb_mii_init); | ||
287 | 356 | ||
288 | static void macb_update_stats(struct macb *bp) | 357 | static void macb_update_stats(struct macb *bp) |
289 | { | 358 | { |
@@ -297,93 +366,147 @@ static void macb_update_stats(struct macb *bp) | |||
297 | *p += __raw_readl(reg); | 366 | *p += __raw_readl(reg); |
298 | } | 367 | } |
299 | 368 | ||
300 | static void macb_tx(struct macb *bp) | 369 | static int macb_halt_tx(struct macb *bp) |
301 | { | 370 | { |
302 | unsigned int tail; | 371 | unsigned long halt_time, timeout; |
303 | unsigned int head; | 372 | u32 status; |
304 | u32 status; | ||
305 | 373 | ||
306 | status = macb_readl(bp, TSR); | 374 | macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT)); |
307 | macb_writel(bp, TSR, status); | ||
308 | 375 | ||
309 | netdev_dbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status); | 376 | timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT); |
377 | do { | ||
378 | halt_time = jiffies; | ||
379 | status = macb_readl(bp, TSR); | ||
380 | if (!(status & MACB_BIT(TGO))) | ||
381 | return 0; | ||
310 | 382 | ||
311 | if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) { | 383 | usleep_range(10, 250); |
312 | int i; | 384 | } while (time_before(halt_time, timeout)); |
313 | netdev_err(bp->dev, "TX %s, resetting buffers\n", | ||
314 | status & MACB_BIT(UND) ? | ||
315 | "underrun" : "retry limit exceeded"); | ||
316 | 385 | ||
317 | /* Transfer ongoing, disable transmitter, to avoid confusion */ | 386 | return -ETIMEDOUT; |
318 | if (status & MACB_BIT(TGO)) | 387 | } |
319 | macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE)); | ||
320 | 388 | ||
321 | head = bp->tx_head; | 389 | static void macb_tx_error_task(struct work_struct *work) |
390 | { | ||
391 | struct macb *bp = container_of(work, struct macb, tx_error_task); | ||
392 | struct macb_tx_skb *tx_skb; | ||
393 | struct sk_buff *skb; | ||
394 | unsigned int tail; | ||
322 | 395 | ||
323 | /*Mark all the buffer as used to avoid sending a lost buffer*/ | 396 | netdev_vdbg(bp->dev, "macb_tx_error_task: t = %u, h = %u\n", |
324 | for (i = 0; i < TX_RING_SIZE; i++) | 397 | bp->tx_tail, bp->tx_head); |
325 | bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); | ||
326 | 398 | ||
327 | /* Add wrap bit */ | 399 | /* Make sure nobody is trying to queue up new packets */ |
328 | bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); | 400 | netif_stop_queue(bp->dev); |
329 | 401 | ||
330 | /* free transmit buffer in upper layer*/ | 402 | /* |
331 | for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { | 403 | * Stop transmission now |
332 | struct ring_info *rp = &bp->tx_skb[tail]; | 404 | * (in case we have just queued new packets) |
333 | struct sk_buff *skb = rp->skb; | 405 | */ |
406 | if (macb_halt_tx(bp)) | ||
407 | /* Just complain for now, reinitializing TX path can be good */ | ||
408 | netdev_err(bp->dev, "BUG: halt tx timed out\n"); | ||
334 | 409 | ||
335 | BUG_ON(skb == NULL); | 410 | /* No need for the lock here as nobody will interrupt us anymore */ |
336 | 411 | ||
337 | rmb(); | 412 | /* |
413 | * Treat frames in TX queue including the ones that caused the error. | ||
414 | * Free transmit buffers in upper layer. | ||
415 | */ | ||
416 | for (tail = bp->tx_tail; tail != bp->tx_head; tail++) { | ||
417 | struct macb_dma_desc *desc; | ||
418 | u32 ctrl; | ||
419 | |||
420 | desc = macb_tx_desc(bp, tail); | ||
421 | ctrl = desc->ctrl; | ||
422 | tx_skb = macb_tx_skb(bp, tail); | ||
423 | skb = tx_skb->skb; | ||
424 | |||
425 | if (ctrl & MACB_BIT(TX_USED)) { | ||
426 | netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n", | ||
427 | macb_tx_ring_wrap(tail), skb->data); | ||
428 | bp->stats.tx_packets++; | ||
429 | bp->stats.tx_bytes += skb->len; | ||
430 | } else { | ||
431 | /* | ||
432 | * "Buffers exhausted mid-frame" errors may only happen | ||
433 | * if the driver is buggy, so complain loudly about those. | ||
434 | * Statistics are updated by hardware. | ||
435 | */ | ||
436 | if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED)) | ||
437 | netdev_err(bp->dev, | ||
438 | "BUG: TX buffers exhausted mid-frame\n"); | ||
338 | 439 | ||
339 | dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, | 440 | desc->ctrl = ctrl | MACB_BIT(TX_USED); |
340 | DMA_TO_DEVICE); | ||
341 | rp->skb = NULL; | ||
342 | dev_kfree_skb_irq(skb); | ||
343 | } | 441 | } |
344 | 442 | ||
345 | bp->tx_head = bp->tx_tail = 0; | 443 | dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len, |
346 | 444 | DMA_TO_DEVICE); | |
347 | /* Enable the transmitter again */ | 445 | tx_skb->skb = NULL; |
348 | if (status & MACB_BIT(TGO)) | 446 | dev_kfree_skb(skb); |
349 | macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE)); | ||
350 | } | 447 | } |
351 | 448 | ||
352 | if (!(status & MACB_BIT(COMP))) | 449 | /* Make descriptor updates visible to hardware */ |
353 | /* | 450 | wmb(); |
354 | * This may happen when a buffer becomes complete | 451 | |
355 | * between reading the ISR and scanning the | 452 | /* Reinitialize the TX desc queue */ |
356 | * descriptors. Nothing to worry about. | 453 | macb_writel(bp, TBQP, bp->tx_ring_dma); |
357 | */ | 454 | /* Make TX ring reflect state of hardware */ |
358 | return; | 455 | bp->tx_head = bp->tx_tail = 0; |
456 | |||
457 | /* Now we are ready to start transmission again */ | ||
458 | netif_wake_queue(bp->dev); | ||
459 | |||
460 | /* Housework before enabling TX IRQ */ | ||
461 | macb_writel(bp, TSR, macb_readl(bp, TSR)); | ||
462 | macb_writel(bp, IER, MACB_TX_INT_FLAGS); | ||
463 | } | ||
464 | |||
465 | static void macb_tx_interrupt(struct macb *bp) | ||
466 | { | ||
467 | unsigned int tail; | ||
468 | unsigned int head; | ||
469 | u32 status; | ||
470 | |||
471 | status = macb_readl(bp, TSR); | ||
472 | macb_writel(bp, TSR, status); | ||
473 | |||
474 | netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", | ||
475 | (unsigned long)status); | ||
359 | 476 | ||
360 | head = bp->tx_head; | 477 | head = bp->tx_head; |
361 | for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { | 478 | for (tail = bp->tx_tail; tail != head; tail++) { |
362 | struct ring_info *rp = &bp->tx_skb[tail]; | 479 | struct macb_tx_skb *tx_skb; |
363 | struct sk_buff *skb = rp->skb; | 480 | struct sk_buff *skb; |
364 | u32 bufstat; | 481 | struct macb_dma_desc *desc; |
482 | u32 ctrl; | ||
365 | 483 | ||
366 | BUG_ON(skb == NULL); | 484 | desc = macb_tx_desc(bp, tail); |
367 | 485 | ||
486 | /* Make hw descriptor updates visible to CPU */ | ||
368 | rmb(); | 487 | rmb(); |
369 | bufstat = bp->tx_ring[tail].ctrl; | ||
370 | 488 | ||
371 | if (!(bufstat & MACB_BIT(TX_USED))) | 489 | ctrl = desc->ctrl; |
490 | |||
491 | if (!(ctrl & MACB_BIT(TX_USED))) | ||
372 | break; | 492 | break; |
373 | 493 | ||
374 | netdev_dbg(bp->dev, "skb %u (data %p) TX complete\n", | 494 | tx_skb = macb_tx_skb(bp, tail); |
375 | tail, skb->data); | 495 | skb = tx_skb->skb; |
376 | dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, | 496 | |
497 | netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", | ||
498 | macb_tx_ring_wrap(tail), skb->data); | ||
499 | dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len, | ||
377 | DMA_TO_DEVICE); | 500 | DMA_TO_DEVICE); |
378 | bp->stats.tx_packets++; | 501 | bp->stats.tx_packets++; |
379 | bp->stats.tx_bytes += skb->len; | 502 | bp->stats.tx_bytes += skb->len; |
380 | rp->skb = NULL; | 503 | tx_skb->skb = NULL; |
381 | dev_kfree_skb_irq(skb); | 504 | dev_kfree_skb_irq(skb); |
382 | } | 505 | } |
383 | 506 | ||
384 | bp->tx_tail = tail; | 507 | bp->tx_tail = tail; |
385 | if (netif_queue_stopped(bp->dev) && | 508 | if (netif_queue_stopped(bp->dev) |
386 | TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH) | 509 | && macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH) |
387 | netif_wake_queue(bp->dev); | 510 | netif_wake_queue(bp->dev); |
388 | } | 511 | } |
389 | 512 | ||
@@ -392,31 +515,48 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, | |||
392 | { | 515 | { |
393 | unsigned int len; | 516 | unsigned int len; |
394 | unsigned int frag; | 517 | unsigned int frag; |
395 | unsigned int offset = 0; | 518 | unsigned int offset; |
396 | struct sk_buff *skb; | 519 | struct sk_buff *skb; |
520 | struct macb_dma_desc *desc; | ||
397 | 521 | ||
398 | len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl); | 522 | desc = macb_rx_desc(bp, last_frag); |
523 | len = MACB_BFEXT(RX_FRMLEN, desc->ctrl); | ||
399 | 524 | ||
400 | netdev_dbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n", | 525 | netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n", |
401 | first_frag, last_frag, len); | 526 | macb_rx_ring_wrap(first_frag), |
527 | macb_rx_ring_wrap(last_frag), len); | ||
402 | 528 | ||
403 | skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET); | 529 | /* |
530 | * The ethernet header starts NET_IP_ALIGN bytes into the | ||
531 | * first buffer. Since the header is 14 bytes, this makes the | ||
532 | * payload word-aligned. | ||
533 | * | ||
534 | * Instead of calling skb_reserve(NET_IP_ALIGN), we just copy | ||
535 | * the two padding bytes into the skb so that we avoid hitting | ||
536 | * the slowpath in memcpy(), and pull them off afterwards. | ||
537 | */ | ||
538 | skb = netdev_alloc_skb(bp->dev, len + NET_IP_ALIGN); | ||
404 | if (!skb) { | 539 | if (!skb) { |
405 | bp->stats.rx_dropped++; | 540 | bp->stats.rx_dropped++; |
406 | for (frag = first_frag; ; frag = NEXT_RX(frag)) { | 541 | for (frag = first_frag; ; frag++) { |
407 | bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); | 542 | desc = macb_rx_desc(bp, frag); |
543 | desc->addr &= ~MACB_BIT(RX_USED); | ||
408 | if (frag == last_frag) | 544 | if (frag == last_frag) |
409 | break; | 545 | break; |
410 | } | 546 | } |
547 | |||
548 | /* Make descriptor updates visible to hardware */ | ||
411 | wmb(); | 549 | wmb(); |
550 | |||
412 | return 1; | 551 | return 1; |
413 | } | 552 | } |
414 | 553 | ||
415 | skb_reserve(skb, RX_OFFSET); | 554 | offset = 0; |
555 | len += NET_IP_ALIGN; | ||
416 | skb_checksum_none_assert(skb); | 556 | skb_checksum_none_assert(skb); |
417 | skb_put(skb, len); | 557 | skb_put(skb, len); |
418 | 558 | ||
419 | for (frag = first_frag; ; frag = NEXT_RX(frag)) { | 559 | for (frag = first_frag; ; frag++) { |
420 | unsigned int frag_len = RX_BUFFER_SIZE; | 560 | unsigned int frag_len = RX_BUFFER_SIZE; |
421 | 561 | ||
422 | if (offset + frag_len > len) { | 562 | if (offset + frag_len > len) { |
@@ -424,22 +564,24 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, | |||
424 | frag_len = len - offset; | 564 | frag_len = len - offset; |
425 | } | 565 | } |
426 | skb_copy_to_linear_data_offset(skb, offset, | 566 | skb_copy_to_linear_data_offset(skb, offset, |
427 | (bp->rx_buffers + | 567 | macb_rx_buffer(bp, frag), frag_len); |
428 | (RX_BUFFER_SIZE * frag)), | ||
429 | frag_len); | ||
430 | offset += RX_BUFFER_SIZE; | 568 | offset += RX_BUFFER_SIZE; |
431 | bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); | 569 | desc = macb_rx_desc(bp, frag); |
432 | wmb(); | 570 | desc->addr &= ~MACB_BIT(RX_USED); |
433 | 571 | ||
434 | if (frag == last_frag) | 572 | if (frag == last_frag) |
435 | break; | 573 | break; |
436 | } | 574 | } |
437 | 575 | ||
576 | /* Make descriptor updates visible to hardware */ | ||
577 | wmb(); | ||
578 | |||
579 | __skb_pull(skb, NET_IP_ALIGN); | ||
438 | skb->protocol = eth_type_trans(skb, bp->dev); | 580 | skb->protocol = eth_type_trans(skb, bp->dev); |
439 | 581 | ||
440 | bp->stats.rx_packets++; | 582 | bp->stats.rx_packets++; |
441 | bp->stats.rx_bytes += len; | 583 | bp->stats.rx_bytes += skb->len; |
442 | netdev_dbg(bp->dev, "received skb of length %u, csum: %08x\n", | 584 | netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n", |
443 | skb->len, skb->csum); | 585 | skb->len, skb->csum); |
444 | netif_receive_skb(skb); | 586 | netif_receive_skb(skb); |
445 | 587 | ||
@@ -452,8 +594,12 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin, | |||
452 | { | 594 | { |
453 | unsigned int frag; | 595 | unsigned int frag; |
454 | 596 | ||
455 | for (frag = begin; frag != end; frag = NEXT_RX(frag)) | 597 | for (frag = begin; frag != end; frag++) { |
456 | bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); | 598 | struct macb_dma_desc *desc = macb_rx_desc(bp, frag); |
599 | desc->addr &= ~MACB_BIT(RX_USED); | ||
600 | } | ||
601 | |||
602 | /* Make descriptor updates visible to hardware */ | ||
457 | wmb(); | 603 | wmb(); |
458 | 604 | ||
459 | /* | 605 | /* |
@@ -466,15 +612,18 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin, | |||
466 | static int macb_rx(struct macb *bp, int budget) | 612 | static int macb_rx(struct macb *bp, int budget) |
467 | { | 613 | { |
468 | int received = 0; | 614 | int received = 0; |
469 | unsigned int tail = bp->rx_tail; | 615 | unsigned int tail; |
470 | int first_frag = -1; | 616 | int first_frag = -1; |
471 | 617 | ||
472 | for (; budget > 0; tail = NEXT_RX(tail)) { | 618 | for (tail = bp->rx_tail; budget > 0; tail++) { |
619 | struct macb_dma_desc *desc = macb_rx_desc(bp, tail); | ||
473 | u32 addr, ctrl; | 620 | u32 addr, ctrl; |
474 | 621 | ||
622 | /* Make hw descriptor updates visible to CPU */ | ||
475 | rmb(); | 623 | rmb(); |
476 | addr = bp->rx_ring[tail].addr; | 624 | |
477 | ctrl = bp->rx_ring[tail].ctrl; | 625 | addr = desc->addr; |
626 | ctrl = desc->ctrl; | ||
478 | 627 | ||
479 | if (!(addr & MACB_BIT(RX_USED))) | 628 | if (!(addr & MACB_BIT(RX_USED))) |
480 | break; | 629 | break; |
@@ -517,7 +666,7 @@ static int macb_poll(struct napi_struct *napi, int budget) | |||
517 | 666 | ||
518 | work_done = 0; | 667 | work_done = 0; |
519 | 668 | ||
520 | netdev_dbg(bp->dev, "poll: status = %08lx, budget = %d\n", | 669 | netdev_vdbg(bp->dev, "poll: status = %08lx, budget = %d\n", |
521 | (unsigned long)status, budget); | 670 | (unsigned long)status, budget); |
522 | 671 | ||
523 | work_done = macb_rx(bp, budget); | 672 | work_done = macb_rx(bp, budget); |
@@ -552,10 +701,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
552 | while (status) { | 701 | while (status) { |
553 | /* close possible race with dev_close */ | 702 | /* close possible race with dev_close */ |
554 | if (unlikely(!netif_running(dev))) { | 703 | if (unlikely(!netif_running(dev))) { |
555 | macb_writel(bp, IDR, ~0UL); | 704 | macb_writel(bp, IDR, -1); |
556 | break; | 705 | break; |
557 | } | 706 | } |
558 | 707 | ||
708 | netdev_vdbg(bp->dev, "isr = 0x%08lx\n", (unsigned long)status); | ||
709 | |||
559 | if (status & MACB_RX_INT_FLAGS) { | 710 | if (status & MACB_RX_INT_FLAGS) { |
560 | /* | 711 | /* |
561 | * There's no point taking any more interrupts | 712 | * There's no point taking any more interrupts |
@@ -567,14 +718,19 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
567 | macb_writel(bp, IDR, MACB_RX_INT_FLAGS); | 718 | macb_writel(bp, IDR, MACB_RX_INT_FLAGS); |
568 | 719 | ||
569 | if (napi_schedule_prep(&bp->napi)) { | 720 | if (napi_schedule_prep(&bp->napi)) { |
570 | netdev_dbg(bp->dev, "scheduling RX softirq\n"); | 721 | netdev_vdbg(bp->dev, "scheduling RX softirq\n"); |
571 | __napi_schedule(&bp->napi); | 722 | __napi_schedule(&bp->napi); |
572 | } | 723 | } |
573 | } | 724 | } |
574 | 725 | ||
575 | if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) | | 726 | if (unlikely(status & (MACB_TX_ERR_FLAGS))) { |
576 | MACB_BIT(ISR_RLE))) | 727 | macb_writel(bp, IDR, MACB_TX_INT_FLAGS); |
577 | macb_tx(bp); | 728 | schedule_work(&bp->tx_error_task); |
729 | break; | ||
730 | } | ||
731 | |||
732 | if (status & MACB_BIT(TCOMP)) | ||
733 | macb_tx_interrupt(bp); | ||
578 | 734 | ||
579 | /* | 735 | /* |
580 | * Link change detection isn't possible with RMII, so we'll | 736 | * Link change detection isn't possible with RMII, so we'll |
@@ -626,11 +782,13 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
626 | struct macb *bp = netdev_priv(dev); | 782 | struct macb *bp = netdev_priv(dev); |
627 | dma_addr_t mapping; | 783 | dma_addr_t mapping; |
628 | unsigned int len, entry; | 784 | unsigned int len, entry; |
785 | struct macb_dma_desc *desc; | ||
786 | struct macb_tx_skb *tx_skb; | ||
629 | u32 ctrl; | 787 | u32 ctrl; |
630 | unsigned long flags; | 788 | unsigned long flags; |
631 | 789 | ||
632 | #ifdef DEBUG | 790 | #if defined(DEBUG) && defined(VERBOSE_DEBUG) |
633 | netdev_dbg(bp->dev, | 791 | netdev_vdbg(bp->dev, |
634 | "start_xmit: len %u head %p data %p tail %p end %p\n", | 792 | "start_xmit: len %u head %p data %p tail %p end %p\n", |
635 | skb->len, skb->head, skb->data, | 793 | skb->len, skb->head, skb->data, |
636 | skb_tail_pointer(skb), skb_end_pointer(skb)); | 794 | skb_tail_pointer(skb), skb_end_pointer(skb)); |
@@ -642,7 +800,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
642 | spin_lock_irqsave(&bp->lock, flags); | 800 | spin_lock_irqsave(&bp->lock, flags); |
643 | 801 | ||
644 | /* This is a hard error, log it. */ | 802 | /* This is a hard error, log it. */ |
645 | if (TX_BUFFS_AVAIL(bp) < 1) { | 803 | if (macb_tx_ring_avail(bp) < 1) { |
646 | netif_stop_queue(dev); | 804 | netif_stop_queue(dev); |
647 | spin_unlock_irqrestore(&bp->lock, flags); | 805 | spin_unlock_irqrestore(&bp->lock, flags); |
648 | netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n"); | 806 | netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n"); |
@@ -651,13 +809,16 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
651 | return NETDEV_TX_BUSY; | 809 | return NETDEV_TX_BUSY; |
652 | } | 810 | } |
653 | 811 | ||
654 | entry = bp->tx_head; | 812 | entry = macb_tx_ring_wrap(bp->tx_head); |
655 | netdev_dbg(bp->dev, "Allocated ring entry %u\n", entry); | 813 | bp->tx_head++; |
814 | netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry); | ||
656 | mapping = dma_map_single(&bp->pdev->dev, skb->data, | 815 | mapping = dma_map_single(&bp->pdev->dev, skb->data, |
657 | len, DMA_TO_DEVICE); | 816 | len, DMA_TO_DEVICE); |
658 | bp->tx_skb[entry].skb = skb; | 817 | |
659 | bp->tx_skb[entry].mapping = mapping; | 818 | tx_skb = &bp->tx_skb[entry]; |
660 | netdev_dbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n", | 819 | tx_skb->skb = skb; |
820 | tx_skb->mapping = mapping; | ||
821 | netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n", | ||
661 | skb->data, (unsigned long)mapping); | 822 | skb->data, (unsigned long)mapping); |
662 | 823 | ||
663 | ctrl = MACB_BF(TX_FRMLEN, len); | 824 | ctrl = MACB_BF(TX_FRMLEN, len); |
@@ -665,18 +826,18 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
665 | if (entry == (TX_RING_SIZE - 1)) | 826 | if (entry == (TX_RING_SIZE - 1)) |
666 | ctrl |= MACB_BIT(TX_WRAP); | 827 | ctrl |= MACB_BIT(TX_WRAP); |
667 | 828 | ||
668 | bp->tx_ring[entry].addr = mapping; | 829 | desc = &bp->tx_ring[entry]; |
669 | bp->tx_ring[entry].ctrl = ctrl; | 830 | desc->addr = mapping; |
670 | wmb(); | 831 | desc->ctrl = ctrl; |
671 | 832 | ||
672 | entry = NEXT_TX(entry); | 833 | /* Make newly initialized descriptor visible to hardware */ |
673 | bp->tx_head = entry; | 834 | wmb(); |
674 | 835 | ||
675 | skb_tx_timestamp(skb); | 836 | skb_tx_timestamp(skb); |
676 | 837 | ||
677 | macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); | 838 | macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); |
678 | 839 | ||
679 | if (TX_BUFFS_AVAIL(bp) < 1) | 840 | if (macb_tx_ring_avail(bp) < 1) |
680 | netif_stop_queue(dev); | 841 | netif_stop_queue(dev); |
681 | 842 | ||
682 | spin_unlock_irqrestore(&bp->lock, flags); | 843 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -712,7 +873,7 @@ static int macb_alloc_consistent(struct macb *bp) | |||
712 | { | 873 | { |
713 | int size; | 874 | int size; |
714 | 875 | ||
715 | size = TX_RING_SIZE * sizeof(struct ring_info); | 876 | size = TX_RING_SIZE * sizeof(struct macb_tx_skb); |
716 | bp->tx_skb = kmalloc(size, GFP_KERNEL); | 877 | bp->tx_skb = kmalloc(size, GFP_KERNEL); |
717 | if (!bp->tx_skb) | 878 | if (!bp->tx_skb) |
718 | goto out_err; | 879 | goto out_err; |
@@ -775,9 +936,6 @@ static void macb_init_rings(struct macb *bp) | |||
775 | 936 | ||
776 | static void macb_reset_hw(struct macb *bp) | 937 | static void macb_reset_hw(struct macb *bp) |
777 | { | 938 | { |
778 | /* Make sure we have the write buffer for ourselves */ | ||
779 | wmb(); | ||
780 | |||
781 | /* | 939 | /* |
782 | * Disable RX and TX (XXX: Should we halt the transmission | 940 | * Disable RX and TX (XXX: Should we halt the transmission |
783 | * more gracefully?) | 941 | * more gracefully?) |
@@ -788,11 +946,11 @@ static void macb_reset_hw(struct macb *bp) | |||
788 | macb_writel(bp, NCR, MACB_BIT(CLRSTAT)); | 946 | macb_writel(bp, NCR, MACB_BIT(CLRSTAT)); |
789 | 947 | ||
790 | /* Clear all status flags */ | 948 | /* Clear all status flags */ |
791 | macb_writel(bp, TSR, ~0UL); | 949 | macb_writel(bp, TSR, -1); |
792 | macb_writel(bp, RSR, ~0UL); | 950 | macb_writel(bp, RSR, -1); |
793 | 951 | ||
794 | /* Disable all interrupts */ | 952 | /* Disable all interrupts */ |
795 | macb_writel(bp, IDR, ~0UL); | 953 | macb_writel(bp, IDR, -1); |
796 | macb_readl(bp, ISR); | 954 | macb_readl(bp, ISR); |
797 | } | 955 | } |
798 | 956 | ||
@@ -879,9 +1037,10 @@ static void macb_init_hw(struct macb *bp) | |||
879 | u32 config; | 1037 | u32 config; |
880 | 1038 | ||
881 | macb_reset_hw(bp); | 1039 | macb_reset_hw(bp); |
882 | __macb_set_hwaddr(bp); | 1040 | macb_set_hwaddr(bp); |
883 | 1041 | ||
884 | config = macb_mdc_clk_div(bp); | 1042 | config = macb_mdc_clk_div(bp); |
1043 | config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */ | ||
885 | config |= MACB_BIT(PAE); /* PAuse Enable */ | 1044 | config |= MACB_BIT(PAE); /* PAuse Enable */ |
886 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ | 1045 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ |
887 | config |= MACB_BIT(BIG); /* Receive oversized frames */ | 1046 | config |= MACB_BIT(BIG); /* Receive oversized frames */ |
@@ -891,6 +1050,8 @@ static void macb_init_hw(struct macb *bp) | |||
891 | config |= MACB_BIT(NBC); /* No BroadCast */ | 1050 | config |= MACB_BIT(NBC); /* No BroadCast */ |
892 | config |= macb_dbw(bp); | 1051 | config |= macb_dbw(bp); |
893 | macb_writel(bp, NCFGR, config); | 1052 | macb_writel(bp, NCFGR, config); |
1053 | bp->speed = SPEED_10; | ||
1054 | bp->duplex = DUPLEX_HALF; | ||
894 | 1055 | ||
895 | macb_configure_dma(bp); | 1056 | macb_configure_dma(bp); |
896 | 1057 | ||
@@ -902,13 +1063,8 @@ static void macb_init_hw(struct macb *bp) | |||
902 | macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE)); | 1063 | macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE)); |
903 | 1064 | ||
904 | /* Enable interrupts */ | 1065 | /* Enable interrupts */ |
905 | macb_writel(bp, IER, (MACB_BIT(RCOMP) | 1066 | macb_writel(bp, IER, (MACB_RX_INT_FLAGS |
906 | | MACB_BIT(RXUBR) | 1067 | | MACB_TX_INT_FLAGS |
907 | | MACB_BIT(ISR_TUND) | ||
908 | | MACB_BIT(ISR_RLE) | ||
909 | | MACB_BIT(TXERR) | ||
910 | | MACB_BIT(TCOMP) | ||
911 | | MACB_BIT(ISR_ROVR) | ||
912 | | MACB_BIT(HRESP))); | 1068 | | MACB_BIT(HRESP))); |
913 | 1069 | ||
914 | } | 1070 | } |
@@ -996,7 +1152,7 @@ static void macb_sethashtable(struct net_device *dev) | |||
996 | /* | 1152 | /* |
997 | * Enable/Disable promiscuous and multicast modes. | 1153 | * Enable/Disable promiscuous and multicast modes. |
998 | */ | 1154 | */ |
999 | static void macb_set_rx_mode(struct net_device *dev) | 1155 | void macb_set_rx_mode(struct net_device *dev) |
1000 | { | 1156 | { |
1001 | unsigned long cfg; | 1157 | unsigned long cfg; |
1002 | struct macb *bp = netdev_priv(dev); | 1158 | struct macb *bp = netdev_priv(dev); |
@@ -1028,6 +1184,7 @@ static void macb_set_rx_mode(struct net_device *dev) | |||
1028 | 1184 | ||
1029 | macb_writel(bp, NCFGR, cfg); | 1185 | macb_writel(bp, NCFGR, cfg); |
1030 | } | 1186 | } |
1187 | EXPORT_SYMBOL_GPL(macb_set_rx_mode); | ||
1031 | 1188 | ||
1032 | static int macb_open(struct net_device *dev) | 1189 | static int macb_open(struct net_device *dev) |
1033 | { | 1190 | { |
@@ -1135,7 +1292,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) | |||
1135 | return nstat; | 1292 | return nstat; |
1136 | } | 1293 | } |
1137 | 1294 | ||
1138 | static struct net_device_stats *macb_get_stats(struct net_device *dev) | 1295 | struct net_device_stats *macb_get_stats(struct net_device *dev) |
1139 | { | 1296 | { |
1140 | struct macb *bp = netdev_priv(dev); | 1297 | struct macb *bp = netdev_priv(dev); |
1141 | struct net_device_stats *nstat = &bp->stats; | 1298 | struct net_device_stats *nstat = &bp->stats; |
@@ -1181,6 +1338,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) | |||
1181 | 1338 | ||
1182 | return nstat; | 1339 | return nstat; |
1183 | } | 1340 | } |
1341 | EXPORT_SYMBOL_GPL(macb_get_stats); | ||
1184 | 1342 | ||
1185 | static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1343 | static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
1186 | { | 1344 | { |
@@ -1204,25 +1362,55 @@ static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1204 | return phy_ethtool_sset(phydev, cmd); | 1362 | return phy_ethtool_sset(phydev, cmd); |
1205 | } | 1363 | } |
1206 | 1364 | ||
1207 | static void macb_get_drvinfo(struct net_device *dev, | 1365 | static int macb_get_regs_len(struct net_device *netdev) |
1208 | struct ethtool_drvinfo *info) | 1366 | { |
1367 | return MACB_GREGS_NBR * sizeof(u32); | ||
1368 | } | ||
1369 | |||
1370 | static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
1371 | void *p) | ||
1209 | { | 1372 | { |
1210 | struct macb *bp = netdev_priv(dev); | 1373 | struct macb *bp = netdev_priv(dev); |
1374 | unsigned int tail, head; | ||
1375 | u32 *regs_buff = p; | ||
1376 | |||
1377 | regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1)) | ||
1378 | | MACB_GREGS_VERSION; | ||
1379 | |||
1380 | tail = macb_tx_ring_wrap(bp->tx_tail); | ||
1381 | head = macb_tx_ring_wrap(bp->tx_head); | ||
1382 | |||
1383 | regs_buff[0] = macb_readl(bp, NCR); | ||
1384 | regs_buff[1] = macb_or_gem_readl(bp, NCFGR); | ||
1385 | regs_buff[2] = macb_readl(bp, NSR); | ||
1386 | regs_buff[3] = macb_readl(bp, TSR); | ||
1387 | regs_buff[4] = macb_readl(bp, RBQP); | ||
1388 | regs_buff[5] = macb_readl(bp, TBQP); | ||
1389 | regs_buff[6] = macb_readl(bp, RSR); | ||
1390 | regs_buff[7] = macb_readl(bp, IMR); | ||
1211 | 1391 | ||
1212 | strcpy(info->driver, bp->pdev->dev.driver->name); | 1392 | regs_buff[8] = tail; |
1213 | strcpy(info->version, "$Revision: 1.14 $"); | 1393 | regs_buff[9] = head; |
1214 | strcpy(info->bus_info, dev_name(&bp->pdev->dev)); | 1394 | regs_buff[10] = macb_tx_dma(bp, tail); |
1395 | regs_buff[11] = macb_tx_dma(bp, head); | ||
1396 | |||
1397 | if (macb_is_gem(bp)) { | ||
1398 | regs_buff[12] = gem_readl(bp, USRIO); | ||
1399 | regs_buff[13] = gem_readl(bp, DMACFG); | ||
1400 | } | ||
1215 | } | 1401 | } |
1216 | 1402 | ||
1217 | static const struct ethtool_ops macb_ethtool_ops = { | 1403 | const struct ethtool_ops macb_ethtool_ops = { |
1218 | .get_settings = macb_get_settings, | 1404 | .get_settings = macb_get_settings, |
1219 | .set_settings = macb_set_settings, | 1405 | .set_settings = macb_set_settings, |
1220 | .get_drvinfo = macb_get_drvinfo, | 1406 | .get_regs_len = macb_get_regs_len, |
1407 | .get_regs = macb_get_regs, | ||
1221 | .get_link = ethtool_op_get_link, | 1408 | .get_link = ethtool_op_get_link, |
1222 | .get_ts_info = ethtool_op_get_ts_info, | 1409 | .get_ts_info = ethtool_op_get_ts_info, |
1223 | }; | 1410 | }; |
1411 | EXPORT_SYMBOL_GPL(macb_ethtool_ops); | ||
1224 | 1412 | ||
1225 | static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 1413 | int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
1226 | { | 1414 | { |
1227 | struct macb *bp = netdev_priv(dev); | 1415 | struct macb *bp = netdev_priv(dev); |
1228 | struct phy_device *phydev = bp->phy_dev; | 1416 | struct phy_device *phydev = bp->phy_dev; |
@@ -1235,6 +1423,7 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1235 | 1423 | ||
1236 | return phy_mii_ioctl(phydev, rq, cmd); | 1424 | return phy_mii_ioctl(phydev, rq, cmd); |
1237 | } | 1425 | } |
1426 | EXPORT_SYMBOL_GPL(macb_ioctl); | ||
1238 | 1427 | ||
1239 | static const struct net_device_ops macb_netdev_ops = { | 1428 | static const struct net_device_ops macb_netdev_ops = { |
1240 | .ndo_open = macb_open, | 1429 | .ndo_open = macb_open, |
@@ -1306,6 +1495,7 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1306 | struct phy_device *phydev; | 1495 | struct phy_device *phydev; |
1307 | u32 config; | 1496 | u32 config; |
1308 | int err = -ENXIO; | 1497 | int err = -ENXIO; |
1498 | struct pinctrl *pinctrl; | ||
1309 | 1499 | ||
1310 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1500 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1311 | if (!regs) { | 1501 | if (!regs) { |
@@ -1313,6 +1503,15 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1313 | goto err_out; | 1503 | goto err_out; |
1314 | } | 1504 | } |
1315 | 1505 | ||
1506 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
1507 | if (IS_ERR(pinctrl)) { | ||
1508 | err = PTR_ERR(pinctrl); | ||
1509 | if (err == -EPROBE_DEFER) | ||
1510 | goto err_out; | ||
1511 | |||
1512 | dev_warn(&pdev->dev, "No pinctrl provided\n"); | ||
1513 | } | ||
1514 | |||
1316 | err = -ENOMEM; | 1515 | err = -ENOMEM; |
1317 | dev = alloc_etherdev(sizeof(*bp)); | 1516 | dev = alloc_etherdev(sizeof(*bp)); |
1318 | if (!dev) | 1517 | if (!dev) |
@@ -1328,6 +1527,7 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1328 | bp->dev = dev; | 1527 | bp->dev = dev; |
1329 | 1528 | ||
1330 | spin_lock_init(&bp->lock); | 1529 | spin_lock_init(&bp->lock); |
1530 | INIT_WORK(&bp->tx_error_task, macb_tx_error_task); | ||
1331 | 1531 | ||
1332 | bp->pclk = clk_get(&pdev->dev, "pclk"); | 1532 | bp->pclk = clk_get(&pdev->dev, "pclk"); |
1333 | if (IS_ERR(bp->pclk)) { | 1533 | if (IS_ERR(bp->pclk)) { |
@@ -1384,7 +1584,9 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1384 | bp->phy_interface = err; | 1584 | bp->phy_interface = err; |
1385 | } | 1585 | } |
1386 | 1586 | ||
1387 | if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) | 1587 | if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) |
1588 | macb_or_gem_writel(bp, USRIO, GEM_BIT(RGMII)); | ||
1589 | else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) | ||
1388 | #if defined(CONFIG_ARCH_AT91) | 1590 | #if defined(CONFIG_ARCH_AT91) |
1389 | macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | | 1591 | macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | |
1390 | MACB_BIT(CLKEN))); | 1592 | MACB_BIT(CLKEN))); |
@@ -1398,8 +1600,6 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1398 | macb_or_gem_writel(bp, USRIO, MACB_BIT(MII)); | 1600 | macb_or_gem_writel(bp, USRIO, MACB_BIT(MII)); |
1399 | #endif | 1601 | #endif |
1400 | 1602 | ||
1401 | bp->tx_pending = DEF_TX_RING_PENDING; | ||
1402 | |||
1403 | err = register_netdev(dev); | 1603 | err = register_netdev(dev); |
1404 | if (err) { | 1604 | if (err) { |
1405 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); | 1605 | dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); |
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 335e288f5314..864e38042b2d 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -10,10 +10,15 @@ | |||
10 | #ifndef _MACB_H | 10 | #ifndef _MACB_H |
11 | #define _MACB_H | 11 | #define _MACB_H |
12 | 12 | ||
13 | #define MACB_GREGS_NBR 16 | ||
14 | #define MACB_GREGS_VERSION 1 | ||
15 | |||
13 | /* MACB register offsets */ | 16 | /* MACB register offsets */ |
14 | #define MACB_NCR 0x0000 | 17 | #define MACB_NCR 0x0000 |
15 | #define MACB_NCFGR 0x0004 | 18 | #define MACB_NCFGR 0x0004 |
16 | #define MACB_NSR 0x0008 | 19 | #define MACB_NSR 0x0008 |
20 | #define MACB_TAR 0x000c /* AT91RM9200 only */ | ||
21 | #define MACB_TCR 0x0010 /* AT91RM9200 only */ | ||
17 | #define MACB_TSR 0x0014 | 22 | #define MACB_TSR 0x0014 |
18 | #define MACB_RBQP 0x0018 | 23 | #define MACB_RBQP 0x0018 |
19 | #define MACB_TBQP 0x001c | 24 | #define MACB_TBQP 0x001c |
@@ -133,6 +138,8 @@ | |||
133 | #define MACB_RTY_SIZE 1 | 138 | #define MACB_RTY_SIZE 1 |
134 | #define MACB_PAE_OFFSET 13 | 139 | #define MACB_PAE_OFFSET 13 |
135 | #define MACB_PAE_SIZE 1 | 140 | #define MACB_PAE_SIZE 1 |
141 | #define MACB_RM9200_RMII_OFFSET 13 /* AT91RM9200 only */ | ||
142 | #define MACB_RM9200_RMII_SIZE 1 /* AT91RM9200 only */ | ||
136 | #define MACB_RBOF_OFFSET 14 | 143 | #define MACB_RBOF_OFFSET 14 |
137 | #define MACB_RBOF_SIZE 2 | 144 | #define MACB_RBOF_SIZE 2 |
138 | #define MACB_RLCE_OFFSET 16 | 145 | #define MACB_RLCE_OFFSET 16 |
@@ -145,6 +152,8 @@ | |||
145 | #define MACB_IRXFCS_SIZE 1 | 152 | #define MACB_IRXFCS_SIZE 1 |
146 | 153 | ||
147 | /* GEM specific NCFGR bitfields. */ | 154 | /* GEM specific NCFGR bitfields. */ |
155 | #define GEM_GBE_OFFSET 10 | ||
156 | #define GEM_GBE_SIZE 1 | ||
148 | #define GEM_CLK_OFFSET 18 | 157 | #define GEM_CLK_OFFSET 18 |
149 | #define GEM_CLK_SIZE 3 | 158 | #define GEM_CLK_SIZE 3 |
150 | #define GEM_DBW_OFFSET 21 | 159 | #define GEM_DBW_OFFSET 21 |
@@ -178,6 +187,8 @@ | |||
178 | #define MACB_TGO_SIZE 1 | 187 | #define MACB_TGO_SIZE 1 |
179 | #define MACB_BEX_OFFSET 4 | 188 | #define MACB_BEX_OFFSET 4 |
180 | #define MACB_BEX_SIZE 1 | 189 | #define MACB_BEX_SIZE 1 |
190 | #define MACB_RM9200_BNQ_OFFSET 4 /* AT91RM9200 only */ | ||
191 | #define MACB_RM9200_BNQ_SIZE 1 /* AT91RM9200 only */ | ||
181 | #define MACB_COMP_OFFSET 5 | 192 | #define MACB_COMP_OFFSET 5 |
182 | #define MACB_COMP_SIZE 1 | 193 | #define MACB_COMP_SIZE 1 |
183 | #define MACB_UND_OFFSET 6 | 194 | #define MACB_UND_OFFSET 6 |
@@ -246,6 +257,8 @@ | |||
246 | /* Bitfields in USRIO (AT91) */ | 257 | /* Bitfields in USRIO (AT91) */ |
247 | #define MACB_RMII_OFFSET 0 | 258 | #define MACB_RMII_OFFSET 0 |
248 | #define MACB_RMII_SIZE 1 | 259 | #define MACB_RMII_SIZE 1 |
260 | #define GEM_RGMII_OFFSET 0 /* GEM gigabit mode */ | ||
261 | #define GEM_RGMII_SIZE 1 | ||
249 | #define MACB_CLKEN_OFFSET 1 | 262 | #define MACB_CLKEN_OFFSET 1 |
250 | #define MACB_CLKEN_SIZE 1 | 263 | #define MACB_CLKEN_SIZE 1 |
251 | 264 | ||
@@ -352,7 +365,12 @@ | |||
352 | __v; \ | 365 | __v; \ |
353 | }) | 366 | }) |
354 | 367 | ||
355 | struct dma_desc { | 368 | /** |
369 | * struct macb_dma_desc - Hardware DMA descriptor | ||
370 | * @addr: DMA address of data buffer | ||
371 | * @ctrl: Control and status bits | ||
372 | */ | ||
373 | struct macb_dma_desc { | ||
356 | u32 addr; | 374 | u32 addr; |
357 | u32 ctrl; | 375 | u32 ctrl; |
358 | }; | 376 | }; |
@@ -417,7 +435,12 @@ struct dma_desc { | |||
417 | #define MACB_TX_USED_OFFSET 31 | 435 | #define MACB_TX_USED_OFFSET 31 |
418 | #define MACB_TX_USED_SIZE 1 | 436 | #define MACB_TX_USED_SIZE 1 |
419 | 437 | ||
420 | struct ring_info { | 438 | /** |
439 | * struct macb_tx_skb - data about an skb which is being transmitted | ||
440 | * @skb: skb currently being transmitted | ||
441 | * @mapping: DMA address of the skb's data buffer | ||
442 | */ | ||
443 | struct macb_tx_skb { | ||
421 | struct sk_buff *skb; | 444 | struct sk_buff *skb; |
422 | dma_addr_t mapping; | 445 | dma_addr_t mapping; |
423 | }; | 446 | }; |
@@ -502,12 +525,12 @@ struct macb { | |||
502 | void __iomem *regs; | 525 | void __iomem *regs; |
503 | 526 | ||
504 | unsigned int rx_tail; | 527 | unsigned int rx_tail; |
505 | struct dma_desc *rx_ring; | 528 | struct macb_dma_desc *rx_ring; |
506 | void *rx_buffers; | 529 | void *rx_buffers; |
507 | 530 | ||
508 | unsigned int tx_head, tx_tail; | 531 | unsigned int tx_head, tx_tail; |
509 | struct dma_desc *tx_ring; | 532 | struct macb_dma_desc *tx_ring; |
510 | struct ring_info *tx_skb; | 533 | struct macb_tx_skb *tx_skb; |
511 | 534 | ||
512 | spinlock_t lock; | 535 | spinlock_t lock; |
513 | struct platform_device *pdev; | 536 | struct platform_device *pdev; |
@@ -515,6 +538,7 @@ struct macb { | |||
515 | struct clk *hclk; | 538 | struct clk *hclk; |
516 | struct net_device *dev; | 539 | struct net_device *dev; |
517 | struct napi_struct napi; | 540 | struct napi_struct napi; |
541 | struct work_struct tx_error_task; | ||
518 | struct net_device_stats stats; | 542 | struct net_device_stats stats; |
519 | union { | 543 | union { |
520 | struct macb_stats macb; | 544 | struct macb_stats macb; |
@@ -525,8 +549,6 @@ struct macb { | |||
525 | dma_addr_t tx_ring_dma; | 549 | dma_addr_t tx_ring_dma; |
526 | dma_addr_t rx_buffers_dma; | 550 | dma_addr_t rx_buffers_dma; |
527 | 551 | ||
528 | unsigned int rx_pending, tx_pending; | ||
529 | |||
530 | struct mii_bus *mii_bus; | 552 | struct mii_bus *mii_bus; |
531 | struct phy_device *phy_dev; | 553 | struct phy_device *phy_dev; |
532 | unsigned int link; | 554 | unsigned int link; |
@@ -534,8 +556,22 @@ struct macb { | |||
534 | unsigned int duplex; | 556 | unsigned int duplex; |
535 | 557 | ||
536 | phy_interface_t phy_interface; | 558 | phy_interface_t phy_interface; |
559 | |||
560 | /* AT91RM9200 transmit */ | ||
561 | struct sk_buff *skb; /* holds skb until xmit interrupt completes */ | ||
562 | dma_addr_t skb_physaddr; /* phys addr from pci_map_single */ | ||
563 | int skb_length; /* saved skb length for pci_unmap_single */ | ||
537 | }; | 564 | }; |
538 | 565 | ||
566 | extern const struct ethtool_ops macb_ethtool_ops; | ||
567 | |||
568 | int macb_mii_init(struct macb *bp); | ||
569 | int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | ||
570 | struct net_device_stats *macb_get_stats(struct net_device *dev); | ||
571 | void macb_set_rx_mode(struct net_device *dev); | ||
572 | void macb_set_hwaddr(struct macb *bp); | ||
573 | void macb_get_hwaddr(struct macb *bp); | ||
574 | |||
539 | static inline bool macb_is_gem(struct macb *bp) | 575 | static inline bool macb_is_gem(struct macb *bp) |
540 | { | 576 | { |
541 | return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2; | 577 | return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2; |
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 16814b34d4b6..b407043ce9b0 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c | |||
@@ -191,6 +191,7 @@ | |||
191 | #define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ | 191 | #define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */ |
192 | #define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ | 192 | #define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */ |
193 | #define DMA_CONTROL_DFF 0x01000000 /* Disable flush of rx frames */ | 193 | #define DMA_CONTROL_DFF 0x01000000 /* Disable flush of rx frames */ |
194 | #define DMA_CONTROL_OSF 0x00000004 /* Operate on 2nd tx frame */ | ||
194 | 195 | ||
195 | /* DMA Normal interrupt */ | 196 | /* DMA Normal interrupt */ |
196 | #define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */ | 197 | #define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */ |
@@ -210,7 +211,7 @@ | |||
210 | #define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */ | 211 | #define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */ |
211 | 212 | ||
212 | #define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ | 213 | #define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \ |
213 | DMA_INTR_ENA_TUE) | 214 | DMA_INTR_ENA_TUE | DMA_INTR_ENA_TIE) |
214 | 215 | ||
215 | #define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \ | 216 | #define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \ |
216 | DMA_INTR_ENA_RWE | DMA_INTR_ENA_RSE | \ | 217 | DMA_INTR_ENA_RWE | DMA_INTR_ENA_RSE | \ |
@@ -373,6 +374,7 @@ struct xgmac_priv { | |||
373 | struct sk_buff **tx_skbuff; | 374 | struct sk_buff **tx_skbuff; |
374 | unsigned int tx_head; | 375 | unsigned int tx_head; |
375 | unsigned int tx_tail; | 376 | unsigned int tx_tail; |
377 | int tx_irq_cnt; | ||
376 | 378 | ||
377 | void __iomem *base; | 379 | void __iomem *base; |
378 | unsigned int dma_buf_sz; | 380 | unsigned int dma_buf_sz; |
@@ -663,6 +665,7 @@ static void xgmac_rx_refill(struct xgmac_priv *priv) | |||
663 | { | 665 | { |
664 | struct xgmac_dma_desc *p; | 666 | struct xgmac_dma_desc *p; |
665 | dma_addr_t paddr; | 667 | dma_addr_t paddr; |
668 | int bufsz = priv->dev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||
666 | 669 | ||
667 | while (dma_ring_space(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ) > 1) { | 670 | while (dma_ring_space(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ) > 1) { |
668 | int entry = priv->rx_head; | 671 | int entry = priv->rx_head; |
@@ -671,13 +674,13 @@ static void xgmac_rx_refill(struct xgmac_priv *priv) | |||
671 | p = priv->dma_rx + entry; | 674 | p = priv->dma_rx + entry; |
672 | 675 | ||
673 | if (priv->rx_skbuff[entry] == NULL) { | 676 | if (priv->rx_skbuff[entry] == NULL) { |
674 | skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz); | 677 | skb = netdev_alloc_skb_ip_align(priv->dev, bufsz); |
675 | if (unlikely(skb == NULL)) | 678 | if (unlikely(skb == NULL)) |
676 | break; | 679 | break; |
677 | 680 | ||
678 | priv->rx_skbuff[entry] = skb; | 681 | priv->rx_skbuff[entry] = skb; |
679 | paddr = dma_map_single(priv->device, skb->data, | 682 | paddr = dma_map_single(priv->device, skb->data, |
680 | priv->dma_buf_sz, DMA_FROM_DEVICE); | 683 | bufsz, DMA_FROM_DEVICE); |
681 | desc_set_buf_addr(p, paddr, priv->dma_buf_sz); | 684 | desc_set_buf_addr(p, paddr, priv->dma_buf_sz); |
682 | } | 685 | } |
683 | 686 | ||
@@ -701,10 +704,10 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev) | |||
701 | unsigned int bfsize; | 704 | unsigned int bfsize; |
702 | 705 | ||
703 | /* Set the Buffer size according to the MTU; | 706 | /* Set the Buffer size according to the MTU; |
704 | * indeed, in case of jumbo we need to bump-up the buffer sizes. | 707 | * The total buffer size including any IP offset must be a multiple |
708 | * of 8 bytes. | ||
705 | */ | 709 | */ |
706 | bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN + 64, | 710 | bfsize = ALIGN(dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN, 8); |
707 | 64); | ||
708 | 711 | ||
709 | netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); | 712 | netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); |
710 | 713 | ||
@@ -845,9 +848,6 @@ static void xgmac_free_dma_desc_rings(struct xgmac_priv *priv) | |||
845 | static void xgmac_tx_complete(struct xgmac_priv *priv) | 848 | static void xgmac_tx_complete(struct xgmac_priv *priv) |
846 | { | 849 | { |
847 | int i; | 850 | int i; |
848 | void __iomem *ioaddr = priv->base; | ||
849 | |||
850 | writel(DMA_STATUS_TU | DMA_STATUS_NIS, ioaddr + XGMAC_DMA_STATUS); | ||
851 | 851 | ||
852 | while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) { | 852 | while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) { |
853 | unsigned int entry = priv->tx_tail; | 853 | unsigned int entry = priv->tx_tail; |
@@ -888,7 +888,7 @@ static void xgmac_tx_complete(struct xgmac_priv *priv) | |||
888 | } | 888 | } |
889 | 889 | ||
890 | if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) > | 890 | if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) > |
891 | TX_THRESH) | 891 | MAX_SKB_FRAGS) |
892 | netif_wake_queue(priv->dev); | 892 | netif_wake_queue(priv->dev); |
893 | } | 893 | } |
894 | 894 | ||
@@ -965,8 +965,7 @@ static int xgmac_hw_init(struct net_device *dev) | |||
965 | ctrl |= XGMAC_CONTROL_IPC; | 965 | ctrl |= XGMAC_CONTROL_IPC; |
966 | writel(ctrl, ioaddr + XGMAC_CONTROL); | 966 | writel(ctrl, ioaddr + XGMAC_CONTROL); |
967 | 967 | ||
968 | value = DMA_CONTROL_DFF; | 968 | writel(DMA_CONTROL_OSF, ioaddr + XGMAC_DMA_CONTROL); |
969 | writel(value, ioaddr + XGMAC_DMA_CONTROL); | ||
970 | 969 | ||
971 | /* Set the HW DMA mode and the COE */ | 970 | /* Set the HW DMA mode and the COE */ |
972 | writel(XGMAC_OMR_TSF | XGMAC_OMR_RFD | XGMAC_OMR_RFA | | 971 | writel(XGMAC_OMR_TSF | XGMAC_OMR_RFD | XGMAC_OMR_RFA | |
@@ -1060,19 +1059,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1060 | struct xgmac_priv *priv = netdev_priv(dev); | 1059 | struct xgmac_priv *priv = netdev_priv(dev); |
1061 | unsigned int entry; | 1060 | unsigned int entry; |
1062 | int i; | 1061 | int i; |
1062 | u32 irq_flag; | ||
1063 | int nfrags = skb_shinfo(skb)->nr_frags; | 1063 | int nfrags = skb_shinfo(skb)->nr_frags; |
1064 | struct xgmac_dma_desc *desc, *first; | 1064 | struct xgmac_dma_desc *desc, *first; |
1065 | unsigned int desc_flags; | 1065 | unsigned int desc_flags; |
1066 | unsigned int len; | 1066 | unsigned int len; |
1067 | dma_addr_t paddr; | 1067 | dma_addr_t paddr; |
1068 | 1068 | ||
1069 | if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < | 1069 | priv->tx_irq_cnt = (priv->tx_irq_cnt + 1) & (DMA_TX_RING_SZ/4 - 1); |
1070 | (nfrags + 1)) { | 1070 | irq_flag = priv->tx_irq_cnt ? 0 : TXDESC_INTERRUPT; |
1071 | writel(DMA_INTR_DEFAULT_MASK | DMA_INTR_ENA_TIE, | ||
1072 | priv->base + XGMAC_DMA_INTR_ENA); | ||
1073 | netif_stop_queue(dev); | ||
1074 | return NETDEV_TX_BUSY; | ||
1075 | } | ||
1076 | 1071 | ||
1077 | desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? | 1072 | desc_flags = (skb->ip_summed == CHECKSUM_PARTIAL) ? |
1078 | TXDESC_CSUM_ALL : 0; | 1073 | TXDESC_CSUM_ALL : 0; |
@@ -1113,9 +1108,9 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1113 | /* Interrupt on completition only for the latest segment */ | 1108 | /* Interrupt on completition only for the latest segment */ |
1114 | if (desc != first) | 1109 | if (desc != first) |
1115 | desc_set_tx_owner(desc, desc_flags | | 1110 | desc_set_tx_owner(desc, desc_flags | |
1116 | TXDESC_LAST_SEG | TXDESC_INTERRUPT); | 1111 | TXDESC_LAST_SEG | irq_flag); |
1117 | else | 1112 | else |
1118 | desc_flags |= TXDESC_LAST_SEG | TXDESC_INTERRUPT; | 1113 | desc_flags |= TXDESC_LAST_SEG | irq_flag; |
1119 | 1114 | ||
1120 | /* Set owner on first desc last to avoid race condition */ | 1115 | /* Set owner on first desc last to avoid race condition */ |
1121 | wmb(); | 1116 | wmb(); |
@@ -1124,6 +1119,9 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1124 | priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); | 1119 | priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ); |
1125 | 1120 | ||
1126 | writel(1, priv->base + XGMAC_DMA_TX_POLL); | 1121 | writel(1, priv->base + XGMAC_DMA_TX_POLL); |
1122 | if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) < | ||
1123 | MAX_SKB_FRAGS) | ||
1124 | netif_stop_queue(dev); | ||
1127 | 1125 | ||
1128 | return NETDEV_TX_OK; | 1126 | return NETDEV_TX_OK; |
1129 | } | 1127 | } |
@@ -1139,9 +1137,6 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit) | |||
1139 | struct sk_buff *skb; | 1137 | struct sk_buff *skb; |
1140 | int frame_len; | 1138 | int frame_len; |
1141 | 1139 | ||
1142 | writel(DMA_STATUS_RI | DMA_STATUS_NIS, | ||
1143 | priv->base + XGMAC_DMA_STATUS); | ||
1144 | |||
1145 | entry = priv->rx_tail; | 1140 | entry = priv->rx_tail; |
1146 | p = priv->dma_rx + entry; | 1141 | p = priv->dma_rx + entry; |
1147 | if (desc_get_owner(p)) | 1142 | if (desc_get_owner(p)) |
@@ -1180,8 +1175,6 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit) | |||
1180 | 1175 | ||
1181 | xgmac_rx_refill(priv); | 1176 | xgmac_rx_refill(priv); |
1182 | 1177 | ||
1183 | writel(1, priv->base + XGMAC_DMA_RX_POLL); | ||
1184 | |||
1185 | return count; | 1178 | return count; |
1186 | } | 1179 | } |
1187 | 1180 | ||
@@ -1205,7 +1198,7 @@ static int xgmac_poll(struct napi_struct *napi, int budget) | |||
1205 | 1198 | ||
1206 | if (work_done < budget) { | 1199 | if (work_done < budget) { |
1207 | napi_complete(napi); | 1200 | napi_complete(napi); |
1208 | writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); | 1201 | __raw_writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA); |
1209 | } | 1202 | } |
1210 | return work_done; | 1203 | return work_done; |
1211 | } | 1204 | } |
@@ -1350,7 +1343,7 @@ static irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id) | |||
1350 | struct xgmac_priv *priv = netdev_priv(dev); | 1343 | struct xgmac_priv *priv = netdev_priv(dev); |
1351 | void __iomem *ioaddr = priv->base; | 1344 | void __iomem *ioaddr = priv->base; |
1352 | 1345 | ||
1353 | intr_status = readl(ioaddr + XGMAC_INT_STAT); | 1346 | intr_status = __raw_readl(ioaddr + XGMAC_INT_STAT); |
1354 | if (intr_status & XGMAC_INT_STAT_PMT) { | 1347 | if (intr_status & XGMAC_INT_STAT_PMT) { |
1355 | netdev_dbg(priv->dev, "received Magic frame\n"); | 1348 | netdev_dbg(priv->dev, "received Magic frame\n"); |
1356 | /* clear the PMT bits 5 and 6 by reading the PMT */ | 1349 | /* clear the PMT bits 5 and 6 by reading the PMT */ |
@@ -1368,9 +1361,9 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id) | |||
1368 | struct xgmac_extra_stats *x = &priv->xstats; | 1361 | struct xgmac_extra_stats *x = &priv->xstats; |
1369 | 1362 | ||
1370 | /* read the status register (CSR5) */ | 1363 | /* read the status register (CSR5) */ |
1371 | intr_status = readl(priv->base + XGMAC_DMA_STATUS); | 1364 | intr_status = __raw_readl(priv->base + XGMAC_DMA_STATUS); |
1372 | intr_status &= readl(priv->base + XGMAC_DMA_INTR_ENA); | 1365 | intr_status &= __raw_readl(priv->base + XGMAC_DMA_INTR_ENA); |
1373 | writel(intr_status, priv->base + XGMAC_DMA_STATUS); | 1366 | __raw_writel(intr_status, priv->base + XGMAC_DMA_STATUS); |
1374 | 1367 | ||
1375 | /* It displays the DMA process states (CSR5 register) */ | 1368 | /* It displays the DMA process states (CSR5 register) */ |
1376 | /* ABNORMAL interrupts */ | 1369 | /* ABNORMAL interrupts */ |
@@ -1405,8 +1398,8 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id) | |||
1405 | } | 1398 | } |
1406 | 1399 | ||
1407 | /* TX/RX NORMAL interrupts */ | 1400 | /* TX/RX NORMAL interrupts */ |
1408 | if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU)) { | 1401 | if (intr_status & (DMA_STATUS_RI | DMA_STATUS_TU | DMA_STATUS_TI)) { |
1409 | writel(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); | 1402 | __raw_writel(DMA_INTR_ABNORMAL, priv->base + XGMAC_DMA_INTR_ENA); |
1410 | napi_schedule(&priv->napi); | 1403 | napi_schedule(&priv->napi); |
1411 | } | 1404 | } |
1412 | 1405 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb3/common.h b/drivers/net/ethernet/chelsio/cxgb3/common.h index df01b6343241..8c82248ce416 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/common.h +++ b/drivers/net/ethernet/chelsio/cxgb3/common.h | |||
@@ -42,10 +42,9 @@ | |||
42 | #include <linux/mdio.h> | 42 | #include <linux/mdio.h> |
43 | #include "version.h" | 43 | #include "version.h" |
44 | 44 | ||
45 | #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) | 45 | #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ##__VA_ARGS__) |
46 | #define CH_WARN(adap, fmt, ...) dev_warn(&adap->pdev->dev, fmt, ## __VA_ARGS__) | 46 | #define CH_WARN(adap, fmt, ...) dev_warn(&adap->pdev->dev, fmt, ##__VA_ARGS__) |
47 | #define CH_ALERT(adap, fmt, ...) \ | 47 | #define CH_ALERT(adap, fmt, ...) dev_alert(&adap->pdev->dev, fmt, ##__VA_ARGS__) |
48 | dev_printk(KERN_ALERT, &adap->pdev->dev, fmt, ## __VA_ARGS__) | ||
49 | 48 | ||
50 | /* | 49 | /* |
51 | * More powerful macro that selectively prints messages based on msg_enable. | 50 | * More powerful macro that selectively prints messages based on msg_enable. |
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index a059f0c27e28..2fb01bf18155 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c | |||
@@ -1758,21 +1758,7 @@ static struct pci_driver rio_driver = { | |||
1758 | .remove = __devexit_p(rio_remove1), | 1758 | .remove = __devexit_p(rio_remove1), |
1759 | }; | 1759 | }; |
1760 | 1760 | ||
1761 | static int __init | 1761 | module_pci_driver(rio_driver); |
1762 | rio_init (void) | ||
1763 | { | ||
1764 | return pci_register_driver(&rio_driver); | ||
1765 | } | ||
1766 | |||
1767 | static void __exit | ||
1768 | rio_exit (void) | ||
1769 | { | ||
1770 | pci_unregister_driver (&rio_driver); | ||
1771 | } | ||
1772 | |||
1773 | module_init (rio_init); | ||
1774 | module_exit (rio_exit); | ||
1775 | |||
1776 | /* | 1762 | /* |
1777 | 1763 | ||
1778 | Compile command: | 1764 | Compile command: |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index cf4c05bdf5fe..abf26c7c1d19 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "be_hw.h" | 34 | #include "be_hw.h" |
35 | #include "be_roce.h" | 35 | #include "be_roce.h" |
36 | 36 | ||
37 | #define DRV_VER "4.4.31.0u" | 37 | #define DRV_VER "4.4.161.0u" |
38 | #define DRV_NAME "be2net" | 38 | #define DRV_NAME "be2net" |
39 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" | 39 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" |
40 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" | 40 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" |
@@ -53,6 +53,7 @@ | |||
53 | #define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ | 53 | #define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ |
54 | #define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */ | 54 | #define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */ |
55 | #define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */ | 55 | #define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */ |
56 | #define OC_DEVICE_ID6 0x728 /* Device id for VF in SkyHawk */ | ||
56 | #define OC_SUBSYS_DEVICE_ID1 0xE602 | 57 | #define OC_SUBSYS_DEVICE_ID1 0xE602 |
57 | #define OC_SUBSYS_DEVICE_ID2 0xE642 | 58 | #define OC_SUBSYS_DEVICE_ID2 0xE642 |
58 | #define OC_SUBSYS_DEVICE_ID3 0xE612 | 59 | #define OC_SUBSYS_DEVICE_ID3 0xE612 |
@@ -71,6 +72,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
71 | case BE_DEVICE_ID2: | 72 | case BE_DEVICE_ID2: |
72 | return BE3_NAME; | 73 | return BE3_NAME; |
73 | case OC_DEVICE_ID5: | 74 | case OC_DEVICE_ID5: |
75 | case OC_DEVICE_ID6: | ||
74 | return OC_NAME_SH; | 76 | return OC_NAME_SH; |
75 | default: | 77 | default: |
76 | return BE_NAME; | 78 | return BE_NAME; |
@@ -346,7 +348,6 @@ struct be_adapter { | |||
346 | struct pci_dev *pdev; | 348 | struct pci_dev *pdev; |
347 | struct net_device *netdev; | 349 | struct net_device *netdev; |
348 | 350 | ||
349 | u8 __iomem *csr; | ||
350 | u8 __iomem *db; /* Door Bell */ | 351 | u8 __iomem *db; /* Door Bell */ |
351 | 352 | ||
352 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ | 353 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ |
@@ -374,11 +375,8 @@ struct be_adapter { | |||
374 | struct be_rx_obj rx_obj[MAX_RX_QS]; | 375 | struct be_rx_obj rx_obj[MAX_RX_QS]; |
375 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ | 376 | u32 big_page_size; /* Compounded page size shared by rx wrbs */ |
376 | 377 | ||
377 | u8 eq_next_idx; | ||
378 | struct be_drv_stats drv_stats; | 378 | struct be_drv_stats drv_stats; |
379 | |||
380 | u16 vlans_added; | 379 | u16 vlans_added; |
381 | u16 max_vlans; /* Number of vlans supported */ | ||
382 | u8 vlan_tag[VLAN_N_VID]; | 380 | u8 vlan_tag[VLAN_N_VID]; |
383 | u8 vlan_prio_bmap; /* Available Priority BitMap */ | 381 | u8 vlan_prio_bmap; /* Available Priority BitMap */ |
384 | u16 recommended_prio; /* Recommended Priority */ | 382 | u16 recommended_prio; /* Recommended Priority */ |
@@ -391,6 +389,7 @@ struct be_adapter { | |||
391 | 389 | ||
392 | struct delayed_work func_recovery_work; | 390 | struct delayed_work func_recovery_work; |
393 | u32 flags; | 391 | u32 flags; |
392 | u32 cmd_privileges; | ||
394 | /* Ethtool knobs and info */ | 393 | /* Ethtool knobs and info */ |
395 | char fw_ver[FW_VER_LEN]; | 394 | char fw_ver[FW_VER_LEN]; |
396 | int if_handle; /* Used to configure filtering */ | 395 | int if_handle; /* Used to configure filtering */ |
@@ -408,10 +407,8 @@ struct be_adapter { | |||
408 | u32 rx_fc; /* Rx flow control */ | 407 | u32 rx_fc; /* Rx flow control */ |
409 | u32 tx_fc; /* Tx flow control */ | 408 | u32 tx_fc; /* Tx flow control */ |
410 | bool stats_cmd_sent; | 409 | bool stats_cmd_sent; |
411 | u8 generation; /* BladeEngine ASIC generation */ | ||
412 | u32 if_type; | 410 | u32 if_type; |
413 | struct { | 411 | struct { |
414 | u8 __iomem *base; /* Door Bell */ | ||
415 | u32 size; | 412 | u32 size; |
416 | u32 total_size; | 413 | u32 total_size; |
417 | u64 io_addr; | 414 | u64 io_addr; |
@@ -434,10 +431,18 @@ struct be_adapter { | |||
434 | struct phy_info phy; | 431 | struct phy_info phy; |
435 | u8 wol_cap; | 432 | u8 wol_cap; |
436 | bool wol; | 433 | bool wol; |
437 | u32 max_pmac_cnt; /* Max secondary UC MACs programmable */ | ||
438 | u32 uc_macs; /* Count of secondary UC MAC programmed */ | 434 | u32 uc_macs; /* Count of secondary UC MAC programmed */ |
439 | u32 msg_enable; | 435 | u32 msg_enable; |
440 | int be_get_temp_freq; | 436 | int be_get_temp_freq; |
437 | u16 max_mcast_mac; | ||
438 | u16 max_tx_queues; | ||
439 | u16 max_rss_queues; | ||
440 | u16 max_rx_queues; | ||
441 | u16 max_pmac_cnt; | ||
442 | u16 max_vlans; | ||
443 | u16 max_event_queues; | ||
444 | u32 if_cap_flags; | ||
445 | u8 pf_number; | ||
441 | }; | 446 | }; |
442 | 447 | ||
443 | #define be_physfn(adapter) (!adapter->virtfn) | 448 | #define be_physfn(adapter) (!adapter->virtfn) |
@@ -448,21 +453,25 @@ struct be_adapter { | |||
448 | for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ | 453 | for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ |
449 | i++, vf_cfg++) | 454 | i++, vf_cfg++) |
450 | 455 | ||
451 | /* BladeEngine Generation numbers */ | ||
452 | #define BE_GEN2 2 | ||
453 | #define BE_GEN3 3 | ||
454 | |||
455 | #define ON 1 | 456 | #define ON 1 |
456 | #define OFF 0 | 457 | #define OFF 0 |
457 | #define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ | ||
458 | (adapter->pdev->device == OC_DEVICE_ID4)) | ||
459 | 458 | ||
460 | #define skyhawk_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID5) | 459 | #define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3 || \ |
460 | adapter->pdev->device == OC_DEVICE_ID4) | ||
461 | |||
462 | #define skyhawk_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID5 || \ | ||
463 | adapter->pdev->device == OC_DEVICE_ID6) | ||
464 | |||
465 | #define BE3_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID2 || \ | ||
466 | adapter->pdev->device == OC_DEVICE_ID2) | ||
461 | 467 | ||
468 | #define BE2_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID1 || \ | ||
469 | adapter->pdev->device == OC_DEVICE_ID1) | ||
462 | 470 | ||
463 | #define be_roce_supported(adapter) ((adapter->if_type == SLI_INTF_TYPE_3 || \ | 471 | #define BEx_chip(adapter) (BE3_chip(adapter) || BE2_chip(adapter)) |
464 | adapter->sli_family == SKYHAWK_SLI_FAMILY) && \ | 472 | |
465 | (adapter->function_mode & RDMA_ENABLED)) | 473 | #define be_roce_supported(adapter) (skyhawk_chip(adapter) && \ |
474 | (adapter->function_mode & RDMA_ENABLED)) | ||
466 | 475 | ||
467 | extern const struct ethtool_ops be_ethtool_ops; | 476 | extern const struct ethtool_ops be_ethtool_ops; |
468 | 477 | ||
@@ -637,12 +646,6 @@ static inline bool be_is_wol_excluded(struct be_adapter *adapter) | |||
637 | } | 646 | } |
638 | } | 647 | } |
639 | 648 | ||
640 | static inline bool be_type_2_3(struct be_adapter *adapter) | ||
641 | { | ||
642 | return (adapter->if_type == SLI_INTF_TYPE_2 || | ||
643 | adapter->if_type == SLI_INTF_TYPE_3) ? true : false; | ||
644 | } | ||
645 | |||
646 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 649 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
647 | u16 num_popped); | 650 | u16 num_popped); |
648 | extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); | 651 | extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index af60bb26e330..f2875aa47661 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -19,6 +19,55 @@ | |||
19 | #include "be.h" | 19 | #include "be.h" |
20 | #include "be_cmds.h" | 20 | #include "be_cmds.h" |
21 | 21 | ||
22 | static struct be_cmd_priv_map cmd_priv_map[] = { | ||
23 | { | ||
24 | OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, | ||
25 | CMD_SUBSYSTEM_ETH, | ||
26 | BE_PRIV_LNKMGMT | BE_PRIV_VHADM | | ||
27 | BE_PRIV_DEVCFG | BE_PRIV_DEVSEC | ||
28 | }, | ||
29 | { | ||
30 | OPCODE_COMMON_GET_FLOW_CONTROL, | ||
31 | CMD_SUBSYSTEM_COMMON, | ||
32 | BE_PRIV_LNKQUERY | BE_PRIV_VHADM | | ||
33 | BE_PRIV_DEVCFG | BE_PRIV_DEVSEC | ||
34 | }, | ||
35 | { | ||
36 | OPCODE_COMMON_SET_FLOW_CONTROL, | ||
37 | CMD_SUBSYSTEM_COMMON, | ||
38 | BE_PRIV_LNKMGMT | BE_PRIV_VHADM | | ||
39 | BE_PRIV_DEVCFG | BE_PRIV_DEVSEC | ||
40 | }, | ||
41 | { | ||
42 | OPCODE_ETH_GET_PPORT_STATS, | ||
43 | CMD_SUBSYSTEM_ETH, | ||
44 | BE_PRIV_LNKMGMT | BE_PRIV_VHADM | | ||
45 | BE_PRIV_DEVCFG | BE_PRIV_DEVSEC | ||
46 | }, | ||
47 | { | ||
48 | OPCODE_COMMON_GET_PHY_DETAILS, | ||
49 | CMD_SUBSYSTEM_COMMON, | ||
50 | BE_PRIV_LNKMGMT | BE_PRIV_VHADM | | ||
51 | BE_PRIV_DEVCFG | BE_PRIV_DEVSEC | ||
52 | } | ||
53 | }; | ||
54 | |||
55 | static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, | ||
56 | u8 subsystem) | ||
57 | { | ||
58 | int i; | ||
59 | int num_entries = sizeof(cmd_priv_map)/sizeof(struct be_cmd_priv_map); | ||
60 | u32 cmd_privileges = adapter->cmd_privileges; | ||
61 | |||
62 | for (i = 0; i < num_entries; i++) | ||
63 | if (opcode == cmd_priv_map[i].opcode && | ||
64 | subsystem == cmd_priv_map[i].subsystem) | ||
65 | if (!(cmd_privileges & cmd_priv_map[i].priv_mask)) | ||
66 | return false; | ||
67 | |||
68 | return true; | ||
69 | } | ||
70 | |||
22 | static inline void *embedded_payload(struct be_mcc_wrb *wrb) | 71 | static inline void *embedded_payload(struct be_mcc_wrb *wrb) |
23 | { | 72 | { |
24 | return wrb->payload.embedded_payload; | 73 | return wrb->payload.embedded_payload; |
@@ -419,14 +468,13 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) | |||
419 | static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) | 468 | static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) |
420 | { | 469 | { |
421 | u32 sem; | 470 | u32 sem; |
471 | u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH : | ||
472 | SLIPORT_SEMAPHORE_OFFSET_BE; | ||
422 | 473 | ||
423 | if (lancer_chip(adapter)) | 474 | pci_read_config_dword(adapter->pdev, reg, &sem); |
424 | sem = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET); | 475 | *stage = sem & POST_STAGE_MASK; |
425 | else | ||
426 | sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); | ||
427 | 476 | ||
428 | *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; | 477 | if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK) |
429 | if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) | ||
430 | return -1; | 478 | return -1; |
431 | else | 479 | else |
432 | return 0; | 480 | return 0; |
@@ -452,10 +500,33 @@ int lancer_wait_ready(struct be_adapter *adapter) | |||
452 | return status; | 500 | return status; |
453 | } | 501 | } |
454 | 502 | ||
503 | static bool lancer_provisioning_error(struct be_adapter *adapter) | ||
504 | { | ||
505 | u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; | ||
506 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | ||
507 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { | ||
508 | sliport_err1 = ioread32(adapter->db + | ||
509 | SLIPORT_ERROR1_OFFSET); | ||
510 | sliport_err2 = ioread32(adapter->db + | ||
511 | SLIPORT_ERROR2_OFFSET); | ||
512 | |||
513 | if (sliport_err1 == SLIPORT_ERROR_NO_RESOURCE1 && | ||
514 | sliport_err2 == SLIPORT_ERROR_NO_RESOURCE2) | ||
515 | return true; | ||
516 | } | ||
517 | return false; | ||
518 | } | ||
519 | |||
455 | int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | 520 | int lancer_test_and_set_rdy_state(struct be_adapter *adapter) |
456 | { | 521 | { |
457 | int status; | 522 | int status; |
458 | u32 sliport_status, err, reset_needed; | 523 | u32 sliport_status, err, reset_needed; |
524 | bool resource_error; | ||
525 | |||
526 | resource_error = lancer_provisioning_error(adapter); | ||
527 | if (resource_error) | ||
528 | return -1; | ||
529 | |||
459 | status = lancer_wait_ready(adapter); | 530 | status = lancer_wait_ready(adapter); |
460 | if (!status) { | 531 | if (!status) { |
461 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | 532 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); |
@@ -477,6 +548,14 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | |||
477 | status = -1; | 548 | status = -1; |
478 | } | 549 | } |
479 | } | 550 | } |
551 | /* Stop error recovery if error is not recoverable. | ||
552 | * No resource error is temporary errors and will go away | ||
553 | * when PF provisions resources. | ||
554 | */ | ||
555 | resource_error = lancer_provisioning_error(adapter); | ||
556 | if (status == -1 && !resource_error) | ||
557 | adapter->eeh_error = true; | ||
558 | |||
480 | return status; | 559 | return status; |
481 | } | 560 | } |
482 | 561 | ||
@@ -601,6 +680,9 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter) | |||
601 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 680 | struct be_queue_info *mccq = &adapter->mcc_obj.q; |
602 | struct be_mcc_wrb *wrb; | 681 | struct be_mcc_wrb *wrb; |
603 | 682 | ||
683 | if (!mccq->created) | ||
684 | return NULL; | ||
685 | |||
604 | if (atomic_read(&mccq->used) >= mccq->len) { | 686 | if (atomic_read(&mccq->used) >= mccq->len) { |
605 | dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n"); | 687 | dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n"); |
606 | return NULL; | 688 | return NULL; |
@@ -1155,8 +1237,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
1155 | req->id = cpu_to_le16(q->id); | 1237 | req->id = cpu_to_le16(q->id); |
1156 | 1238 | ||
1157 | status = be_mbox_notify_wait(adapter); | 1239 | status = be_mbox_notify_wait(adapter); |
1158 | if (!status) | 1240 | q->created = false; |
1159 | q->created = false; | ||
1160 | 1241 | ||
1161 | mutex_unlock(&adapter->mbox_lock); | 1242 | mutex_unlock(&adapter->mbox_lock); |
1162 | return status; | 1243 | return status; |
@@ -1183,8 +1264,7 @@ int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q) | |||
1183 | req->id = cpu_to_le16(q->id); | 1264 | req->id = cpu_to_le16(q->id); |
1184 | 1265 | ||
1185 | status = be_mcc_notify_wait(adapter); | 1266 | status = be_mcc_notify_wait(adapter); |
1186 | if (!status) | 1267 | q->created = false; |
1187 | q->created = false; | ||
1188 | 1268 | ||
1189 | err: | 1269 | err: |
1190 | spin_unlock_bh(&adapter->mcc_lock); | 1270 | spin_unlock_bh(&adapter->mcc_lock); |
@@ -1281,7 +1361,8 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) | |||
1281 | be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH, | 1361 | be_wrb_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH, |
1282 | OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb, nonemb_cmd); | 1362 | OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size, wrb, nonemb_cmd); |
1283 | 1363 | ||
1284 | if (adapter->generation == BE_GEN3) | 1364 | /* version 1 of the cmd is not supported only by BE2 */ |
1365 | if (!BE2_chip(adapter)) | ||
1285 | hdr->version = 1; | 1366 | hdr->version = 1; |
1286 | 1367 | ||
1287 | be_mcc_notify(adapter); | 1368 | be_mcc_notify(adapter); |
@@ -1301,6 +1382,10 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter, | |||
1301 | struct lancer_cmd_req_pport_stats *req; | 1382 | struct lancer_cmd_req_pport_stats *req; |
1302 | int status = 0; | 1383 | int status = 0; |
1303 | 1384 | ||
1385 | if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS, | ||
1386 | CMD_SUBSYSTEM_ETH)) | ||
1387 | return -EPERM; | ||
1388 | |||
1304 | spin_lock_bh(&adapter->mcc_lock); | 1389 | spin_lock_bh(&adapter->mcc_lock); |
1305 | 1390 | ||
1306 | wrb = wrb_from_mccq(adapter); | 1391 | wrb = wrb_from_mccq(adapter); |
@@ -1367,7 +1452,8 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed, | |||
1367 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1452 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
1368 | OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); | 1453 | OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); |
1369 | 1454 | ||
1370 | if (adapter->generation == BE_GEN3 || lancer_chip(adapter)) | 1455 | /* version 1 of the cmd is not supported only by BE2 */ |
1456 | if (!BE2_chip(adapter)) | ||
1371 | req->hdr.version = 1; | 1457 | req->hdr.version = 1; |
1372 | 1458 | ||
1373 | req->hdr.domain = dom; | 1459 | req->hdr.domain = dom; |
@@ -1658,9 +1744,9 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) | |||
1658 | /* Reset mcast promisc mode if already set by setting mask | 1744 | /* Reset mcast promisc mode if already set by setting mask |
1659 | * and not setting flags field | 1745 | * and not setting flags field |
1660 | */ | 1746 | */ |
1661 | if (!lancer_chip(adapter) || be_physfn(adapter)) | 1747 | req->if_flags_mask |= |
1662 | req->if_flags_mask |= | 1748 | cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS & |
1663 | cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS); | 1749 | adapter->if_cap_flags); |
1664 | 1750 | ||
1665 | req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev)); | 1751 | req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev)); |
1666 | netdev_for_each_mc_addr(ha, adapter->netdev) | 1752 | netdev_for_each_mc_addr(ha, adapter->netdev) |
@@ -1680,6 +1766,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) | |||
1680 | struct be_cmd_req_set_flow_control *req; | 1766 | struct be_cmd_req_set_flow_control *req; |
1681 | int status; | 1767 | int status; |
1682 | 1768 | ||
1769 | if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL, | ||
1770 | CMD_SUBSYSTEM_COMMON)) | ||
1771 | return -EPERM; | ||
1772 | |||
1683 | spin_lock_bh(&adapter->mcc_lock); | 1773 | spin_lock_bh(&adapter->mcc_lock); |
1684 | 1774 | ||
1685 | wrb = wrb_from_mccq(adapter); | 1775 | wrb = wrb_from_mccq(adapter); |
@@ -1709,6 +1799,10 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) | |||
1709 | struct be_cmd_req_get_flow_control *req; | 1799 | struct be_cmd_req_get_flow_control *req; |
1710 | int status; | 1800 | int status; |
1711 | 1801 | ||
1802 | if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL, | ||
1803 | CMD_SUBSYSTEM_COMMON)) | ||
1804 | return -EPERM; | ||
1805 | |||
1712 | spin_lock_bh(&adapter->mcc_lock); | 1806 | spin_lock_bh(&adapter->mcc_lock); |
1713 | 1807 | ||
1714 | wrb = wrb_from_mccq(adapter); | 1808 | wrb = wrb_from_mccq(adapter); |
@@ -2067,7 +2161,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | |||
2067 | int offset) | 2161 | int offset) |
2068 | { | 2162 | { |
2069 | struct be_mcc_wrb *wrb; | 2163 | struct be_mcc_wrb *wrb; |
2070 | struct be_cmd_write_flashrom *req; | 2164 | struct be_cmd_read_flash_crc *req; |
2071 | int status; | 2165 | int status; |
2072 | 2166 | ||
2073 | spin_lock_bh(&adapter->mcc_lock); | 2167 | spin_lock_bh(&adapter->mcc_lock); |
@@ -2080,7 +2174,8 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | |||
2080 | req = embedded_payload(wrb); | 2174 | req = embedded_payload(wrb); |
2081 | 2175 | ||
2082 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 2176 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
2083 | OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4, wrb, NULL); | 2177 | OPCODE_COMMON_READ_FLASHROM, sizeof(*req), |
2178 | wrb, NULL); | ||
2084 | 2179 | ||
2085 | req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT); | 2180 | req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT); |
2086 | req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT); | 2181 | req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT); |
@@ -2089,7 +2184,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | |||
2089 | 2184 | ||
2090 | status = be_mcc_notify_wait(adapter); | 2185 | status = be_mcc_notify_wait(adapter); |
2091 | if (!status) | 2186 | if (!status) |
2092 | memcpy(flashed_crc, req->params.data_buf, 4); | 2187 | memcpy(flashed_crc, req->crc, 4); |
2093 | 2188 | ||
2094 | err: | 2189 | err: |
2095 | spin_unlock_bh(&adapter->mcc_lock); | 2190 | spin_unlock_bh(&adapter->mcc_lock); |
@@ -2275,6 +2370,10 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) | |||
2275 | struct be_dma_mem cmd; | 2370 | struct be_dma_mem cmd; |
2276 | int status; | 2371 | int status; |
2277 | 2372 | ||
2373 | if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS, | ||
2374 | CMD_SUBSYSTEM_COMMON)) | ||
2375 | return -EPERM; | ||
2376 | |||
2278 | spin_lock_bh(&adapter->mcc_lock); | 2377 | spin_lock_bh(&adapter->mcc_lock); |
2279 | 2378 | ||
2280 | wrb = wrb_from_mccq(adapter); | 2379 | wrb = wrb_from_mccq(adapter); |
@@ -2434,6 +2533,42 @@ err: | |||
2434 | return status; | 2533 | return status; |
2435 | } | 2534 | } |
2436 | 2535 | ||
2536 | /* Get privilege(s) for a function */ | ||
2537 | int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege, | ||
2538 | u32 domain) | ||
2539 | { | ||
2540 | struct be_mcc_wrb *wrb; | ||
2541 | struct be_cmd_req_get_fn_privileges *req; | ||
2542 | int status; | ||
2543 | |||
2544 | spin_lock_bh(&adapter->mcc_lock); | ||
2545 | |||
2546 | wrb = wrb_from_mccq(adapter); | ||
2547 | if (!wrb) { | ||
2548 | status = -EBUSY; | ||
2549 | goto err; | ||
2550 | } | ||
2551 | |||
2552 | req = embedded_payload(wrb); | ||
2553 | |||
2554 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2555 | OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req), | ||
2556 | wrb, NULL); | ||
2557 | |||
2558 | req->hdr.domain = domain; | ||
2559 | |||
2560 | status = be_mcc_notify_wait(adapter); | ||
2561 | if (!status) { | ||
2562 | struct be_cmd_resp_get_fn_privileges *resp = | ||
2563 | embedded_payload(wrb); | ||
2564 | *privilege = le32_to_cpu(resp->privilege_mask); | ||
2565 | } | ||
2566 | |||
2567 | err: | ||
2568 | spin_unlock_bh(&adapter->mcc_lock); | ||
2569 | return status; | ||
2570 | } | ||
2571 | |||
2437 | /* Uses synchronous MCCQ */ | 2572 | /* Uses synchronous MCCQ */ |
2438 | int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, | 2573 | int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, |
2439 | bool *pmac_id_active, u32 *pmac_id, u8 domain) | 2574 | bool *pmac_id_active, u32 *pmac_id, u8 domain) |
@@ -2651,6 +2786,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) | |||
2651 | int payload_len = sizeof(*req); | 2786 | int payload_len = sizeof(*req); |
2652 | struct be_dma_mem cmd; | 2787 | struct be_dma_mem cmd; |
2653 | 2788 | ||
2789 | if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, | ||
2790 | CMD_SUBSYSTEM_ETH)) | ||
2791 | return -EPERM; | ||
2792 | |||
2654 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | 2793 | memset(&cmd, 0, sizeof(struct be_dma_mem)); |
2655 | cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1); | 2794 | cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1); |
2656 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, | 2795 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, |
@@ -2792,6 +2931,240 @@ err: | |||
2792 | return status; | 2931 | return status; |
2793 | } | 2932 | } |
2794 | 2933 | ||
2934 | static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, | ||
2935 | u32 max_buf_size) | ||
2936 | { | ||
2937 | struct be_nic_resource_desc *desc = (struct be_nic_resource_desc *)buf; | ||
2938 | int i; | ||
2939 | |||
2940 | for (i = 0; i < desc_count; i++) { | ||
2941 | desc->desc_len = RESOURCE_DESC_SIZE; | ||
2942 | if (((void *)desc + desc->desc_len) > | ||
2943 | (void *)(buf + max_buf_size)) { | ||
2944 | desc = NULL; | ||
2945 | break; | ||
2946 | } | ||
2947 | |||
2948 | if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_ID) | ||
2949 | break; | ||
2950 | |||
2951 | desc = (void *)desc + desc->desc_len; | ||
2952 | } | ||
2953 | |||
2954 | if (!desc || i == MAX_RESOURCE_DESC) | ||
2955 | return NULL; | ||
2956 | |||
2957 | return desc; | ||
2958 | } | ||
2959 | |||
2960 | /* Uses Mbox */ | ||
2961 | int be_cmd_get_func_config(struct be_adapter *adapter) | ||
2962 | { | ||
2963 | struct be_mcc_wrb *wrb; | ||
2964 | struct be_cmd_req_get_func_config *req; | ||
2965 | int status; | ||
2966 | struct be_dma_mem cmd; | ||
2967 | |||
2968 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | ||
2969 | cmd.size = sizeof(struct be_cmd_resp_get_func_config); | ||
2970 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, | ||
2971 | &cmd.dma); | ||
2972 | if (!cmd.va) { | ||
2973 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | ||
2974 | return -ENOMEM; | ||
2975 | } | ||
2976 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
2977 | return -1; | ||
2978 | |||
2979 | wrb = wrb_from_mbox(adapter); | ||
2980 | if (!wrb) { | ||
2981 | status = -EBUSY; | ||
2982 | goto err; | ||
2983 | } | ||
2984 | |||
2985 | req = cmd.va; | ||
2986 | |||
2987 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2988 | OPCODE_COMMON_GET_FUNC_CONFIG, | ||
2989 | cmd.size, wrb, &cmd); | ||
2990 | |||
2991 | status = be_mbox_notify_wait(adapter); | ||
2992 | if (!status) { | ||
2993 | struct be_cmd_resp_get_func_config *resp = cmd.va; | ||
2994 | u32 desc_count = le32_to_cpu(resp->desc_count); | ||
2995 | struct be_nic_resource_desc *desc; | ||
2996 | |||
2997 | desc = be_get_nic_desc(resp->func_param, desc_count, | ||
2998 | sizeof(resp->func_param)); | ||
2999 | if (!desc) { | ||
3000 | status = -EINVAL; | ||
3001 | goto err; | ||
3002 | } | ||
3003 | |||
3004 | adapter->pf_number = desc->pf_num; | ||
3005 | adapter->max_pmac_cnt = le16_to_cpu(desc->unicast_mac_count); | ||
3006 | adapter->max_vlans = le16_to_cpu(desc->vlan_count); | ||
3007 | adapter->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count); | ||
3008 | adapter->max_tx_queues = le16_to_cpu(desc->txq_count); | ||
3009 | adapter->max_rss_queues = le16_to_cpu(desc->rssq_count); | ||
3010 | adapter->max_rx_queues = le16_to_cpu(desc->rq_count); | ||
3011 | |||
3012 | adapter->max_event_queues = le16_to_cpu(desc->eq_count); | ||
3013 | adapter->if_cap_flags = le32_to_cpu(desc->cap_flags); | ||
3014 | } | ||
3015 | err: | ||
3016 | mutex_unlock(&adapter->mbox_lock); | ||
3017 | pci_free_consistent(adapter->pdev, cmd.size, | ||
3018 | cmd.va, cmd.dma); | ||
3019 | return status; | ||
3020 | } | ||
3021 | |||
3022 | /* Uses sync mcc */ | ||
3023 | int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, | ||
3024 | u8 domain) | ||
3025 | { | ||
3026 | struct be_mcc_wrb *wrb; | ||
3027 | struct be_cmd_req_get_profile_config *req; | ||
3028 | int status; | ||
3029 | struct be_dma_mem cmd; | ||
3030 | |||
3031 | memset(&cmd, 0, sizeof(struct be_dma_mem)); | ||
3032 | cmd.size = sizeof(struct be_cmd_resp_get_profile_config); | ||
3033 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, | ||
3034 | &cmd.dma); | ||
3035 | if (!cmd.va) { | ||
3036 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | ||
3037 | return -ENOMEM; | ||
3038 | } | ||
3039 | |||
3040 | spin_lock_bh(&adapter->mcc_lock); | ||
3041 | |||
3042 | wrb = wrb_from_mccq(adapter); | ||
3043 | if (!wrb) { | ||
3044 | status = -EBUSY; | ||
3045 | goto err; | ||
3046 | } | ||
3047 | |||
3048 | req = cmd.va; | ||
3049 | |||
3050 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3051 | OPCODE_COMMON_GET_PROFILE_CONFIG, | ||
3052 | cmd.size, wrb, &cmd); | ||
3053 | |||
3054 | req->type = ACTIVE_PROFILE_TYPE; | ||
3055 | req->hdr.domain = domain; | ||
3056 | |||
3057 | status = be_mcc_notify_wait(adapter); | ||
3058 | if (!status) { | ||
3059 | struct be_cmd_resp_get_profile_config *resp = cmd.va; | ||
3060 | u32 desc_count = le32_to_cpu(resp->desc_count); | ||
3061 | struct be_nic_resource_desc *desc; | ||
3062 | |||
3063 | desc = be_get_nic_desc(resp->func_param, desc_count, | ||
3064 | sizeof(resp->func_param)); | ||
3065 | |||
3066 | if (!desc) { | ||
3067 | status = -EINVAL; | ||
3068 | goto err; | ||
3069 | } | ||
3070 | *cap_flags = le32_to_cpu(desc->cap_flags); | ||
3071 | } | ||
3072 | err: | ||
3073 | spin_unlock_bh(&adapter->mcc_lock); | ||
3074 | pci_free_consistent(adapter->pdev, cmd.size, | ||
3075 | cmd.va, cmd.dma); | ||
3076 | return status; | ||
3077 | } | ||
3078 | |||
3079 | /* Uses sync mcc */ | ||
3080 | int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, | ||
3081 | u8 domain) | ||
3082 | { | ||
3083 | struct be_mcc_wrb *wrb; | ||
3084 | struct be_cmd_req_set_profile_config *req; | ||
3085 | int status; | ||
3086 | |||
3087 | spin_lock_bh(&adapter->mcc_lock); | ||
3088 | |||
3089 | wrb = wrb_from_mccq(adapter); | ||
3090 | if (!wrb) { | ||
3091 | status = -EBUSY; | ||
3092 | goto err; | ||
3093 | } | ||
3094 | |||
3095 | req = embedded_payload(wrb); | ||
3096 | |||
3097 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3098 | OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req), | ||
3099 | wrb, NULL); | ||
3100 | |||
3101 | req->hdr.domain = domain; | ||
3102 | req->desc_count = cpu_to_le32(1); | ||
3103 | |||
3104 | req->nic_desc.desc_type = NIC_RESOURCE_DESC_TYPE_ID; | ||
3105 | req->nic_desc.desc_len = RESOURCE_DESC_SIZE; | ||
3106 | req->nic_desc.flags = (1 << QUN) | (1 << IMM) | (1 << NOSV); | ||
3107 | req->nic_desc.pf_num = adapter->pf_number; | ||
3108 | req->nic_desc.vf_num = domain; | ||
3109 | |||
3110 | /* Mark fields invalid */ | ||
3111 | req->nic_desc.unicast_mac_count = 0xFFFF; | ||
3112 | req->nic_desc.mcc_count = 0xFFFF; | ||
3113 | req->nic_desc.vlan_count = 0xFFFF; | ||
3114 | req->nic_desc.mcast_mac_count = 0xFFFF; | ||
3115 | req->nic_desc.txq_count = 0xFFFF; | ||
3116 | req->nic_desc.rq_count = 0xFFFF; | ||
3117 | req->nic_desc.rssq_count = 0xFFFF; | ||
3118 | req->nic_desc.lro_count = 0xFFFF; | ||
3119 | req->nic_desc.cq_count = 0xFFFF; | ||
3120 | req->nic_desc.toe_conn_count = 0xFFFF; | ||
3121 | req->nic_desc.eq_count = 0xFFFF; | ||
3122 | req->nic_desc.link_param = 0xFF; | ||
3123 | req->nic_desc.bw_min = 0xFFFFFFFF; | ||
3124 | req->nic_desc.acpi_params = 0xFF; | ||
3125 | req->nic_desc.wol_param = 0x0F; | ||
3126 | |||
3127 | /* Change BW */ | ||
3128 | req->nic_desc.bw_min = cpu_to_le32(bps); | ||
3129 | req->nic_desc.bw_max = cpu_to_le32(bps); | ||
3130 | status = be_mcc_notify_wait(adapter); | ||
3131 | err: | ||
3132 | spin_unlock_bh(&adapter->mcc_lock); | ||
3133 | return status; | ||
3134 | } | ||
3135 | |||
3136 | /* Uses sync mcc */ | ||
3137 | int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) | ||
3138 | { | ||
3139 | struct be_mcc_wrb *wrb; | ||
3140 | struct be_cmd_enable_disable_vf *req; | ||
3141 | int status; | ||
3142 | |||
3143 | if (!lancer_chip(adapter)) | ||
3144 | return 0; | ||
3145 | |||
3146 | spin_lock_bh(&adapter->mcc_lock); | ||
3147 | |||
3148 | wrb = wrb_from_mccq(adapter); | ||
3149 | if (!wrb) { | ||
3150 | status = -EBUSY; | ||
3151 | goto err; | ||
3152 | } | ||
3153 | |||
3154 | req = embedded_payload(wrb); | ||
3155 | |||
3156 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3157 | OPCODE_COMMON_ENABLE_DISABLE_VF, sizeof(*req), | ||
3158 | wrb, NULL); | ||
3159 | |||
3160 | req->hdr.domain = domain; | ||
3161 | req->enable = 1; | ||
3162 | status = be_mcc_notify_wait(adapter); | ||
3163 | err: | ||
3164 | spin_unlock_bh(&adapter->mcc_lock); | ||
3165 | return status; | ||
3166 | } | ||
3167 | |||
2795 | int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, | 3168 | int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, |
2796 | int wrb_payload_size, u16 *cmd_status, u16 *ext_status) | 3169 | int wrb_payload_size, u16 *cmd_status, u16 *ext_status) |
2797 | { | 3170 | { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 0936e21e3cff..d6552e19ffee 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -196,9 +196,14 @@ struct be_mcc_mailbox { | |||
196 | #define OPCODE_COMMON_GET_MAC_LIST 147 | 196 | #define OPCODE_COMMON_GET_MAC_LIST 147 |
197 | #define OPCODE_COMMON_SET_MAC_LIST 148 | 197 | #define OPCODE_COMMON_SET_MAC_LIST 148 |
198 | #define OPCODE_COMMON_GET_HSW_CONFIG 152 | 198 | #define OPCODE_COMMON_GET_HSW_CONFIG 152 |
199 | #define OPCODE_COMMON_GET_FUNC_CONFIG 160 | ||
200 | #define OPCODE_COMMON_GET_PROFILE_CONFIG 164 | ||
201 | #define OPCODE_COMMON_SET_PROFILE_CONFIG 165 | ||
199 | #define OPCODE_COMMON_SET_HSW_CONFIG 153 | 202 | #define OPCODE_COMMON_SET_HSW_CONFIG 153 |
203 | #define OPCODE_COMMON_GET_FN_PRIVILEGES 170 | ||
200 | #define OPCODE_COMMON_READ_OBJECT 171 | 204 | #define OPCODE_COMMON_READ_OBJECT 171 |
201 | #define OPCODE_COMMON_WRITE_OBJECT 172 | 205 | #define OPCODE_COMMON_WRITE_OBJECT 172 |
206 | #define OPCODE_COMMON_ENABLE_DISABLE_VF 196 | ||
202 | 207 | ||
203 | #define OPCODE_ETH_RSS_CONFIG 1 | 208 | #define OPCODE_ETH_RSS_CONFIG 1 |
204 | #define OPCODE_ETH_ACPI_CONFIG 2 | 209 | #define OPCODE_ETH_ACPI_CONFIG 2 |
@@ -1151,14 +1156,22 @@ struct flashrom_params { | |||
1151 | u32 op_type; | 1156 | u32 op_type; |
1152 | u32 data_buf_size; | 1157 | u32 data_buf_size; |
1153 | u32 offset; | 1158 | u32 offset; |
1154 | u8 data_buf[4]; | ||
1155 | }; | 1159 | }; |
1156 | 1160 | ||
1157 | struct be_cmd_write_flashrom { | 1161 | struct be_cmd_write_flashrom { |
1158 | struct be_cmd_req_hdr hdr; | 1162 | struct be_cmd_req_hdr hdr; |
1159 | struct flashrom_params params; | 1163 | struct flashrom_params params; |
1160 | }; | 1164 | u8 data_buf[32768]; |
1165 | u8 rsvd[4]; | ||
1166 | } __packed; | ||
1161 | 1167 | ||
1168 | /* cmd to read flash crc */ | ||
1169 | struct be_cmd_read_flash_crc { | ||
1170 | struct be_cmd_req_hdr hdr; | ||
1171 | struct flashrom_params params; | ||
1172 | u8 crc[4]; | ||
1173 | u8 rsvd[4]; | ||
1174 | }; | ||
1162 | /**************** Lancer Firmware Flash ************/ | 1175 | /**************** Lancer Firmware Flash ************/ |
1163 | struct amap_lancer_write_obj_context { | 1176 | struct amap_lancer_write_obj_context { |
1164 | u8 write_length[24]; | 1177 | u8 write_length[24]; |
@@ -1429,6 +1442,41 @@ struct be_cmd_resp_set_func_cap { | |||
1429 | u8 rsvd[212]; | 1442 | u8 rsvd[212]; |
1430 | }; | 1443 | }; |
1431 | 1444 | ||
1445 | /*********************** Function Privileges ***********************/ | ||
1446 | enum { | ||
1447 | BE_PRIV_DEFAULT = 0x1, | ||
1448 | BE_PRIV_LNKQUERY = 0x2, | ||
1449 | BE_PRIV_LNKSTATS = 0x4, | ||
1450 | BE_PRIV_LNKMGMT = 0x8, | ||
1451 | BE_PRIV_LNKDIAG = 0x10, | ||
1452 | BE_PRIV_UTILQUERY = 0x20, | ||
1453 | BE_PRIV_FILTMGMT = 0x40, | ||
1454 | BE_PRIV_IFACEMGMT = 0x80, | ||
1455 | BE_PRIV_VHADM = 0x100, | ||
1456 | BE_PRIV_DEVCFG = 0x200, | ||
1457 | BE_PRIV_DEVSEC = 0x400 | ||
1458 | }; | ||
1459 | #define MAX_PRIVILEGES (BE_PRIV_VHADM | BE_PRIV_DEVCFG | \ | ||
1460 | BE_PRIV_DEVSEC) | ||
1461 | #define MIN_PRIVILEGES BE_PRIV_DEFAULT | ||
1462 | |||
1463 | struct be_cmd_priv_map { | ||
1464 | u8 opcode; | ||
1465 | u8 subsystem; | ||
1466 | u32 priv_mask; | ||
1467 | }; | ||
1468 | |||
1469 | struct be_cmd_req_get_fn_privileges { | ||
1470 | struct be_cmd_req_hdr hdr; | ||
1471 | u32 rsvd; | ||
1472 | }; | ||
1473 | |||
1474 | struct be_cmd_resp_get_fn_privileges { | ||
1475 | struct be_cmd_resp_hdr hdr; | ||
1476 | u32 privilege_mask; | ||
1477 | }; | ||
1478 | |||
1479 | |||
1432 | /******************** GET/SET_MACLIST **************************/ | 1480 | /******************** GET/SET_MACLIST **************************/ |
1433 | #define BE_MAX_MAC 64 | 1481 | #define BE_MAX_MAC 64 |
1434 | struct be_cmd_req_get_mac_list { | 1482 | struct be_cmd_req_get_mac_list { |
@@ -1608,33 +1656,6 @@ struct be_cmd_resp_get_stats_v1 { | |||
1608 | struct be_hw_stats_v1 hw_stats; | 1656 | struct be_hw_stats_v1 hw_stats; |
1609 | }; | 1657 | }; |
1610 | 1658 | ||
1611 | static inline void *hw_stats_from_cmd(struct be_adapter *adapter) | ||
1612 | { | ||
1613 | if (adapter->generation == BE_GEN3) { | ||
1614 | struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va; | ||
1615 | |||
1616 | return &cmd->hw_stats; | ||
1617 | } else { | ||
1618 | struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va; | ||
1619 | |||
1620 | return &cmd->hw_stats; | ||
1621 | } | ||
1622 | } | ||
1623 | |||
1624 | static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) | ||
1625 | { | ||
1626 | if (adapter->generation == BE_GEN3) { | ||
1627 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
1628 | |||
1629 | return &hw_stats->erx; | ||
1630 | } else { | ||
1631 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
1632 | |||
1633 | return &hw_stats->erx; | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | |||
1638 | /************** get fat capabilites *******************/ | 1659 | /************** get fat capabilites *******************/ |
1639 | #define MAX_MODULES 27 | 1660 | #define MAX_MODULES 27 |
1640 | #define MAX_MODES 4 | 1661 | #define MAX_MODES 4 |
@@ -1684,6 +1705,96 @@ struct be_cmd_req_set_ext_fat_caps { | |||
1684 | struct be_fat_conf_params set_params; | 1705 | struct be_fat_conf_params set_params; |
1685 | }; | 1706 | }; |
1686 | 1707 | ||
1708 | #define RESOURCE_DESC_SIZE 72 | ||
1709 | #define NIC_RESOURCE_DESC_TYPE_ID 0x41 | ||
1710 | #define MAX_RESOURCE_DESC 4 | ||
1711 | |||
1712 | /* QOS unit number */ | ||
1713 | #define QUN 4 | ||
1714 | /* Immediate */ | ||
1715 | #define IMM 6 | ||
1716 | /* No save */ | ||
1717 | #define NOSV 7 | ||
1718 | |||
1719 | struct be_nic_resource_desc { | ||
1720 | u8 desc_type; | ||
1721 | u8 desc_len; | ||
1722 | u8 rsvd1; | ||
1723 | u8 flags; | ||
1724 | u8 vf_num; | ||
1725 | u8 rsvd2; | ||
1726 | u8 pf_num; | ||
1727 | u8 rsvd3; | ||
1728 | u16 unicast_mac_count; | ||
1729 | u8 rsvd4[6]; | ||
1730 | u16 mcc_count; | ||
1731 | u16 vlan_count; | ||
1732 | u16 mcast_mac_count; | ||
1733 | u16 txq_count; | ||
1734 | u16 rq_count; | ||
1735 | u16 rssq_count; | ||
1736 | u16 lro_count; | ||
1737 | u16 cq_count; | ||
1738 | u16 toe_conn_count; | ||
1739 | u16 eq_count; | ||
1740 | u32 rsvd5; | ||
1741 | u32 cap_flags; | ||
1742 | u8 link_param; | ||
1743 | u8 rsvd6[3]; | ||
1744 | u32 bw_min; | ||
1745 | u32 bw_max; | ||
1746 | u8 acpi_params; | ||
1747 | u8 wol_param; | ||
1748 | u16 rsvd7; | ||
1749 | u32 rsvd8[3]; | ||
1750 | }; | ||
1751 | |||
1752 | struct be_cmd_req_get_func_config { | ||
1753 | struct be_cmd_req_hdr hdr; | ||
1754 | }; | ||
1755 | |||
1756 | struct be_cmd_resp_get_func_config { | ||
1757 | struct be_cmd_req_hdr hdr; | ||
1758 | u32 desc_count; | ||
1759 | u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE]; | ||
1760 | }; | ||
1761 | |||
1762 | #define ACTIVE_PROFILE_TYPE 0x2 | ||
1763 | struct be_cmd_req_get_profile_config { | ||
1764 | struct be_cmd_req_hdr hdr; | ||
1765 | u8 rsvd; | ||
1766 | u8 type; | ||
1767 | u16 rsvd1; | ||
1768 | }; | ||
1769 | |||
1770 | struct be_cmd_resp_get_profile_config { | ||
1771 | struct be_cmd_req_hdr hdr; | ||
1772 | u32 desc_count; | ||
1773 | u8 func_param[MAX_RESOURCE_DESC * RESOURCE_DESC_SIZE]; | ||
1774 | }; | ||
1775 | |||
1776 | struct be_cmd_req_set_profile_config { | ||
1777 | struct be_cmd_req_hdr hdr; | ||
1778 | u32 rsvd; | ||
1779 | u32 desc_count; | ||
1780 | struct be_nic_resource_desc nic_desc; | ||
1781 | }; | ||
1782 | |||
1783 | struct be_cmd_resp_set_profile_config { | ||
1784 | struct be_cmd_req_hdr hdr; | ||
1785 | }; | ||
1786 | |||
1787 | struct be_cmd_enable_disable_vf { | ||
1788 | struct be_cmd_req_hdr hdr; | ||
1789 | u8 enable; | ||
1790 | u8 rsvd[3]; | ||
1791 | }; | ||
1792 | |||
1793 | static inline bool check_privilege(struct be_adapter *adapter, u32 flags) | ||
1794 | { | ||
1795 | return flags & adapter->cmd_privileges ? true : false; | ||
1796 | } | ||
1797 | |||
1687 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 1798 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
1688 | extern int be_fw_wait_ready(struct be_adapter *adapter); | 1799 | extern int be_fw_wait_ready(struct be_adapter *adapter); |
1689 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 1800 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -1780,6 +1891,8 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); | |||
1780 | extern int be_cmd_req_native_mode(struct be_adapter *adapter); | 1891 | extern int be_cmd_req_native_mode(struct be_adapter *adapter); |
1781 | extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); | 1892 | extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); |
1782 | extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); | 1893 | extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); |
1894 | extern int be_cmd_get_fn_privileges(struct be_adapter *adapter, | ||
1895 | u32 *privilege, u32 domain); | ||
1783 | extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, | 1896 | extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, |
1784 | bool *pmac_id_active, u32 *pmac_id, | 1897 | bool *pmac_id_active, u32 *pmac_id, |
1785 | u8 domain); | 1898 | u8 domain); |
@@ -1798,4 +1911,10 @@ extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, | |||
1798 | extern int lancer_wait_ready(struct be_adapter *adapter); | 1911 | extern int lancer_wait_ready(struct be_adapter *adapter); |
1799 | extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter); | 1912 | extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter); |
1800 | extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); | 1913 | extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); |
1914 | extern int be_cmd_get_func_config(struct be_adapter *adapter); | ||
1915 | extern int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, | ||
1916 | u8 domain); | ||
1801 | 1917 | ||
1918 | extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, | ||
1919 | u8 domain); | ||
1920 | extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 8e6fb0ba6aa9..00454a10f88d 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -261,6 +261,9 @@ be_get_reg_len(struct net_device *netdev) | |||
261 | struct be_adapter *adapter = netdev_priv(netdev); | 261 | struct be_adapter *adapter = netdev_priv(netdev); |
262 | u32 log_size = 0; | 262 | u32 log_size = 0; |
263 | 263 | ||
264 | if (!check_privilege(adapter, MAX_PRIVILEGES)) | ||
265 | return 0; | ||
266 | |||
264 | if (be_physfn(adapter)) { | 267 | if (be_physfn(adapter)) { |
265 | if (lancer_chip(adapter)) | 268 | if (lancer_chip(adapter)) |
266 | log_size = lancer_cmd_get_file_len(adapter, | 269 | log_size = lancer_cmd_get_file_len(adapter, |
@@ -525,6 +528,10 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
525 | u8 link_status; | 528 | u8 link_status; |
526 | u16 link_speed = 0; | 529 | u16 link_speed = 0; |
527 | int status; | 530 | int status; |
531 | u32 auto_speeds; | ||
532 | u32 fixed_speeds; | ||
533 | u32 dac_cable_len; | ||
534 | u16 interface_type; | ||
528 | 535 | ||
529 | if (adapter->phy.link_speed < 0) { | 536 | if (adapter->phy.link_speed < 0) { |
530 | status = be_cmd_link_status_query(adapter, &link_speed, | 537 | status = be_cmd_link_status_query(adapter, &link_speed, |
@@ -534,39 +541,46 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
534 | ethtool_cmd_speed_set(ecmd, link_speed); | 541 | ethtool_cmd_speed_set(ecmd, link_speed); |
535 | 542 | ||
536 | status = be_cmd_get_phy_info(adapter); | 543 | status = be_cmd_get_phy_info(adapter); |
537 | if (status) | 544 | if (!status) { |
538 | return status; | 545 | interface_type = adapter->phy.interface_type; |
539 | 546 | auto_speeds = adapter->phy.auto_speeds_supported; | |
540 | ecmd->supported = | 547 | fixed_speeds = adapter->phy.fixed_speeds_supported; |
541 | convert_to_et_setting(adapter->phy.interface_type, | 548 | dac_cable_len = adapter->phy.dac_cable_len; |
542 | adapter->phy.auto_speeds_supported | | 549 | |
543 | adapter->phy.fixed_speeds_supported); | 550 | ecmd->supported = |
544 | ecmd->advertising = | 551 | convert_to_et_setting(interface_type, |
545 | convert_to_et_setting(adapter->phy.interface_type, | 552 | auto_speeds | |
546 | adapter->phy.auto_speeds_supported); | 553 | fixed_speeds); |
547 | 554 | ecmd->advertising = | |
548 | ecmd->port = be_get_port_type(adapter->phy.interface_type, | 555 | convert_to_et_setting(interface_type, |
549 | adapter->phy.dac_cable_len); | 556 | auto_speeds); |
550 | 557 | ||
551 | if (adapter->phy.auto_speeds_supported) { | 558 | ecmd->port = be_get_port_type(interface_type, |
552 | ecmd->supported |= SUPPORTED_Autoneg; | 559 | dac_cable_len); |
553 | ecmd->autoneg = AUTONEG_ENABLE; | 560 | |
554 | ecmd->advertising |= ADVERTISED_Autoneg; | 561 | if (adapter->phy.auto_speeds_supported) { |
555 | } | 562 | ecmd->supported |= SUPPORTED_Autoneg; |
563 | ecmd->autoneg = AUTONEG_ENABLE; | ||
564 | ecmd->advertising |= ADVERTISED_Autoneg; | ||
565 | } | ||
556 | 566 | ||
557 | if (be_pause_supported(adapter)) { | ||
558 | ecmd->supported |= SUPPORTED_Pause; | 567 | ecmd->supported |= SUPPORTED_Pause; |
559 | ecmd->advertising |= ADVERTISED_Pause; | 568 | if (be_pause_supported(adapter)) |
560 | } | 569 | ecmd->advertising |= ADVERTISED_Pause; |
561 | 570 | ||
562 | switch (adapter->phy.interface_type) { | 571 | switch (adapter->phy.interface_type) { |
563 | case PHY_TYPE_KR_10GB: | 572 | case PHY_TYPE_KR_10GB: |
564 | case PHY_TYPE_KX4_10GB: | 573 | case PHY_TYPE_KX4_10GB: |
565 | ecmd->transceiver = XCVR_INTERNAL; | 574 | ecmd->transceiver = XCVR_INTERNAL; |
566 | break; | 575 | break; |
567 | default: | 576 | default: |
568 | ecmd->transceiver = XCVR_EXTERNAL; | 577 | ecmd->transceiver = XCVR_EXTERNAL; |
569 | break; | 578 | break; |
579 | } | ||
580 | } else { | ||
581 | ecmd->port = PORT_OTHER; | ||
582 | ecmd->autoneg = AUTONEG_DISABLE; | ||
583 | ecmd->transceiver = XCVR_DUMMY1; | ||
570 | } | 584 | } |
571 | 585 | ||
572 | /* Save for future use */ | 586 | /* Save for future use */ |
@@ -787,6 +801,10 @@ static int | |||
787 | be_get_eeprom_len(struct net_device *netdev) | 801 | be_get_eeprom_len(struct net_device *netdev) |
788 | { | 802 | { |
789 | struct be_adapter *adapter = netdev_priv(netdev); | 803 | struct be_adapter *adapter = netdev_priv(netdev); |
804 | |||
805 | if (!check_privilege(adapter, MAX_PRIVILEGES)) | ||
806 | return 0; | ||
807 | |||
790 | if (lancer_chip(adapter)) { | 808 | if (lancer_chip(adapter)) { |
791 | if (be_physfn(adapter)) | 809 | if (be_physfn(adapter)) |
792 | return lancer_cmd_get_file_len(adapter, | 810 | return lancer_cmd_get_file_len(adapter, |
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index b755f7061dce..541d4530d5bf 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
@@ -31,12 +31,12 @@ | |||
31 | 31 | ||
32 | #define MPU_EP_CONTROL 0 | 32 | #define MPU_EP_CONTROL 0 |
33 | 33 | ||
34 | /********** MPU semphore ******************/ | 34 | /********** MPU semphore: used for SH & BE *************/ |
35 | #define MPU_EP_SEMAPHORE_OFFSET 0xac | 35 | #define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c |
36 | #define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400 | 36 | #define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 |
37 | #define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF | 37 | #define POST_STAGE_MASK 0x0000FFFF |
38 | #define EP_SEMAPHORE_POST_ERR_MASK 0x1 | 38 | #define POST_ERR_MASK 0x1 |
39 | #define EP_SEMAPHORE_POST_ERR_SHIFT 31 | 39 | #define POST_ERR_SHIFT 31 |
40 | 40 | ||
41 | /* MPU semphore POST stage values */ | 41 | /* MPU semphore POST stage values */ |
42 | #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ | 42 | #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ |
@@ -59,6 +59,9 @@ | |||
59 | #define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002 | 59 | #define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002 |
60 | #define PHYSDEV_CONTROL_INP_MASK 0x40000000 | 60 | #define PHYSDEV_CONTROL_INP_MASK 0x40000000 |
61 | 61 | ||
62 | #define SLIPORT_ERROR_NO_RESOURCE1 0x2 | ||
63 | #define SLIPORT_ERROR_NO_RESOURCE2 0x9 | ||
64 | |||
62 | /********* Memory BAR register ************/ | 65 | /********* Memory BAR register ************/ |
63 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 66 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
64 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt | 67 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt |
@@ -102,11 +105,6 @@ | |||
102 | #define SLI_INTF_TYPE_2 2 | 105 | #define SLI_INTF_TYPE_2 2 |
103 | #define SLI_INTF_TYPE_3 3 | 106 | #define SLI_INTF_TYPE_3 3 |
104 | 107 | ||
105 | /* SLI family */ | ||
106 | #define BE_SLI_FAMILY 0x0 | ||
107 | #define LANCER_A0_SLI_FAMILY 0xA | ||
108 | #define SKYHAWK_SLI_FAMILY 0x2 | ||
109 | |||
110 | /********* ISR0 Register offset **********/ | 108 | /********* ISR0 Register offset **********/ |
111 | #define CEV_ISR0_OFFSET 0xC18 | 109 | #define CEV_ISR0_OFFSET 0xC18 |
112 | #define CEV_ISR_SIZE 4 | 110 | #define CEV_ISR_SIZE 4 |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index d1b6cc587639..c365722218ff 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -44,6 +44,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | |||
44 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, | 44 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, |
45 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)}, | 45 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)}, |
46 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)}, | 46 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID5)}, |
47 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID6)}, | ||
47 | { 0 } | 48 | { 0 } |
48 | }; | 49 | }; |
49 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 50 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
@@ -237,23 +238,46 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) | |||
237 | int status = 0; | 238 | int status = 0; |
238 | u8 current_mac[ETH_ALEN]; | 239 | u8 current_mac[ETH_ALEN]; |
239 | u32 pmac_id = adapter->pmac_id[0]; | 240 | u32 pmac_id = adapter->pmac_id[0]; |
241 | bool active_mac = true; | ||
240 | 242 | ||
241 | if (!is_valid_ether_addr(addr->sa_data)) | 243 | if (!is_valid_ether_addr(addr->sa_data)) |
242 | return -EADDRNOTAVAIL; | 244 | return -EADDRNOTAVAIL; |
243 | 245 | ||
244 | status = be_cmd_mac_addr_query(adapter, current_mac, false, | 246 | /* For BE VF, MAC address is already activated by PF. |
245 | adapter->if_handle, 0); | 247 | * Hence only operation left is updating netdev->devaddr. |
248 | * Update it if user is passing the same MAC which was used | ||
249 | * during configuring VF MAC from PF(Hypervisor). | ||
250 | */ | ||
251 | if (!lancer_chip(adapter) && !be_physfn(adapter)) { | ||
252 | status = be_cmd_mac_addr_query(adapter, current_mac, | ||
253 | false, adapter->if_handle, 0); | ||
254 | if (!status && !memcmp(current_mac, addr->sa_data, ETH_ALEN)) | ||
255 | goto done; | ||
256 | else | ||
257 | goto err; | ||
258 | } | ||
259 | |||
260 | if (!memcmp(addr->sa_data, netdev->dev_addr, ETH_ALEN)) | ||
261 | goto done; | ||
262 | |||
263 | /* For Lancer check if any MAC is active. | ||
264 | * If active, get its mac id. | ||
265 | */ | ||
266 | if (lancer_chip(adapter) && !be_physfn(adapter)) | ||
267 | be_cmd_get_mac_from_list(adapter, current_mac, &active_mac, | ||
268 | &pmac_id, 0); | ||
269 | |||
270 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, | ||
271 | adapter->if_handle, | ||
272 | &adapter->pmac_id[0], 0); | ||
273 | |||
246 | if (status) | 274 | if (status) |
247 | goto err; | 275 | goto err; |
248 | 276 | ||
249 | if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) { | 277 | if (active_mac) |
250 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, | 278 | be_cmd_pmac_del(adapter, adapter->if_handle, |
251 | adapter->if_handle, &adapter->pmac_id[0], 0); | 279 | pmac_id, 0); |
252 | if (status) | 280 | done: |
253 | goto err; | ||
254 | |||
255 | be_cmd_pmac_del(adapter, adapter->if_handle, pmac_id, 0); | ||
256 | } | ||
257 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 281 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
258 | return 0; | 282 | return 0; |
259 | err: | 283 | err: |
@@ -261,7 +285,35 @@ err: | |||
261 | return status; | 285 | return status; |
262 | } | 286 | } |
263 | 287 | ||
264 | static void populate_be2_stats(struct be_adapter *adapter) | 288 | /* BE2 supports only v0 cmd */ |
289 | static void *hw_stats_from_cmd(struct be_adapter *adapter) | ||
290 | { | ||
291 | if (BE2_chip(adapter)) { | ||
292 | struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va; | ||
293 | |||
294 | return &cmd->hw_stats; | ||
295 | } else { | ||
296 | struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va; | ||
297 | |||
298 | return &cmd->hw_stats; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | /* BE2 supports only v0 cmd */ | ||
303 | static void *be_erx_stats_from_cmd(struct be_adapter *adapter) | ||
304 | { | ||
305 | if (BE2_chip(adapter)) { | ||
306 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | ||
307 | |||
308 | return &hw_stats->erx; | ||
309 | } else { | ||
310 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | ||
311 | |||
312 | return &hw_stats->erx; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static void populate_be_v0_stats(struct be_adapter *adapter) | ||
265 | { | 317 | { |
266 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); | 318 | struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter); |
267 | struct be_pmem_stats *pmem_sts = &hw_stats->pmem; | 319 | struct be_pmem_stats *pmem_sts = &hw_stats->pmem; |
@@ -310,7 +362,7 @@ static void populate_be2_stats(struct be_adapter *adapter) | |||
310 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; | 362 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; |
311 | } | 363 | } |
312 | 364 | ||
313 | static void populate_be3_stats(struct be_adapter *adapter) | 365 | static void populate_be_v1_stats(struct be_adapter *adapter) |
314 | { | 366 | { |
315 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); | 367 | struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter); |
316 | struct be_pmem_stats *pmem_sts = &hw_stats->pmem; | 368 | struct be_pmem_stats *pmem_sts = &hw_stats->pmem; |
@@ -412,28 +464,25 @@ void be_parse_stats(struct be_adapter *adapter) | |||
412 | struct be_rx_obj *rxo; | 464 | struct be_rx_obj *rxo; |
413 | int i; | 465 | int i; |
414 | 466 | ||
415 | if (adapter->generation == BE_GEN3) { | 467 | if (lancer_chip(adapter)) { |
416 | if (lancer_chip(adapter)) | 468 | populate_lancer_stats(adapter); |
417 | populate_lancer_stats(adapter); | ||
418 | else | ||
419 | populate_be3_stats(adapter); | ||
420 | } else { | 469 | } else { |
421 | populate_be2_stats(adapter); | 470 | if (BE2_chip(adapter)) |
422 | } | 471 | populate_be_v0_stats(adapter); |
423 | 472 | else | |
424 | if (lancer_chip(adapter)) | 473 | /* for BE3 and Skyhawk */ |
425 | goto done; | 474 | populate_be_v1_stats(adapter); |
426 | 475 | ||
427 | /* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */ | 476 | /* as erx_v1 is longer than v0, ok to use v1 for v0 access */ |
428 | for_all_rx_queues(adapter, rxo, i) { | 477 | for_all_rx_queues(adapter, rxo, i) { |
429 | /* below erx HW counter can actually wrap around after | 478 | /* below erx HW counter can actually wrap around after |
430 | * 65535. Driver accumulates a 32-bit value | 479 | * 65535. Driver accumulates a 32-bit value |
431 | */ | 480 | */ |
432 | accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags, | 481 | accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags, |
433 | (u16)erx->rx_drops_no_fragments[rxo->q.id]); | 482 | (u16)erx->rx_drops_no_fragments \ |
483 | [rxo->q.id]); | ||
484 | } | ||
434 | } | 485 | } |
435 | done: | ||
436 | return; | ||
437 | } | 486 | } |
438 | 487 | ||
439 | static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, | 488 | static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, |
@@ -597,16 +646,6 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, | |||
597 | hdr, skb_shinfo(skb)->gso_size); | 646 | hdr, skb_shinfo(skb)->gso_size); |
598 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) | 647 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) |
599 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); | 648 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); |
600 | if (lancer_chip(adapter) && adapter->sli_family == | ||
601 | LANCER_A0_SLI_FAMILY) { | ||
602 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1); | ||
603 | if (is_tcp_pkt(skb)) | ||
604 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, | ||
605 | tcpcs, hdr, 1); | ||
606 | else if (is_udp_pkt(skb)) | ||
607 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, | ||
608 | udpcs, hdr, 1); | ||
609 | } | ||
610 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 649 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
611 | if (is_tcp_pkt(skb)) | 650 | if (is_tcp_pkt(skb)) |
612 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); | 651 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); |
@@ -856,11 +895,15 @@ static int be_vlan_add_vid(struct net_device *netdev, u16 vid) | |||
856 | struct be_adapter *adapter = netdev_priv(netdev); | 895 | struct be_adapter *adapter = netdev_priv(netdev); |
857 | int status = 0; | 896 | int status = 0; |
858 | 897 | ||
859 | if (!be_physfn(adapter)) { | 898 | if (!lancer_chip(adapter) && !be_physfn(adapter)) { |
860 | status = -EINVAL; | 899 | status = -EINVAL; |
861 | goto ret; | 900 | goto ret; |
862 | } | 901 | } |
863 | 902 | ||
903 | /* Packets with VID 0 are always received by Lancer by default */ | ||
904 | if (lancer_chip(adapter) && vid == 0) | ||
905 | goto ret; | ||
906 | |||
864 | adapter->vlan_tag[vid] = 1; | 907 | adapter->vlan_tag[vid] = 1; |
865 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) | 908 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) |
866 | status = be_vid_config(adapter); | 909 | status = be_vid_config(adapter); |
@@ -878,11 +921,15 @@ static int be_vlan_rem_vid(struct net_device *netdev, u16 vid) | |||
878 | struct be_adapter *adapter = netdev_priv(netdev); | 921 | struct be_adapter *adapter = netdev_priv(netdev); |
879 | int status = 0; | 922 | int status = 0; |
880 | 923 | ||
881 | if (!be_physfn(adapter)) { | 924 | if (!lancer_chip(adapter) && !be_physfn(adapter)) { |
882 | status = -EINVAL; | 925 | status = -EINVAL; |
883 | goto ret; | 926 | goto ret; |
884 | } | 927 | } |
885 | 928 | ||
929 | /* Packets with VID 0 are always received by Lancer by default */ | ||
930 | if (lancer_chip(adapter) && vid == 0) | ||
931 | goto ret; | ||
932 | |||
886 | adapter->vlan_tag[vid] = 0; | 933 | adapter->vlan_tag[vid] = 0; |
887 | if (adapter->vlans_added <= adapter->max_vlans) | 934 | if (adapter->vlans_added <= adapter->max_vlans) |
888 | status = be_vid_config(adapter); | 935 | status = be_vid_config(adapter); |
@@ -917,7 +964,7 @@ static void be_set_rx_mode(struct net_device *netdev) | |||
917 | 964 | ||
918 | /* Enable multicast promisc if num configured exceeds what we support */ | 965 | /* Enable multicast promisc if num configured exceeds what we support */ |
919 | if (netdev->flags & IFF_ALLMULTI || | 966 | if (netdev->flags & IFF_ALLMULTI || |
920 | netdev_mc_count(netdev) > BE_MAX_MC) { | 967 | netdev_mc_count(netdev) > adapter->max_mcast_mac) { |
921 | be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON); | 968 | be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON); |
922 | goto done; | 969 | goto done; |
923 | } | 970 | } |
@@ -962,6 +1009,9 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | |||
962 | struct be_adapter *adapter = netdev_priv(netdev); | 1009 | struct be_adapter *adapter = netdev_priv(netdev); |
963 | struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf]; | 1010 | struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf]; |
964 | int status; | 1011 | int status; |
1012 | bool active_mac = false; | ||
1013 | u32 pmac_id; | ||
1014 | u8 old_mac[ETH_ALEN]; | ||
965 | 1015 | ||
966 | if (!sriov_enabled(adapter)) | 1016 | if (!sriov_enabled(adapter)) |
967 | return -EPERM; | 1017 | return -EPERM; |
@@ -970,6 +1020,12 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | |||
970 | return -EINVAL; | 1020 | return -EINVAL; |
971 | 1021 | ||
972 | if (lancer_chip(adapter)) { | 1022 | if (lancer_chip(adapter)) { |
1023 | status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac, | ||
1024 | &pmac_id, vf + 1); | ||
1025 | if (!status && active_mac) | ||
1026 | be_cmd_pmac_del(adapter, vf_cfg->if_handle, | ||
1027 | pmac_id, vf + 1); | ||
1028 | |||
973 | status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1); | 1029 | status = be_cmd_set_mac_list(adapter, mac, 1, vf + 1); |
974 | } else { | 1030 | } else { |
975 | status = be_cmd_pmac_del(adapter, vf_cfg->if_handle, | 1031 | status = be_cmd_pmac_del(adapter, vf_cfg->if_handle, |
@@ -1062,7 +1118,10 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
1062 | return -EINVAL; | 1118 | return -EINVAL; |
1063 | } | 1119 | } |
1064 | 1120 | ||
1065 | status = be_cmd_set_qos(adapter, rate / 10, vf + 1); | 1121 | if (lancer_chip(adapter)) |
1122 | status = be_cmd_set_profile_config(adapter, rate / 10, vf + 1); | ||
1123 | else | ||
1124 | status = be_cmd_set_qos(adapter, rate / 10, vf + 1); | ||
1066 | 1125 | ||
1067 | if (status) | 1126 | if (status) |
1068 | dev_err(&adapter->pdev->dev, | 1127 | dev_err(&adapter->pdev->dev, |
@@ -1837,12 +1896,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) | |||
1837 | 1896 | ||
1838 | static int be_num_txqs_want(struct be_adapter *adapter) | 1897 | static int be_num_txqs_want(struct be_adapter *adapter) |
1839 | { | 1898 | { |
1840 | if (sriov_want(adapter) || be_is_mc(adapter) || | 1899 | if ((!lancer_chip(adapter) && sriov_want(adapter)) || |
1841 | lancer_chip(adapter) || !be_physfn(adapter) || | 1900 | be_is_mc(adapter) || |
1842 | adapter->generation == BE_GEN2) | 1901 | (!lancer_chip(adapter) && !be_physfn(adapter)) || |
1902 | BE2_chip(adapter)) | ||
1843 | return 1; | 1903 | return 1; |
1844 | else | 1904 | else |
1845 | return MAX_TX_QS; | 1905 | return adapter->max_tx_queues; |
1846 | } | 1906 | } |
1847 | 1907 | ||
1848 | static int be_tx_cqs_create(struct be_adapter *adapter) | 1908 | static int be_tx_cqs_create(struct be_adapter *adapter) |
@@ -2177,9 +2237,11 @@ static void be_msix_disable(struct be_adapter *adapter) | |||
2177 | static uint be_num_rss_want(struct be_adapter *adapter) | 2237 | static uint be_num_rss_want(struct be_adapter *adapter) |
2178 | { | 2238 | { |
2179 | u32 num = 0; | 2239 | u32 num = 0; |
2240 | |||
2180 | if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && | 2241 | if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && |
2181 | !sriov_want(adapter) && be_physfn(adapter)) { | 2242 | (lancer_chip(adapter) || |
2182 | num = (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; | 2243 | (!sriov_want(adapter) && be_physfn(adapter)))) { |
2244 | num = adapter->max_rss_queues; | ||
2183 | num = min_t(u32, num, (u32)netif_get_num_default_rss_queues()); | 2245 | num = min_t(u32, num, (u32)netif_get_num_default_rss_queues()); |
2184 | } | 2246 | } |
2185 | return num; | 2247 | return num; |
@@ -2579,10 +2641,30 @@ static int be_clear(struct be_adapter *adapter) | |||
2579 | be_tx_queues_destroy(adapter); | 2641 | be_tx_queues_destroy(adapter); |
2580 | be_evt_queues_destroy(adapter); | 2642 | be_evt_queues_destroy(adapter); |
2581 | 2643 | ||
2644 | kfree(adapter->pmac_id); | ||
2645 | adapter->pmac_id = NULL; | ||
2646 | |||
2582 | be_msix_disable(adapter); | 2647 | be_msix_disable(adapter); |
2583 | return 0; | 2648 | return 0; |
2584 | } | 2649 | } |
2585 | 2650 | ||
2651 | static void be_get_vf_if_cap_flags(struct be_adapter *adapter, | ||
2652 | u32 *cap_flags, u8 domain) | ||
2653 | { | ||
2654 | bool profile_present = false; | ||
2655 | int status; | ||
2656 | |||
2657 | if (lancer_chip(adapter)) { | ||
2658 | status = be_cmd_get_profile_config(adapter, cap_flags, domain); | ||
2659 | if (!status) | ||
2660 | profile_present = true; | ||
2661 | } | ||
2662 | |||
2663 | if (!profile_present) | ||
2664 | *cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | ||
2665 | BE_IF_FLAGS_MULTICAST; | ||
2666 | } | ||
2667 | |||
2586 | static int be_vf_setup_init(struct be_adapter *adapter) | 2668 | static int be_vf_setup_init(struct be_adapter *adapter) |
2587 | { | 2669 | { |
2588 | struct be_vf_cfg *vf_cfg; | 2670 | struct be_vf_cfg *vf_cfg; |
@@ -2634,9 +2716,13 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2634 | if (status) | 2716 | if (status) |
2635 | goto err; | 2717 | goto err; |
2636 | 2718 | ||
2637 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | ||
2638 | BE_IF_FLAGS_MULTICAST; | ||
2639 | for_all_vfs(adapter, vf_cfg, vf) { | 2719 | for_all_vfs(adapter, vf_cfg, vf) { |
2720 | be_get_vf_if_cap_flags(adapter, &cap_flags, vf + 1); | ||
2721 | |||
2722 | en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED | | ||
2723 | BE_IF_FLAGS_BROADCAST | | ||
2724 | BE_IF_FLAGS_MULTICAST); | ||
2725 | |||
2640 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2726 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
2641 | &vf_cfg->if_handle, vf + 1); | 2727 | &vf_cfg->if_handle, vf + 1); |
2642 | if (status) | 2728 | if (status) |
@@ -2661,6 +2747,8 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2661 | if (status) | 2747 | if (status) |
2662 | goto err; | 2748 | goto err; |
2663 | vf_cfg->def_vid = def_vlan; | 2749 | vf_cfg->def_vid = def_vlan; |
2750 | |||
2751 | be_cmd_enable_vf(adapter, vf + 1); | ||
2664 | } | 2752 | } |
2665 | return 0; | 2753 | return 0; |
2666 | err: | 2754 | err: |
@@ -2674,7 +2762,10 @@ static void be_setup_init(struct be_adapter *adapter) | |||
2674 | adapter->if_handle = -1; | 2762 | adapter->if_handle = -1; |
2675 | adapter->be3_native = false; | 2763 | adapter->be3_native = false; |
2676 | adapter->promiscuous = false; | 2764 | adapter->promiscuous = false; |
2677 | adapter->eq_next_idx = 0; | 2765 | if (be_physfn(adapter)) |
2766 | adapter->cmd_privileges = MAX_PRIVILEGES; | ||
2767 | else | ||
2768 | adapter->cmd_privileges = MIN_PRIVILEGES; | ||
2678 | } | 2769 | } |
2679 | 2770 | ||
2680 | static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, | 2771 | static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, |
@@ -2712,12 +2803,93 @@ static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, | |||
2712 | return status; | 2803 | return status; |
2713 | } | 2804 | } |
2714 | 2805 | ||
2806 | static void be_get_resources(struct be_adapter *adapter) | ||
2807 | { | ||
2808 | int status; | ||
2809 | bool profile_present = false; | ||
2810 | |||
2811 | if (lancer_chip(adapter)) { | ||
2812 | status = be_cmd_get_func_config(adapter); | ||
2813 | |||
2814 | if (!status) | ||
2815 | profile_present = true; | ||
2816 | } | ||
2817 | |||
2818 | if (profile_present) { | ||
2819 | /* Sanity fixes for Lancer */ | ||
2820 | adapter->max_pmac_cnt = min_t(u16, adapter->max_pmac_cnt, | ||
2821 | BE_UC_PMAC_COUNT); | ||
2822 | adapter->max_vlans = min_t(u16, adapter->max_vlans, | ||
2823 | BE_NUM_VLANS_SUPPORTED); | ||
2824 | adapter->max_mcast_mac = min_t(u16, adapter->max_mcast_mac, | ||
2825 | BE_MAX_MC); | ||
2826 | adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues, | ||
2827 | MAX_TX_QS); | ||
2828 | adapter->max_rss_queues = min_t(u16, adapter->max_rss_queues, | ||
2829 | BE3_MAX_RSS_QS); | ||
2830 | adapter->max_event_queues = min_t(u16, | ||
2831 | adapter->max_event_queues, | ||
2832 | BE3_MAX_RSS_QS); | ||
2833 | |||
2834 | if (adapter->max_rss_queues && | ||
2835 | adapter->max_rss_queues == adapter->max_rx_queues) | ||
2836 | adapter->max_rss_queues -= 1; | ||
2837 | |||
2838 | if (adapter->max_event_queues < adapter->max_rss_queues) | ||
2839 | adapter->max_rss_queues = adapter->max_event_queues; | ||
2840 | |||
2841 | } else { | ||
2842 | if (be_physfn(adapter)) | ||
2843 | adapter->max_pmac_cnt = BE_UC_PMAC_COUNT; | ||
2844 | else | ||
2845 | adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT; | ||
2846 | |||
2847 | if (adapter->function_mode & FLEX10_MODE) | ||
2848 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8; | ||
2849 | else | ||
2850 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; | ||
2851 | |||
2852 | adapter->max_mcast_mac = BE_MAX_MC; | ||
2853 | adapter->max_tx_queues = MAX_TX_QS; | ||
2854 | adapter->max_rss_queues = (adapter->be3_native) ? | ||
2855 | BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; | ||
2856 | adapter->max_event_queues = BE3_MAX_RSS_QS; | ||
2857 | |||
2858 | adapter->if_cap_flags = BE_IF_FLAGS_UNTAGGED | | ||
2859 | BE_IF_FLAGS_BROADCAST | | ||
2860 | BE_IF_FLAGS_MULTICAST | | ||
2861 | BE_IF_FLAGS_PASS_L3L4_ERRORS | | ||
2862 | BE_IF_FLAGS_MCAST_PROMISCUOUS | | ||
2863 | BE_IF_FLAGS_VLAN_PROMISCUOUS | | ||
2864 | BE_IF_FLAGS_PROMISCUOUS; | ||
2865 | |||
2866 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) | ||
2867 | adapter->if_cap_flags |= BE_IF_FLAGS_RSS; | ||
2868 | } | ||
2869 | } | ||
2870 | |||
2715 | /* Routine to query per function resource limits */ | 2871 | /* Routine to query per function resource limits */ |
2716 | static int be_get_config(struct be_adapter *adapter) | 2872 | static int be_get_config(struct be_adapter *adapter) |
2717 | { | 2873 | { |
2718 | int pos; | 2874 | int pos, status; |
2719 | u16 dev_num_vfs; | 2875 | u16 dev_num_vfs; |
2720 | 2876 | ||
2877 | status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, | ||
2878 | &adapter->function_mode, | ||
2879 | &adapter->function_caps); | ||
2880 | if (status) | ||
2881 | goto err; | ||
2882 | |||
2883 | be_get_resources(adapter); | ||
2884 | |||
2885 | /* primary mac needs 1 pmac entry */ | ||
2886 | adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1, | ||
2887 | sizeof(u32), GFP_KERNEL); | ||
2888 | if (!adapter->pmac_id) { | ||
2889 | status = -ENOMEM; | ||
2890 | goto err; | ||
2891 | } | ||
2892 | |||
2721 | pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV); | 2893 | pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV); |
2722 | if (pos) { | 2894 | if (pos) { |
2723 | pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF, | 2895 | pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF, |
@@ -2726,13 +2898,14 @@ static int be_get_config(struct be_adapter *adapter) | |||
2726 | dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS); | 2898 | dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS); |
2727 | adapter->dev_num_vfs = dev_num_vfs; | 2899 | adapter->dev_num_vfs = dev_num_vfs; |
2728 | } | 2900 | } |
2729 | return 0; | 2901 | err: |
2902 | return status; | ||
2730 | } | 2903 | } |
2731 | 2904 | ||
2732 | static int be_setup(struct be_adapter *adapter) | 2905 | static int be_setup(struct be_adapter *adapter) |
2733 | { | 2906 | { |
2734 | struct device *dev = &adapter->pdev->dev; | 2907 | struct device *dev = &adapter->pdev->dev; |
2735 | u32 cap_flags, en_flags; | 2908 | u32 en_flags; |
2736 | u32 tx_fc, rx_fc; | 2909 | u32 tx_fc, rx_fc; |
2737 | int status; | 2910 | int status; |
2738 | u8 mac[ETH_ALEN]; | 2911 | u8 mac[ETH_ALEN]; |
@@ -2740,9 +2913,12 @@ static int be_setup(struct be_adapter *adapter) | |||
2740 | 2913 | ||
2741 | be_setup_init(adapter); | 2914 | be_setup_init(adapter); |
2742 | 2915 | ||
2743 | be_get_config(adapter); | 2916 | if (!lancer_chip(adapter)) |
2917 | be_cmd_req_native_mode(adapter); | ||
2744 | 2918 | ||
2745 | be_cmd_req_native_mode(adapter); | 2919 | status = be_get_config(adapter); |
2920 | if (status) | ||
2921 | goto err; | ||
2746 | 2922 | ||
2747 | be_msix_enable(adapter); | 2923 | be_msix_enable(adapter); |
2748 | 2924 | ||
@@ -2762,24 +2938,22 @@ static int be_setup(struct be_adapter *adapter) | |||
2762 | if (status) | 2938 | if (status) |
2763 | goto err; | 2939 | goto err; |
2764 | 2940 | ||
2941 | be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0); | ||
2942 | /* In UMC mode FW does not return right privileges. | ||
2943 | * Override with correct privilege equivalent to PF. | ||
2944 | */ | ||
2945 | if (be_is_mc(adapter)) | ||
2946 | adapter->cmd_privileges = MAX_PRIVILEGES; | ||
2947 | |||
2765 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 2948 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
2766 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2949 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2767 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | | ||
2768 | BE_IF_FLAGS_VLAN_PROMISCUOUS | BE_IF_FLAGS_PROMISCUOUS; | ||
2769 | 2950 | ||
2770 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { | 2951 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) |
2771 | cap_flags |= BE_IF_FLAGS_RSS; | ||
2772 | en_flags |= BE_IF_FLAGS_RSS; | 2952 | en_flags |= BE_IF_FLAGS_RSS; |
2773 | } | ||
2774 | 2953 | ||
2775 | if (lancer_chip(adapter) && !be_physfn(adapter)) { | 2954 | en_flags = en_flags & adapter->if_cap_flags; |
2776 | en_flags = BE_IF_FLAGS_UNTAGGED | | ||
2777 | BE_IF_FLAGS_BROADCAST | | ||
2778 | BE_IF_FLAGS_MULTICAST; | ||
2779 | cap_flags = en_flags; | ||
2780 | } | ||
2781 | 2955 | ||
2782 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2956 | status = be_cmd_if_create(adapter, adapter->if_cap_flags, en_flags, |
2783 | &adapter->if_handle, 0); | 2957 | &adapter->if_handle, 0); |
2784 | if (status != 0) | 2958 | if (status != 0) |
2785 | goto err; | 2959 | goto err; |
@@ -2827,8 +3001,8 @@ static int be_setup(struct be_adapter *adapter) | |||
2827 | dev_warn(dev, "device doesn't support SRIOV\n"); | 3001 | dev_warn(dev, "device doesn't support SRIOV\n"); |
2828 | } | 3002 | } |
2829 | 3003 | ||
2830 | be_cmd_get_phy_info(adapter); | 3004 | status = be_cmd_get_phy_info(adapter); |
2831 | if (be_pause_supported(adapter)) | 3005 | if (!status && be_pause_supported(adapter)) |
2832 | adapter->phy.fc_autoneg = 1; | 3006 | adapter->phy.fc_autoneg = 1; |
2833 | 3007 | ||
2834 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); | 3008 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
@@ -2895,7 +3069,7 @@ static bool is_comp_in_ufi(struct be_adapter *adapter, | |||
2895 | int i = 0, img_type = 0; | 3069 | int i = 0, img_type = 0; |
2896 | struct flash_section_info_g2 *fsec_g2 = NULL; | 3070 | struct flash_section_info_g2 *fsec_g2 = NULL; |
2897 | 3071 | ||
2898 | if (adapter->generation != BE_GEN3) | 3072 | if (BE2_chip(adapter)) |
2899 | fsec_g2 = (struct flash_section_info_g2 *)fsec; | 3073 | fsec_g2 = (struct flash_section_info_g2 *)fsec; |
2900 | 3074 | ||
2901 | for (i = 0; i < MAX_FLASH_COMP; i++) { | 3075 | for (i = 0; i < MAX_FLASH_COMP; i++) { |
@@ -2928,7 +3102,49 @@ struct flash_section_info *get_fsec_info(struct be_adapter *adapter, | |||
2928 | return NULL; | 3102 | return NULL; |
2929 | } | 3103 | } |
2930 | 3104 | ||
2931 | static int be_flash_data(struct be_adapter *adapter, | 3105 | static int be_flash(struct be_adapter *adapter, const u8 *img, |
3106 | struct be_dma_mem *flash_cmd, int optype, int img_size) | ||
3107 | { | ||
3108 | u32 total_bytes = 0, flash_op, num_bytes = 0; | ||
3109 | int status = 0; | ||
3110 | struct be_cmd_write_flashrom *req = flash_cmd->va; | ||
3111 | |||
3112 | total_bytes = img_size; | ||
3113 | while (total_bytes) { | ||
3114 | num_bytes = min_t(u32, 32*1024, total_bytes); | ||
3115 | |||
3116 | total_bytes -= num_bytes; | ||
3117 | |||
3118 | if (!total_bytes) { | ||
3119 | if (optype == OPTYPE_PHY_FW) | ||
3120 | flash_op = FLASHROM_OPER_PHY_FLASH; | ||
3121 | else | ||
3122 | flash_op = FLASHROM_OPER_FLASH; | ||
3123 | } else { | ||
3124 | if (optype == OPTYPE_PHY_FW) | ||
3125 | flash_op = FLASHROM_OPER_PHY_SAVE; | ||
3126 | else | ||
3127 | flash_op = FLASHROM_OPER_SAVE; | ||
3128 | } | ||
3129 | |||
3130 | memcpy(req->data_buf, img, num_bytes); | ||
3131 | img += num_bytes; | ||
3132 | status = be_cmd_write_flashrom(adapter, flash_cmd, optype, | ||
3133 | flash_op, num_bytes); | ||
3134 | if (status) { | ||
3135 | if (status == ILLEGAL_IOCTL_REQ && | ||
3136 | optype == OPTYPE_PHY_FW) | ||
3137 | break; | ||
3138 | dev_err(&adapter->pdev->dev, | ||
3139 | "cmd to write to flash rom failed.\n"); | ||
3140 | return status; | ||
3141 | } | ||
3142 | } | ||
3143 | return 0; | ||
3144 | } | ||
3145 | |||
3146 | /* For BE2 and BE3 */ | ||
3147 | static int be_flash_BEx(struct be_adapter *adapter, | ||
2932 | const struct firmware *fw, | 3148 | const struct firmware *fw, |
2933 | struct be_dma_mem *flash_cmd, | 3149 | struct be_dma_mem *flash_cmd, |
2934 | int num_of_images) | 3150 | int num_of_images) |
@@ -2936,12 +3152,9 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2936 | { | 3152 | { |
2937 | int status = 0, i, filehdr_size = 0; | 3153 | int status = 0, i, filehdr_size = 0; |
2938 | int img_hdrs_size = (num_of_images * sizeof(struct image_hdr)); | 3154 | int img_hdrs_size = (num_of_images * sizeof(struct image_hdr)); |
2939 | u32 total_bytes = 0, flash_op; | ||
2940 | int num_bytes; | ||
2941 | const u8 *p = fw->data; | 3155 | const u8 *p = fw->data; |
2942 | struct be_cmd_write_flashrom *req = flash_cmd->va; | ||
2943 | const struct flash_comp *pflashcomp; | 3156 | const struct flash_comp *pflashcomp; |
2944 | int num_comp, hdr_size; | 3157 | int num_comp, redboot; |
2945 | struct flash_section_info *fsec = NULL; | 3158 | struct flash_section_info *fsec = NULL; |
2946 | 3159 | ||
2947 | struct flash_comp gen3_flash_types[] = { | 3160 | struct flash_comp gen3_flash_types[] = { |
@@ -2986,7 +3199,7 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2986 | FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE} | 3199 | FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE} |
2987 | }; | 3200 | }; |
2988 | 3201 | ||
2989 | if (adapter->generation == BE_GEN3) { | 3202 | if (BE3_chip(adapter)) { |
2990 | pflashcomp = gen3_flash_types; | 3203 | pflashcomp = gen3_flash_types; |
2991 | filehdr_size = sizeof(struct flash_file_hdr_g3); | 3204 | filehdr_size = sizeof(struct flash_file_hdr_g3); |
2992 | num_comp = ARRAY_SIZE(gen3_flash_types); | 3205 | num_comp = ARRAY_SIZE(gen3_flash_types); |
@@ -2995,6 +3208,7 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2995 | filehdr_size = sizeof(struct flash_file_hdr_g2); | 3208 | filehdr_size = sizeof(struct flash_file_hdr_g2); |
2996 | num_comp = ARRAY_SIZE(gen2_flash_types); | 3209 | num_comp = ARRAY_SIZE(gen2_flash_types); |
2997 | } | 3210 | } |
3211 | |||
2998 | /* Get flash section info*/ | 3212 | /* Get flash section info*/ |
2999 | fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw); | 3213 | fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw); |
3000 | if (!fsec) { | 3214 | if (!fsec) { |
@@ -3010,70 +3224,105 @@ static int be_flash_data(struct be_adapter *adapter, | |||
3010 | memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) | 3224 | memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) |
3011 | continue; | 3225 | continue; |
3012 | 3226 | ||
3013 | if (pflashcomp[i].optype == OPTYPE_PHY_FW) { | 3227 | if (pflashcomp[i].optype == OPTYPE_PHY_FW && |
3014 | if (!phy_flashing_required(adapter)) | 3228 | !phy_flashing_required(adapter)) |
3015 | continue; | 3229 | continue; |
3016 | } | ||
3017 | |||
3018 | hdr_size = filehdr_size + | ||
3019 | (num_of_images * sizeof(struct image_hdr)); | ||
3020 | 3230 | ||
3021 | if ((pflashcomp[i].optype == OPTYPE_REDBOOT) && | 3231 | if (pflashcomp[i].optype == OPTYPE_REDBOOT) { |
3022 | (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset, | 3232 | redboot = be_flash_redboot(adapter, fw->data, |
3023 | pflashcomp[i].size, hdr_size))) | 3233 | pflashcomp[i].offset, pflashcomp[i].size, |
3024 | continue; | 3234 | filehdr_size + img_hdrs_size); |
3235 | if (!redboot) | ||
3236 | continue; | ||
3237 | } | ||
3025 | 3238 | ||
3026 | /* Flash the component */ | ||
3027 | p = fw->data; | 3239 | p = fw->data; |
3028 | p += filehdr_size + pflashcomp[i].offset + img_hdrs_size; | 3240 | p += filehdr_size + pflashcomp[i].offset + img_hdrs_size; |
3029 | if (p + pflashcomp[i].size > fw->data + fw->size) | 3241 | if (p + pflashcomp[i].size > fw->data + fw->size) |
3030 | return -1; | 3242 | return -1; |
3031 | total_bytes = pflashcomp[i].size; | 3243 | |
3032 | while (total_bytes) { | 3244 | status = be_flash(adapter, p, flash_cmd, pflashcomp[i].optype, |
3033 | if (total_bytes > 32*1024) | 3245 | pflashcomp[i].size); |
3034 | num_bytes = 32*1024; | 3246 | if (status) { |
3035 | else | 3247 | dev_err(&adapter->pdev->dev, |
3036 | num_bytes = total_bytes; | 3248 | "Flashing section type %d failed.\n", |
3037 | total_bytes -= num_bytes; | 3249 | pflashcomp[i].img_type); |
3038 | if (!total_bytes) { | 3250 | return status; |
3039 | if (pflashcomp[i].optype == OPTYPE_PHY_FW) | ||
3040 | flash_op = FLASHROM_OPER_PHY_FLASH; | ||
3041 | else | ||
3042 | flash_op = FLASHROM_OPER_FLASH; | ||
3043 | } else { | ||
3044 | if (pflashcomp[i].optype == OPTYPE_PHY_FW) | ||
3045 | flash_op = FLASHROM_OPER_PHY_SAVE; | ||
3046 | else | ||
3047 | flash_op = FLASHROM_OPER_SAVE; | ||
3048 | } | ||
3049 | memcpy(req->params.data_buf, p, num_bytes); | ||
3050 | p += num_bytes; | ||
3051 | status = be_cmd_write_flashrom(adapter, flash_cmd, | ||
3052 | pflashcomp[i].optype, flash_op, num_bytes); | ||
3053 | if (status) { | ||
3054 | if ((status == ILLEGAL_IOCTL_REQ) && | ||
3055 | (pflashcomp[i].optype == | ||
3056 | OPTYPE_PHY_FW)) | ||
3057 | break; | ||
3058 | dev_err(&adapter->pdev->dev, | ||
3059 | "cmd to write to flash rom failed.\n"); | ||
3060 | return -1; | ||
3061 | } | ||
3062 | } | 3251 | } |
3063 | } | 3252 | } |
3064 | return 0; | 3253 | return 0; |
3065 | } | 3254 | } |
3066 | 3255 | ||
3067 | static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) | 3256 | static int be_flash_skyhawk(struct be_adapter *adapter, |
3257 | const struct firmware *fw, | ||
3258 | struct be_dma_mem *flash_cmd, int num_of_images) | ||
3068 | { | 3259 | { |
3069 | if (fhdr == NULL) | 3260 | int status = 0, i, filehdr_size = 0; |
3070 | return 0; | 3261 | int img_offset, img_size, img_optype, redboot; |
3071 | if (fhdr->build[0] == '3') | 3262 | int img_hdrs_size = num_of_images * sizeof(struct image_hdr); |
3072 | return BE_GEN3; | 3263 | const u8 *p = fw->data; |
3073 | else if (fhdr->build[0] == '2') | 3264 | struct flash_section_info *fsec = NULL; |
3074 | return BE_GEN2; | 3265 | |
3075 | else | 3266 | filehdr_size = sizeof(struct flash_file_hdr_g3); |
3076 | return 0; | 3267 | fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw); |
3268 | if (!fsec) { | ||
3269 | dev_err(&adapter->pdev->dev, | ||
3270 | "Invalid Cookie. UFI corrupted ?\n"); | ||
3271 | return -1; | ||
3272 | } | ||
3273 | |||
3274 | for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) { | ||
3275 | img_offset = le32_to_cpu(fsec->fsec_entry[i].offset); | ||
3276 | img_size = le32_to_cpu(fsec->fsec_entry[i].pad_size); | ||
3277 | |||
3278 | switch (le32_to_cpu(fsec->fsec_entry[i].type)) { | ||
3279 | case IMAGE_FIRMWARE_iSCSI: | ||
3280 | img_optype = OPTYPE_ISCSI_ACTIVE; | ||
3281 | break; | ||
3282 | case IMAGE_BOOT_CODE: | ||
3283 | img_optype = OPTYPE_REDBOOT; | ||
3284 | break; | ||
3285 | case IMAGE_OPTION_ROM_ISCSI: | ||
3286 | img_optype = OPTYPE_BIOS; | ||
3287 | break; | ||
3288 | case IMAGE_OPTION_ROM_PXE: | ||
3289 | img_optype = OPTYPE_PXE_BIOS; | ||
3290 | break; | ||
3291 | case IMAGE_OPTION_ROM_FCoE: | ||
3292 | img_optype = OPTYPE_FCOE_BIOS; | ||
3293 | break; | ||
3294 | case IMAGE_FIRMWARE_BACKUP_iSCSI: | ||
3295 | img_optype = OPTYPE_ISCSI_BACKUP; | ||
3296 | break; | ||
3297 | case IMAGE_NCSI: | ||
3298 | img_optype = OPTYPE_NCSI_FW; | ||
3299 | break; | ||
3300 | default: | ||
3301 | continue; | ||
3302 | } | ||
3303 | |||
3304 | if (img_optype == OPTYPE_REDBOOT) { | ||
3305 | redboot = be_flash_redboot(adapter, fw->data, | ||
3306 | img_offset, img_size, | ||
3307 | filehdr_size + img_hdrs_size); | ||
3308 | if (!redboot) | ||
3309 | continue; | ||
3310 | } | ||
3311 | |||
3312 | p = fw->data; | ||
3313 | p += filehdr_size + img_offset + img_hdrs_size; | ||
3314 | if (p + img_size > fw->data + fw->size) | ||
3315 | return -1; | ||
3316 | |||
3317 | status = be_flash(adapter, p, flash_cmd, img_optype, img_size); | ||
3318 | if (status) { | ||
3319 | dev_err(&adapter->pdev->dev, | ||
3320 | "Flashing section type %d failed.\n", | ||
3321 | fsec->fsec_entry[i].type); | ||
3322 | return status; | ||
3323 | } | ||
3324 | } | ||
3325 | return 0; | ||
3077 | } | 3326 | } |
3078 | 3327 | ||
3079 | static int lancer_wait_idle(struct be_adapter *adapter) | 3328 | static int lancer_wait_idle(struct be_adapter *adapter) |
@@ -3207,6 +3456,28 @@ lancer_fw_exit: | |||
3207 | return status; | 3456 | return status; |
3208 | } | 3457 | } |
3209 | 3458 | ||
3459 | #define UFI_TYPE2 2 | ||
3460 | #define UFI_TYPE3 3 | ||
3461 | #define UFI_TYPE4 4 | ||
3462 | static int be_get_ufi_type(struct be_adapter *adapter, | ||
3463 | struct flash_file_hdr_g2 *fhdr) | ||
3464 | { | ||
3465 | if (fhdr == NULL) | ||
3466 | goto be_get_ufi_exit; | ||
3467 | |||
3468 | if (skyhawk_chip(adapter) && fhdr->build[0] == '4') | ||
3469 | return UFI_TYPE4; | ||
3470 | else if (BE3_chip(adapter) && fhdr->build[0] == '3') | ||
3471 | return UFI_TYPE3; | ||
3472 | else if (BE2_chip(adapter) && fhdr->build[0] == '2') | ||
3473 | return UFI_TYPE2; | ||
3474 | |||
3475 | be_get_ufi_exit: | ||
3476 | dev_err(&adapter->pdev->dev, | ||
3477 | "UFI and Interface are not compatible for flashing\n"); | ||
3478 | return -1; | ||
3479 | } | ||
3480 | |||
3210 | static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | 3481 | static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) |
3211 | { | 3482 | { |
3212 | struct flash_file_hdr_g2 *fhdr; | 3483 | struct flash_file_hdr_g2 *fhdr; |
@@ -3214,12 +3485,9 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | |||
3214 | struct image_hdr *img_hdr_ptr = NULL; | 3485 | struct image_hdr *img_hdr_ptr = NULL; |
3215 | struct be_dma_mem flash_cmd; | 3486 | struct be_dma_mem flash_cmd; |
3216 | const u8 *p; | 3487 | const u8 *p; |
3217 | int status = 0, i = 0, num_imgs = 0; | 3488 | int status = 0, i = 0, num_imgs = 0, ufi_type = 0; |
3218 | 3489 | ||
3219 | p = fw->data; | 3490 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom); |
3220 | fhdr = (struct flash_file_hdr_g2 *) p; | ||
3221 | |||
3222 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; | ||
3223 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, | 3491 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, |
3224 | &flash_cmd.dma, GFP_KERNEL); | 3492 | &flash_cmd.dma, GFP_KERNEL); |
3225 | if (!flash_cmd.va) { | 3493 | if (!flash_cmd.va) { |
@@ -3229,27 +3497,32 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | |||
3229 | goto be_fw_exit; | 3497 | goto be_fw_exit; |
3230 | } | 3498 | } |
3231 | 3499 | ||
3232 | if ((adapter->generation == BE_GEN3) && | 3500 | p = fw->data; |
3233 | (get_ufigen_type(fhdr) == BE_GEN3)) { | 3501 | fhdr = (struct flash_file_hdr_g2 *)p; |
3234 | fhdr3 = (struct flash_file_hdr_g3 *) fw->data; | 3502 | |
3235 | num_imgs = le32_to_cpu(fhdr3->num_imgs); | 3503 | ufi_type = be_get_ufi_type(adapter, fhdr); |
3236 | for (i = 0; i < num_imgs; i++) { | 3504 | |
3237 | img_hdr_ptr = (struct image_hdr *) (fw->data + | 3505 | fhdr3 = (struct flash_file_hdr_g3 *)fw->data; |
3238 | (sizeof(struct flash_file_hdr_g3) + | 3506 | num_imgs = le32_to_cpu(fhdr3->num_imgs); |
3239 | i * sizeof(struct image_hdr))); | 3507 | for (i = 0; i < num_imgs; i++) { |
3240 | if (le32_to_cpu(img_hdr_ptr->imageid) == 1) | 3508 | img_hdr_ptr = (struct image_hdr *)(fw->data + |
3241 | status = be_flash_data(adapter, fw, &flash_cmd, | 3509 | (sizeof(struct flash_file_hdr_g3) + |
3242 | num_imgs); | 3510 | i * sizeof(struct image_hdr))); |
3511 | if (le32_to_cpu(img_hdr_ptr->imageid) == 1) { | ||
3512 | if (ufi_type == UFI_TYPE4) | ||
3513 | status = be_flash_skyhawk(adapter, fw, | ||
3514 | &flash_cmd, num_imgs); | ||
3515 | else if (ufi_type == UFI_TYPE3) | ||
3516 | status = be_flash_BEx(adapter, fw, &flash_cmd, | ||
3517 | num_imgs); | ||
3243 | } | 3518 | } |
3244 | } else if ((adapter->generation == BE_GEN2) && | ||
3245 | (get_ufigen_type(fhdr) == BE_GEN2)) { | ||
3246 | status = be_flash_data(adapter, fw, &flash_cmd, 0); | ||
3247 | } else { | ||
3248 | dev_err(&adapter->pdev->dev, | ||
3249 | "UFI and Interface are not compatible for flashing\n"); | ||
3250 | status = -1; | ||
3251 | } | 3519 | } |
3252 | 3520 | ||
3521 | if (ufi_type == UFI_TYPE2) | ||
3522 | status = be_flash_BEx(adapter, fw, &flash_cmd, 0); | ||
3523 | else if (ufi_type == -1) | ||
3524 | status = -1; | ||
3525 | |||
3253 | dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, | 3526 | dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, |
3254 | flash_cmd.dma); | 3527 | flash_cmd.dma); |
3255 | if (status) { | 3528 | if (status) { |
@@ -3344,80 +3617,47 @@ static void be_netdev_init(struct net_device *netdev) | |||
3344 | 3617 | ||
3345 | static void be_unmap_pci_bars(struct be_adapter *adapter) | 3618 | static void be_unmap_pci_bars(struct be_adapter *adapter) |
3346 | { | 3619 | { |
3347 | if (adapter->csr) | ||
3348 | iounmap(adapter->csr); | ||
3349 | if (adapter->db) | 3620 | if (adapter->db) |
3350 | iounmap(adapter->db); | 3621 | pci_iounmap(adapter->pdev, adapter->db); |
3351 | if (adapter->roce_db.base) | ||
3352 | pci_iounmap(adapter->pdev, adapter->roce_db.base); | ||
3353 | } | 3622 | } |
3354 | 3623 | ||
3355 | static int lancer_roce_map_pci_bars(struct be_adapter *adapter) | 3624 | static int db_bar(struct be_adapter *adapter) |
3356 | { | 3625 | { |
3357 | struct pci_dev *pdev = adapter->pdev; | 3626 | if (lancer_chip(adapter) || !be_physfn(adapter)) |
3358 | u8 __iomem *addr; | 3627 | return 0; |
3359 | 3628 | else | |
3360 | addr = pci_iomap(pdev, 2, 0); | 3629 | return 4; |
3361 | if (addr == NULL) | 3630 | } |
3362 | return -ENOMEM; | ||
3363 | 3631 | ||
3364 | adapter->roce_db.base = addr; | 3632 | static int be_roce_map_pci_bars(struct be_adapter *adapter) |
3365 | adapter->roce_db.io_addr = pci_resource_start(pdev, 2); | 3633 | { |
3366 | adapter->roce_db.size = 8192; | 3634 | if (skyhawk_chip(adapter)) { |
3367 | adapter->roce_db.total_size = pci_resource_len(pdev, 2); | 3635 | adapter->roce_db.size = 4096; |
3636 | adapter->roce_db.io_addr = pci_resource_start(adapter->pdev, | ||
3637 | db_bar(adapter)); | ||
3638 | adapter->roce_db.total_size = pci_resource_len(adapter->pdev, | ||
3639 | db_bar(adapter)); | ||
3640 | } | ||
3368 | return 0; | 3641 | return 0; |
3369 | } | 3642 | } |
3370 | 3643 | ||
3371 | static int be_map_pci_bars(struct be_adapter *adapter) | 3644 | static int be_map_pci_bars(struct be_adapter *adapter) |
3372 | { | 3645 | { |
3373 | u8 __iomem *addr; | 3646 | u8 __iomem *addr; |
3374 | int db_reg; | 3647 | u32 sli_intf; |
3375 | 3648 | ||
3376 | if (lancer_chip(adapter)) { | 3649 | pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); |
3377 | if (be_type_2_3(adapter)) { | 3650 | adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> |
3378 | addr = ioremap_nocache( | 3651 | SLI_INTF_IF_TYPE_SHIFT; |
3379 | pci_resource_start(adapter->pdev, 0), | ||
3380 | pci_resource_len(adapter->pdev, 0)); | ||
3381 | if (addr == NULL) | ||
3382 | return -ENOMEM; | ||
3383 | adapter->db = addr; | ||
3384 | } | ||
3385 | if (adapter->if_type == SLI_INTF_TYPE_3) { | ||
3386 | if (lancer_roce_map_pci_bars(adapter)) | ||
3387 | goto pci_map_err; | ||
3388 | } | ||
3389 | return 0; | ||
3390 | } | ||
3391 | |||
3392 | if (be_physfn(adapter)) { | ||
3393 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), | ||
3394 | pci_resource_len(adapter->pdev, 2)); | ||
3395 | if (addr == NULL) | ||
3396 | return -ENOMEM; | ||
3397 | adapter->csr = addr; | ||
3398 | } | ||
3399 | 3652 | ||
3400 | if (adapter->generation == BE_GEN2) { | 3653 | addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); |
3401 | db_reg = 4; | ||
3402 | } else { | ||
3403 | if (be_physfn(adapter)) | ||
3404 | db_reg = 4; | ||
3405 | else | ||
3406 | db_reg = 0; | ||
3407 | } | ||
3408 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, db_reg), | ||
3409 | pci_resource_len(adapter->pdev, db_reg)); | ||
3410 | if (addr == NULL) | 3654 | if (addr == NULL) |
3411 | goto pci_map_err; | 3655 | goto pci_map_err; |
3412 | adapter->db = addr; | 3656 | adapter->db = addr; |
3413 | if (adapter->sli_family == SKYHAWK_SLI_FAMILY) { | 3657 | |
3414 | adapter->roce_db.size = 4096; | 3658 | be_roce_map_pci_bars(adapter); |
3415 | adapter->roce_db.io_addr = | ||
3416 | pci_resource_start(adapter->pdev, db_reg); | ||
3417 | adapter->roce_db.total_size = | ||
3418 | pci_resource_len(adapter->pdev, db_reg); | ||
3419 | } | ||
3420 | return 0; | 3659 | return 0; |
3660 | |||
3421 | pci_map_err: | 3661 | pci_map_err: |
3422 | be_unmap_pci_bars(adapter); | 3662 | be_unmap_pci_bars(adapter); |
3423 | return -ENOMEM; | 3663 | return -ENOMEM; |
@@ -3437,7 +3677,6 @@ static void be_ctrl_cleanup(struct be_adapter *adapter) | |||
3437 | if (mem->va) | 3677 | if (mem->va) |
3438 | dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, | 3678 | dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, |
3439 | mem->dma); | 3679 | mem->dma); |
3440 | kfree(adapter->pmac_id); | ||
3441 | } | 3680 | } |
3442 | 3681 | ||
3443 | static int be_ctrl_init(struct be_adapter *adapter) | 3682 | static int be_ctrl_init(struct be_adapter *adapter) |
@@ -3445,8 +3684,14 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
3445 | struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; | 3684 | struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; |
3446 | struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; | 3685 | struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; |
3447 | struct be_dma_mem *rx_filter = &adapter->rx_filter; | 3686 | struct be_dma_mem *rx_filter = &adapter->rx_filter; |
3687 | u32 sli_intf; | ||
3448 | int status; | 3688 | int status; |
3449 | 3689 | ||
3690 | pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3691 | adapter->sli_family = (sli_intf & SLI_INTF_FAMILY_MASK) >> | ||
3692 | SLI_INTF_FAMILY_SHIFT; | ||
3693 | adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; | ||
3694 | |||
3450 | status = be_map_pci_bars(adapter); | 3695 | status = be_map_pci_bars(adapter); |
3451 | if (status) | 3696 | if (status) |
3452 | goto done; | 3697 | goto done; |
@@ -3473,13 +3718,6 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
3473 | goto free_mbox; | 3718 | goto free_mbox; |
3474 | } | 3719 | } |
3475 | memset(rx_filter->va, 0, rx_filter->size); | 3720 | memset(rx_filter->va, 0, rx_filter->size); |
3476 | |||
3477 | /* primary mac needs 1 pmac entry */ | ||
3478 | adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1, | ||
3479 | sizeof(*adapter->pmac_id), GFP_KERNEL); | ||
3480 | if (!adapter->pmac_id) | ||
3481 | return -ENOMEM; | ||
3482 | |||
3483 | mutex_init(&adapter->mbox_lock); | 3721 | mutex_init(&adapter->mbox_lock); |
3484 | spin_lock_init(&adapter->mcc_lock); | 3722 | spin_lock_init(&adapter->mcc_lock); |
3485 | spin_lock_init(&adapter->mcc_cq_lock); | 3723 | spin_lock_init(&adapter->mcc_cq_lock); |
@@ -3512,14 +3750,14 @@ static int be_stats_init(struct be_adapter *adapter) | |||
3512 | { | 3750 | { |
3513 | struct be_dma_mem *cmd = &adapter->stats_cmd; | 3751 | struct be_dma_mem *cmd = &adapter->stats_cmd; |
3514 | 3752 | ||
3515 | if (adapter->generation == BE_GEN2) { | 3753 | if (lancer_chip(adapter)) |
3754 | cmd->size = sizeof(struct lancer_cmd_req_pport_stats); | ||
3755 | else if (BE2_chip(adapter)) | ||
3516 | cmd->size = sizeof(struct be_cmd_req_get_stats_v0); | 3756 | cmd->size = sizeof(struct be_cmd_req_get_stats_v0); |
3517 | } else { | 3757 | else |
3518 | if (lancer_chip(adapter)) | 3758 | /* BE3 and Skyhawk */ |
3519 | cmd->size = sizeof(struct lancer_cmd_req_pport_stats); | 3759 | cmd->size = sizeof(struct be_cmd_req_get_stats_v1); |
3520 | else | 3760 | |
3521 | cmd->size = sizeof(struct be_cmd_req_get_stats_v1); | ||
3522 | } | ||
3523 | cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, | 3761 | cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, |
3524 | GFP_KERNEL); | 3762 | GFP_KERNEL); |
3525 | if (cmd->va == NULL) | 3763 | if (cmd->va == NULL) |
@@ -3573,6 +3811,9 @@ u32 be_get_fw_log_level(struct be_adapter *adapter) | |||
3573 | u32 level = 0; | 3811 | u32 level = 0; |
3574 | int j; | 3812 | int j; |
3575 | 3813 | ||
3814 | if (lancer_chip(adapter)) | ||
3815 | return 0; | ||
3816 | |||
3576 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); | 3817 | memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); |
3577 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); | 3818 | extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); |
3578 | extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, | 3819 | extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size, |
@@ -3598,26 +3839,12 @@ u32 be_get_fw_log_level(struct be_adapter *adapter) | |||
3598 | err: | 3839 | err: |
3599 | return level; | 3840 | return level; |
3600 | } | 3841 | } |
3842 | |||
3601 | static int be_get_initial_config(struct be_adapter *adapter) | 3843 | static int be_get_initial_config(struct be_adapter *adapter) |
3602 | { | 3844 | { |
3603 | int status; | 3845 | int status; |
3604 | u32 level; | 3846 | u32 level; |
3605 | 3847 | ||
3606 | status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, | ||
3607 | &adapter->function_mode, &adapter->function_caps); | ||
3608 | if (status) | ||
3609 | return status; | ||
3610 | |||
3611 | if (adapter->function_mode & FLEX10_MODE) | ||
3612 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8; | ||
3613 | else | ||
3614 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; | ||
3615 | |||
3616 | if (be_physfn(adapter)) | ||
3617 | adapter->max_pmac_cnt = BE_UC_PMAC_COUNT; | ||
3618 | else | ||
3619 | adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT; | ||
3620 | |||
3621 | status = be_cmd_get_cntl_attributes(adapter); | 3848 | status = be_cmd_get_cntl_attributes(adapter); |
3622 | if (status) | 3849 | if (status) |
3623 | return status; | 3850 | return status; |
@@ -3642,55 +3869,6 @@ static int be_get_initial_config(struct be_adapter *adapter) | |||
3642 | return 0; | 3869 | return 0; |
3643 | } | 3870 | } |
3644 | 3871 | ||
3645 | static int be_dev_type_check(struct be_adapter *adapter) | ||
3646 | { | ||
3647 | struct pci_dev *pdev = adapter->pdev; | ||
3648 | u32 sli_intf = 0, if_type; | ||
3649 | |||
3650 | switch (pdev->device) { | ||
3651 | case BE_DEVICE_ID1: | ||
3652 | case OC_DEVICE_ID1: | ||
3653 | adapter->generation = BE_GEN2; | ||
3654 | break; | ||
3655 | case BE_DEVICE_ID2: | ||
3656 | case OC_DEVICE_ID2: | ||
3657 | adapter->generation = BE_GEN3; | ||
3658 | break; | ||
3659 | case OC_DEVICE_ID3: | ||
3660 | case OC_DEVICE_ID4: | ||
3661 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3662 | adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | ||
3663 | SLI_INTF_IF_TYPE_SHIFT; | ||
3664 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | ||
3665 | SLI_INTF_IF_TYPE_SHIFT; | ||
3666 | if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || | ||
3667 | !be_type_2_3(adapter)) { | ||
3668 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | ||
3669 | return -EINVAL; | ||
3670 | } | ||
3671 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> | ||
3672 | SLI_INTF_FAMILY_SHIFT); | ||
3673 | adapter->generation = BE_GEN3; | ||
3674 | break; | ||
3675 | case OC_DEVICE_ID5: | ||
3676 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3677 | if ((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) { | ||
3678 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | ||
3679 | return -EINVAL; | ||
3680 | } | ||
3681 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> | ||
3682 | SLI_INTF_FAMILY_SHIFT); | ||
3683 | adapter->generation = BE_GEN3; | ||
3684 | break; | ||
3685 | default: | ||
3686 | adapter->generation = 0; | ||
3687 | } | ||
3688 | |||
3689 | pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3690 | adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; | ||
3691 | return 0; | ||
3692 | } | ||
3693 | |||
3694 | static int lancer_recover_func(struct be_adapter *adapter) | 3872 | static int lancer_recover_func(struct be_adapter *adapter) |
3695 | { | 3873 | { |
3696 | int status; | 3874 | int status; |
@@ -3721,8 +3899,9 @@ static int lancer_recover_func(struct be_adapter *adapter) | |||
3721 | "Adapter SLIPORT recovery succeeded\n"); | 3899 | "Adapter SLIPORT recovery succeeded\n"); |
3722 | return 0; | 3900 | return 0; |
3723 | err: | 3901 | err: |
3724 | dev_err(&adapter->pdev->dev, | 3902 | if (adapter->eeh_error) |
3725 | "Adapter SLIPORT recovery failed\n"); | 3903 | dev_err(&adapter->pdev->dev, |
3904 | "Adapter SLIPORT recovery failed\n"); | ||
3726 | 3905 | ||
3727 | return status; | 3906 | return status; |
3728 | } | 3907 | } |
@@ -3845,11 +4024,6 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3845 | adapter = netdev_priv(netdev); | 4024 | adapter = netdev_priv(netdev); |
3846 | adapter->pdev = pdev; | 4025 | adapter->pdev = pdev; |
3847 | pci_set_drvdata(pdev, adapter); | 4026 | pci_set_drvdata(pdev, adapter); |
3848 | |||
3849 | status = be_dev_type_check(adapter); | ||
3850 | if (status) | ||
3851 | goto free_netdev; | ||
3852 | |||
3853 | adapter->netdev = netdev; | 4027 | adapter->netdev = netdev; |
3854 | SET_NETDEV_DEV(netdev, &pdev->dev); | 4028 | SET_NETDEV_DEV(netdev, &pdev->dev); |
3855 | 4029 | ||
@@ -4023,9 +4197,6 @@ static void be_shutdown(struct pci_dev *pdev) | |||
4023 | 4197 | ||
4024 | netif_device_detach(adapter->netdev); | 4198 | netif_device_detach(adapter->netdev); |
4025 | 4199 | ||
4026 | if (adapter->wol) | ||
4027 | be_setup_wol(adapter, true); | ||
4028 | |||
4029 | be_cmd_reset_function(adapter); | 4200 | be_cmd_reset_function(adapter); |
4030 | 4201 | ||
4031 | pci_disable_device(pdev); | 4202 | pci_disable_device(pdev); |
@@ -4061,9 +4232,13 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, | |||
4061 | 4232 | ||
4062 | /* The error could cause the FW to trigger a flash debug dump. | 4233 | /* The error could cause the FW to trigger a flash debug dump. |
4063 | * Resetting the card while flash dump is in progress | 4234 | * Resetting the card while flash dump is in progress |
4064 | * can cause it not to recover; wait for it to finish | 4235 | * can cause it not to recover; wait for it to finish. |
4236 | * Wait only for first function as it is needed only once per | ||
4237 | * adapter. | ||
4065 | */ | 4238 | */ |
4066 | ssleep(30); | 4239 | if (pdev->devfn == 0) |
4240 | ssleep(30); | ||
4241 | |||
4067 | return PCI_ERS_RESULT_NEED_RESET; | 4242 | return PCI_ERS_RESULT_NEED_RESET; |
4068 | } | 4243 | } |
4069 | 4244 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c index deecc44b3617..55d32aa0a093 100644 --- a/drivers/net/ethernet/emulex/benet/be_roce.c +++ b/drivers/net/ethernet/emulex/benet/be_roce.c | |||
@@ -47,10 +47,7 @@ static void _be_roce_dev_add(struct be_adapter *adapter) | |||
47 | dev_info.dpp_unmapped_len = 0; | 47 | dev_info.dpp_unmapped_len = 0; |
48 | } | 48 | } |
49 | dev_info.pdev = adapter->pdev; | 49 | dev_info.pdev = adapter->pdev; |
50 | if (adapter->sli_family == SKYHAWK_SLI_FAMILY) | 50 | dev_info.db = adapter->db; |
51 | dev_info.db = adapter->db; | ||
52 | else | ||
53 | dev_info.db = adapter->roce_db.base; | ||
54 | dev_info.unmapped_db = adapter->roce_db.io_addr; | 51 | dev_info.unmapped_db = adapter->roce_db.io_addr; |
55 | dev_info.db_page_size = adapter->roce_db.size; | 52 | dev_info.db_page_size = adapter->roce_db.size; |
56 | dev_info.db_total_size = adapter->roce_db.total_size; | 53 | dev_info.db_total_size = adapter->roce_db.total_size; |
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index feff51664dcf..5ba6e1cbd346 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig | |||
@@ -92,4 +92,13 @@ config GIANFAR | |||
92 | This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, | 92 | This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, |
93 | and MPC86xx family of chips, and the FEC on the 8540. | 93 | and MPC86xx family of chips, and the FEC on the 8540. |
94 | 94 | ||
95 | config FEC_PTP | ||
96 | bool "PTP Hardware Clock (PHC)" | ||
97 | depends on FEC && ARCH_MXC | ||
98 | select PTP_1588_CLOCK | ||
99 | default y if SOC_IMX6Q | ||
100 | --help--- | ||
101 | Say Y here if you want to use PTP Hardware Clock (PHC) in the | ||
102 | driver. Only the basic clock operations have been implemented. | ||
103 | |||
95 | endif # NET_VENDOR_FREESCALE | 104 | endif # NET_VENDOR_FREESCALE |
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile index 3d1839afff65..d4d19b3d00ae 100644 --- a/drivers/net/ethernet/freescale/Makefile +++ b/drivers/net/ethernet/freescale/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_FEC) += fec.o | 5 | obj-$(CONFIG_FEC) += fec.o |
6 | obj-$(CONFIG_FEC_PTP) += fec_ptp.o | ||
6 | obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o | 7 | obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o |
7 | ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y) | 8 | ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y) |
8 | obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o | 9 | obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o |
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index fffd20528b5d..2665162ff4e5 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c | |||
@@ -140,21 +140,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); | |||
140 | #endif | 140 | #endif |
141 | #endif /* CONFIG_M5272 */ | 141 | #endif /* CONFIG_M5272 */ |
142 | 142 | ||
143 | /* The number of Tx and Rx buffers. These are allocated from the page | ||
144 | * pool. The code may assume these are power of two, so it it best | ||
145 | * to keep them that size. | ||
146 | * We don't need to allocate pages for the transmitter. We just use | ||
147 | * the skbuffer directly. | ||
148 | */ | ||
149 | #define FEC_ENET_RX_PAGES 8 | ||
150 | #define FEC_ENET_RX_FRSIZE 2048 | ||
151 | #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE) | ||
152 | #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) | ||
153 | #define FEC_ENET_TX_FRSIZE 2048 | ||
154 | #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE) | ||
155 | #define TX_RING_SIZE 16 /* Must be power of two */ | ||
156 | #define TX_RING_MOD_MASK 15 /* for this to work */ | ||
157 | |||
158 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) | 143 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) |
159 | #error "FEC: descriptor ring size constants too large" | 144 | #error "FEC: descriptor ring size constants too large" |
160 | #endif | 145 | #endif |
@@ -179,9 +164,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); | |||
179 | #define PKT_MINBUF_SIZE 64 | 164 | #define PKT_MINBUF_SIZE 64 |
180 | #define PKT_MAXBLR_SIZE 1520 | 165 | #define PKT_MAXBLR_SIZE 1520 |
181 | 166 | ||
182 | /* This device has up to three irqs on some platforms */ | ||
183 | #define FEC_IRQ_NUM 3 | ||
184 | |||
185 | /* | 167 | /* |
186 | * The 5270/5271/5280/5282/532x RX control register also contains maximum frame | 168 | * The 5270/5271/5280/5282/532x RX control register also contains maximum frame |
187 | * size bits. Other FEC hardware does not, so we need to take that into | 169 | * size bits. Other FEC hardware does not, so we need to take that into |
@@ -194,61 +176,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); | |||
194 | #define OPT_FRAME_SIZE 0 | 176 | #define OPT_FRAME_SIZE 0 |
195 | #endif | 177 | #endif |
196 | 178 | ||
197 | /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and | ||
198 | * tx_bd_base always point to the base of the buffer descriptors. The | ||
199 | * cur_rx and cur_tx point to the currently available buffer. | ||
200 | * The dirty_tx tracks the current buffer that is being sent by the | ||
201 | * controller. The cur_tx and dirty_tx are equal under both completely | ||
202 | * empty and completely full conditions. The empty/ready indicator in | ||
203 | * the buffer descriptor determines the actual condition. | ||
204 | */ | ||
205 | struct fec_enet_private { | ||
206 | /* Hardware registers of the FEC device */ | ||
207 | void __iomem *hwp; | ||
208 | |||
209 | struct net_device *netdev; | ||
210 | |||
211 | struct clk *clk_ipg; | ||
212 | struct clk *clk_ahb; | ||
213 | |||
214 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | ||
215 | unsigned char *tx_bounce[TX_RING_SIZE]; | ||
216 | struct sk_buff* tx_skbuff[TX_RING_SIZE]; | ||
217 | struct sk_buff* rx_skbuff[RX_RING_SIZE]; | ||
218 | ushort skb_cur; | ||
219 | ushort skb_dirty; | ||
220 | |||
221 | /* CPM dual port RAM relative addresses */ | ||
222 | dma_addr_t bd_dma; | ||
223 | /* Address of Rx and Tx buffers */ | ||
224 | struct bufdesc *rx_bd_base; | ||
225 | struct bufdesc *tx_bd_base; | ||
226 | /* The next free ring entry */ | ||
227 | struct bufdesc *cur_rx, *cur_tx; | ||
228 | /* The ring entries to be free()ed */ | ||
229 | struct bufdesc *dirty_tx; | ||
230 | |||
231 | uint tx_full; | ||
232 | /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ | ||
233 | spinlock_t hw_lock; | ||
234 | |||
235 | struct platform_device *pdev; | ||
236 | |||
237 | int opened; | ||
238 | int dev_id; | ||
239 | |||
240 | /* Phylib and MDIO interface */ | ||
241 | struct mii_bus *mii_bus; | ||
242 | struct phy_device *phy_dev; | ||
243 | int mii_timeout; | ||
244 | uint phy_speed; | ||
245 | phy_interface_t phy_interface; | ||
246 | int link; | ||
247 | int full_duplex; | ||
248 | struct completion mdio_done; | ||
249 | int irq[FEC_IRQ_NUM]; | ||
250 | }; | ||
251 | |||
252 | /* FEC MII MMFR bits definition */ | 179 | /* FEC MII MMFR bits definition */ |
253 | #define FEC_MMFR_ST (1 << 30) | 180 | #define FEC_MMFR_ST (1 << 30) |
254 | #define FEC_MMFR_OP_READ (2 << 28) | 181 | #define FEC_MMFR_OP_READ (2 << 28) |
@@ -353,6 +280,17 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
353 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | 280 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); |
354 | bdp->cbd_sc = status; | 281 | bdp->cbd_sc = status; |
355 | 282 | ||
283 | #ifdef CONFIG_FEC_PTP | ||
284 | bdp->cbd_bdu = 0; | ||
285 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && | ||
286 | fep->hwts_tx_en)) { | ||
287 | bdp->cbd_esc = (BD_ENET_TX_TS | BD_ENET_TX_INT); | ||
288 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
289 | } else { | ||
290 | |||
291 | bdp->cbd_esc = BD_ENET_TX_INT; | ||
292 | } | ||
293 | #endif | ||
356 | /* Trigger transmission start */ | 294 | /* Trigger transmission start */ |
357 | writel(0, fep->hwp + FEC_X_DES_ACTIVE); | 295 | writel(0, fep->hwp + FEC_X_DES_ACTIVE); |
358 | 296 | ||
@@ -510,10 +448,17 @@ fec_restart(struct net_device *ndev, int duplex) | |||
510 | writel(1 << 8, fep->hwp + FEC_X_WMRK); | 448 | writel(1 << 8, fep->hwp + FEC_X_WMRK); |
511 | } | 449 | } |
512 | 450 | ||
451 | #ifdef CONFIG_FEC_PTP | ||
452 | ecntl |= (1 << 4); | ||
453 | #endif | ||
454 | |||
513 | /* And last, enable the transmit and receive processing */ | 455 | /* And last, enable the transmit and receive processing */ |
514 | writel(ecntl, fep->hwp + FEC_ECNTRL); | 456 | writel(ecntl, fep->hwp + FEC_ECNTRL); |
515 | writel(0, fep->hwp + FEC_R_DES_ACTIVE); | 457 | writel(0, fep->hwp + FEC_R_DES_ACTIVE); |
516 | 458 | ||
459 | #ifdef CONFIG_FEC_PTP | ||
460 | fec_ptp_start_cyclecounter(ndev); | ||
461 | #endif | ||
517 | /* Enable interrupts we wish to service */ | 462 | /* Enable interrupts we wish to service */ |
518 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); | 463 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); |
519 | } | 464 | } |
@@ -599,6 +544,19 @@ fec_enet_tx(struct net_device *ndev) | |||
599 | ndev->stats.tx_packets++; | 544 | ndev->stats.tx_packets++; |
600 | } | 545 | } |
601 | 546 | ||
547 | #ifdef CONFIG_FEC_PTP | ||
548 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { | ||
549 | struct skb_shared_hwtstamps shhwtstamps; | ||
550 | unsigned long flags; | ||
551 | |||
552 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | ||
553 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
554 | shhwtstamps.hwtstamp = ns_to_ktime( | ||
555 | timecounter_cyc2time(&fep->tc, bdp->ts)); | ||
556 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
557 | skb_tstamp_tx(skb, &shhwtstamps); | ||
558 | } | ||
559 | #endif | ||
602 | if (status & BD_ENET_TX_READY) | 560 | if (status & BD_ENET_TX_READY) |
603 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); | 561 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); |
604 | 562 | ||
@@ -725,6 +683,21 @@ fec_enet_rx(struct net_device *ndev) | |||
725 | skb_put(skb, pkt_len - 4); /* Make room */ | 683 | skb_put(skb, pkt_len - 4); /* Make room */ |
726 | skb_copy_to_linear_data(skb, data, pkt_len - 4); | 684 | skb_copy_to_linear_data(skb, data, pkt_len - 4); |
727 | skb->protocol = eth_type_trans(skb, ndev); | 685 | skb->protocol = eth_type_trans(skb, ndev); |
686 | #ifdef CONFIG_FEC_PTP | ||
687 | /* Get receive timestamp from the skb */ | ||
688 | if (fep->hwts_rx_en) { | ||
689 | struct skb_shared_hwtstamps *shhwtstamps = | ||
690 | skb_hwtstamps(skb); | ||
691 | unsigned long flags; | ||
692 | |||
693 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | ||
694 | |||
695 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
696 | shhwtstamps->hwtstamp = ns_to_ktime( | ||
697 | timecounter_cyc2time(&fep->tc, bdp->ts)); | ||
698 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
699 | } | ||
700 | #endif | ||
728 | if (!skb_defer_rx_timestamp(skb)) | 701 | if (!skb_defer_rx_timestamp(skb)) |
729 | netif_rx(skb); | 702 | netif_rx(skb); |
730 | } | 703 | } |
@@ -739,6 +712,12 @@ rx_processing_done: | |||
739 | status |= BD_ENET_RX_EMPTY; | 712 | status |= BD_ENET_RX_EMPTY; |
740 | bdp->cbd_sc = status; | 713 | bdp->cbd_sc = status; |
741 | 714 | ||
715 | #ifdef CONFIG_FEC_PTP | ||
716 | bdp->cbd_esc = BD_ENET_RX_INT; | ||
717 | bdp->cbd_prot = 0; | ||
718 | bdp->cbd_bdu = 0; | ||
719 | #endif | ||
720 | |||
742 | /* Update BD pointer to next entry */ | 721 | /* Update BD pointer to next entry */ |
743 | if (status & BD_ENET_RX_WRAP) | 722 | if (status & BD_ENET_RX_WRAP) |
744 | bdp = fep->rx_bd_base; | 723 | bdp = fep->rx_bd_base; |
@@ -1178,6 +1157,10 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) | |||
1178 | if (!phydev) | 1157 | if (!phydev) |
1179 | return -ENODEV; | 1158 | return -ENODEV; |
1180 | 1159 | ||
1160 | #ifdef CONFIG_FEC_PTP | ||
1161 | if (cmd == SIOCSHWTSTAMP) | ||
1162 | return fec_ptp_ioctl(ndev, rq, cmd); | ||
1163 | #endif | ||
1181 | return phy_mii_ioctl(phydev, rq, cmd); | 1164 | return phy_mii_ioctl(phydev, rq, cmd); |
1182 | } | 1165 | } |
1183 | 1166 | ||
@@ -1224,6 +1207,9 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) | |||
1224 | bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data, | 1207 | bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data, |
1225 | FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); | 1208 | FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); |
1226 | bdp->cbd_sc = BD_ENET_RX_EMPTY; | 1209 | bdp->cbd_sc = BD_ENET_RX_EMPTY; |
1210 | #ifdef CONFIG_FEC_PTP | ||
1211 | bdp->cbd_esc = BD_ENET_RX_INT; | ||
1212 | #endif | ||
1227 | bdp++; | 1213 | bdp++; |
1228 | } | 1214 | } |
1229 | 1215 | ||
@@ -1237,6 +1223,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) | |||
1237 | 1223 | ||
1238 | bdp->cbd_sc = 0; | 1224 | bdp->cbd_sc = 0; |
1239 | bdp->cbd_bufaddr = 0; | 1225 | bdp->cbd_bufaddr = 0; |
1226 | |||
1227 | #ifdef CONFIG_FEC_PTP | ||
1228 | bdp->cbd_esc = BD_ENET_RX_INT; | ||
1229 | #endif | ||
1240 | bdp++; | 1230 | bdp++; |
1241 | } | 1231 | } |
1242 | 1232 | ||
@@ -1638,9 +1628,19 @@ fec_probe(struct platform_device *pdev) | |||
1638 | goto failed_clk; | 1628 | goto failed_clk; |
1639 | } | 1629 | } |
1640 | 1630 | ||
1631 | #ifdef CONFIG_FEC_PTP | ||
1632 | fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); | ||
1633 | if (IS_ERR(fep->clk_ptp)) { | ||
1634 | ret = PTR_ERR(fep->clk_ptp); | ||
1635 | goto failed_clk; | ||
1636 | } | ||
1637 | #endif | ||
1638 | |||
1641 | clk_prepare_enable(fep->clk_ahb); | 1639 | clk_prepare_enable(fep->clk_ahb); |
1642 | clk_prepare_enable(fep->clk_ipg); | 1640 | clk_prepare_enable(fep->clk_ipg); |
1643 | 1641 | #ifdef CONFIG_FEC_PTP | |
1642 | clk_prepare_enable(fep->clk_ptp); | ||
1643 | #endif | ||
1644 | reg_phy = devm_regulator_get(&pdev->dev, "phy"); | 1644 | reg_phy = devm_regulator_get(&pdev->dev, "phy"); |
1645 | if (!IS_ERR(reg_phy)) { | 1645 | if (!IS_ERR(reg_phy)) { |
1646 | ret = regulator_enable(reg_phy); | 1646 | ret = regulator_enable(reg_phy); |
@@ -1668,6 +1668,10 @@ fec_probe(struct platform_device *pdev) | |||
1668 | if (ret) | 1668 | if (ret) |
1669 | goto failed_register; | 1669 | goto failed_register; |
1670 | 1670 | ||
1671 | #ifdef CONFIG_FEC_PTP | ||
1672 | fec_ptp_init(ndev, pdev); | ||
1673 | #endif | ||
1674 | |||
1671 | return 0; | 1675 | return 0; |
1672 | 1676 | ||
1673 | failed_register: | 1677 | failed_register: |
@@ -1677,6 +1681,9 @@ failed_init: | |||
1677 | failed_regulator: | 1681 | failed_regulator: |
1678 | clk_disable_unprepare(fep->clk_ahb); | 1682 | clk_disable_unprepare(fep->clk_ahb); |
1679 | clk_disable_unprepare(fep->clk_ipg); | 1683 | clk_disable_unprepare(fep->clk_ipg); |
1684 | #ifdef CONFIG_FEC_PTP | ||
1685 | clk_disable_unprepare(fep->clk_ptp); | ||
1686 | #endif | ||
1680 | failed_pin: | 1687 | failed_pin: |
1681 | failed_clk: | 1688 | failed_clk: |
1682 | for (i = 0; i < FEC_IRQ_NUM; i++) { | 1689 | for (i = 0; i < FEC_IRQ_NUM; i++) { |
@@ -1709,6 +1716,12 @@ fec_drv_remove(struct platform_device *pdev) | |||
1709 | if (irq > 0) | 1716 | if (irq > 0) |
1710 | free_irq(irq, ndev); | 1717 | free_irq(irq, ndev); |
1711 | } | 1718 | } |
1719 | #ifdef CONFIG_FEC_PTP | ||
1720 | del_timer_sync(&fep->time_keep); | ||
1721 | clk_disable_unprepare(fep->clk_ptp); | ||
1722 | if (fep->ptp_clock) | ||
1723 | ptp_clock_unregister(fep->ptp_clock); | ||
1724 | #endif | ||
1712 | clk_disable_unprepare(fep->clk_ahb); | 1725 | clk_disable_unprepare(fep->clk_ahb); |
1713 | clk_disable_unprepare(fep->clk_ipg); | 1726 | clk_disable_unprepare(fep->clk_ipg); |
1714 | iounmap(fep->hwp); | 1727 | iounmap(fep->hwp); |
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 8408c627b195..c5a3bc1475c7 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
@@ -13,6 +13,12 @@ | |||
13 | #define FEC_H | 13 | #define FEC_H |
14 | /****************************************************************************/ | 14 | /****************************************************************************/ |
15 | 15 | ||
16 | #ifdef CONFIG_FEC_PTP | ||
17 | #include <linux/clocksource.h> | ||
18 | #include <linux/net_tstamp.h> | ||
19 | #include <linux/ptp_clock_kernel.h> | ||
20 | #endif | ||
21 | |||
16 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ | 22 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
17 | defined(CONFIG_M520x) || defined(CONFIG_M532x) || \ | 23 | defined(CONFIG_M520x) || defined(CONFIG_M532x) || \ |
18 | defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) | 24 | defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) |
@@ -88,6 +94,13 @@ struct bufdesc { | |||
88 | unsigned short cbd_datlen; /* Data length */ | 94 | unsigned short cbd_datlen; /* Data length */ |
89 | unsigned short cbd_sc; /* Control and status info */ | 95 | unsigned short cbd_sc; /* Control and status info */ |
90 | unsigned long cbd_bufaddr; /* Buffer address */ | 96 | unsigned long cbd_bufaddr; /* Buffer address */ |
97 | #ifdef CONFIG_FEC_PTP | ||
98 | unsigned long cbd_esc; | ||
99 | unsigned long cbd_prot; | ||
100 | unsigned long cbd_bdu; | ||
101 | unsigned long ts; | ||
102 | unsigned short res0[4]; | ||
103 | #endif | ||
91 | }; | 104 | }; |
92 | #else | 105 | #else |
93 | struct bufdesc { | 106 | struct bufdesc { |
@@ -147,6 +160,112 @@ struct bufdesc { | |||
147 | #define BD_ENET_TX_CSL ((ushort)0x0001) | 160 | #define BD_ENET_TX_CSL ((ushort)0x0001) |
148 | #define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ | 161 | #define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ |
149 | 162 | ||
163 | /*enhanced buffer desciptor control/status used by Ethernet transmit*/ | ||
164 | #define BD_ENET_TX_INT 0x40000000 | ||
165 | #define BD_ENET_TX_TS 0x20000000 | ||
166 | |||
167 | |||
168 | /* This device has up to three irqs on some platforms */ | ||
169 | #define FEC_IRQ_NUM 3 | ||
170 | |||
171 | /* The number of Tx and Rx buffers. These are allocated from the page | ||
172 | * pool. The code may assume these are power of two, so it it best | ||
173 | * to keep them that size. | ||
174 | * We don't need to allocate pages for the transmitter. We just use | ||
175 | * the skbuffer directly. | ||
176 | */ | ||
177 | |||
178 | #define FEC_ENET_RX_PAGES 8 | ||
179 | #define FEC_ENET_RX_FRSIZE 2048 | ||
180 | #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE) | ||
181 | #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) | ||
182 | #define FEC_ENET_TX_FRSIZE 2048 | ||
183 | #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE) | ||
184 | #define TX_RING_SIZE 16 /* Must be power of two */ | ||
185 | #define TX_RING_MOD_MASK 15 /* for this to work */ | ||
186 | |||
187 | #define BD_ENET_RX_INT 0x00800000 | ||
188 | #define BD_ENET_RX_PTP ((ushort)0x0400) | ||
189 | |||
190 | /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and | ||
191 | * tx_bd_base always point to the base of the buffer descriptors. The | ||
192 | * cur_rx and cur_tx point to the currently available buffer. | ||
193 | * The dirty_tx tracks the current buffer that is being sent by the | ||
194 | * controller. The cur_tx and dirty_tx are equal under both completely | ||
195 | * empty and completely full conditions. The empty/ready indicator in | ||
196 | * the buffer descriptor determines the actual condition. | ||
197 | */ | ||
198 | struct fec_enet_private { | ||
199 | /* Hardware registers of the FEC device */ | ||
200 | void __iomem *hwp; | ||
201 | |||
202 | struct net_device *netdev; | ||
203 | |||
204 | struct clk *clk_ipg; | ||
205 | struct clk *clk_ahb; | ||
206 | #ifdef CONFIG_FEC_PTP | ||
207 | struct clk *clk_ptp; | ||
208 | #endif | ||
209 | |||
210 | /* The saved address of a sent-in-place packet/buffer, for skfree(). */ | ||
211 | unsigned char *tx_bounce[TX_RING_SIZE]; | ||
212 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | ||
213 | struct sk_buff *rx_skbuff[RX_RING_SIZE]; | ||
214 | ushort skb_cur; | ||
215 | ushort skb_dirty; | ||
216 | |||
217 | /* CPM dual port RAM relative addresses */ | ||
218 | dma_addr_t bd_dma; | ||
219 | /* Address of Rx and Tx buffers */ | ||
220 | struct bufdesc *rx_bd_base; | ||
221 | struct bufdesc *tx_bd_base; | ||
222 | /* The next free ring entry */ | ||
223 | struct bufdesc *cur_rx, *cur_tx; | ||
224 | /* The ring entries to be free()ed */ | ||
225 | struct bufdesc *dirty_tx; | ||
226 | |||
227 | uint tx_full; | ||
228 | /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ | ||
229 | spinlock_t hw_lock; | ||
230 | |||
231 | struct platform_device *pdev; | ||
232 | |||
233 | int opened; | ||
234 | int dev_id; | ||
235 | |||
236 | /* Phylib and MDIO interface */ | ||
237 | struct mii_bus *mii_bus; | ||
238 | struct phy_device *phy_dev; | ||
239 | int mii_timeout; | ||
240 | uint phy_speed; | ||
241 | phy_interface_t phy_interface; | ||
242 | int link; | ||
243 | int full_duplex; | ||
244 | struct completion mdio_done; | ||
245 | int irq[FEC_IRQ_NUM]; | ||
246 | |||
247 | #ifdef CONFIG_FEC_PTP | ||
248 | struct ptp_clock *ptp_clock; | ||
249 | struct ptp_clock_info ptp_caps; | ||
250 | unsigned long last_overflow_check; | ||
251 | spinlock_t tmreg_lock; | ||
252 | struct cyclecounter cc; | ||
253 | struct timecounter tc; | ||
254 | int rx_hwtstamp_filter; | ||
255 | u32 base_incval; | ||
256 | u32 cycle_speed; | ||
257 | int hwts_rx_en; | ||
258 | int hwts_tx_en; | ||
259 | struct timer_list time_keep; | ||
260 | #endif | ||
261 | |||
262 | }; | ||
263 | |||
264 | #ifdef CONFIG_FEC_PTP | ||
265 | void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev); | ||
266 | void fec_ptp_start_cyclecounter(struct net_device *ndev); | ||
267 | int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd); | ||
268 | #endif | ||
150 | 269 | ||
151 | /****************************************************************************/ | 270 | /****************************************************************************/ |
152 | #endif /* FEC_H */ | 271 | #endif /* FEC_H */ |
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c new file mode 100644 index 000000000000..c40526c78c20 --- /dev/null +++ b/drivers/net/ethernet/freescale/fec_ptp.c | |||
@@ -0,0 +1,383 @@ | |||
1 | /* | ||
2 | * Fast Ethernet Controller (ENET) PTP driver for MX6x. | ||
3 | * | ||
4 | * Copyright (C) 2012 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/ptrace.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | #include <linux/etherdevice.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/spinlock.h> | ||
35 | #include <linux/workqueue.h> | ||
36 | #include <linux/bitops.h> | ||
37 | #include <linux/io.h> | ||
38 | #include <linux/irq.h> | ||
39 | #include <linux/clk.h> | ||
40 | #include <linux/platform_device.h> | ||
41 | #include <linux/phy.h> | ||
42 | #include <linux/fec.h> | ||
43 | #include <linux/of.h> | ||
44 | #include <linux/of_device.h> | ||
45 | #include <linux/of_gpio.h> | ||
46 | #include <linux/of_net.h> | ||
47 | |||
48 | #include "fec.h" | ||
49 | |||
50 | /* FEC 1588 register bits */ | ||
51 | #define FEC_T_CTRL_SLAVE 0x00002000 | ||
52 | #define FEC_T_CTRL_CAPTURE 0x00000800 | ||
53 | #define FEC_T_CTRL_RESTART 0x00000200 | ||
54 | #define FEC_T_CTRL_PERIOD_RST 0x00000030 | ||
55 | #define FEC_T_CTRL_PERIOD_EN 0x00000010 | ||
56 | #define FEC_T_CTRL_ENABLE 0x00000001 | ||
57 | |||
58 | #define FEC_T_INC_MASK 0x0000007f | ||
59 | #define FEC_T_INC_OFFSET 0 | ||
60 | #define FEC_T_INC_CORR_MASK 0x00007f00 | ||
61 | #define FEC_T_INC_CORR_OFFSET 8 | ||
62 | |||
63 | #define FEC_ATIME_CTRL 0x400 | ||
64 | #define FEC_ATIME 0x404 | ||
65 | #define FEC_ATIME_EVT_OFFSET 0x408 | ||
66 | #define FEC_ATIME_EVT_PERIOD 0x40c | ||
67 | #define FEC_ATIME_CORR 0x410 | ||
68 | #define FEC_ATIME_INC 0x414 | ||
69 | #define FEC_TS_TIMESTAMP 0x418 | ||
70 | |||
71 | #define FEC_CC_MULT (1 << 31) | ||
72 | /** | ||
73 | * fec_ptp_read - read raw cycle counter (to be used by time counter) | ||
74 | * @cc: the cyclecounter structure | ||
75 | * | ||
76 | * this function reads the cyclecounter registers and is called by the | ||
77 | * cyclecounter structure used to construct a ns counter from the | ||
78 | * arbitrary fixed point registers | ||
79 | */ | ||
80 | static cycle_t fec_ptp_read(const struct cyclecounter *cc) | ||
81 | { | ||
82 | struct fec_enet_private *fep = | ||
83 | container_of(cc, struct fec_enet_private, cc); | ||
84 | u32 tempval; | ||
85 | |||
86 | tempval = readl(fep->hwp + FEC_ATIME_CTRL); | ||
87 | tempval |= FEC_T_CTRL_CAPTURE; | ||
88 | writel(tempval, fep->hwp + FEC_ATIME_CTRL); | ||
89 | |||
90 | return readl(fep->hwp + FEC_ATIME); | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * fec_ptp_start_cyclecounter - create the cycle counter from hw | ||
95 | * @ndev: network device | ||
96 | * | ||
97 | * this function initializes the timecounter and cyclecounter | ||
98 | * structures for use in generated a ns counter from the arbitrary | ||
99 | * fixed point cycles registers in the hardware. | ||
100 | */ | ||
101 | void fec_ptp_start_cyclecounter(struct net_device *ndev) | ||
102 | { | ||
103 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
104 | unsigned long flags; | ||
105 | int inc; | ||
106 | |||
107 | inc = 1000000000 / clk_get_rate(fep->clk_ptp); | ||
108 | |||
109 | /* grab the ptp lock */ | ||
110 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
111 | |||
112 | /* 1ns counter */ | ||
113 | writel(inc << FEC_T_INC_OFFSET, fep->hwp + FEC_ATIME_INC); | ||
114 | |||
115 | /* use free running count */ | ||
116 | writel(0, fep->hwp + FEC_ATIME_EVT_PERIOD); | ||
117 | |||
118 | writel(FEC_T_CTRL_ENABLE, fep->hwp + FEC_ATIME_CTRL); | ||
119 | |||
120 | memset(&fep->cc, 0, sizeof(fep->cc)); | ||
121 | fep->cc.read = fec_ptp_read; | ||
122 | fep->cc.mask = CLOCKSOURCE_MASK(32); | ||
123 | fep->cc.shift = 31; | ||
124 | fep->cc.mult = FEC_CC_MULT; | ||
125 | |||
126 | /* reset the ns time counter */ | ||
127 | timecounter_init(&fep->tc, &fep->cc, ktime_to_ns(ktime_get_real())); | ||
128 | |||
129 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * fec_ptp_adjfreq - adjust ptp cycle frequency | ||
134 | * @ptp: the ptp clock structure | ||
135 | * @ppb: parts per billion adjustment from base | ||
136 | * | ||
137 | * Adjust the frequency of the ptp cycle counter by the | ||
138 | * indicated ppb from the base frequency. | ||
139 | * | ||
140 | * Because ENET hardware frequency adjust is complex, | ||
141 | * using software method to do that. | ||
142 | */ | ||
143 | static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | ||
144 | { | ||
145 | u64 diff; | ||
146 | unsigned long flags; | ||
147 | int neg_adj = 0; | ||
148 | u32 mult = FEC_CC_MULT; | ||
149 | |||
150 | struct fec_enet_private *fep = | ||
151 | container_of(ptp, struct fec_enet_private, ptp_caps); | ||
152 | |||
153 | if (ppb < 0) { | ||
154 | ppb = -ppb; | ||
155 | neg_adj = 1; | ||
156 | } | ||
157 | |||
158 | diff = mult; | ||
159 | diff *= ppb; | ||
160 | diff = div_u64(diff, 1000000000ULL); | ||
161 | |||
162 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
163 | /* | ||
164 | * dummy read to set cycle_last in tc to now. | ||
165 | * So use adjusted mult to calculate when next call | ||
166 | * timercounter_read. | ||
167 | */ | ||
168 | timecounter_read(&fep->tc); | ||
169 | |||
170 | fep->cc.mult = neg_adj ? mult - diff : mult + diff; | ||
171 | |||
172 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * fec_ptp_adjtime | ||
179 | * @ptp: the ptp clock structure | ||
180 | * @delta: offset to adjust the cycle counter by | ||
181 | * | ||
182 | * adjust the timer by resetting the timecounter structure. | ||
183 | */ | ||
184 | static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | ||
185 | { | ||
186 | struct fec_enet_private *fep = | ||
187 | container_of(ptp, struct fec_enet_private, ptp_caps); | ||
188 | unsigned long flags; | ||
189 | u64 now; | ||
190 | |||
191 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
192 | |||
193 | now = timecounter_read(&fep->tc); | ||
194 | now += delta; | ||
195 | |||
196 | /* reset the timecounter */ | ||
197 | timecounter_init(&fep->tc, &fep->cc, now); | ||
198 | |||
199 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * fec_ptp_gettime | ||
206 | * @ptp: the ptp clock structure | ||
207 | * @ts: timespec structure to hold the current time value | ||
208 | * | ||
209 | * read the timecounter and return the correct value on ns, | ||
210 | * after converting it into a struct timespec. | ||
211 | */ | ||
212 | static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | ||
213 | { | ||
214 | struct fec_enet_private *adapter = | ||
215 | container_of(ptp, struct fec_enet_private, ptp_caps); | ||
216 | u64 ns; | ||
217 | u32 remainder; | ||
218 | unsigned long flags; | ||
219 | |||
220 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | ||
221 | ns = timecounter_read(&adapter->tc); | ||
222 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | ||
223 | |||
224 | ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); | ||
225 | ts->tv_nsec = remainder; | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | /** | ||
231 | * fec_ptp_settime | ||
232 | * @ptp: the ptp clock structure | ||
233 | * @ts: the timespec containing the new time for the cycle counter | ||
234 | * | ||
235 | * reset the timecounter to use a new base value instead of the kernel | ||
236 | * wall timer value. | ||
237 | */ | ||
238 | static int fec_ptp_settime(struct ptp_clock_info *ptp, | ||
239 | const struct timespec *ts) | ||
240 | { | ||
241 | struct fec_enet_private *fep = | ||
242 | container_of(ptp, struct fec_enet_private, ptp_caps); | ||
243 | |||
244 | u64 ns; | ||
245 | unsigned long flags; | ||
246 | |||
247 | ns = ts->tv_sec * 1000000000ULL; | ||
248 | ns += ts->tv_nsec; | ||
249 | |||
250 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
251 | timecounter_init(&fep->tc, &fep->cc, ns); | ||
252 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * fec_ptp_enable | ||
258 | * @ptp: the ptp clock structure | ||
259 | * @rq: the requested feature to change | ||
260 | * @on: whether to enable or disable the feature | ||
261 | * | ||
262 | */ | ||
263 | static int fec_ptp_enable(struct ptp_clock_info *ptp, | ||
264 | struct ptp_clock_request *rq, int on) | ||
265 | { | ||
266 | return -EOPNOTSUPP; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * fec_ptp_hwtstamp_ioctl - control hardware time stamping | ||
271 | * @ndev: pointer to net_device | ||
272 | * @ifreq: ioctl data | ||
273 | * @cmd: particular ioctl requested | ||
274 | */ | ||
275 | int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) | ||
276 | { | ||
277 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
278 | |||
279 | struct hwtstamp_config config; | ||
280 | |||
281 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | ||
282 | return -EFAULT; | ||
283 | |||
284 | /* reserved for future extensions */ | ||
285 | if (config.flags) | ||
286 | return -EINVAL; | ||
287 | |||
288 | switch (config.tx_type) { | ||
289 | case HWTSTAMP_TX_OFF: | ||
290 | fep->hwts_tx_en = 0; | ||
291 | break; | ||
292 | case HWTSTAMP_TX_ON: | ||
293 | fep->hwts_tx_en = 1; | ||
294 | break; | ||
295 | default: | ||
296 | return -ERANGE; | ||
297 | } | ||
298 | |||
299 | switch (config.rx_filter) { | ||
300 | case HWTSTAMP_FILTER_NONE: | ||
301 | if (fep->hwts_rx_en) | ||
302 | fep->hwts_rx_en = 0; | ||
303 | config.rx_filter = HWTSTAMP_FILTER_NONE; | ||
304 | break; | ||
305 | |||
306 | default: | ||
307 | /* | ||
308 | * register RXMTRL must be set in order to do V1 packets, | ||
309 | * therefore it is not possible to time stamp both V1 Sync and | ||
310 | * Delay_Req messages and hardware does not support | ||
311 | * timestamping all packets => return error | ||
312 | */ | ||
313 | fep->hwts_rx_en = 1; | ||
314 | config.rx_filter = HWTSTAMP_FILTER_ALL; | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? | ||
319 | -EFAULT : 0; | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * fec_time_keep - call timecounter_read every second to avoid timer overrun | ||
324 | * because ENET just support 32bit counter, will timeout in 4s | ||
325 | */ | ||
326 | static void fec_time_keep(unsigned long _data) | ||
327 | { | ||
328 | struct fec_enet_private *fep = (struct fec_enet_private *)_data; | ||
329 | u64 ns; | ||
330 | unsigned long flags; | ||
331 | |||
332 | spin_lock_irqsave(&fep->tmreg_lock, flags); | ||
333 | ns = timecounter_read(&fep->tc); | ||
334 | spin_unlock_irqrestore(&fep->tmreg_lock, flags); | ||
335 | |||
336 | mod_timer(&fep->time_keep, jiffies + HZ); | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * fec_ptp_init | ||
341 | * @ndev: The FEC network adapter | ||
342 | * | ||
343 | * This function performs the required steps for enabling ptp | ||
344 | * support. If ptp support has already been loaded it simply calls the | ||
345 | * cyclecounter init routine and exits. | ||
346 | */ | ||
347 | |||
348 | void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev) | ||
349 | { | ||
350 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
351 | |||
352 | fep->ptp_caps.owner = THIS_MODULE; | ||
353 | snprintf(fep->ptp_caps.name, 16, "fec ptp"); | ||
354 | |||
355 | fep->ptp_caps.max_adj = 250000000; | ||
356 | fep->ptp_caps.n_alarm = 0; | ||
357 | fep->ptp_caps.n_ext_ts = 0; | ||
358 | fep->ptp_caps.n_per_out = 0; | ||
359 | fep->ptp_caps.pps = 0; | ||
360 | fep->ptp_caps.adjfreq = fec_ptp_adjfreq; | ||
361 | fep->ptp_caps.adjtime = fec_ptp_adjtime; | ||
362 | fep->ptp_caps.gettime = fec_ptp_gettime; | ||
363 | fep->ptp_caps.settime = fec_ptp_settime; | ||
364 | fep->ptp_caps.enable = fec_ptp_enable; | ||
365 | |||
366 | spin_lock_init(&fep->tmreg_lock); | ||
367 | |||
368 | fec_ptp_start_cyclecounter(ndev); | ||
369 | |||
370 | init_timer(&fep->time_keep); | ||
371 | fep->time_keep.data = (unsigned long)fep; | ||
372 | fep->time_keep.function = fec_time_keep; | ||
373 | fep->time_keep.expires = jiffies + HZ; | ||
374 | add_timer(&fep->time_keep); | ||
375 | |||
376 | fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); | ||
377 | if (IS_ERR(fep->ptp_clock)) { | ||
378 | fep->ptp_clock = NULL; | ||
379 | pr_err("ptp_clock_register failed\n"); | ||
380 | } else { | ||
381 | pr_info("registered PHC device on %s\n", ndev->name); | ||
382 | } | ||
383 | } | ||
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 19ac096cb07b..bffb2edd6858 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -210,7 +210,7 @@ static int gfar_init_bds(struct net_device *ndev) | |||
210 | skb = gfar_new_skb(ndev); | 210 | skb = gfar_new_skb(ndev); |
211 | if (!skb) { | 211 | if (!skb) { |
212 | netdev_err(ndev, "Can't allocate RX buffers\n"); | 212 | netdev_err(ndev, "Can't allocate RX buffers\n"); |
213 | goto err_rxalloc_fail; | 213 | return -ENOMEM; |
214 | } | 214 | } |
215 | rx_queue->rx_skbuff[j] = skb; | 215 | rx_queue->rx_skbuff[j] = skb; |
216 | 216 | ||
@@ -223,10 +223,6 @@ static int gfar_init_bds(struct net_device *ndev) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | return 0; | 225 | return 0; |
226 | |||
227 | err_rxalloc_fail: | ||
228 | free_skb_resources(priv); | ||
229 | return -ENOMEM; | ||
230 | } | 226 | } |
231 | 227 | ||
232 | static int gfar_alloc_skb_resources(struct net_device *ndev) | 228 | static int gfar_alloc_skb_resources(struct net_device *ndev) |
@@ -1359,7 +1355,11 @@ static int gfar_restore(struct device *dev) | |||
1359 | return 0; | 1355 | return 0; |
1360 | } | 1356 | } |
1361 | 1357 | ||
1362 | gfar_init_bds(ndev); | 1358 | if (gfar_init_bds(ndev)) { |
1359 | free_skb_resources(priv); | ||
1360 | return -ENOMEM; | ||
1361 | } | ||
1362 | |||
1363 | init_registers(ndev); | 1363 | init_registers(ndev); |
1364 | gfar_set_mac_address(ndev); | 1364 | gfar_set_mac_address(ndev); |
1365 | gfar_init_mac(ndev); | 1365 | gfar_init_mac(ndev); |
@@ -1712,6 +1712,7 @@ static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue) | |||
1712 | tx_queue->tx_skbuff[i] = NULL; | 1712 | tx_queue->tx_skbuff[i] = NULL; |
1713 | } | 1713 | } |
1714 | kfree(tx_queue->tx_skbuff); | 1714 | kfree(tx_queue->tx_skbuff); |
1715 | tx_queue->tx_skbuff = NULL; | ||
1715 | } | 1716 | } |
1716 | 1717 | ||
1717 | static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) | 1718 | static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) |
@@ -1735,6 +1736,7 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) | |||
1735 | rxbdp++; | 1736 | rxbdp++; |
1736 | } | 1737 | } |
1737 | kfree(rx_queue->rx_skbuff); | 1738 | kfree(rx_queue->rx_skbuff); |
1739 | rx_queue->rx_skbuff = NULL; | ||
1738 | } | 1740 | } |
1739 | 1741 | ||
1740 | /* If there are any tx skbs or rx skbs still around, free them. | 1742 | /* If there are any tx skbs or rx skbs still around, free them. |
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index 479e43e2f1ef..84c6b6cf9c14 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c | |||
@@ -738,13 +738,11 @@ static int __devexit mal_remove(struct platform_device *ofdev) | |||
738 | /* Synchronize with scheduled polling */ | 738 | /* Synchronize with scheduled polling */ |
739 | napi_disable(&mal->napi); | 739 | napi_disable(&mal->napi); |
740 | 740 | ||
741 | if (!list_empty(&mal->list)) { | 741 | if (!list_empty(&mal->list)) |
742 | /* This is *very* bad */ | 742 | /* This is *very* bad */ |
743 | printk(KERN_EMERG | 743 | WARN(1, KERN_EMERG |
744 | "mal%d: commac list is not empty on remove!\n", | 744 | "mal%d: commac list is not empty on remove!\n", |
745 | mal->index); | 745 | mal->index); |
746 | WARN_ON(1); | ||
747 | } | ||
748 | 746 | ||
749 | dev_set_drvdata(&ofdev->dev, NULL); | 747 | dev_set_drvdata(&ofdev->dev, NULL); |
750 | 748 | ||
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 0cafe4fe9406..73d28d51b5d9 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig | |||
@@ -93,6 +93,7 @@ config E1000E | |||
93 | config IGB | 93 | config IGB |
94 | tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" | 94 | tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" |
95 | depends on PCI | 95 | depends on PCI |
96 | select PTP_1588_CLOCK | ||
96 | ---help--- | 97 | ---help--- |
97 | This driver supports Intel(R) 82575/82576 gigabit ethernet family of | 98 | This driver supports Intel(R) 82575/82576 gigabit ethernet family of |
98 | adapters. For more information on how to identify your adapter, go | 99 | adapters. For more information on how to identify your adapter, go |
@@ -120,19 +121,6 @@ config IGB_DCA | |||
120 | driver. DCA is a method for warming the CPU cache before data | 121 | driver. DCA is a method for warming the CPU cache before data |
121 | is used, with the intent of lessening the impact of cache misses. | 122 | is used, with the intent of lessening the impact of cache misses. |
122 | 123 | ||
123 | config IGB_PTP | ||
124 | bool "PTP Hardware Clock (PHC)" | ||
125 | default n | ||
126 | depends on IGB && EXPERIMENTAL | ||
127 | select PPS | ||
128 | select PTP_1588_CLOCK | ||
129 | ---help--- | ||
130 | Say Y here if you want to use PTP Hardware Clock (PHC) in the | ||
131 | driver. Only the basic clock operations have been implemented. | ||
132 | |||
133 | Every timestamp and clock read operations must consult the | ||
134 | overflow counter to form a correct time value. | ||
135 | |||
136 | config IGBVF | 124 | config IGBVF |
137 | tristate "Intel(R) 82576 Virtual Function Ethernet support" | 125 | tristate "Intel(R) 82576 Virtual Function Ethernet support" |
138 | depends on PCI | 126 | depends on PCI |
@@ -180,6 +168,7 @@ config IXGBE | |||
180 | tristate "Intel(R) 10GbE PCI Express adapters support" | 168 | tristate "Intel(R) 10GbE PCI Express adapters support" |
181 | depends on PCI && INET | 169 | depends on PCI && INET |
182 | select MDIO | 170 | select MDIO |
171 | select PTP_1588_CLOCK | ||
183 | ---help--- | 172 | ---help--- |
184 | This driver supports Intel(R) 10GbE PCI Express family of | 173 | This driver supports Intel(R) 10GbE PCI Express family of |
185 | adapters. For more information on how to identify your adapter, go | 174 | adapters. For more information on how to identify your adapter, go |
@@ -222,19 +211,6 @@ config IXGBE_DCB | |||
222 | 211 | ||
223 | If unsure, say N. | 212 | If unsure, say N. |
224 | 213 | ||
225 | config IXGBE_PTP | ||
226 | bool "PTP Clock Support" | ||
227 | default n | ||
228 | depends on IXGBE && EXPERIMENTAL | ||
229 | select PPS | ||
230 | select PTP_1588_CLOCK | ||
231 | ---help--- | ||
232 | Say Y here if you want support for 1588 Timestamping with a | ||
233 | PHC device, using the PTP 1588 Clock support. This is | ||
234 | required to enable timestamping support for the device. | ||
235 | |||
236 | If unsure, say N. | ||
237 | |||
238 | config IXGBEVF | 214 | config IXGBEVF |
239 | tristate "Intel(R) 82599 Virtual Function Ethernet support" | 215 | tristate "Intel(R) 82599 Virtual Function Ethernet support" |
240 | depends on PCI_MSI | 216 | depends on PCI_MSI |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.c b/drivers/net/ethernet/intel/e1000/e1000_hw.c index 3d6839528761..8fedd2451538 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.c +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.c | |||
@@ -107,6 +107,7 @@ u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = { | |||
107 | }; | 107 | }; |
108 | 108 | ||
109 | static DEFINE_SPINLOCK(e1000_eeprom_lock); | 109 | static DEFINE_SPINLOCK(e1000_eeprom_lock); |
110 | static DEFINE_SPINLOCK(e1000_phy_lock); | ||
110 | 111 | ||
111 | /** | 112 | /** |
112 | * e1000_set_phy_type - Set the phy type member in the hw struct. | 113 | * e1000_set_phy_type - Set the phy type member in the hw struct. |
@@ -2830,19 +2831,25 @@ static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw) | |||
2830 | s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data) | 2831 | s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data) |
2831 | { | 2832 | { |
2832 | u32 ret_val; | 2833 | u32 ret_val; |
2834 | unsigned long flags; | ||
2833 | 2835 | ||
2834 | e_dbg("e1000_read_phy_reg"); | 2836 | e_dbg("e1000_read_phy_reg"); |
2835 | 2837 | ||
2838 | spin_lock_irqsave(&e1000_phy_lock, flags); | ||
2839 | |||
2836 | if ((hw->phy_type == e1000_phy_igp) && | 2840 | if ((hw->phy_type == e1000_phy_igp) && |
2837 | (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { | 2841 | (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { |
2838 | ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, | 2842 | ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, |
2839 | (u16) reg_addr); | 2843 | (u16) reg_addr); |
2840 | if (ret_val) | 2844 | if (ret_val) { |
2845 | spin_unlock_irqrestore(&e1000_phy_lock, flags); | ||
2841 | return ret_val; | 2846 | return ret_val; |
2847 | } | ||
2842 | } | 2848 | } |
2843 | 2849 | ||
2844 | ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, | 2850 | ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, |
2845 | phy_data); | 2851 | phy_data); |
2852 | spin_unlock_irqrestore(&e1000_phy_lock, flags); | ||
2846 | 2853 | ||
2847 | return ret_val; | 2854 | return ret_val; |
2848 | } | 2855 | } |
@@ -2965,19 +2972,25 @@ static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr, | |||
2965 | s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data) | 2972 | s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data) |
2966 | { | 2973 | { |
2967 | u32 ret_val; | 2974 | u32 ret_val; |
2975 | unsigned long flags; | ||
2968 | 2976 | ||
2969 | e_dbg("e1000_write_phy_reg"); | 2977 | e_dbg("e1000_write_phy_reg"); |
2970 | 2978 | ||
2979 | spin_lock_irqsave(&e1000_phy_lock, flags); | ||
2980 | |||
2971 | if ((hw->phy_type == e1000_phy_igp) && | 2981 | if ((hw->phy_type == e1000_phy_igp) && |
2972 | (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { | 2982 | (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { |
2973 | ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, | 2983 | ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, |
2974 | (u16) reg_addr); | 2984 | (u16) reg_addr); |
2975 | if (ret_val) | 2985 | if (ret_val) { |
2986 | spin_unlock_irqrestore(&e1000_phy_lock, flags); | ||
2976 | return ret_val; | 2987 | return ret_val; |
2988 | } | ||
2977 | } | 2989 | } |
2978 | 2990 | ||
2979 | ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, | 2991 | ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr, |
2980 | phy_data); | 2992 | phy_data); |
2993 | spin_unlock_irqrestore(&e1000_phy_lock, flags); | ||
2981 | 2994 | ||
2982 | return ret_val; | 2995 | return ret_val; |
2983 | } | 2996 | } |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index f444eb0b76d8..dadb13be479a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -5067,6 +5067,17 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5067 | return NETDEV_TX_OK; | 5067 | return NETDEV_TX_OK; |
5068 | } | 5068 | } |
5069 | 5069 | ||
5070 | /* | ||
5071 | * The minimum packet size with TCTL.PSP set is 17 bytes so | ||
5072 | * pad skb in order to meet this minimum size requirement | ||
5073 | */ | ||
5074 | if (unlikely(skb->len < 17)) { | ||
5075 | if (skb_pad(skb, 17 - skb->len)) | ||
5076 | return NETDEV_TX_OK; | ||
5077 | skb->len = 17; | ||
5078 | skb_set_tail_pointer(skb, 17); | ||
5079 | } | ||
5080 | |||
5070 | mss = skb_shinfo(skb)->gso_size; | 5081 | mss = skb_shinfo(skb)->gso_size; |
5071 | if (mss) { | 5082 | if (mss) { |
5072 | u8 hdr_len; | 5083 | u8 hdr_len; |
diff --git a/drivers/net/ethernet/intel/igb/Makefile b/drivers/net/ethernet/intel/igb/Makefile index 97c197fd4a8e..624476cfa727 100644 --- a/drivers/net/ethernet/intel/igb/Makefile +++ b/drivers/net/ethernet/intel/igb/Makefile | |||
@@ -34,6 +34,4 @@ obj-$(CONFIG_IGB) += igb.o | |||
34 | 34 | ||
35 | igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \ | 35 | igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \ |
36 | e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \ | 36 | e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \ |
37 | e1000_i210.o | 37 | e1000_i210.o igb_ptp.o |
38 | |||
39 | igb-$(CONFIG_IGB_PTP) += igb_ptp.o | ||
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index ca4641e2f748..deb05970b9f1 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -319,6 +319,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
319 | nvm->ops.acquire = igb_acquire_nvm_i210; | 319 | nvm->ops.acquire = igb_acquire_nvm_i210; |
320 | nvm->ops.release = igb_release_nvm_i210; | 320 | nvm->ops.release = igb_release_nvm_i210; |
321 | nvm->ops.read = igb_read_nvm_srrd_i210; | 321 | nvm->ops.read = igb_read_nvm_srrd_i210; |
322 | nvm->ops.write = igb_write_nvm_srwr_i210; | ||
322 | nvm->ops.valid_led_default = igb_valid_led_default_i210; | 323 | nvm->ops.valid_led_default = igb_valid_led_default_i210; |
323 | break; | 324 | break; |
324 | case e1000_i211: | 325 | case e1000_i211: |
@@ -2233,19 +2234,16 @@ s32 igb_set_eee_i350(struct e1000_hw *hw) | |||
2233 | 2234 | ||
2234 | /* enable or disable per user setting */ | 2235 | /* enable or disable per user setting */ |
2235 | if (!(hw->dev_spec._82575.eee_disable)) { | 2236 | if (!(hw->dev_spec._82575.eee_disable)) { |
2236 | ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | | 2237 | u32 eee_su = rd32(E1000_EEE_SU); |
2237 | E1000_IPCNFG_EEE_100M_AN); | 2238 | |
2238 | eeer |= (E1000_EEER_TX_LPI_EN | | 2239 | ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); |
2239 | E1000_EEER_RX_LPI_EN | | 2240 | eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | |
2240 | E1000_EEER_LPI_FC); | 2241 | E1000_EEER_LPI_FC); |
2241 | 2242 | ||
2242 | /* keep the LPI clock running before EEE is enabled */ | 2243 | /* This bit should not be set in normal operation. */ |
2243 | if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) { | 2244 | if (eee_su & E1000_EEE_SU_LPI_CLK_STP) |
2244 | u32 eee_su; | 2245 | hw_dbg("LPI Clock Stop Bit should not be set!\n"); |
2245 | eee_su = rd32(E1000_EEE_SU); | 2246 | |
2246 | eee_su &= ~E1000_EEE_SU_LPI_CLK_STP; | ||
2247 | wr32(E1000_EEE_SU, eee_su); | ||
2248 | } | ||
2249 | 2247 | ||
2250 | } else { | 2248 | } else { |
2251 | ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | | 2249 | ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | |
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h index e85c453f5428..44b76b3b6816 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.h +++ b/drivers/net/ethernet/intel/igb/e1000_82575.h | |||
@@ -172,10 +172,13 @@ struct e1000_adv_tx_context_desc { | |||
172 | #define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ | 172 | #define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ |
173 | #define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */ | 173 | #define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */ |
174 | #define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */ | 174 | #define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */ |
175 | #define E1000_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */ | ||
175 | 176 | ||
176 | #define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ | 177 | #define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ |
177 | #define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ | 178 | #define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ |
179 | #define E1000_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */ | ||
178 | #define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ | 180 | #define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ |
181 | #define E1000_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */ | ||
179 | 182 | ||
180 | /* Additional DCA related definitions, note change in position of CPUID */ | 183 | /* Additional DCA related definitions, note change in position of CPUID */ |
181 | #define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ | 184 | #define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ |
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index de4b41ec3c40..e647cff9a5e3 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h | |||
@@ -636,6 +636,7 @@ | |||
636 | /* NVM Word Offsets */ | 636 | /* NVM Word Offsets */ |
637 | #define NVM_COMPAT 0x0003 | 637 | #define NVM_COMPAT 0x0003 |
638 | #define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */ | 638 | #define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */ |
639 | #define NVM_VERSION 0x0005 | ||
639 | #define NVM_INIT_CONTROL2_REG 0x000F | 640 | #define NVM_INIT_CONTROL2_REG 0x000F |
640 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 | 641 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 |
641 | #define NVM_INIT_CONTROL3_PORT_A 0x0024 | 642 | #define NVM_INIT_CONTROL3_PORT_A 0x0024 |
@@ -653,6 +654,19 @@ | |||
653 | #define NVM_LED_1_CFG 0x001C | 654 | #define NVM_LED_1_CFG 0x001C |
654 | #define NVM_LED_0_2_CFG 0x001F | 655 | #define NVM_LED_0_2_CFG 0x001F |
655 | 656 | ||
657 | /* NVM version defines */ | ||
658 | #define NVM_ETRACK_WORD 0x0042 | ||
659 | #define NVM_COMB_VER_OFF 0x0083 | ||
660 | #define NVM_COMB_VER_PTR 0x003d | ||
661 | #define NVM_MAJOR_MASK 0xF000 | ||
662 | #define NVM_MINOR_MASK 0x0FF0 | ||
663 | #define NVM_BUILD_MASK 0x000F | ||
664 | #define NVM_COMB_VER_MASK 0x00FF | ||
665 | #define NVM_MAJOR_SHIFT 12 | ||
666 | #define NVM_MINOR_SHIFT 4 | ||
667 | #define NVM_COMB_VER_SHFT 8 | ||
668 | #define NVM_VER_INVALID 0xFFFF | ||
669 | #define NVM_ETRACK_SHIFT 16 | ||
656 | 670 | ||
657 | #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ | 671 | #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ |
658 | #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ | 672 | #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index 77a5f939bc74..41474298d365 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c | |||
@@ -423,6 +423,100 @@ s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | /** | 425 | /** |
426 | * igb_read_invm_version - Reads iNVM version and image type | ||
427 | * @hw: pointer to the HW structure | ||
428 | * @invm_ver: version structure for the version read | ||
429 | * | ||
430 | * Reads iNVM version and image type. | ||
431 | **/ | ||
432 | s32 igb_read_invm_version(struct e1000_hw *hw, | ||
433 | struct e1000_fw_version *invm_ver) { | ||
434 | u32 *record = NULL; | ||
435 | u32 *next_record = NULL; | ||
436 | u32 i = 0; | ||
437 | u32 invm_dword = 0; | ||
438 | u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE / | ||
439 | E1000_INVM_RECORD_SIZE_IN_BYTES); | ||
440 | u32 buffer[E1000_INVM_SIZE]; | ||
441 | s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND; | ||
442 | u16 version = 0; | ||
443 | |||
444 | /* Read iNVM memory */ | ||
445 | for (i = 0; i < E1000_INVM_SIZE; i++) { | ||
446 | invm_dword = rd32(E1000_INVM_DATA_REG(i)); | ||
447 | buffer[i] = invm_dword; | ||
448 | } | ||
449 | |||
450 | /* Read version number */ | ||
451 | for (i = 1; i < invm_blocks; i++) { | ||
452 | record = &buffer[invm_blocks - i]; | ||
453 | next_record = &buffer[invm_blocks - i + 1]; | ||
454 | |||
455 | /* Check if we have first version location used */ | ||
456 | if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) { | ||
457 | version = 0; | ||
458 | status = E1000_SUCCESS; | ||
459 | break; | ||
460 | } | ||
461 | /* Check if we have second version location used */ | ||
462 | else if ((i == 1) && | ||
463 | ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) { | ||
464 | version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; | ||
465 | status = E1000_SUCCESS; | ||
466 | break; | ||
467 | } | ||
468 | /* Check if we have odd version location | ||
469 | * used and it is the last one used | ||
470 | */ | ||
471 | else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) && | ||
472 | ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) && | ||
473 | (i != 1))) { | ||
474 | version = (*next_record & E1000_INVM_VER_FIELD_TWO) | ||
475 | >> 13; | ||
476 | status = E1000_SUCCESS; | ||
477 | break; | ||
478 | } | ||
479 | /* Check if we have even version location | ||
480 | * used and it is the last one used | ||
481 | */ | ||
482 | else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) && | ||
483 | ((*record & 0x3) == 0)) { | ||
484 | version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3; | ||
485 | status = E1000_SUCCESS; | ||
486 | break; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | if (status == E1000_SUCCESS) { | ||
491 | invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK) | ||
492 | >> E1000_INVM_MAJOR_SHIFT; | ||
493 | invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK; | ||
494 | } | ||
495 | /* Read Image Type */ | ||
496 | for (i = 1; i < invm_blocks; i++) { | ||
497 | record = &buffer[invm_blocks - i]; | ||
498 | next_record = &buffer[invm_blocks - i + 1]; | ||
499 | |||
500 | /* Check if we have image type in first location used */ | ||
501 | if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) { | ||
502 | invm_ver->invm_img_type = 0; | ||
503 | status = E1000_SUCCESS; | ||
504 | break; | ||
505 | } | ||
506 | /* Check if we have image type in first location used */ | ||
507 | else if ((((*record & 0x3) == 0) && | ||
508 | ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) || | ||
509 | ((((*record & 0x3) != 0) && (i != 1)))) { | ||
510 | invm_ver->invm_img_type = | ||
511 | (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23; | ||
512 | status = E1000_SUCCESS; | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | return status; | ||
517 | } | ||
518 | |||
519 | /** | ||
426 | * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum | 520 | * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum |
427 | * @hw: pointer to the HW structure | 521 | * @hw: pointer to the HW structure |
428 | * | 522 | * |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h index 5dc2bd3f50bc..974d23584d70 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.h +++ b/drivers/net/ethernet/intel/igb/e1000_i210.h | |||
@@ -43,6 +43,8 @@ extern void igb_release_nvm_i210(struct e1000_hw *hw); | |||
43 | extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); | 43 | extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data); |
44 | extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, | 44 | extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, |
45 | u16 *data); | 45 | u16 *data); |
46 | extern s32 igb_read_invm_version(struct e1000_hw *hw, | ||
47 | struct e1000_fw_version *invm_ver); | ||
46 | 48 | ||
47 | #define E1000_STM_OPCODE 0xDB00 | 49 | #define E1000_STM_OPCODE 0xDB00 |
48 | #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 | 50 | #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 |
@@ -65,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE { | |||
65 | 67 | ||
66 | #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 | 68 | #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 |
67 | #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 | 69 | #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 |
70 | #define E1000_INVM_ULT_BYTES_SIZE 8 | ||
71 | #define E1000_INVM_RECORD_SIZE_IN_BYTES 4 | ||
72 | #define E1000_INVM_VER_FIELD_ONE 0x1FF8 | ||
73 | #define E1000_INVM_VER_FIELD_TWO 0x7FE000 | ||
74 | #define E1000_INVM_IMGTYPE_FIELD 0x1F800000 | ||
75 | |||
76 | #define E1000_INVM_MAJOR_MASK 0x3F0 | ||
77 | #define E1000_INVM_MINOR_MASK 0xF | ||
78 | #define E1000_INVM_MAJOR_SHIFT 4 | ||
68 | 79 | ||
69 | #define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ | 80 | #define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ |
70 | (ID_LED_OFF1_OFF2 << 4) | \ | 81 | (ID_LED_OFF1_OFF2 << 4) | \ |
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index 819c145ac762..7acddfe9e6d5 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c | |||
@@ -1391,6 +1391,10 @@ s32 igb_validate_mdi_setting(struct e1000_hw *hw) | |||
1391 | { | 1391 | { |
1392 | s32 ret_val = 0; | 1392 | s32 ret_val = 0; |
1393 | 1393 | ||
1394 | /* All MDI settings are supported on 82580 and newer. */ | ||
1395 | if (hw->mac.type >= e1000_82580) | ||
1396 | goto out; | ||
1397 | |||
1394 | if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) { | 1398 | if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) { |
1395 | hw_dbg("Invalid MDI setting detected\n"); | 1399 | hw_dbg("Invalid MDI setting detected\n"); |
1396 | hw->phy.mdix = 1; | 1400 | hw->phy.mdix = 1; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h index cbddc4e51e30..e2b2c4b9c951 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.h +++ b/drivers/net/ethernet/intel/igb/e1000_mac.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "e1000_phy.h" | 33 | #include "e1000_phy.h" |
34 | #include "e1000_nvm.h" | 34 | #include "e1000_nvm.h" |
35 | #include "e1000_defines.h" | 35 | #include "e1000_defines.h" |
36 | #include "e1000_i210.h" | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Functions that should not be called directly from drivers but can be used | 39 | * Functions that should not be called directly from drivers but can be used |
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c index aa5fcdf3f357..7db3f80bcd57 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.c +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c | |||
@@ -710,3 +710,74 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw) | |||
710 | out: | 710 | out: |
711 | return ret_val; | 711 | return ret_val; |
712 | } | 712 | } |
713 | |||
714 | /** | ||
715 | * igb_get_fw_version - Get firmware version information | ||
716 | * @hw: pointer to the HW structure | ||
717 | * @fw_vers: pointer to output structure | ||
718 | * | ||
719 | * unsupported MAC types will return all 0 version structure | ||
720 | **/ | ||
721 | void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers) | ||
722 | { | ||
723 | u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; | ||
724 | u16 fw_version; | ||
725 | |||
726 | memset(fw_vers, 0, sizeof(struct e1000_fw_version)); | ||
727 | |||
728 | switch (hw->mac.type) { | ||
729 | case e1000_i211: | ||
730 | igb_read_invm_version(hw, fw_vers); | ||
731 | return; | ||
732 | case e1000_82575: | ||
733 | case e1000_82576: | ||
734 | case e1000_82580: | ||
735 | case e1000_i350: | ||
736 | case e1000_i210: | ||
737 | break; | ||
738 | default: | ||
739 | return; | ||
740 | } | ||
741 | /* basic eeprom version numbers */ | ||
742 | hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version); | ||
743 | fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK) >> NVM_MAJOR_SHIFT; | ||
744 | fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK); | ||
745 | |||
746 | /* etrack id */ | ||
747 | hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl); | ||
748 | hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh); | ||
749 | fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) | eeprom_verl; | ||
750 | |||
751 | switch (hw->mac.type) { | ||
752 | case e1000_i210: | ||
753 | case e1000_i350: | ||
754 | /* find combo image version */ | ||
755 | hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset); | ||
756 | if ((comb_offset != 0x0) && (comb_offset != NVM_VER_INVALID)) { | ||
757 | |||
758 | hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset | ||
759 | + 1), 1, &comb_verh); | ||
760 | hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset), | ||
761 | 1, &comb_verl); | ||
762 | |||
763 | /* get Option Rom version if it exists and is valid */ | ||
764 | if ((comb_verh && comb_verl) && | ||
765 | ((comb_verh != NVM_VER_INVALID) && | ||
766 | (comb_verl != NVM_VER_INVALID))) { | ||
767 | |||
768 | fw_vers->or_valid = true; | ||
769 | fw_vers->or_major = | ||
770 | comb_verl >> NVM_COMB_VER_SHFT; | ||
771 | fw_vers->or_build = | ||
772 | ((comb_verl << NVM_COMB_VER_SHFT) | ||
773 | | (comb_verh >> NVM_COMB_VER_SHFT)); | ||
774 | fw_vers->or_patch = | ||
775 | comb_verh & NVM_COMB_VER_MASK; | ||
776 | } | ||
777 | } | ||
778 | break; | ||
779 | default: | ||
780 | break; | ||
781 | } | ||
782 | return; | ||
783 | } | ||
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h index 825b0228cac0..7012d458c6f7 100644 --- a/drivers/net/ethernet/intel/igb/e1000_nvm.h +++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h | |||
@@ -40,4 +40,20 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); | |||
40 | s32 igb_validate_nvm_checksum(struct e1000_hw *hw); | 40 | s32 igb_validate_nvm_checksum(struct e1000_hw *hw); |
41 | s32 igb_update_nvm_checksum(struct e1000_hw *hw); | 41 | s32 igb_update_nvm_checksum(struct e1000_hw *hw); |
42 | 42 | ||
43 | struct e1000_fw_version { | ||
44 | u32 etrack_id; | ||
45 | u16 eep_major; | ||
46 | u16 eep_minor; | ||
47 | |||
48 | u8 invm_major; | ||
49 | u8 invm_minor; | ||
50 | u8 invm_img_type; | ||
51 | |||
52 | bool or_valid; | ||
53 | u16 or_major; | ||
54 | u16 or_build; | ||
55 | u16 or_patch; | ||
56 | }; | ||
57 | void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers); | ||
58 | |||
43 | #endif | 59 | #endif |
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index 3404bc79f4ca..fe76004aca4e 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c | |||
@@ -1207,20 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) | |||
1207 | u16 phy_data; | 1207 | u16 phy_data; |
1208 | bool link; | 1208 | bool link; |
1209 | 1209 | ||
1210 | /* | 1210 | /* I210 and I211 devices support Auto-Crossover in forced operation. */ |
1211 | * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI | 1211 | if (phy->type != e1000_phy_i210) { |
1212 | * forced whenever speed and duplex are forced. | 1212 | /* |
1213 | */ | 1213 | * Clear Auto-Crossover to force MDI manually. M88E1000 |
1214 | ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); | 1214 | * requires MDI forced whenever speed and duplex are forced. |
1215 | if (ret_val) | 1215 | */ |
1216 | goto out; | 1216 | ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, |
1217 | &phy_data); | ||
1218 | if (ret_val) | ||
1219 | goto out; | ||
1217 | 1220 | ||
1218 | phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; | 1221 | phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; |
1219 | ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); | 1222 | ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, |
1220 | if (ret_val) | 1223 | phy_data); |
1221 | goto out; | 1224 | if (ret_val) |
1225 | goto out; | ||
1222 | 1226 | ||
1223 | hw_dbg("M88E1000 PSCR: %X\n", phy_data); | 1227 | hw_dbg("M88E1000 PSCR: %X\n", phy_data); |
1228 | } | ||
1224 | 1229 | ||
1225 | ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); | 1230 | ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); |
1226 | if (ret_val) | 1231 | if (ret_val) |
@@ -1710,6 +1715,26 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw) | |||
1710 | 1715 | ||
1711 | switch (hw->phy.id) { | 1716 | switch (hw->phy.id) { |
1712 | case I210_I_PHY_ID: | 1717 | case I210_I_PHY_ID: |
1718 | /* Get cable length from PHY Cable Diagnostics Control Reg */ | ||
1719 | ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) + | ||
1720 | (I347AT4_PCDL + phy->addr), | ||
1721 | &phy_data); | ||
1722 | if (ret_val) | ||
1723 | return ret_val; | ||
1724 | |||
1725 | /* Check if the unit of cable length is meters or cm */ | ||
1726 | ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) + | ||
1727 | I347AT4_PCDC, &phy_data2); | ||
1728 | if (ret_val) | ||
1729 | return ret_val; | ||
1730 | |||
1731 | is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT); | ||
1732 | |||
1733 | /* Populate the phy structure with cable length in meters */ | ||
1734 | phy->min_cable_length = phy_data / (is_cm ? 100 : 1); | ||
1735 | phy->max_cable_length = phy_data / (is_cm ? 100 : 1); | ||
1736 | phy->cable_length = phy_data / (is_cm ? 100 : 1); | ||
1737 | break; | ||
1713 | case I347AT4_E_PHY_ID: | 1738 | case I347AT4_E_PHY_ID: |
1714 | /* Remember the original page select and set it to 7 */ | 1739 | /* Remember the original page select and set it to 7 */ |
1715 | ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, | 1740 | ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, |
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 8aad230c0592..796db53954d9 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h | |||
@@ -34,11 +34,9 @@ | |||
34 | #include "e1000_mac.h" | 34 | #include "e1000_mac.h" |
35 | #include "e1000_82575.h" | 35 | #include "e1000_82575.h" |
36 | 36 | ||
37 | #ifdef CONFIG_IGB_PTP | ||
38 | #include <linux/clocksource.h> | 37 | #include <linux/clocksource.h> |
39 | #include <linux/net_tstamp.h> | 38 | #include <linux/net_tstamp.h> |
40 | #include <linux/ptp_clock_kernel.h> | 39 | #include <linux/ptp_clock_kernel.h> |
41 | #endif /* CONFIG_IGB_PTP */ | ||
42 | #include <linux/bitops.h> | 40 | #include <linux/bitops.h> |
43 | #include <linux/if_vlan.h> | 41 | #include <linux/if_vlan.h> |
44 | 42 | ||
@@ -132,9 +130,10 @@ struct vf_data_storage { | |||
132 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 | 130 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 |
133 | 131 | ||
134 | /* Supported Rx Buffer Sizes */ | 132 | /* Supported Rx Buffer Sizes */ |
135 | #define IGB_RXBUFFER_256 256 | 133 | #define IGB_RXBUFFER_256 256 |
136 | #define IGB_RXBUFFER_16384 16384 | 134 | #define IGB_RXBUFFER_2048 2048 |
137 | #define IGB_RX_HDR_LEN IGB_RXBUFFER_256 | 135 | #define IGB_RX_HDR_LEN IGB_RXBUFFER_256 |
136 | #define IGB_RX_BUFSZ IGB_RXBUFFER_2048 | ||
138 | 137 | ||
139 | /* How many Tx Descriptors do we need to call netif_wake_queue ? */ | 138 | /* How many Tx Descriptors do we need to call netif_wake_queue ? */ |
140 | #define IGB_TX_QUEUE_WAKE 16 | 139 | #define IGB_TX_QUEUE_WAKE 16 |
@@ -174,11 +173,9 @@ struct igb_tx_buffer { | |||
174 | }; | 173 | }; |
175 | 174 | ||
176 | struct igb_rx_buffer { | 175 | struct igb_rx_buffer { |
177 | struct sk_buff *skb; | ||
178 | dma_addr_t dma; | 176 | dma_addr_t dma; |
179 | struct page *page; | 177 | struct page *page; |
180 | dma_addr_t page_dma; | 178 | unsigned int page_offset; |
181 | u32 page_offset; | ||
182 | }; | 179 | }; |
183 | 180 | ||
184 | struct igb_tx_queue_stats { | 181 | struct igb_tx_queue_stats { |
@@ -205,22 +202,6 @@ struct igb_ring_container { | |||
205 | u8 itr; /* current ITR setting for ring */ | 202 | u8 itr; /* current ITR setting for ring */ |
206 | }; | 203 | }; |
207 | 204 | ||
208 | struct igb_q_vector { | ||
209 | struct igb_adapter *adapter; /* backlink */ | ||
210 | int cpu; /* CPU for DCA */ | ||
211 | u32 eims_value; /* EIMS mask value */ | ||
212 | |||
213 | struct igb_ring_container rx, tx; | ||
214 | |||
215 | struct napi_struct napi; | ||
216 | |||
217 | u16 itr_val; | ||
218 | u8 set_itr; | ||
219 | void __iomem *itr_register; | ||
220 | |||
221 | char name[IFNAMSIZ + 9]; | ||
222 | }; | ||
223 | |||
224 | struct igb_ring { | 205 | struct igb_ring { |
225 | struct igb_q_vector *q_vector; /* backlink to q_vector */ | 206 | struct igb_q_vector *q_vector; /* backlink to q_vector */ |
226 | struct net_device *netdev; /* back pointer to net_device */ | 207 | struct net_device *netdev; /* back pointer to net_device */ |
@@ -232,15 +213,17 @@ struct igb_ring { | |||
232 | void *desc; /* descriptor ring memory */ | 213 | void *desc; /* descriptor ring memory */ |
233 | unsigned long flags; /* ring specific flags */ | 214 | unsigned long flags; /* ring specific flags */ |
234 | void __iomem *tail; /* pointer to ring tail register */ | 215 | void __iomem *tail; /* pointer to ring tail register */ |
216 | dma_addr_t dma; /* phys address of the ring */ | ||
217 | unsigned int size; /* length of desc. ring in bytes */ | ||
235 | 218 | ||
236 | u16 count; /* number of desc. in the ring */ | 219 | u16 count; /* number of desc. in the ring */ |
237 | u8 queue_index; /* logical index of the ring*/ | 220 | u8 queue_index; /* logical index of the ring*/ |
238 | u8 reg_idx; /* physical index of the ring */ | 221 | u8 reg_idx; /* physical index of the ring */ |
239 | u32 size; /* length of desc. ring in bytes */ | ||
240 | 222 | ||
241 | /* everything past this point are written often */ | 223 | /* everything past this point are written often */ |
242 | u16 next_to_clean ____cacheline_aligned_in_smp; | 224 | u16 next_to_clean; |
243 | u16 next_to_use; | 225 | u16 next_to_use; |
226 | u16 next_to_alloc; | ||
244 | 227 | ||
245 | union { | 228 | union { |
246 | /* TX */ | 229 | /* TX */ |
@@ -251,12 +234,30 @@ struct igb_ring { | |||
251 | }; | 234 | }; |
252 | /* RX */ | 235 | /* RX */ |
253 | struct { | 236 | struct { |
237 | struct sk_buff *skb; | ||
254 | struct igb_rx_queue_stats rx_stats; | 238 | struct igb_rx_queue_stats rx_stats; |
255 | struct u64_stats_sync rx_syncp; | 239 | struct u64_stats_sync rx_syncp; |
256 | }; | 240 | }; |
257 | }; | 241 | }; |
258 | /* Items past this point are only used during ring alloc / free */ | 242 | } ____cacheline_internodealigned_in_smp; |
259 | dma_addr_t dma; /* phys address of the ring */ | 243 | |
244 | struct igb_q_vector { | ||
245 | struct igb_adapter *adapter; /* backlink */ | ||
246 | int cpu; /* CPU for DCA */ | ||
247 | u32 eims_value; /* EIMS mask value */ | ||
248 | |||
249 | u16 itr_val; | ||
250 | u8 set_itr; | ||
251 | void __iomem *itr_register; | ||
252 | |||
253 | struct igb_ring_container rx, tx; | ||
254 | |||
255 | struct napi_struct napi; | ||
256 | struct rcu_head rcu; /* to avoid race with update stats on free */ | ||
257 | char name[IFNAMSIZ + 9]; | ||
258 | |||
259 | /* for dynamic allocation of rings associated with this q_vector */ | ||
260 | struct igb_ring ring[0] ____cacheline_internodealigned_in_smp; | ||
260 | }; | 261 | }; |
261 | 262 | ||
262 | enum e1000_ring_flags_t { | 263 | enum e1000_ring_flags_t { |
@@ -373,7 +374,6 @@ struct igb_adapter { | |||
373 | u32 wvbr; | 374 | u32 wvbr; |
374 | u32 *shadow_vfta; | 375 | u32 *shadow_vfta; |
375 | 376 | ||
376 | #ifdef CONFIG_IGB_PTP | ||
377 | struct ptp_clock *ptp_clock; | 377 | struct ptp_clock *ptp_clock; |
378 | struct ptp_clock_info ptp_caps; | 378 | struct ptp_clock_info ptp_caps; |
379 | struct delayed_work ptp_overflow_work; | 379 | struct delayed_work ptp_overflow_work; |
@@ -382,7 +382,6 @@ struct igb_adapter { | |||
382 | spinlock_t tmreg_lock; | 382 | spinlock_t tmreg_lock; |
383 | struct cyclecounter cc; | 383 | struct cyclecounter cc; |
384 | struct timecounter tc; | 384 | struct timecounter tc; |
385 | #endif /* CONFIG_IGB_PTP */ | ||
386 | 385 | ||
387 | char fw_version[32]; | 386 | char fw_version[32]; |
388 | }; | 387 | }; |
@@ -436,18 +435,27 @@ extern bool igb_has_link(struct igb_adapter *adapter); | |||
436 | extern void igb_set_ethtool_ops(struct net_device *); | 435 | extern void igb_set_ethtool_ops(struct net_device *); |
437 | extern void igb_power_up_link(struct igb_adapter *); | 436 | extern void igb_power_up_link(struct igb_adapter *); |
438 | extern void igb_set_fw_version(struct igb_adapter *); | 437 | extern void igb_set_fw_version(struct igb_adapter *); |
439 | #ifdef CONFIG_IGB_PTP | ||
440 | extern void igb_ptp_init(struct igb_adapter *adapter); | 438 | extern void igb_ptp_init(struct igb_adapter *adapter); |
441 | extern void igb_ptp_stop(struct igb_adapter *adapter); | 439 | extern void igb_ptp_stop(struct igb_adapter *adapter); |
442 | extern void igb_ptp_reset(struct igb_adapter *adapter); | 440 | extern void igb_ptp_reset(struct igb_adapter *adapter); |
443 | extern void igb_ptp_tx_work(struct work_struct *work); | 441 | extern void igb_ptp_tx_work(struct work_struct *work); |
444 | extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter); | 442 | extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter); |
445 | extern void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, | 443 | extern void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, |
446 | union e1000_adv_rx_desc *rx_desc, | ||
447 | struct sk_buff *skb); | 444 | struct sk_buff *skb); |
445 | extern void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, | ||
446 | unsigned char *va, | ||
447 | struct sk_buff *skb); | ||
448 | static inline void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, | ||
449 | union e1000_adv_rx_desc *rx_desc, | ||
450 | struct sk_buff *skb) | ||
451 | { | ||
452 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS) && | ||
453 | !igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) | ||
454 | igb_ptp_rx_rgtstamp(q_vector, skb); | ||
455 | } | ||
456 | |||
448 | extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev, | 457 | extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev, |
449 | struct ifreq *ifr, int cmd); | 458 | struct ifreq *ifr, int cmd); |
450 | #endif /* CONFIG_IGB_PTP */ | ||
451 | 459 | ||
452 | static inline s32 igb_reset_phy(struct e1000_hw *hw) | 460 | static inline s32 igb_reset_phy(struct e1000_hw *hw) |
453 | { | 461 | { |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 2ea012849825..d8b1bee606c0 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/pm_runtime.h> | 39 | #include <linux/pm_runtime.h> |
40 | #include <linux/highmem.h> | ||
40 | 41 | ||
41 | #include "igb.h" | 42 | #include "igb.h" |
42 | 43 | ||
@@ -1685,16 +1686,24 @@ static void igb_create_lbtest_frame(struct sk_buff *skb, | |||
1685 | memset(&skb->data[frame_size + 12], 0xAF, 1); | 1686 | memset(&skb->data[frame_size + 12], 0xAF, 1); |
1686 | } | 1687 | } |
1687 | 1688 | ||
1688 | static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) | 1689 | static int igb_check_lbtest_frame(struct igb_rx_buffer *rx_buffer, |
1690 | unsigned int frame_size) | ||
1689 | { | 1691 | { |
1690 | frame_size /= 2; | 1692 | unsigned char *data; |
1691 | if (*(skb->data + 3) == 0xFF) { | 1693 | bool match = true; |
1692 | if ((*(skb->data + frame_size + 10) == 0xBE) && | 1694 | |
1693 | (*(skb->data + frame_size + 12) == 0xAF)) { | 1695 | frame_size >>= 1; |
1694 | return 0; | 1696 | |
1695 | } | 1697 | data = kmap(rx_buffer->page); |
1696 | } | 1698 | |
1697 | return 13; | 1699 | if (data[3] != 0xFF || |
1700 | data[frame_size + 10] != 0xBE || | ||
1701 | data[frame_size + 12] != 0xAF) | ||
1702 | match = false; | ||
1703 | |||
1704 | kunmap(rx_buffer->page); | ||
1705 | |||
1706 | return match; | ||
1698 | } | 1707 | } |
1699 | 1708 | ||
1700 | static int igb_clean_test_rings(struct igb_ring *rx_ring, | 1709 | static int igb_clean_test_rings(struct igb_ring *rx_ring, |
@@ -1704,9 +1713,7 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, | |||
1704 | union e1000_adv_rx_desc *rx_desc; | 1713 | union e1000_adv_rx_desc *rx_desc; |
1705 | struct igb_rx_buffer *rx_buffer_info; | 1714 | struct igb_rx_buffer *rx_buffer_info; |
1706 | struct igb_tx_buffer *tx_buffer_info; | 1715 | struct igb_tx_buffer *tx_buffer_info; |
1707 | struct netdev_queue *txq; | ||
1708 | u16 rx_ntc, tx_ntc, count = 0; | 1716 | u16 rx_ntc, tx_ntc, count = 0; |
1709 | unsigned int total_bytes = 0, total_packets = 0; | ||
1710 | 1717 | ||
1711 | /* initialize next to clean and descriptor values */ | 1718 | /* initialize next to clean and descriptor values */ |
1712 | rx_ntc = rx_ring->next_to_clean; | 1719 | rx_ntc = rx_ring->next_to_clean; |
@@ -1717,21 +1724,24 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, | |||
1717 | /* check rx buffer */ | 1724 | /* check rx buffer */ |
1718 | rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; | 1725 | rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; |
1719 | 1726 | ||
1720 | /* unmap rx buffer, will be remapped by alloc_rx_buffers */ | 1727 | /* sync Rx buffer for CPU read */ |
1721 | dma_unmap_single(rx_ring->dev, | 1728 | dma_sync_single_for_cpu(rx_ring->dev, |
1722 | rx_buffer_info->dma, | 1729 | rx_buffer_info->dma, |
1723 | IGB_RX_HDR_LEN, | 1730 | IGB_RX_BUFSZ, |
1724 | DMA_FROM_DEVICE); | 1731 | DMA_FROM_DEVICE); |
1725 | rx_buffer_info->dma = 0; | ||
1726 | 1732 | ||
1727 | /* verify contents of skb */ | 1733 | /* verify contents of skb */ |
1728 | if (!igb_check_lbtest_frame(rx_buffer_info->skb, size)) | 1734 | if (igb_check_lbtest_frame(rx_buffer_info, size)) |
1729 | count++; | 1735 | count++; |
1730 | 1736 | ||
1737 | /* sync Rx buffer for device write */ | ||
1738 | dma_sync_single_for_device(rx_ring->dev, | ||
1739 | rx_buffer_info->dma, | ||
1740 | IGB_RX_BUFSZ, | ||
1741 | DMA_FROM_DEVICE); | ||
1742 | |||
1731 | /* unmap buffer on tx side */ | 1743 | /* unmap buffer on tx side */ |
1732 | tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; | 1744 | tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; |
1733 | total_bytes += tx_buffer_info->bytecount; | ||
1734 | total_packets += tx_buffer_info->gso_segs; | ||
1735 | igb_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); | 1745 | igb_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); |
1736 | 1746 | ||
1737 | /* increment rx/tx next to clean counters */ | 1747 | /* increment rx/tx next to clean counters */ |
@@ -1746,8 +1756,7 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring, | |||
1746 | rx_desc = IGB_RX_DESC(rx_ring, rx_ntc); | 1756 | rx_desc = IGB_RX_DESC(rx_ring, rx_ntc); |
1747 | } | 1757 | } |
1748 | 1758 | ||
1749 | txq = netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index); | 1759 | netdev_tx_reset_queue(txring_txq(tx_ring)); |
1750 | netdev_tx_completed_queue(txq, total_packets, total_bytes); | ||
1751 | 1760 | ||
1752 | /* re-map buffers to ring, store next to clean values */ | 1761 | /* re-map buffers to ring, store next to clean values */ |
1753 | igb_alloc_rx_buffers(rx_ring, count); | 1762 | igb_alloc_rx_buffers(rx_ring, count); |
@@ -2301,7 +2310,6 @@ static int igb_get_ts_info(struct net_device *dev, | |||
2301 | struct igb_adapter *adapter = netdev_priv(dev); | 2310 | struct igb_adapter *adapter = netdev_priv(dev); |
2302 | 2311 | ||
2303 | switch (adapter->hw.mac.type) { | 2312 | switch (adapter->hw.mac.type) { |
2304 | #ifdef CONFIG_IGB_PTP | ||
2305 | case e1000_82576: | 2313 | case e1000_82576: |
2306 | case e1000_82580: | 2314 | case e1000_82580: |
2307 | case e1000_i350: | 2315 | case e1000_i350: |
@@ -2337,7 +2345,6 @@ static int igb_get_ts_info(struct net_device *dev, | |||
2337 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); | 2345 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); |
2338 | 2346 | ||
2339 | return 0; | 2347 | return 0; |
2340 | #endif /* CONFIG_IGB_PTP */ | ||
2341 | default: | 2348 | default: |
2342 | return -EOPNOTSUPP; | 2349 | return -EOPNOTSUPP; |
2343 | } | 2350 | } |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index e1ceb37ef12e..082ce73dc627 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -61,7 +61,7 @@ | |||
61 | 61 | ||
62 | #define MAJ 4 | 62 | #define MAJ 4 |
63 | #define MIN 0 | 63 | #define MIN 0 |
64 | #define BUILD 1 | 64 | #define BUILD 17 |
65 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ | 65 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ |
66 | __stringify(BUILD) "-k" | 66 | __stringify(BUILD) "-k" |
67 | char igb_driver_name[] = "igb"; | 67 | char igb_driver_name[] = "igb"; |
@@ -534,31 +534,27 @@ rx_ring_summary: | |||
534 | 534 | ||
535 | if (staterr & E1000_RXD_STAT_DD) { | 535 | if (staterr & E1000_RXD_STAT_DD) { |
536 | /* Descriptor Done */ | 536 | /* Descriptor Done */ |
537 | pr_info("%s[0x%03X] %016llX %016llX -------" | 537 | pr_info("%s[0x%03X] %016llX %016llX ---------------- %s\n", |
538 | "--------- %p%s\n", "RWB", i, | 538 | "RWB", i, |
539 | le64_to_cpu(u0->a), | 539 | le64_to_cpu(u0->a), |
540 | le64_to_cpu(u0->b), | 540 | le64_to_cpu(u0->b), |
541 | buffer_info->skb, next_desc); | 541 | next_desc); |
542 | } else { | 542 | } else { |
543 | pr_info("%s[0x%03X] %016llX %016llX %016llX" | 543 | pr_info("%s[0x%03X] %016llX %016llX %016llX %s\n", |
544 | " %p%s\n", "R ", i, | 544 | "R ", i, |
545 | le64_to_cpu(u0->a), | 545 | le64_to_cpu(u0->a), |
546 | le64_to_cpu(u0->b), | 546 | le64_to_cpu(u0->b), |
547 | (u64)buffer_info->dma, | 547 | (u64)buffer_info->dma, |
548 | buffer_info->skb, next_desc); | 548 | next_desc); |
549 | 549 | ||
550 | if (netif_msg_pktdata(adapter) && | 550 | if (netif_msg_pktdata(adapter) && |
551 | buffer_info->dma && buffer_info->skb) { | 551 | buffer_info->dma && buffer_info->page) { |
552 | print_hex_dump(KERN_INFO, "", | ||
553 | DUMP_PREFIX_ADDRESS, | ||
554 | 16, 1, buffer_info->skb->data, | ||
555 | IGB_RX_HDR_LEN, true); | ||
556 | print_hex_dump(KERN_INFO, "", | 552 | print_hex_dump(KERN_INFO, "", |
557 | DUMP_PREFIX_ADDRESS, | 553 | DUMP_PREFIX_ADDRESS, |
558 | 16, 1, | 554 | 16, 1, |
559 | page_address(buffer_info->page) + | 555 | page_address(buffer_info->page) + |
560 | buffer_info->page_offset, | 556 | buffer_info->page_offset, |
561 | PAGE_SIZE/2, true); | 557 | IGB_RX_BUFSZ, true); |
562 | } | 558 | } |
563 | } | 559 | } |
564 | } | 560 | } |
@@ -656,80 +652,6 @@ static void igb_cache_ring_register(struct igb_adapter *adapter) | |||
656 | } | 652 | } |
657 | } | 653 | } |
658 | 654 | ||
659 | static void igb_free_queues(struct igb_adapter *adapter) | ||
660 | { | ||
661 | int i; | ||
662 | |||
663 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
664 | kfree(adapter->tx_ring[i]); | ||
665 | adapter->tx_ring[i] = NULL; | ||
666 | } | ||
667 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
668 | kfree(adapter->rx_ring[i]); | ||
669 | adapter->rx_ring[i] = NULL; | ||
670 | } | ||
671 | adapter->num_rx_queues = 0; | ||
672 | adapter->num_tx_queues = 0; | ||
673 | } | ||
674 | |||
675 | /** | ||
676 | * igb_alloc_queues - Allocate memory for all rings | ||
677 | * @adapter: board private structure to initialize | ||
678 | * | ||
679 | * We allocate one ring per queue at run-time since we don't know the | ||
680 | * number of queues at compile-time. | ||
681 | **/ | ||
682 | static int igb_alloc_queues(struct igb_adapter *adapter) | ||
683 | { | ||
684 | struct igb_ring *ring; | ||
685 | int i; | ||
686 | |||
687 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
688 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | ||
689 | if (!ring) | ||
690 | goto err; | ||
691 | ring->count = adapter->tx_ring_count; | ||
692 | ring->queue_index = i; | ||
693 | ring->dev = &adapter->pdev->dev; | ||
694 | ring->netdev = adapter->netdev; | ||
695 | /* For 82575, context index must be unique per ring. */ | ||
696 | if (adapter->hw.mac.type == e1000_82575) | ||
697 | set_bit(IGB_RING_FLAG_TX_CTX_IDX, &ring->flags); | ||
698 | adapter->tx_ring[i] = ring; | ||
699 | } | ||
700 | |||
701 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
702 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | ||
703 | if (!ring) | ||
704 | goto err; | ||
705 | ring->count = adapter->rx_ring_count; | ||
706 | ring->queue_index = i; | ||
707 | ring->dev = &adapter->pdev->dev; | ||
708 | ring->netdev = adapter->netdev; | ||
709 | /* set flag indicating ring supports SCTP checksum offload */ | ||
710 | if (adapter->hw.mac.type >= e1000_82576) | ||
711 | set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags); | ||
712 | |||
713 | /* | ||
714 | * On i350, i210, and i211, loopback VLAN packets | ||
715 | * have the tag byte-swapped. | ||
716 | * */ | ||
717 | if (adapter->hw.mac.type >= e1000_i350) | ||
718 | set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags); | ||
719 | |||
720 | adapter->rx_ring[i] = ring; | ||
721 | } | ||
722 | |||
723 | igb_cache_ring_register(adapter); | ||
724 | |||
725 | return 0; | ||
726 | |||
727 | err: | ||
728 | igb_free_queues(adapter); | ||
729 | |||
730 | return -ENOMEM; | ||
731 | } | ||
732 | |||
733 | /** | 655 | /** |
734 | * igb_write_ivar - configure ivar for given MSI-X vector | 656 | * igb_write_ivar - configure ivar for given MSI-X vector |
735 | * @hw: pointer to the HW structure | 657 | * @hw: pointer to the HW structure |
@@ -960,6 +882,35 @@ static void igb_reset_interrupt_capability(struct igb_adapter *adapter) | |||
960 | } | 882 | } |
961 | 883 | ||
962 | /** | 884 | /** |
885 | * igb_free_q_vector - Free memory allocated for specific interrupt vector | ||
886 | * @adapter: board private structure to initialize | ||
887 | * @v_idx: Index of vector to be freed | ||
888 | * | ||
889 | * This function frees the memory allocated to the q_vector. In addition if | ||
890 | * NAPI is enabled it will delete any references to the NAPI struct prior | ||
891 | * to freeing the q_vector. | ||
892 | **/ | ||
893 | static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx) | ||
894 | { | ||
895 | struct igb_q_vector *q_vector = adapter->q_vector[v_idx]; | ||
896 | |||
897 | if (q_vector->tx.ring) | ||
898 | adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL; | ||
899 | |||
900 | if (q_vector->rx.ring) | ||
901 | adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL; | ||
902 | |||
903 | adapter->q_vector[v_idx] = NULL; | ||
904 | netif_napi_del(&q_vector->napi); | ||
905 | |||
906 | /* | ||
907 | * ixgbe_get_stats64() might access the rings on this vector, | ||
908 | * we must wait a grace period before freeing it. | ||
909 | */ | ||
910 | kfree_rcu(q_vector, rcu); | ||
911 | } | ||
912 | |||
913 | /** | ||
963 | * igb_free_q_vectors - Free memory allocated for interrupt vectors | 914 | * igb_free_q_vectors - Free memory allocated for interrupt vectors |
964 | * @adapter: board private structure to initialize | 915 | * @adapter: board private structure to initialize |
965 | * | 916 | * |
@@ -969,17 +920,14 @@ static void igb_reset_interrupt_capability(struct igb_adapter *adapter) | |||
969 | **/ | 920 | **/ |
970 | static void igb_free_q_vectors(struct igb_adapter *adapter) | 921 | static void igb_free_q_vectors(struct igb_adapter *adapter) |
971 | { | 922 | { |
972 | int v_idx; | 923 | int v_idx = adapter->num_q_vectors; |
973 | 924 | ||
974 | for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { | 925 | adapter->num_tx_queues = 0; |
975 | struct igb_q_vector *q_vector = adapter->q_vector[v_idx]; | 926 | adapter->num_rx_queues = 0; |
976 | adapter->q_vector[v_idx] = NULL; | ||
977 | if (!q_vector) | ||
978 | continue; | ||
979 | netif_napi_del(&q_vector->napi); | ||
980 | kfree(q_vector); | ||
981 | } | ||
982 | adapter->num_q_vectors = 0; | 927 | adapter->num_q_vectors = 0; |
928 | |||
929 | while (v_idx--) | ||
930 | igb_free_q_vector(adapter, v_idx); | ||
983 | } | 931 | } |
984 | 932 | ||
985 | /** | 933 | /** |
@@ -990,7 +938,6 @@ static void igb_free_q_vectors(struct igb_adapter *adapter) | |||
990 | */ | 938 | */ |
991 | static void igb_clear_interrupt_scheme(struct igb_adapter *adapter) | 939 | static void igb_clear_interrupt_scheme(struct igb_adapter *adapter) |
992 | { | 940 | { |
993 | igb_free_queues(adapter); | ||
994 | igb_free_q_vectors(adapter); | 941 | igb_free_q_vectors(adapter); |
995 | igb_reset_interrupt_capability(adapter); | 942 | igb_reset_interrupt_capability(adapter); |
996 | } | 943 | } |
@@ -1001,7 +948,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter) | |||
1001 | * Attempt to configure interrupts using the best available | 948 | * Attempt to configure interrupts using the best available |
1002 | * capabilities of the hardware and kernel. | 949 | * capabilities of the hardware and kernel. |
1003 | **/ | 950 | **/ |
1004 | static int igb_set_interrupt_capability(struct igb_adapter *adapter) | 951 | static void igb_set_interrupt_capability(struct igb_adapter *adapter) |
1005 | { | 952 | { |
1006 | int err; | 953 | int err; |
1007 | int numvecs, i; | 954 | int numvecs, i; |
@@ -1038,7 +985,7 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) | |||
1038 | adapter->msix_entries, | 985 | adapter->msix_entries, |
1039 | numvecs); | 986 | numvecs); |
1040 | if (err == 0) | 987 | if (err == 0) |
1041 | goto out; | 988 | return; |
1042 | 989 | ||
1043 | igb_reset_interrupt_capability(adapter); | 990 | igb_reset_interrupt_capability(adapter); |
1044 | 991 | ||
@@ -1068,105 +1015,183 @@ msi_only: | |||
1068 | adapter->num_q_vectors = 1; | 1015 | adapter->num_q_vectors = 1; |
1069 | if (!pci_enable_msi(adapter->pdev)) | 1016 | if (!pci_enable_msi(adapter->pdev)) |
1070 | adapter->flags |= IGB_FLAG_HAS_MSI; | 1017 | adapter->flags |= IGB_FLAG_HAS_MSI; |
1071 | out: | 1018 | } |
1072 | /* Notify the stack of the (possibly) reduced queue counts. */ | 1019 | |
1073 | rtnl_lock(); | 1020 | static void igb_add_ring(struct igb_ring *ring, |
1074 | netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); | 1021 | struct igb_ring_container *head) |
1075 | err = netif_set_real_num_rx_queues(adapter->netdev, | 1022 | { |
1076 | adapter->num_rx_queues); | 1023 | head->ring = ring; |
1077 | rtnl_unlock(); | 1024 | head->count++; |
1078 | return err; | ||
1079 | } | 1025 | } |
1080 | 1026 | ||
1081 | /** | 1027 | /** |
1082 | * igb_alloc_q_vectors - Allocate memory for interrupt vectors | 1028 | * igb_alloc_q_vector - Allocate memory for a single interrupt vector |
1083 | * @adapter: board private structure to initialize | 1029 | * @adapter: board private structure to initialize |
1030 | * @v_count: q_vectors allocated on adapter, used for ring interleaving | ||
1031 | * @v_idx: index of vector in adapter struct | ||
1032 | * @txr_count: total number of Tx rings to allocate | ||
1033 | * @txr_idx: index of first Tx ring to allocate | ||
1034 | * @rxr_count: total number of Rx rings to allocate | ||
1035 | * @rxr_idx: index of first Rx ring to allocate | ||
1084 | * | 1036 | * |
1085 | * We allocate one q_vector per queue interrupt. If allocation fails we | 1037 | * We allocate one q_vector. If allocation fails we return -ENOMEM. |
1086 | * return -ENOMEM. | ||
1087 | **/ | 1038 | **/ |
1088 | static int igb_alloc_q_vectors(struct igb_adapter *adapter) | 1039 | static int igb_alloc_q_vector(struct igb_adapter *adapter, |
1040 | int v_count, int v_idx, | ||
1041 | int txr_count, int txr_idx, | ||
1042 | int rxr_count, int rxr_idx) | ||
1089 | { | 1043 | { |
1090 | struct igb_q_vector *q_vector; | 1044 | struct igb_q_vector *q_vector; |
1091 | struct e1000_hw *hw = &adapter->hw; | 1045 | struct igb_ring *ring; |
1092 | int v_idx; | 1046 | int ring_count, size; |
1093 | 1047 | ||
1094 | for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { | 1048 | /* igb only supports 1 Tx and/or 1 Rx queue per vector */ |
1095 | q_vector = kzalloc(sizeof(struct igb_q_vector), | 1049 | if (txr_count > 1 || rxr_count > 1) |
1096 | GFP_KERNEL); | 1050 | return -ENOMEM; |
1097 | if (!q_vector) | 1051 | |
1098 | goto err_out; | 1052 | ring_count = txr_count + rxr_count; |
1099 | q_vector->adapter = adapter; | 1053 | size = sizeof(struct igb_q_vector) + |
1100 | q_vector->itr_register = hw->hw_addr + E1000_EITR(0); | 1054 | (sizeof(struct igb_ring) * ring_count); |
1101 | q_vector->itr_val = IGB_START_ITR; | 1055 | |
1102 | netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64); | 1056 | /* allocate q_vector and rings */ |
1103 | adapter->q_vector[v_idx] = q_vector; | 1057 | q_vector = kzalloc(size, GFP_KERNEL); |
1058 | if (!q_vector) | ||
1059 | return -ENOMEM; | ||
1060 | |||
1061 | /* initialize NAPI */ | ||
1062 | netif_napi_add(adapter->netdev, &q_vector->napi, | ||
1063 | igb_poll, 64); | ||
1064 | |||
1065 | /* tie q_vector and adapter together */ | ||
1066 | adapter->q_vector[v_idx] = q_vector; | ||
1067 | q_vector->adapter = adapter; | ||
1068 | |||
1069 | /* initialize work limits */ | ||
1070 | q_vector->tx.work_limit = adapter->tx_work_limit; | ||
1071 | |||
1072 | /* initialize ITR configuration */ | ||
1073 | q_vector->itr_register = adapter->hw.hw_addr + E1000_EITR(0); | ||
1074 | q_vector->itr_val = IGB_START_ITR; | ||
1075 | |||
1076 | /* initialize pointer to rings */ | ||
1077 | ring = q_vector->ring; | ||
1078 | |||
1079 | if (txr_count) { | ||
1080 | /* assign generic ring traits */ | ||
1081 | ring->dev = &adapter->pdev->dev; | ||
1082 | ring->netdev = adapter->netdev; | ||
1083 | |||
1084 | /* configure backlink on ring */ | ||
1085 | ring->q_vector = q_vector; | ||
1086 | |||
1087 | /* update q_vector Tx values */ | ||
1088 | igb_add_ring(ring, &q_vector->tx); | ||
1089 | |||
1090 | /* For 82575, context index must be unique per ring. */ | ||
1091 | if (adapter->hw.mac.type == e1000_82575) | ||
1092 | set_bit(IGB_RING_FLAG_TX_CTX_IDX, &ring->flags); | ||
1093 | |||
1094 | /* apply Tx specific ring traits */ | ||
1095 | ring->count = adapter->tx_ring_count; | ||
1096 | ring->queue_index = txr_idx; | ||
1097 | |||
1098 | /* assign ring to adapter */ | ||
1099 | adapter->tx_ring[txr_idx] = ring; | ||
1100 | |||
1101 | /* push pointer to next ring */ | ||
1102 | ring++; | ||
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | return 0; | 1105 | if (rxr_count) { |
1106 | /* assign generic ring traits */ | ||
1107 | ring->dev = &adapter->pdev->dev; | ||
1108 | ring->netdev = adapter->netdev; | ||
1107 | 1109 | ||
1108 | err_out: | 1110 | /* configure backlink on ring */ |
1109 | igb_free_q_vectors(adapter); | 1111 | ring->q_vector = q_vector; |
1110 | return -ENOMEM; | ||
1111 | } | ||
1112 | 1112 | ||
1113 | static void igb_map_rx_ring_to_vector(struct igb_adapter *adapter, | 1113 | /* update q_vector Rx values */ |
1114 | int ring_idx, int v_idx) | 1114 | igb_add_ring(ring, &q_vector->rx); |
1115 | { | ||
1116 | struct igb_q_vector *q_vector = adapter->q_vector[v_idx]; | ||
1117 | 1115 | ||
1118 | q_vector->rx.ring = adapter->rx_ring[ring_idx]; | 1116 | /* set flag indicating ring supports SCTP checksum offload */ |
1119 | q_vector->rx.ring->q_vector = q_vector; | 1117 | if (adapter->hw.mac.type >= e1000_82576) |
1120 | q_vector->rx.count++; | 1118 | set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags); |
1121 | q_vector->itr_val = adapter->rx_itr_setting; | ||
1122 | if (q_vector->itr_val && q_vector->itr_val <= 3) | ||
1123 | q_vector->itr_val = IGB_START_ITR; | ||
1124 | } | ||
1125 | 1119 | ||
1126 | static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter, | 1120 | /* |
1127 | int ring_idx, int v_idx) | 1121 | * On i350, i210, and i211, loopback VLAN packets |
1128 | { | 1122 | * have the tag byte-swapped. |
1129 | struct igb_q_vector *q_vector = adapter->q_vector[v_idx]; | 1123 | * */ |
1124 | if (adapter->hw.mac.type >= e1000_i350) | ||
1125 | set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags); | ||
1130 | 1126 | ||
1131 | q_vector->tx.ring = adapter->tx_ring[ring_idx]; | 1127 | /* apply Rx specific ring traits */ |
1132 | q_vector->tx.ring->q_vector = q_vector; | 1128 | ring->count = adapter->rx_ring_count; |
1133 | q_vector->tx.count++; | 1129 | ring->queue_index = rxr_idx; |
1134 | q_vector->itr_val = adapter->tx_itr_setting; | 1130 | |
1135 | q_vector->tx.work_limit = adapter->tx_work_limit; | 1131 | /* assign ring to adapter */ |
1136 | if (q_vector->itr_val && q_vector->itr_val <= 3) | 1132 | adapter->rx_ring[rxr_idx] = ring; |
1137 | q_vector->itr_val = IGB_START_ITR; | 1133 | } |
1134 | |||
1135 | return 0; | ||
1138 | } | 1136 | } |
1139 | 1137 | ||
1138 | |||
1140 | /** | 1139 | /** |
1141 | * igb_map_ring_to_vector - maps allocated queues to vectors | 1140 | * igb_alloc_q_vectors - Allocate memory for interrupt vectors |
1141 | * @adapter: board private structure to initialize | ||
1142 | * | 1142 | * |
1143 | * This function maps the recently allocated queues to vectors. | 1143 | * We allocate one q_vector per queue interrupt. If allocation fails we |
1144 | * return -ENOMEM. | ||
1144 | **/ | 1145 | **/ |
1145 | static int igb_map_ring_to_vector(struct igb_adapter *adapter) | 1146 | static int igb_alloc_q_vectors(struct igb_adapter *adapter) |
1146 | { | 1147 | { |
1147 | int i; | 1148 | int q_vectors = adapter->num_q_vectors; |
1148 | int v_idx = 0; | 1149 | int rxr_remaining = adapter->num_rx_queues; |
1150 | int txr_remaining = adapter->num_tx_queues; | ||
1151 | int rxr_idx = 0, txr_idx = 0, v_idx = 0; | ||
1152 | int err; | ||
1149 | 1153 | ||
1150 | if ((adapter->num_q_vectors < adapter->num_rx_queues) || | 1154 | if (q_vectors >= (rxr_remaining + txr_remaining)) { |
1151 | (adapter->num_q_vectors < adapter->num_tx_queues)) | 1155 | for (; rxr_remaining; v_idx++) { |
1152 | return -ENOMEM; | 1156 | err = igb_alloc_q_vector(adapter, q_vectors, v_idx, |
1157 | 0, 0, 1, rxr_idx); | ||
1153 | 1158 | ||
1154 | if (adapter->num_q_vectors >= | 1159 | if (err) |
1155 | (adapter->num_rx_queues + adapter->num_tx_queues)) { | 1160 | goto err_out; |
1156 | for (i = 0; i < adapter->num_rx_queues; i++) | 1161 | |
1157 | igb_map_rx_ring_to_vector(adapter, i, v_idx++); | 1162 | /* update counts and index */ |
1158 | for (i = 0; i < adapter->num_tx_queues; i++) | 1163 | rxr_remaining--; |
1159 | igb_map_tx_ring_to_vector(adapter, i, v_idx++); | 1164 | rxr_idx++; |
1160 | } else { | ||
1161 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
1162 | if (i < adapter->num_tx_queues) | ||
1163 | igb_map_tx_ring_to_vector(adapter, i, v_idx); | ||
1164 | igb_map_rx_ring_to_vector(adapter, i, v_idx++); | ||
1165 | } | 1165 | } |
1166 | for (; i < adapter->num_tx_queues; i++) | ||
1167 | igb_map_tx_ring_to_vector(adapter, i, v_idx++); | ||
1168 | } | 1166 | } |
1167 | |||
1168 | for (; v_idx < q_vectors; v_idx++) { | ||
1169 | int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx); | ||
1170 | int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx); | ||
1171 | err = igb_alloc_q_vector(adapter, q_vectors, v_idx, | ||
1172 | tqpv, txr_idx, rqpv, rxr_idx); | ||
1173 | |||
1174 | if (err) | ||
1175 | goto err_out; | ||
1176 | |||
1177 | /* update counts and index */ | ||
1178 | rxr_remaining -= rqpv; | ||
1179 | txr_remaining -= tqpv; | ||
1180 | rxr_idx++; | ||
1181 | txr_idx++; | ||
1182 | } | ||
1183 | |||
1169 | return 0; | 1184 | return 0; |
1185 | |||
1186 | err_out: | ||
1187 | adapter->num_tx_queues = 0; | ||
1188 | adapter->num_rx_queues = 0; | ||
1189 | adapter->num_q_vectors = 0; | ||
1190 | |||
1191 | while (v_idx--) | ||
1192 | igb_free_q_vector(adapter, v_idx); | ||
1193 | |||
1194 | return -ENOMEM; | ||
1170 | } | 1195 | } |
1171 | 1196 | ||
1172 | /** | 1197 | /** |
@@ -1179,9 +1204,7 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter) | |||
1179 | struct pci_dev *pdev = adapter->pdev; | 1204 | struct pci_dev *pdev = adapter->pdev; |
1180 | int err; | 1205 | int err; |
1181 | 1206 | ||
1182 | err = igb_set_interrupt_capability(adapter); | 1207 | igb_set_interrupt_capability(adapter); |
1183 | if (err) | ||
1184 | return err; | ||
1185 | 1208 | ||
1186 | err = igb_alloc_q_vectors(adapter); | 1209 | err = igb_alloc_q_vectors(adapter); |
1187 | if (err) { | 1210 | if (err) { |
@@ -1189,24 +1212,10 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter) | |||
1189 | goto err_alloc_q_vectors; | 1212 | goto err_alloc_q_vectors; |
1190 | } | 1213 | } |
1191 | 1214 | ||
1192 | err = igb_alloc_queues(adapter); | 1215 | igb_cache_ring_register(adapter); |
1193 | if (err) { | ||
1194 | dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); | ||
1195 | goto err_alloc_queues; | ||
1196 | } | ||
1197 | |||
1198 | err = igb_map_ring_to_vector(adapter); | ||
1199 | if (err) { | ||
1200 | dev_err(&pdev->dev, "Invalid q_vector to ring mapping\n"); | ||
1201 | goto err_map_queues; | ||
1202 | } | ||
1203 | |||
1204 | 1216 | ||
1205 | return 0; | 1217 | return 0; |
1206 | err_map_queues: | 1218 | |
1207 | igb_free_queues(adapter); | ||
1208 | err_alloc_queues: | ||
1209 | igb_free_q_vectors(adapter); | ||
1210 | err_alloc_q_vectors: | 1219 | err_alloc_q_vectors: |
1211 | igb_reset_interrupt_capability(adapter); | 1220 | igb_reset_interrupt_capability(adapter); |
1212 | return err; | 1221 | return err; |
@@ -1229,11 +1238,11 @@ static int igb_request_irq(struct igb_adapter *adapter) | |||
1229 | if (!err) | 1238 | if (!err) |
1230 | goto request_done; | 1239 | goto request_done; |
1231 | /* fall back to MSI */ | 1240 | /* fall back to MSI */ |
1241 | igb_free_all_tx_resources(adapter); | ||
1242 | igb_free_all_rx_resources(adapter); | ||
1232 | igb_clear_interrupt_scheme(adapter); | 1243 | igb_clear_interrupt_scheme(adapter); |
1233 | if (!pci_enable_msi(pdev)) | 1244 | if (!pci_enable_msi(pdev)) |
1234 | adapter->flags |= IGB_FLAG_HAS_MSI; | 1245 | adapter->flags |= IGB_FLAG_HAS_MSI; |
1235 | igb_free_all_tx_resources(adapter); | ||
1236 | igb_free_all_rx_resources(adapter); | ||
1237 | adapter->num_tx_queues = 1; | 1246 | adapter->num_tx_queues = 1; |
1238 | adapter->num_rx_queues = 1; | 1247 | adapter->num_rx_queues = 1; |
1239 | adapter->num_q_vectors = 1; | 1248 | adapter->num_q_vectors = 1; |
@@ -1243,13 +1252,6 @@ static int igb_request_irq(struct igb_adapter *adapter) | |||
1243 | "Unable to allocate memory for vectors\n"); | 1252 | "Unable to allocate memory for vectors\n"); |
1244 | goto request_done; | 1253 | goto request_done; |
1245 | } | 1254 | } |
1246 | err = igb_alloc_queues(adapter); | ||
1247 | if (err) { | ||
1248 | dev_err(&pdev->dev, | ||
1249 | "Unable to allocate memory for queues\n"); | ||
1250 | igb_free_q_vectors(adapter); | ||
1251 | goto request_done; | ||
1252 | } | ||
1253 | igb_setup_all_tx_resources(adapter); | 1255 | igb_setup_all_tx_resources(adapter); |
1254 | igb_setup_all_rx_resources(adapter); | 1256 | igb_setup_all_rx_resources(adapter); |
1255 | } | 1257 | } |
@@ -1706,10 +1708,8 @@ void igb_reset(struct igb_adapter *adapter) | |||
1706 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ | 1708 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ |
1707 | wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); | 1709 | wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); |
1708 | 1710 | ||
1709 | #ifdef CONFIG_IGB_PTP | ||
1710 | /* Re-enable PTP, where applicable. */ | 1711 | /* Re-enable PTP, where applicable. */ |
1711 | igb_ptp_reset(adapter); | 1712 | igb_ptp_reset(adapter); |
1712 | #endif /* CONFIG_IGB_PTP */ | ||
1713 | 1713 | ||
1714 | igb_get_phy_info(hw); | 1714 | igb_get_phy_info(hw); |
1715 | } | 1715 | } |
@@ -1783,58 +1783,34 @@ static const struct net_device_ops igb_netdev_ops = { | |||
1783 | void igb_set_fw_version(struct igb_adapter *adapter) | 1783 | void igb_set_fw_version(struct igb_adapter *adapter) |
1784 | { | 1784 | { |
1785 | struct e1000_hw *hw = &adapter->hw; | 1785 | struct e1000_hw *hw = &adapter->hw; |
1786 | u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; | 1786 | struct e1000_fw_version fw; |
1787 | u16 major, build, patch, fw_version; | 1787 | |
1788 | u32 etrack_id; | 1788 | igb_get_fw_version(hw, &fw); |
1789 | 1789 | ||
1790 | hw->nvm.ops.read(hw, 5, 1, &fw_version); | 1790 | switch (hw->mac.type) { |
1791 | if (adapter->hw.mac.type != e1000_i211) { | 1791 | case e1000_i211: |
1792 | hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh); | ||
1793 | hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl); | ||
1794 | etrack_id = (eeprom_verh << IGB_ETRACK_SHIFT) | eeprom_verl; | ||
1795 | |||
1796 | /* combo image version needs to be found */ | ||
1797 | hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset); | ||
1798 | if ((comb_offset != 0x0) && | ||
1799 | (comb_offset != IGB_NVM_VER_INVALID)) { | ||
1800 | hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset | ||
1801 | + 1), 1, &comb_verh); | ||
1802 | hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset), | ||
1803 | 1, &comb_verl); | ||
1804 | |||
1805 | /* Only display Option Rom if it exists and is valid */ | ||
1806 | if ((comb_verh && comb_verl) && | ||
1807 | ((comb_verh != IGB_NVM_VER_INVALID) && | ||
1808 | (comb_verl != IGB_NVM_VER_INVALID))) { | ||
1809 | major = comb_verl >> IGB_COMB_VER_SHFT; | ||
1810 | build = (comb_verl << IGB_COMB_VER_SHFT) | | ||
1811 | (comb_verh >> IGB_COMB_VER_SHFT); | ||
1812 | patch = comb_verh & IGB_COMB_VER_MASK; | ||
1813 | snprintf(adapter->fw_version, | ||
1814 | sizeof(adapter->fw_version), | ||
1815 | "%d.%d%d, 0x%08x, %d.%d.%d", | ||
1816 | (fw_version & IGB_MAJOR_MASK) >> | ||
1817 | IGB_MAJOR_SHIFT, | ||
1818 | (fw_version & IGB_MINOR_MASK) >> | ||
1819 | IGB_MINOR_SHIFT, | ||
1820 | (fw_version & IGB_BUILD_MASK), | ||
1821 | etrack_id, major, build, patch); | ||
1822 | goto out; | ||
1823 | } | ||
1824 | } | ||
1825 | snprintf(adapter->fw_version, sizeof(adapter->fw_version), | ||
1826 | "%d.%d%d, 0x%08x", | ||
1827 | (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, | ||
1828 | (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, | ||
1829 | (fw_version & IGB_BUILD_MASK), etrack_id); | ||
1830 | } else { | ||
1831 | snprintf(adapter->fw_version, sizeof(adapter->fw_version), | 1792 | snprintf(adapter->fw_version, sizeof(adapter->fw_version), |
1832 | "%d.%d%d", | 1793 | "%2d.%2d-%d", |
1833 | (fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, | 1794 | fw.invm_major, fw.invm_minor, fw.invm_img_type); |
1834 | (fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, | 1795 | break; |
1835 | (fw_version & IGB_BUILD_MASK)); | 1796 | |
1797 | default: | ||
1798 | /* if option is rom valid, display its version too */ | ||
1799 | if (fw.or_valid) { | ||
1800 | snprintf(adapter->fw_version, | ||
1801 | sizeof(adapter->fw_version), | ||
1802 | "%d.%d, 0x%08x, %d.%d.%d", | ||
1803 | fw.eep_major, fw.eep_minor, fw.etrack_id, | ||
1804 | fw.or_major, fw.or_build, fw.or_patch); | ||
1805 | /* no option rom */ | ||
1806 | } else { | ||
1807 | snprintf(adapter->fw_version, | ||
1808 | sizeof(adapter->fw_version), | ||
1809 | "%d.%d, 0x%08x", | ||
1810 | fw.eep_major, fw.eep_minor, fw.etrack_id); | ||
1811 | } | ||
1812 | break; | ||
1836 | } | 1813 | } |
1837 | out: | ||
1838 | return; | 1814 | return; |
1839 | } | 1815 | } |
1840 | 1816 | ||
@@ -2141,10 +2117,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
2141 | 2117 | ||
2142 | #endif | 2118 | #endif |
2143 | 2119 | ||
2144 | #ifdef CONFIG_IGB_PTP | ||
2145 | /* do hw tstamp init after resetting */ | 2120 | /* do hw tstamp init after resetting */ |
2146 | igb_ptp_init(adapter); | 2121 | igb_ptp_init(adapter); |
2147 | #endif /* CONFIG_IGB_PTP */ | ||
2148 | 2122 | ||
2149 | dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); | 2123 | dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); |
2150 | /* print bus type/speed/width info */ | 2124 | /* print bus type/speed/width info */ |
@@ -2219,9 +2193,7 @@ static void __devexit igb_remove(struct pci_dev *pdev) | |||
2219 | struct e1000_hw *hw = &adapter->hw; | 2193 | struct e1000_hw *hw = &adapter->hw; |
2220 | 2194 | ||
2221 | pm_runtime_get_noresume(&pdev->dev); | 2195 | pm_runtime_get_noresume(&pdev->dev); |
2222 | #ifdef CONFIG_IGB_PTP | ||
2223 | igb_ptp_stop(adapter); | 2196 | igb_ptp_stop(adapter); |
2224 | #endif /* CONFIG_IGB_PTP */ | ||
2225 | 2197 | ||
2226 | /* | 2198 | /* |
2227 | * The watchdog timer may be rescheduled, so explicitly | 2199 | * The watchdog timer may be rescheduled, so explicitly |
@@ -2531,6 +2503,17 @@ static int __igb_open(struct net_device *netdev, bool resuming) | |||
2531 | if (err) | 2503 | if (err) |
2532 | goto err_req_irq; | 2504 | goto err_req_irq; |
2533 | 2505 | ||
2506 | /* Notify the stack of the actual queue counts. */ | ||
2507 | err = netif_set_real_num_tx_queues(adapter->netdev, | ||
2508 | adapter->num_tx_queues); | ||
2509 | if (err) | ||
2510 | goto err_set_queues; | ||
2511 | |||
2512 | err = netif_set_real_num_rx_queues(adapter->netdev, | ||
2513 | adapter->num_rx_queues); | ||
2514 | if (err) | ||
2515 | goto err_set_queues; | ||
2516 | |||
2534 | /* From here on the code is the same as igb_up() */ | 2517 | /* From here on the code is the same as igb_up() */ |
2535 | clear_bit(__IGB_DOWN, &adapter->state); | 2518 | clear_bit(__IGB_DOWN, &adapter->state); |
2536 | 2519 | ||
@@ -2560,6 +2543,8 @@ static int __igb_open(struct net_device *netdev, bool resuming) | |||
2560 | 2543 | ||
2561 | return 0; | 2544 | return 0; |
2562 | 2545 | ||
2546 | err_set_queues: | ||
2547 | igb_free_irq(adapter); | ||
2563 | err_req_irq: | 2548 | err_req_irq: |
2564 | igb_release_hw_control(adapter); | 2549 | igb_release_hw_control(adapter); |
2565 | igb_power_down_link(adapter); | 2550 | igb_power_down_link(adapter); |
@@ -2637,10 +2622,8 @@ int igb_setup_tx_resources(struct igb_ring *tx_ring) | |||
2637 | tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); | 2622 | tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); |
2638 | tx_ring->size = ALIGN(tx_ring->size, 4096); | 2623 | tx_ring->size = ALIGN(tx_ring->size, 4096); |
2639 | 2624 | ||
2640 | tx_ring->desc = dma_alloc_coherent(dev, | 2625 | tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size, |
2641 | tx_ring->size, | 2626 | &tx_ring->dma, GFP_KERNEL); |
2642 | &tx_ring->dma, | ||
2643 | GFP_KERNEL); | ||
2644 | if (!tx_ring->desc) | 2627 | if (!tx_ring->desc) |
2645 | goto err; | 2628 | goto err; |
2646 | 2629 | ||
@@ -2777,18 +2760,16 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring) | |||
2777 | if (!rx_ring->rx_buffer_info) | 2760 | if (!rx_ring->rx_buffer_info) |
2778 | goto err; | 2761 | goto err; |
2779 | 2762 | ||
2780 | |||
2781 | /* Round up to nearest 4K */ | 2763 | /* Round up to nearest 4K */ |
2782 | rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc); | 2764 | rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc); |
2783 | rx_ring->size = ALIGN(rx_ring->size, 4096); | 2765 | rx_ring->size = ALIGN(rx_ring->size, 4096); |
2784 | 2766 | ||
2785 | rx_ring->desc = dma_alloc_coherent(dev, | 2767 | rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size, |
2786 | rx_ring->size, | 2768 | &rx_ring->dma, GFP_KERNEL); |
2787 | &rx_ring->dma, | ||
2788 | GFP_KERNEL); | ||
2789 | if (!rx_ring->desc) | 2769 | if (!rx_ring->desc) |
2790 | goto err; | 2770 | goto err; |
2791 | 2771 | ||
2772 | rx_ring->next_to_alloc = 0; | ||
2792 | rx_ring->next_to_clean = 0; | 2773 | rx_ring->next_to_clean = 0; |
2793 | rx_ring->next_to_use = 0; | 2774 | rx_ring->next_to_use = 0; |
2794 | 2775 | ||
@@ -3106,16 +3087,10 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, | |||
3106 | 3087 | ||
3107 | /* set descriptor configuration */ | 3088 | /* set descriptor configuration */ |
3108 | srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; | 3089 | srrctl = IGB_RX_HDR_LEN << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; |
3109 | #if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384 | 3090 | srrctl |= IGB_RX_BUFSZ >> E1000_SRRCTL_BSIZEPKT_SHIFT; |
3110 | srrctl |= IGB_RXBUFFER_16384 >> E1000_SRRCTL_BSIZEPKT_SHIFT; | 3091 | srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; |
3111 | #else | ||
3112 | srrctl |= (PAGE_SIZE / 2) >> E1000_SRRCTL_BSIZEPKT_SHIFT; | ||
3113 | #endif | ||
3114 | srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS; | ||
3115 | #ifdef CONFIG_IGB_PTP | ||
3116 | if (hw->mac.type >= e1000_82580) | 3092 | if (hw->mac.type >= e1000_82580) |
3117 | srrctl |= E1000_SRRCTL_TIMESTAMP; | 3093 | srrctl |= E1000_SRRCTL_TIMESTAMP; |
3118 | #endif /* CONFIG_IGB_PTP */ | ||
3119 | /* Only set Drop Enable if we are supporting multiple queues */ | 3094 | /* Only set Drop Enable if we are supporting multiple queues */ |
3120 | if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1) | 3095 | if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1) |
3121 | srrctl |= E1000_SRRCTL_DROP_EN; | 3096 | srrctl |= E1000_SRRCTL_DROP_EN; |
@@ -3305,36 +3280,27 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring) | |||
3305 | unsigned long size; | 3280 | unsigned long size; |
3306 | u16 i; | 3281 | u16 i; |
3307 | 3282 | ||
3283 | if (rx_ring->skb) | ||
3284 | dev_kfree_skb(rx_ring->skb); | ||
3285 | rx_ring->skb = NULL; | ||
3286 | |||
3308 | if (!rx_ring->rx_buffer_info) | 3287 | if (!rx_ring->rx_buffer_info) |
3309 | return; | 3288 | return; |
3310 | 3289 | ||
3311 | /* Free all the Rx ring sk_buffs */ | 3290 | /* Free all the Rx ring sk_buffs */ |
3312 | for (i = 0; i < rx_ring->count; i++) { | 3291 | for (i = 0; i < rx_ring->count; i++) { |
3313 | struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i]; | 3292 | struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i]; |
3314 | if (buffer_info->dma) { | ||
3315 | dma_unmap_single(rx_ring->dev, | ||
3316 | buffer_info->dma, | ||
3317 | IGB_RX_HDR_LEN, | ||
3318 | DMA_FROM_DEVICE); | ||
3319 | buffer_info->dma = 0; | ||
3320 | } | ||
3321 | 3293 | ||
3322 | if (buffer_info->skb) { | 3294 | if (!buffer_info->page) |
3323 | dev_kfree_skb(buffer_info->skb); | 3295 | continue; |
3324 | buffer_info->skb = NULL; | 3296 | |
3325 | } | 3297 | dma_unmap_page(rx_ring->dev, |
3326 | if (buffer_info->page_dma) { | 3298 | buffer_info->dma, |
3327 | dma_unmap_page(rx_ring->dev, | 3299 | PAGE_SIZE, |
3328 | buffer_info->page_dma, | 3300 | DMA_FROM_DEVICE); |
3329 | PAGE_SIZE / 2, | 3301 | __free_page(buffer_info->page); |
3330 | DMA_FROM_DEVICE); | 3302 | |
3331 | buffer_info->page_dma = 0; | 3303 | buffer_info->page = NULL; |
3332 | } | ||
3333 | if (buffer_info->page) { | ||
3334 | put_page(buffer_info->page); | ||
3335 | buffer_info->page = NULL; | ||
3336 | buffer_info->page_offset = 0; | ||
3337 | } | ||
3338 | } | 3304 | } |
3339 | 3305 | ||
3340 | size = sizeof(struct igb_rx_buffer) * rx_ring->count; | 3306 | size = sizeof(struct igb_rx_buffer) * rx_ring->count; |
@@ -3343,6 +3309,7 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring) | |||
3343 | /* Zero out the descriptor ring */ | 3309 | /* Zero out the descriptor ring */ |
3344 | memset(rx_ring->desc, 0, rx_ring->size); | 3310 | memset(rx_ring->desc, 0, rx_ring->size); |
3345 | 3311 | ||
3312 | rx_ring->next_to_alloc = 0; | ||
3346 | rx_ring->next_to_clean = 0; | 3313 | rx_ring->next_to_clean = 0; |
3347 | rx_ring->next_to_use = 0; | 3314 | rx_ring->next_to_use = 0; |
3348 | } | 3315 | } |
@@ -4159,11 +4126,9 @@ static __le32 igb_tx_cmd_type(u32 tx_flags) | |||
4159 | if (tx_flags & IGB_TX_FLAGS_VLAN) | 4126 | if (tx_flags & IGB_TX_FLAGS_VLAN) |
4160 | cmd_type |= cpu_to_le32(E1000_ADVTXD_DCMD_VLE); | 4127 | cmd_type |= cpu_to_le32(E1000_ADVTXD_DCMD_VLE); |
4161 | 4128 | ||
4162 | #ifdef CONFIG_IGB_PTP | ||
4163 | /* set timestamp bit if present */ | 4129 | /* set timestamp bit if present */ |
4164 | if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP)) | 4130 | if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP)) |
4165 | cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP); | 4131 | cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP); |
4166 | #endif /* CONFIG_IGB_PTP */ | ||
4167 | 4132 | ||
4168 | /* set segmentation bits for TSO */ | 4133 | /* set segmentation bits for TSO */ |
4169 | if (tx_flags & IGB_TX_FLAGS_TSO) | 4134 | if (tx_flags & IGB_TX_FLAGS_TSO) |
@@ -4372,9 +4337,7 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size) | |||
4372 | netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, | 4337 | netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, |
4373 | struct igb_ring *tx_ring) | 4338 | struct igb_ring *tx_ring) |
4374 | { | 4339 | { |
4375 | #ifdef CONFIG_IGB_PTP | ||
4376 | struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); | 4340 | struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); |
4377 | #endif /* CONFIG_IGB_PTP */ | ||
4378 | struct igb_tx_buffer *first; | 4341 | struct igb_tx_buffer *first; |
4379 | int tso; | 4342 | int tso; |
4380 | u32 tx_flags = 0; | 4343 | u32 tx_flags = 0; |
@@ -4397,7 +4360,6 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, | |||
4397 | first->bytecount = skb->len; | 4360 | first->bytecount = skb->len; |
4398 | first->gso_segs = 1; | 4361 | first->gso_segs = 1; |
4399 | 4362 | ||
4400 | #ifdef CONFIG_IGB_PTP | ||
4401 | if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && | 4363 | if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && |
4402 | !(adapter->ptp_tx_skb))) { | 4364 | !(adapter->ptp_tx_skb))) { |
4403 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | 4365 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
@@ -4407,7 +4369,6 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, | |||
4407 | if (adapter->hw.mac.type == e1000_82576) | 4369 | if (adapter->hw.mac.type == e1000_82576) |
4408 | schedule_work(&adapter->ptp_tx_work); | 4370 | schedule_work(&adapter->ptp_tx_work); |
4409 | } | 4371 | } |
4410 | #endif /* CONFIG_IGB_PTP */ | ||
4411 | 4372 | ||
4412 | if (vlan_tx_tag_present(skb)) { | 4373 | if (vlan_tx_tag_present(skb)) { |
4413 | tx_flags |= IGB_TX_FLAGS_VLAN; | 4374 | tx_flags |= IGB_TX_FLAGS_VLAN; |
@@ -4467,10 +4428,11 @@ static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, | |||
4467 | * The minimum packet size with TCTL.PSP set is 17 so pad the skb | 4428 | * The minimum packet size with TCTL.PSP set is 17 so pad the skb |
4468 | * in order to meet this minimum size requirement. | 4429 | * in order to meet this minimum size requirement. |
4469 | */ | 4430 | */ |
4470 | if (skb->len < 17) { | 4431 | if (unlikely(skb->len < 17)) { |
4471 | if (skb_padto(skb, 17)) | 4432 | if (skb_pad(skb, 17 - skb->len)) |
4472 | return NETDEV_TX_OK; | 4433 | return NETDEV_TX_OK; |
4473 | skb->len = 17; | 4434 | skb->len = 17; |
4435 | skb_set_tail_pointer(skb, 17); | ||
4474 | } | 4436 | } |
4475 | 4437 | ||
4476 | return igb_xmit_frame_ring(skb, igb_tx_queue_mapping(adapter, skb)); | 4438 | return igb_xmit_frame_ring(skb, igb_tx_queue_mapping(adapter, skb)); |
@@ -4800,7 +4762,6 @@ static irqreturn_t igb_msix_other(int irq, void *data) | |||
4800 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 4762 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
4801 | } | 4763 | } |
4802 | 4764 | ||
4803 | #ifdef CONFIG_IGB_PTP | ||
4804 | if (icr & E1000_ICR_TS) { | 4765 | if (icr & E1000_ICR_TS) { |
4805 | u32 tsicr = rd32(E1000_TSICR); | 4766 | u32 tsicr = rd32(E1000_TSICR); |
4806 | 4767 | ||
@@ -4811,7 +4772,6 @@ static irqreturn_t igb_msix_other(int irq, void *data) | |||
4811 | schedule_work(&adapter->ptp_tx_work); | 4772 | schedule_work(&adapter->ptp_tx_work); |
4812 | } | 4773 | } |
4813 | } | 4774 | } |
4814 | #endif /* CONFIG_IGB_PTP */ | ||
4815 | 4775 | ||
4816 | wr32(E1000_EIMS, adapter->eims_other); | 4776 | wr32(E1000_EIMS, adapter->eims_other); |
4817 | 4777 | ||
@@ -4851,45 +4811,63 @@ static irqreturn_t igb_msix_ring(int irq, void *data) | |||
4851 | } | 4811 | } |
4852 | 4812 | ||
4853 | #ifdef CONFIG_IGB_DCA | 4813 | #ifdef CONFIG_IGB_DCA |
4814 | static void igb_update_tx_dca(struct igb_adapter *adapter, | ||
4815 | struct igb_ring *tx_ring, | ||
4816 | int cpu) | ||
4817 | { | ||
4818 | struct e1000_hw *hw = &adapter->hw; | ||
4819 | u32 txctrl = dca3_get_tag(tx_ring->dev, cpu); | ||
4820 | |||
4821 | if (hw->mac.type != e1000_82575) | ||
4822 | txctrl <<= E1000_DCA_TXCTRL_CPUID_SHIFT; | ||
4823 | |||
4824 | /* | ||
4825 | * We can enable relaxed ordering for reads, but not writes when | ||
4826 | * DCA is enabled. This is due to a known issue in some chipsets | ||
4827 | * which will cause the DCA tag to be cleared. | ||
4828 | */ | ||
4829 | txctrl |= E1000_DCA_TXCTRL_DESC_RRO_EN | | ||
4830 | E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4831 | E1000_DCA_TXCTRL_DESC_DCA_EN; | ||
4832 | |||
4833 | wr32(E1000_DCA_TXCTRL(tx_ring->reg_idx), txctrl); | ||
4834 | } | ||
4835 | |||
4836 | static void igb_update_rx_dca(struct igb_adapter *adapter, | ||
4837 | struct igb_ring *rx_ring, | ||
4838 | int cpu) | ||
4839 | { | ||
4840 | struct e1000_hw *hw = &adapter->hw; | ||
4841 | u32 rxctrl = dca3_get_tag(&adapter->pdev->dev, cpu); | ||
4842 | |||
4843 | if (hw->mac.type != e1000_82575) | ||
4844 | rxctrl <<= E1000_DCA_RXCTRL_CPUID_SHIFT; | ||
4845 | |||
4846 | /* | ||
4847 | * We can enable relaxed ordering for reads, but not writes when | ||
4848 | * DCA is enabled. This is due to a known issue in some chipsets | ||
4849 | * which will cause the DCA tag to be cleared. | ||
4850 | */ | ||
4851 | rxctrl |= E1000_DCA_RXCTRL_DESC_RRO_EN | | ||
4852 | E1000_DCA_RXCTRL_DESC_DCA_EN; | ||
4853 | |||
4854 | wr32(E1000_DCA_RXCTRL(rx_ring->reg_idx), rxctrl); | ||
4855 | } | ||
4856 | |||
4854 | static void igb_update_dca(struct igb_q_vector *q_vector) | 4857 | static void igb_update_dca(struct igb_q_vector *q_vector) |
4855 | { | 4858 | { |
4856 | struct igb_adapter *adapter = q_vector->adapter; | 4859 | struct igb_adapter *adapter = q_vector->adapter; |
4857 | struct e1000_hw *hw = &adapter->hw; | ||
4858 | int cpu = get_cpu(); | 4860 | int cpu = get_cpu(); |
4859 | 4861 | ||
4860 | if (q_vector->cpu == cpu) | 4862 | if (q_vector->cpu == cpu) |
4861 | goto out_no_update; | 4863 | goto out_no_update; |
4862 | 4864 | ||
4863 | if (q_vector->tx.ring) { | 4865 | if (q_vector->tx.ring) |
4864 | int q = q_vector->tx.ring->reg_idx; | 4866 | igb_update_tx_dca(adapter, q_vector->tx.ring, cpu); |
4865 | u32 dca_txctrl = rd32(E1000_DCA_TXCTRL(q)); | 4867 | |
4866 | if (hw->mac.type == e1000_82575) { | 4868 | if (q_vector->rx.ring) |
4867 | dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK; | 4869 | igb_update_rx_dca(adapter, q_vector->rx.ring, cpu); |
4868 | dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); | 4870 | |
4869 | } else { | ||
4870 | dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576; | ||
4871 | dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) << | ||
4872 | E1000_DCA_TXCTRL_CPUID_SHIFT; | ||
4873 | } | ||
4874 | dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN; | ||
4875 | wr32(E1000_DCA_TXCTRL(q), dca_txctrl); | ||
4876 | } | ||
4877 | if (q_vector->rx.ring) { | ||
4878 | int q = q_vector->rx.ring->reg_idx; | ||
4879 | u32 dca_rxctrl = rd32(E1000_DCA_RXCTRL(q)); | ||
4880 | if (hw->mac.type == e1000_82575) { | ||
4881 | dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK; | ||
4882 | dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); | ||
4883 | } else { | ||
4884 | dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576; | ||
4885 | dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) << | ||
4886 | E1000_DCA_RXCTRL_CPUID_SHIFT; | ||
4887 | } | ||
4888 | dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN; | ||
4889 | dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN; | ||
4890 | dca_rxctrl |= E1000_DCA_RXCTRL_DATA_DCA_EN; | ||
4891 | wr32(E1000_DCA_RXCTRL(q), dca_rxctrl); | ||
4892 | } | ||
4893 | q_vector->cpu = cpu; | 4871 | q_vector->cpu = cpu; |
4894 | out_no_update: | 4872 | out_no_update: |
4895 | put_cpu(); | 4873 | put_cpu(); |
@@ -5545,7 +5523,6 @@ static irqreturn_t igb_intr_msi(int irq, void *data) | |||
5545 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 5523 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
5546 | } | 5524 | } |
5547 | 5525 | ||
5548 | #ifdef CONFIG_IGB_PTP | ||
5549 | if (icr & E1000_ICR_TS) { | 5526 | if (icr & E1000_ICR_TS) { |
5550 | u32 tsicr = rd32(E1000_TSICR); | 5527 | u32 tsicr = rd32(E1000_TSICR); |
5551 | 5528 | ||
@@ -5556,7 +5533,6 @@ static irqreturn_t igb_intr_msi(int irq, void *data) | |||
5556 | schedule_work(&adapter->ptp_tx_work); | 5533 | schedule_work(&adapter->ptp_tx_work); |
5557 | } | 5534 | } |
5558 | } | 5535 | } |
5559 | #endif /* CONFIG_IGB_PTP */ | ||
5560 | 5536 | ||
5561 | napi_schedule(&q_vector->napi); | 5537 | napi_schedule(&q_vector->napi); |
5562 | 5538 | ||
@@ -5599,7 +5575,6 @@ static irqreturn_t igb_intr(int irq, void *data) | |||
5599 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 5575 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
5600 | } | 5576 | } |
5601 | 5577 | ||
5602 | #ifdef CONFIG_IGB_PTP | ||
5603 | if (icr & E1000_ICR_TS) { | 5578 | if (icr & E1000_ICR_TS) { |
5604 | u32 tsicr = rd32(E1000_TSICR); | 5579 | u32 tsicr = rd32(E1000_TSICR); |
5605 | 5580 | ||
@@ -5610,7 +5585,6 @@ static irqreturn_t igb_intr(int irq, void *data) | |||
5610 | schedule_work(&adapter->ptp_tx_work); | 5585 | schedule_work(&adapter->ptp_tx_work); |
5611 | } | 5586 | } |
5612 | } | 5587 | } |
5613 | #endif /* CONFIG_IGB_PTP */ | ||
5614 | 5588 | ||
5615 | napi_schedule(&q_vector->napi); | 5589 | napi_schedule(&q_vector->napi); |
5616 | 5590 | ||
@@ -5840,6 +5814,181 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) | |||
5840 | return !!budget; | 5814 | return !!budget; |
5841 | } | 5815 | } |
5842 | 5816 | ||
5817 | /** | ||
5818 | * igb_reuse_rx_page - page flip buffer and store it back on the ring | ||
5819 | * @rx_ring: rx descriptor ring to store buffers on | ||
5820 | * @old_buff: donor buffer to have page reused | ||
5821 | * | ||
5822 | * Synchronizes page for reuse by the adapter | ||
5823 | **/ | ||
5824 | static void igb_reuse_rx_page(struct igb_ring *rx_ring, | ||
5825 | struct igb_rx_buffer *old_buff) | ||
5826 | { | ||
5827 | struct igb_rx_buffer *new_buff; | ||
5828 | u16 nta = rx_ring->next_to_alloc; | ||
5829 | |||
5830 | new_buff = &rx_ring->rx_buffer_info[nta]; | ||
5831 | |||
5832 | /* update, and store next to alloc */ | ||
5833 | nta++; | ||
5834 | rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; | ||
5835 | |||
5836 | /* transfer page from old buffer to new buffer */ | ||
5837 | memcpy(new_buff, old_buff, sizeof(struct igb_rx_buffer)); | ||
5838 | |||
5839 | /* sync the buffer for use by the device */ | ||
5840 | dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma, | ||
5841 | old_buff->page_offset, | ||
5842 | IGB_RX_BUFSZ, | ||
5843 | DMA_FROM_DEVICE); | ||
5844 | } | ||
5845 | |||
5846 | /** | ||
5847 | * igb_add_rx_frag - Add contents of Rx buffer to sk_buff | ||
5848 | * @rx_ring: rx descriptor ring to transact packets on | ||
5849 | * @rx_buffer: buffer containing page to add | ||
5850 | * @rx_desc: descriptor containing length of buffer written by hardware | ||
5851 | * @skb: sk_buff to place the data into | ||
5852 | * | ||
5853 | * This function will add the data contained in rx_buffer->page to the skb. | ||
5854 | * This is done either through a direct copy if the data in the buffer is | ||
5855 | * less than the skb header size, otherwise it will just attach the page as | ||
5856 | * a frag to the skb. | ||
5857 | * | ||
5858 | * The function will then update the page offset if necessary and return | ||
5859 | * true if the buffer can be reused by the adapter. | ||
5860 | **/ | ||
5861 | static bool igb_add_rx_frag(struct igb_ring *rx_ring, | ||
5862 | struct igb_rx_buffer *rx_buffer, | ||
5863 | union e1000_adv_rx_desc *rx_desc, | ||
5864 | struct sk_buff *skb) | ||
5865 | { | ||
5866 | struct page *page = rx_buffer->page; | ||
5867 | unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); | ||
5868 | |||
5869 | if ((size <= IGB_RX_HDR_LEN) && !skb_is_nonlinear(skb)) { | ||
5870 | unsigned char *va = page_address(page) + rx_buffer->page_offset; | ||
5871 | |||
5872 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { | ||
5873 | igb_ptp_rx_pktstamp(rx_ring->q_vector, va, skb); | ||
5874 | va += IGB_TS_HDR_LEN; | ||
5875 | size -= IGB_TS_HDR_LEN; | ||
5876 | } | ||
5877 | |||
5878 | memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); | ||
5879 | |||
5880 | /* we can reuse buffer as-is, just make sure it is local */ | ||
5881 | if (likely(page_to_nid(page) == numa_node_id())) | ||
5882 | return true; | ||
5883 | |||
5884 | /* this page cannot be reused so discard it */ | ||
5885 | put_page(page); | ||
5886 | return false; | ||
5887 | } | ||
5888 | |||
5889 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | ||
5890 | rx_buffer->page_offset, size, IGB_RX_BUFSZ); | ||
5891 | |||
5892 | /* avoid re-using remote pages */ | ||
5893 | if (unlikely(page_to_nid(page) != numa_node_id())) | ||
5894 | return false; | ||
5895 | |||
5896 | #if (PAGE_SIZE < 8192) | ||
5897 | /* if we are only owner of page we can reuse it */ | ||
5898 | if (unlikely(page_count(page) != 1)) | ||
5899 | return false; | ||
5900 | |||
5901 | /* flip page offset to other buffer */ | ||
5902 | rx_buffer->page_offset ^= IGB_RX_BUFSZ; | ||
5903 | |||
5904 | /* | ||
5905 | * since we are the only owner of the page and we need to | ||
5906 | * increment it, just set the value to 2 in order to avoid | ||
5907 | * an unnecessary locked operation | ||
5908 | */ | ||
5909 | atomic_set(&page->_count, 2); | ||
5910 | #else | ||
5911 | /* move offset up to the next cache line */ | ||
5912 | rx_buffer->page_offset += SKB_DATA_ALIGN(size); | ||
5913 | |||
5914 | if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ)) | ||
5915 | return false; | ||
5916 | |||
5917 | /* bump ref count on page before it is given to the stack */ | ||
5918 | get_page(page); | ||
5919 | #endif | ||
5920 | |||
5921 | return true; | ||
5922 | } | ||
5923 | |||
5924 | static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, | ||
5925 | union e1000_adv_rx_desc *rx_desc, | ||
5926 | struct sk_buff *skb) | ||
5927 | { | ||
5928 | struct igb_rx_buffer *rx_buffer; | ||
5929 | struct page *page; | ||
5930 | |||
5931 | rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; | ||
5932 | |||
5933 | /* | ||
5934 | * This memory barrier is needed to keep us from reading | ||
5935 | * any other fields out of the rx_desc until we know the | ||
5936 | * RXD_STAT_DD bit is set | ||
5937 | */ | ||
5938 | rmb(); | ||
5939 | |||
5940 | page = rx_buffer->page; | ||
5941 | prefetchw(page); | ||
5942 | |||
5943 | if (likely(!skb)) { | ||
5944 | void *page_addr = page_address(page) + | ||
5945 | rx_buffer->page_offset; | ||
5946 | |||
5947 | /* prefetch first cache line of first page */ | ||
5948 | prefetch(page_addr); | ||
5949 | #if L1_CACHE_BYTES < 128 | ||
5950 | prefetch(page_addr + L1_CACHE_BYTES); | ||
5951 | #endif | ||
5952 | |||
5953 | /* allocate a skb to store the frags */ | ||
5954 | skb = netdev_alloc_skb_ip_align(rx_ring->netdev, | ||
5955 | IGB_RX_HDR_LEN); | ||
5956 | if (unlikely(!skb)) { | ||
5957 | rx_ring->rx_stats.alloc_failed++; | ||
5958 | return NULL; | ||
5959 | } | ||
5960 | |||
5961 | /* | ||
5962 | * we will be copying header into skb->data in | ||
5963 | * pskb_may_pull so it is in our interest to prefetch | ||
5964 | * it now to avoid a possible cache miss | ||
5965 | */ | ||
5966 | prefetchw(skb->data); | ||
5967 | } | ||
5968 | |||
5969 | /* we are reusing so sync this buffer for CPU use */ | ||
5970 | dma_sync_single_range_for_cpu(rx_ring->dev, | ||
5971 | rx_buffer->dma, | ||
5972 | rx_buffer->page_offset, | ||
5973 | IGB_RX_BUFSZ, | ||
5974 | DMA_FROM_DEVICE); | ||
5975 | |||
5976 | /* pull page into skb */ | ||
5977 | if (igb_add_rx_frag(rx_ring, rx_buffer, rx_desc, skb)) { | ||
5978 | /* hand second half of page back to the ring */ | ||
5979 | igb_reuse_rx_page(rx_ring, rx_buffer); | ||
5980 | } else { | ||
5981 | /* we are not reusing the buffer so unmap it */ | ||
5982 | dma_unmap_page(rx_ring->dev, rx_buffer->dma, | ||
5983 | PAGE_SIZE, DMA_FROM_DEVICE); | ||
5984 | } | ||
5985 | |||
5986 | /* clear contents of rx_buffer */ | ||
5987 | rx_buffer->page = NULL; | ||
5988 | |||
5989 | return skb; | ||
5990 | } | ||
5991 | |||
5843 | static inline void igb_rx_checksum(struct igb_ring *ring, | 5992 | static inline void igb_rx_checksum(struct igb_ring *ring, |
5844 | union e1000_adv_rx_desc *rx_desc, | 5993 | union e1000_adv_rx_desc *rx_desc, |
5845 | struct sk_buff *skb) | 5994 | struct sk_buff *skb) |
@@ -5889,224 +6038,386 @@ static inline void igb_rx_hash(struct igb_ring *ring, | |||
5889 | skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); | 6038 | skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); |
5890 | } | 6039 | } |
5891 | 6040 | ||
5892 | static void igb_rx_vlan(struct igb_ring *ring, | 6041 | /** |
5893 | union e1000_adv_rx_desc *rx_desc, | 6042 | * igb_is_non_eop - process handling of non-EOP buffers |
5894 | struct sk_buff *skb) | 6043 | * @rx_ring: Rx ring being processed |
6044 | * @rx_desc: Rx descriptor for current buffer | ||
6045 | * @skb: current socket buffer containing buffer in progress | ||
6046 | * | ||
6047 | * This function updates next to clean. If the buffer is an EOP buffer | ||
6048 | * this function exits returning false, otherwise it will place the | ||
6049 | * sk_buff in the next buffer to be chained and return true indicating | ||
6050 | * that this is in fact a non-EOP buffer. | ||
6051 | **/ | ||
6052 | static bool igb_is_non_eop(struct igb_ring *rx_ring, | ||
6053 | union e1000_adv_rx_desc *rx_desc) | ||
5895 | { | 6054 | { |
5896 | if (igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) { | 6055 | u32 ntc = rx_ring->next_to_clean + 1; |
5897 | u16 vid; | ||
5898 | if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) && | ||
5899 | test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags)) | ||
5900 | vid = be16_to_cpu(rx_desc->wb.upper.vlan); | ||
5901 | else | ||
5902 | vid = le16_to_cpu(rx_desc->wb.upper.vlan); | ||
5903 | 6056 | ||
5904 | __vlan_hwaccel_put_tag(skb, vid); | 6057 | /* fetch, update, and store next to clean */ |
5905 | } | 6058 | ntc = (ntc < rx_ring->count) ? ntc : 0; |
6059 | rx_ring->next_to_clean = ntc; | ||
6060 | |||
6061 | prefetch(IGB_RX_DESC(rx_ring, ntc)); | ||
6062 | |||
6063 | if (likely(igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP))) | ||
6064 | return false; | ||
6065 | |||
6066 | return true; | ||
5906 | } | 6067 | } |
5907 | 6068 | ||
5908 | static inline u16 igb_get_hlen(union e1000_adv_rx_desc *rx_desc) | 6069 | /** |
5909 | { | 6070 | * igb_get_headlen - determine size of header for LRO/GRO |
5910 | /* HW will not DMA in data larger than the given buffer, even if it | 6071 | * @data: pointer to the start of the headers |
5911 | * parses the (NFS, of course) header to be larger. In that case, it | 6072 | * @max_len: total length of section to find headers in |
5912 | * fills the header buffer and spills the rest into the page. | 6073 | * |
6074 | * This function is meant to determine the length of headers that will | ||
6075 | * be recognized by hardware for LRO, and GRO offloads. The main | ||
6076 | * motivation of doing this is to only perform one pull for IPv4 TCP | ||
6077 | * packets so that we can do basic things like calculating the gso_size | ||
6078 | * based on the average data per packet. | ||
6079 | **/ | ||
6080 | static unsigned int igb_get_headlen(unsigned char *data, | ||
6081 | unsigned int max_len) | ||
6082 | { | ||
6083 | union { | ||
6084 | unsigned char *network; | ||
6085 | /* l2 headers */ | ||
6086 | struct ethhdr *eth; | ||
6087 | struct vlan_hdr *vlan; | ||
6088 | /* l3 headers */ | ||
6089 | struct iphdr *ipv4; | ||
6090 | struct ipv6hdr *ipv6; | ||
6091 | } hdr; | ||
6092 | __be16 protocol; | ||
6093 | u8 nexthdr = 0; /* default to not TCP */ | ||
6094 | u8 hlen; | ||
6095 | |||
6096 | /* this should never happen, but better safe than sorry */ | ||
6097 | if (max_len < ETH_HLEN) | ||
6098 | return max_len; | ||
6099 | |||
6100 | /* initialize network frame pointer */ | ||
6101 | hdr.network = data; | ||
6102 | |||
6103 | /* set first protocol and move network header forward */ | ||
6104 | protocol = hdr.eth->h_proto; | ||
6105 | hdr.network += ETH_HLEN; | ||
6106 | |||
6107 | /* handle any vlan tag if present */ | ||
6108 | if (protocol == __constant_htons(ETH_P_8021Q)) { | ||
6109 | if ((hdr.network - data) > (max_len - VLAN_HLEN)) | ||
6110 | return max_len; | ||
6111 | |||
6112 | protocol = hdr.vlan->h_vlan_encapsulated_proto; | ||
6113 | hdr.network += VLAN_HLEN; | ||
6114 | } | ||
6115 | |||
6116 | /* handle L3 protocols */ | ||
6117 | if (protocol == __constant_htons(ETH_P_IP)) { | ||
6118 | if ((hdr.network - data) > (max_len - sizeof(struct iphdr))) | ||
6119 | return max_len; | ||
6120 | |||
6121 | /* access ihl as a u8 to avoid unaligned access on ia64 */ | ||
6122 | hlen = (hdr.network[0] & 0x0F) << 2; | ||
6123 | |||
6124 | /* verify hlen meets minimum size requirements */ | ||
6125 | if (hlen < sizeof(struct iphdr)) | ||
6126 | return hdr.network - data; | ||
6127 | |||
6128 | /* record next protocol */ | ||
6129 | nexthdr = hdr.ipv4->protocol; | ||
6130 | hdr.network += hlen; | ||
6131 | } else if (protocol == __constant_htons(ETH_P_IPV6)) { | ||
6132 | if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) | ||
6133 | return max_len; | ||
6134 | |||
6135 | /* record next protocol */ | ||
6136 | nexthdr = hdr.ipv6->nexthdr; | ||
6137 | hdr.network += sizeof(struct ipv6hdr); | ||
6138 | } else { | ||
6139 | return hdr.network - data; | ||
6140 | } | ||
6141 | |||
6142 | /* finally sort out TCP */ | ||
6143 | if (nexthdr == IPPROTO_TCP) { | ||
6144 | if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) | ||
6145 | return max_len; | ||
6146 | |||
6147 | /* access doff as a u8 to avoid unaligned access on ia64 */ | ||
6148 | hlen = (hdr.network[12] & 0xF0) >> 2; | ||
6149 | |||
6150 | /* verify hlen meets minimum size requirements */ | ||
6151 | if (hlen < sizeof(struct tcphdr)) | ||
6152 | return hdr.network - data; | ||
6153 | |||
6154 | hdr.network += hlen; | ||
6155 | } else if (nexthdr == IPPROTO_UDP) { | ||
6156 | if ((hdr.network - data) > (max_len - sizeof(struct udphdr))) | ||
6157 | return max_len; | ||
6158 | |||
6159 | hdr.network += sizeof(struct udphdr); | ||
6160 | } | ||
6161 | |||
6162 | /* | ||
6163 | * If everything has gone correctly hdr.network should be the | ||
6164 | * data section of the packet and will be the end of the header. | ||
6165 | * If not then it probably represents the end of the last recognized | ||
6166 | * header. | ||
5913 | */ | 6167 | */ |
5914 | u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & | 6168 | if ((hdr.network - data) < max_len) |
5915 | E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; | 6169 | return hdr.network - data; |
5916 | if (hlen > IGB_RX_HDR_LEN) | 6170 | else |
5917 | hlen = IGB_RX_HDR_LEN; | 6171 | return max_len; |
5918 | return hlen; | ||
5919 | } | 6172 | } |
5920 | 6173 | ||
5921 | static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) | 6174 | /** |
6175 | * igb_pull_tail - igb specific version of skb_pull_tail | ||
6176 | * @rx_ring: rx descriptor ring packet is being transacted on | ||
6177 | * @rx_desc: pointer to the EOP Rx descriptor | ||
6178 | * @skb: pointer to current skb being adjusted | ||
6179 | * | ||
6180 | * This function is an igb specific version of __pskb_pull_tail. The | ||
6181 | * main difference between this version and the original function is that | ||
6182 | * this function can make several assumptions about the state of things | ||
6183 | * that allow for significant optimizations versus the standard function. | ||
6184 | * As a result we can do things like drop a frag and maintain an accurate | ||
6185 | * truesize for the skb. | ||
6186 | */ | ||
6187 | static void igb_pull_tail(struct igb_ring *rx_ring, | ||
6188 | union e1000_adv_rx_desc *rx_desc, | ||
6189 | struct sk_buff *skb) | ||
5922 | { | 6190 | { |
5923 | struct igb_ring *rx_ring = q_vector->rx.ring; | 6191 | struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; |
5924 | union e1000_adv_rx_desc *rx_desc; | 6192 | unsigned char *va; |
5925 | const int current_node = numa_node_id(); | 6193 | unsigned int pull_len; |
5926 | unsigned int total_bytes = 0, total_packets = 0; | ||
5927 | u16 cleaned_count = igb_desc_unused(rx_ring); | ||
5928 | u16 i = rx_ring->next_to_clean; | ||
5929 | 6194 | ||
5930 | rx_desc = IGB_RX_DESC(rx_ring, i); | 6195 | /* |
6196 | * it is valid to use page_address instead of kmap since we are | ||
6197 | * working with pages allocated out of the lomem pool per | ||
6198 | * alloc_page(GFP_ATOMIC) | ||
6199 | */ | ||
6200 | va = skb_frag_address(frag); | ||
5931 | 6201 | ||
5932 | while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) { | 6202 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { |
5933 | struct igb_rx_buffer *buffer_info = &rx_ring->rx_buffer_info[i]; | 6203 | /* retrieve timestamp from buffer */ |
5934 | struct sk_buff *skb = buffer_info->skb; | 6204 | igb_ptp_rx_pktstamp(rx_ring->q_vector, va, skb); |
5935 | union e1000_adv_rx_desc *next_rxd; | ||
5936 | 6205 | ||
5937 | buffer_info->skb = NULL; | 6206 | /* update pointers to remove timestamp header */ |
5938 | prefetch(skb->data); | 6207 | skb_frag_size_sub(frag, IGB_TS_HDR_LEN); |
6208 | frag->page_offset += IGB_TS_HDR_LEN; | ||
6209 | skb->data_len -= IGB_TS_HDR_LEN; | ||
6210 | skb->len -= IGB_TS_HDR_LEN; | ||
5939 | 6211 | ||
5940 | i++; | 6212 | /* move va to start of packet data */ |
5941 | if (i == rx_ring->count) | 6213 | va += IGB_TS_HDR_LEN; |
5942 | i = 0; | 6214 | } |
6215 | |||
6216 | /* | ||
6217 | * we need the header to contain the greater of either ETH_HLEN or | ||
6218 | * 60 bytes if the skb->len is less than 60 for skb_pad. | ||
6219 | */ | ||
6220 | pull_len = igb_get_headlen(va, IGB_RX_HDR_LEN); | ||
5943 | 6221 | ||
5944 | next_rxd = IGB_RX_DESC(rx_ring, i); | 6222 | /* align pull length to size of long to optimize memcpy performance */ |
5945 | prefetch(next_rxd); | 6223 | skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); |
5946 | 6224 | ||
5947 | /* | 6225 | /* update all of the pointers */ |
5948 | * This memory barrier is needed to keep us from reading | 6226 | skb_frag_size_sub(frag, pull_len); |
5949 | * any other fields out of the rx_desc until we know the | 6227 | frag->page_offset += pull_len; |
5950 | * RXD_STAT_DD bit is set | 6228 | skb->data_len -= pull_len; |
5951 | */ | 6229 | skb->tail += pull_len; |
5952 | rmb(); | 6230 | } |
5953 | 6231 | ||
5954 | if (!skb_is_nonlinear(skb)) { | 6232 | /** |
5955 | __skb_put(skb, igb_get_hlen(rx_desc)); | 6233 | * igb_cleanup_headers - Correct corrupted or empty headers |
5956 | dma_unmap_single(rx_ring->dev, buffer_info->dma, | 6234 | * @rx_ring: rx descriptor ring packet is being transacted on |
5957 | IGB_RX_HDR_LEN, | 6235 | * @rx_desc: pointer to the EOP Rx descriptor |
5958 | DMA_FROM_DEVICE); | 6236 | * @skb: pointer to current skb being fixed |
5959 | buffer_info->dma = 0; | 6237 | * |
6238 | * Address the case where we are pulling data in on pages only | ||
6239 | * and as such no data is present in the skb header. | ||
6240 | * | ||
6241 | * In addition if skb is not at least 60 bytes we need to pad it so that | ||
6242 | * it is large enough to qualify as a valid Ethernet frame. | ||
6243 | * | ||
6244 | * Returns true if an error was encountered and skb was freed. | ||
6245 | **/ | ||
6246 | static bool igb_cleanup_headers(struct igb_ring *rx_ring, | ||
6247 | union e1000_adv_rx_desc *rx_desc, | ||
6248 | struct sk_buff *skb) | ||
6249 | { | ||
6250 | |||
6251 | if (unlikely((igb_test_staterr(rx_desc, | ||
6252 | E1000_RXDEXT_ERR_FRAME_ERR_MASK)))) { | ||
6253 | struct net_device *netdev = rx_ring->netdev; | ||
6254 | if (!(netdev->features & NETIF_F_RXALL)) { | ||
6255 | dev_kfree_skb_any(skb); | ||
6256 | return true; | ||
5960 | } | 6257 | } |
6258 | } | ||
5961 | 6259 | ||
5962 | if (rx_desc->wb.upper.length) { | 6260 | /* place header in linear portion of buffer */ |
5963 | u16 length = le16_to_cpu(rx_desc->wb.upper.length); | 6261 | if (skb_is_nonlinear(skb)) |
6262 | igb_pull_tail(rx_ring, rx_desc, skb); | ||
5964 | 6263 | ||
5965 | skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, | 6264 | /* if skb_pad returns an error the skb was freed */ |
5966 | buffer_info->page, | 6265 | if (unlikely(skb->len < 60)) { |
5967 | buffer_info->page_offset, | 6266 | int pad_len = 60 - skb->len; |
5968 | length); | ||
5969 | 6267 | ||
5970 | skb->len += length; | 6268 | if (skb_pad(skb, pad_len)) |
5971 | skb->data_len += length; | 6269 | return true; |
5972 | skb->truesize += PAGE_SIZE / 2; | 6270 | __skb_put(skb, pad_len); |
6271 | } | ||
5973 | 6272 | ||
5974 | if ((page_count(buffer_info->page) != 1) || | 6273 | return false; |
5975 | (page_to_nid(buffer_info->page) != current_node)) | 6274 | } |
5976 | buffer_info->page = NULL; | ||
5977 | else | ||
5978 | get_page(buffer_info->page); | ||
5979 | 6275 | ||
5980 | dma_unmap_page(rx_ring->dev, buffer_info->page_dma, | 6276 | /** |
5981 | PAGE_SIZE / 2, DMA_FROM_DEVICE); | 6277 | * igb_process_skb_fields - Populate skb header fields from Rx descriptor |
5982 | buffer_info->page_dma = 0; | 6278 | * @rx_ring: rx descriptor ring packet is being transacted on |
5983 | } | 6279 | * @rx_desc: pointer to the EOP Rx descriptor |
6280 | * @skb: pointer to current skb being populated | ||
6281 | * | ||
6282 | * This function checks the ring, descriptor, and packet information in | ||
6283 | * order to populate the hash, checksum, VLAN, timestamp, protocol, and | ||
6284 | * other fields within the skb. | ||
6285 | **/ | ||
6286 | static void igb_process_skb_fields(struct igb_ring *rx_ring, | ||
6287 | union e1000_adv_rx_desc *rx_desc, | ||
6288 | struct sk_buff *skb) | ||
6289 | { | ||
6290 | struct net_device *dev = rx_ring->netdev; | ||
5984 | 6291 | ||
5985 | if (!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)) { | 6292 | igb_rx_hash(rx_ring, rx_desc, skb); |
5986 | struct igb_rx_buffer *next_buffer; | ||
5987 | next_buffer = &rx_ring->rx_buffer_info[i]; | ||
5988 | buffer_info->skb = next_buffer->skb; | ||
5989 | buffer_info->dma = next_buffer->dma; | ||
5990 | next_buffer->skb = skb; | ||
5991 | next_buffer->dma = 0; | ||
5992 | goto next_desc; | ||
5993 | } | ||
5994 | 6293 | ||
5995 | if (unlikely((igb_test_staterr(rx_desc, | 6294 | igb_rx_checksum(rx_ring, rx_desc, skb); |
5996 | E1000_RXDEXT_ERR_FRAME_ERR_MASK)) | ||
5997 | && !(rx_ring->netdev->features & NETIF_F_RXALL))) { | ||
5998 | dev_kfree_skb_any(skb); | ||
5999 | goto next_desc; | ||
6000 | } | ||
6001 | 6295 | ||
6002 | #ifdef CONFIG_IGB_PTP | 6296 | igb_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb); |
6003 | igb_ptp_rx_hwtstamp(q_vector, rx_desc, skb); | ||
6004 | #endif /* CONFIG_IGB_PTP */ | ||
6005 | igb_rx_hash(rx_ring, rx_desc, skb); | ||
6006 | igb_rx_checksum(rx_ring, rx_desc, skb); | ||
6007 | igb_rx_vlan(rx_ring, rx_desc, skb); | ||
6008 | 6297 | ||
6009 | total_bytes += skb->len; | 6298 | if ((dev->features & NETIF_F_HW_VLAN_RX) && |
6010 | total_packets++; | 6299 | igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) { |
6300 | u16 vid; | ||
6301 | if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) && | ||
6302 | test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags)) | ||
6303 | vid = be16_to_cpu(rx_desc->wb.upper.vlan); | ||
6304 | else | ||
6305 | vid = le16_to_cpu(rx_desc->wb.upper.vlan); | ||
6011 | 6306 | ||
6012 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); | 6307 | __vlan_hwaccel_put_tag(skb, vid); |
6308 | } | ||
6013 | 6309 | ||
6014 | napi_gro_receive(&q_vector->napi, skb); | 6310 | skb_record_rx_queue(skb, rx_ring->queue_index); |
6015 | 6311 | ||
6016 | budget--; | 6312 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); |
6017 | next_desc: | 6313 | } |
6018 | if (!budget) | 6314 | |
6019 | break; | 6315 | static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) |
6316 | { | ||
6317 | struct igb_ring *rx_ring = q_vector->rx.ring; | ||
6318 | struct sk_buff *skb = rx_ring->skb; | ||
6319 | unsigned int total_bytes = 0, total_packets = 0; | ||
6320 | u16 cleaned_count = igb_desc_unused(rx_ring); | ||
6321 | |||
6322 | do { | ||
6323 | union e1000_adv_rx_desc *rx_desc; | ||
6020 | 6324 | ||
6021 | cleaned_count++; | ||
6022 | /* return some buffers to hardware, one at a time is too slow */ | 6325 | /* return some buffers to hardware, one at a time is too slow */ |
6023 | if (cleaned_count >= IGB_RX_BUFFER_WRITE) { | 6326 | if (cleaned_count >= IGB_RX_BUFFER_WRITE) { |
6024 | igb_alloc_rx_buffers(rx_ring, cleaned_count); | 6327 | igb_alloc_rx_buffers(rx_ring, cleaned_count); |
6025 | cleaned_count = 0; | 6328 | cleaned_count = 0; |
6026 | } | 6329 | } |
6027 | 6330 | ||
6028 | /* use prefetched values */ | 6331 | rx_desc = IGB_RX_DESC(rx_ring, rx_ring->next_to_clean); |
6029 | rx_desc = next_rxd; | ||
6030 | } | ||
6031 | 6332 | ||
6032 | rx_ring->next_to_clean = i; | 6333 | if (!igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) |
6033 | u64_stats_update_begin(&rx_ring->rx_syncp); | 6334 | break; |
6034 | rx_ring->rx_stats.packets += total_packets; | ||
6035 | rx_ring->rx_stats.bytes += total_bytes; | ||
6036 | u64_stats_update_end(&rx_ring->rx_syncp); | ||
6037 | q_vector->rx.total_packets += total_packets; | ||
6038 | q_vector->rx.total_bytes += total_bytes; | ||
6039 | 6335 | ||
6040 | if (cleaned_count) | 6336 | /* retrieve a buffer from the ring */ |
6041 | igb_alloc_rx_buffers(rx_ring, cleaned_count); | 6337 | skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb); |
6042 | 6338 | ||
6043 | return !!budget; | 6339 | /* exit if we failed to retrieve a buffer */ |
6044 | } | 6340 | if (!skb) |
6341 | break; | ||
6045 | 6342 | ||
6046 | static bool igb_alloc_mapped_skb(struct igb_ring *rx_ring, | 6343 | cleaned_count++; |
6047 | struct igb_rx_buffer *bi) | ||
6048 | { | ||
6049 | struct sk_buff *skb = bi->skb; | ||
6050 | dma_addr_t dma = bi->dma; | ||
6051 | 6344 | ||
6052 | if (dma) | 6345 | /* fetch next buffer in frame if non-eop */ |
6053 | return true; | 6346 | if (igb_is_non_eop(rx_ring, rx_desc)) |
6347 | continue; | ||
6054 | 6348 | ||
6055 | if (likely(!skb)) { | 6349 | /* verify the packet layout is correct */ |
6056 | skb = netdev_alloc_skb_ip_align(rx_ring->netdev, | 6350 | if (igb_cleanup_headers(rx_ring, rx_desc, skb)) { |
6057 | IGB_RX_HDR_LEN); | 6351 | skb = NULL; |
6058 | bi->skb = skb; | 6352 | continue; |
6059 | if (!skb) { | ||
6060 | rx_ring->rx_stats.alloc_failed++; | ||
6061 | return false; | ||
6062 | } | 6353 | } |
6063 | 6354 | ||
6064 | /* initialize skb for ring */ | 6355 | /* probably a little skewed due to removing CRC */ |
6065 | skb_record_rx_queue(skb, rx_ring->queue_index); | 6356 | total_bytes += skb->len; |
6066 | } | ||
6067 | 6357 | ||
6068 | dma = dma_map_single(rx_ring->dev, skb->data, | 6358 | /* populate checksum, timestamp, VLAN, and protocol */ |
6069 | IGB_RX_HDR_LEN, DMA_FROM_DEVICE); | 6359 | igb_process_skb_fields(rx_ring, rx_desc, skb); |
6070 | 6360 | ||
6071 | if (dma_mapping_error(rx_ring->dev, dma)) { | 6361 | napi_gro_receive(&q_vector->napi, skb); |
6072 | rx_ring->rx_stats.alloc_failed++; | ||
6073 | return false; | ||
6074 | } | ||
6075 | 6362 | ||
6076 | bi->dma = dma; | 6363 | /* reset skb pointer */ |
6077 | return true; | 6364 | skb = NULL; |
6365 | |||
6366 | /* update budget accounting */ | ||
6367 | total_packets++; | ||
6368 | } while (likely(total_packets < budget)); | ||
6369 | |||
6370 | /* place incomplete frames back on ring for completion */ | ||
6371 | rx_ring->skb = skb; | ||
6372 | |||
6373 | u64_stats_update_begin(&rx_ring->rx_syncp); | ||
6374 | rx_ring->rx_stats.packets += total_packets; | ||
6375 | rx_ring->rx_stats.bytes += total_bytes; | ||
6376 | u64_stats_update_end(&rx_ring->rx_syncp); | ||
6377 | q_vector->rx.total_packets += total_packets; | ||
6378 | q_vector->rx.total_bytes += total_bytes; | ||
6379 | |||
6380 | if (cleaned_count) | ||
6381 | igb_alloc_rx_buffers(rx_ring, cleaned_count); | ||
6382 | |||
6383 | return (total_packets < budget); | ||
6078 | } | 6384 | } |
6079 | 6385 | ||
6080 | static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, | 6386 | static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, |
6081 | struct igb_rx_buffer *bi) | 6387 | struct igb_rx_buffer *bi) |
6082 | { | 6388 | { |
6083 | struct page *page = bi->page; | 6389 | struct page *page = bi->page; |
6084 | dma_addr_t page_dma = bi->page_dma; | 6390 | dma_addr_t dma; |
6085 | unsigned int page_offset = bi->page_offset ^ (PAGE_SIZE / 2); | ||
6086 | 6391 | ||
6087 | if (page_dma) | 6392 | /* since we are recycling buffers we should seldom need to alloc */ |
6393 | if (likely(page)) | ||
6088 | return true; | 6394 | return true; |
6089 | 6395 | ||
6090 | if (!page) { | 6396 | /* alloc new page for storage */ |
6091 | page = __skb_alloc_page(GFP_ATOMIC, bi->skb); | 6397 | page = __skb_alloc_page(GFP_ATOMIC | __GFP_COLD, NULL); |
6092 | bi->page = page; | 6398 | if (unlikely(!page)) { |
6093 | if (unlikely(!page)) { | 6399 | rx_ring->rx_stats.alloc_failed++; |
6094 | rx_ring->rx_stats.alloc_failed++; | 6400 | return false; |
6095 | return false; | ||
6096 | } | ||
6097 | } | 6401 | } |
6098 | 6402 | ||
6099 | page_dma = dma_map_page(rx_ring->dev, page, | 6403 | /* map page for use */ |
6100 | page_offset, PAGE_SIZE / 2, | 6404 | dma = dma_map_page(rx_ring->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); |
6101 | DMA_FROM_DEVICE); | 6405 | |
6406 | /* | ||
6407 | * if mapping failed free memory back to system since | ||
6408 | * there isn't much point in holding memory we can't use | ||
6409 | */ | ||
6410 | if (dma_mapping_error(rx_ring->dev, dma)) { | ||
6411 | __free_page(page); | ||
6102 | 6412 | ||
6103 | if (dma_mapping_error(rx_ring->dev, page_dma)) { | ||
6104 | rx_ring->rx_stats.alloc_failed++; | 6413 | rx_ring->rx_stats.alloc_failed++; |
6105 | return false; | 6414 | return false; |
6106 | } | 6415 | } |
6107 | 6416 | ||
6108 | bi->page_dma = page_dma; | 6417 | bi->dma = dma; |
6109 | bi->page_offset = page_offset; | 6418 | bi->page = page; |
6419 | bi->page_offset = 0; | ||
6420 | |||
6110 | return true; | 6421 | return true; |
6111 | } | 6422 | } |
6112 | 6423 | ||
@@ -6120,22 +6431,23 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) | |||
6120 | struct igb_rx_buffer *bi; | 6431 | struct igb_rx_buffer *bi; |
6121 | u16 i = rx_ring->next_to_use; | 6432 | u16 i = rx_ring->next_to_use; |
6122 | 6433 | ||
6434 | /* nothing to do */ | ||
6435 | if (!cleaned_count) | ||
6436 | return; | ||
6437 | |||
6123 | rx_desc = IGB_RX_DESC(rx_ring, i); | 6438 | rx_desc = IGB_RX_DESC(rx_ring, i); |
6124 | bi = &rx_ring->rx_buffer_info[i]; | 6439 | bi = &rx_ring->rx_buffer_info[i]; |
6125 | i -= rx_ring->count; | 6440 | i -= rx_ring->count; |
6126 | 6441 | ||
6127 | while (cleaned_count--) { | 6442 | do { |
6128 | if (!igb_alloc_mapped_skb(rx_ring, bi)) | ||
6129 | break; | ||
6130 | |||
6131 | /* Refresh the desc even if buffer_addrs didn't change | ||
6132 | * because each write-back erases this info. */ | ||
6133 | rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); | ||
6134 | |||
6135 | if (!igb_alloc_mapped_page(rx_ring, bi)) | 6443 | if (!igb_alloc_mapped_page(rx_ring, bi)) |
6136 | break; | 6444 | break; |
6137 | 6445 | ||
6138 | rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); | 6446 | /* |
6447 | * Refresh the desc even if buffer_addrs didn't change | ||
6448 | * because each write-back erases this info. | ||
6449 | */ | ||
6450 | rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); | ||
6139 | 6451 | ||
6140 | rx_desc++; | 6452 | rx_desc++; |
6141 | bi++; | 6453 | bi++; |
@@ -6148,17 +6460,25 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) | |||
6148 | 6460 | ||
6149 | /* clear the hdr_addr for the next_to_use descriptor */ | 6461 | /* clear the hdr_addr for the next_to_use descriptor */ |
6150 | rx_desc->read.hdr_addr = 0; | 6462 | rx_desc->read.hdr_addr = 0; |
6151 | } | 6463 | |
6464 | cleaned_count--; | ||
6465 | } while (cleaned_count); | ||
6152 | 6466 | ||
6153 | i += rx_ring->count; | 6467 | i += rx_ring->count; |
6154 | 6468 | ||
6155 | if (rx_ring->next_to_use != i) { | 6469 | if (rx_ring->next_to_use != i) { |
6470 | /* record the next descriptor to use */ | ||
6156 | rx_ring->next_to_use = i; | 6471 | rx_ring->next_to_use = i; |
6157 | 6472 | ||
6158 | /* Force memory writes to complete before letting h/w | 6473 | /* update next to alloc since we have filled the ring */ |
6474 | rx_ring->next_to_alloc = i; | ||
6475 | |||
6476 | /* | ||
6477 | * Force memory writes to complete before letting h/w | ||
6159 | * know there are new descriptors to fetch. (Only | 6478 | * know there are new descriptors to fetch. (Only |
6160 | * applicable for weak-ordered memory model archs, | 6479 | * applicable for weak-ordered memory model archs, |
6161 | * such as IA-64). */ | 6480 | * such as IA-64). |
6481 | */ | ||
6162 | wmb(); | 6482 | wmb(); |
6163 | writel(i, rx_ring->tail); | 6483 | writel(i, rx_ring->tail); |
6164 | } | 6484 | } |
@@ -6207,10 +6527,8 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
6207 | case SIOCGMIIREG: | 6527 | case SIOCGMIIREG: |
6208 | case SIOCSMIIREG: | 6528 | case SIOCSMIIREG: |
6209 | return igb_mii_ioctl(netdev, ifr, cmd); | 6529 | return igb_mii_ioctl(netdev, ifr, cmd); |
6210 | #ifdef CONFIG_IGB_PTP | ||
6211 | case SIOCSHWTSTAMP: | 6530 | case SIOCSHWTSTAMP: |
6212 | return igb_ptp_hwtstamp_ioctl(netdev, ifr, cmd); | 6531 | return igb_ptp_hwtstamp_ioctl(netdev, ifr, cmd); |
6213 | #endif /* CONFIG_IGB_PTP */ | ||
6214 | default: | 6532 | default: |
6215 | return -EOPNOTSUPP; | 6533 | return -EOPNOTSUPP; |
6216 | } | 6534 | } |
@@ -6492,7 +6810,9 @@ static int igb_resume(struct device *dev) | |||
6492 | wr32(E1000_WUS, ~0); | 6810 | wr32(E1000_WUS, ~0); |
6493 | 6811 | ||
6494 | if (netdev->flags & IFF_UP) { | 6812 | if (netdev->flags & IFF_UP) { |
6813 | rtnl_lock(); | ||
6495 | err = __igb_open(netdev, true); | 6814 | err = __igb_open(netdev, true); |
6815 | rtnl_unlock(); | ||
6496 | if (err) | 6816 | if (err) |
6497 | return err; | 6817 | return err; |
6498 | } | 6818 | } |
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index ee21445157a3..aa10f69f9f16 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c | |||
@@ -441,18 +441,46 @@ void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) | |||
441 | adapter->ptp_tx_skb = NULL; | 441 | adapter->ptp_tx_skb = NULL; |
442 | } | 442 | } |
443 | 443 | ||
444 | void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, | 444 | /** |
445 | union e1000_adv_rx_desc *rx_desc, | 445 | * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp |
446 | * @q_vector: Pointer to interrupt specific structure | ||
447 | * @va: Pointer to address containing Rx buffer | ||
448 | * @skb: Buffer containing timestamp and packet | ||
449 | * | ||
450 | * This function is meant to retrieve a timestamp from the first buffer of an | ||
451 | * incoming frame. The value is stored in little endian format starting on | ||
452 | * byte 8. | ||
453 | */ | ||
454 | void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, | ||
455 | unsigned char *va, | ||
456 | struct sk_buff *skb) | ||
457 | { | ||
458 | __le64 *regval = (__le64 *)va; | ||
459 | |||
460 | /* | ||
461 | * The timestamp is recorded in little endian format. | ||
462 | * DWORD: 0 1 2 3 | ||
463 | * Field: Reserved Reserved SYSTIML SYSTIMH | ||
464 | */ | ||
465 | igb_ptp_systim_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb), | ||
466 | le64_to_cpu(regval[1])); | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * igb_ptp_rx_rgtstamp - retrieve Rx timestamp stored in register | ||
471 | * @q_vector: Pointer to interrupt specific structure | ||
472 | * @skb: Buffer containing timestamp and packet | ||
473 | * | ||
474 | * This function is meant to retrieve a timestamp from the internal registers | ||
475 | * of the adapter and store it in the skb. | ||
476 | */ | ||
477 | void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, | ||
446 | struct sk_buff *skb) | 478 | struct sk_buff *skb) |
447 | { | 479 | { |
448 | struct igb_adapter *adapter = q_vector->adapter; | 480 | struct igb_adapter *adapter = q_vector->adapter; |
449 | struct e1000_hw *hw = &adapter->hw; | 481 | struct e1000_hw *hw = &adapter->hw; |
450 | u64 regval; | 482 | u64 regval; |
451 | 483 | ||
452 | if (!igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP | | ||
453 | E1000_RXDADV_STAT_TS)) | ||
454 | return; | ||
455 | |||
456 | /* | 484 | /* |
457 | * If this bit is set, then the RX registers contain the time stamp. No | 485 | * If this bit is set, then the RX registers contain the time stamp. No |
458 | * other packet will be time stamped until we read these registers, so | 486 | * other packet will be time stamped until we read these registers, so |
@@ -464,18 +492,11 @@ void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, | |||
464 | * If nothing went wrong, then it should have a shared tx_flags that we | 492 | * If nothing went wrong, then it should have a shared tx_flags that we |
465 | * can turn into a skb_shared_hwtstamps. | 493 | * can turn into a skb_shared_hwtstamps. |
466 | */ | 494 | */ |
467 | if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { | 495 | if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) |
468 | u32 *stamp = (u32 *)skb->data; | 496 | return; |
469 | regval = le32_to_cpu(*(stamp + 2)); | ||
470 | regval |= (u64)le32_to_cpu(*(stamp + 3)) << 32; | ||
471 | skb_pull(skb, IGB_TS_HDR_LEN); | ||
472 | } else { | ||
473 | if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) | ||
474 | return; | ||
475 | 497 | ||
476 | regval = rd32(E1000_RXSTMPL); | 498 | regval = rd32(E1000_RXSTMPL); |
477 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; | 499 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; |
478 | } | ||
479 | 500 | ||
480 | igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); | 501 | igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); |
481 | } | 502 | } |
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 0ac11f527a84..4051ec404613 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c | |||
@@ -184,6 +184,13 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring, | |||
184 | buffer_info->page_offset, | 184 | buffer_info->page_offset, |
185 | PAGE_SIZE / 2, | 185 | PAGE_SIZE / 2, |
186 | DMA_FROM_DEVICE); | 186 | DMA_FROM_DEVICE); |
187 | if (dma_mapping_error(&pdev->dev, | ||
188 | buffer_info->page_dma)) { | ||
189 | __free_page(buffer_info->page); | ||
190 | buffer_info->page = NULL; | ||
191 | dev_err(&pdev->dev, "RX DMA map failed\n"); | ||
192 | break; | ||
193 | } | ||
187 | } | 194 | } |
188 | 195 | ||
189 | if (!buffer_info->skb) { | 196 | if (!buffer_info->skb) { |
@@ -197,6 +204,12 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring, | |||
197 | buffer_info->dma = dma_map_single(&pdev->dev, skb->data, | 204 | buffer_info->dma = dma_map_single(&pdev->dev, skb->data, |
198 | bufsz, | 205 | bufsz, |
199 | DMA_FROM_DEVICE); | 206 | DMA_FROM_DEVICE); |
207 | if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { | ||
208 | dev_kfree_skb(buffer_info->skb); | ||
209 | buffer_info->skb = NULL; | ||
210 | dev_err(&pdev->dev, "RX DMA map failed\n"); | ||
211 | goto no_buffers; | ||
212 | } | ||
200 | } | 213 | } |
201 | /* Refresh the desc even if buffer_addrs didn't change because | 214 | /* Refresh the desc even if buffer_addrs didn't change because |
202 | * each write-back erases this info. */ | 215 | * each write-back erases this info. */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index 89f40e51fc13..f3a632bf8d96 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile | |||
@@ -34,11 +34,10 @@ obj-$(CONFIG_IXGBE) += ixgbe.o | |||
34 | 34 | ||
35 | ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\ | 35 | ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\ |
36 | ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ | 36 | ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ |
37 | ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o | 37 | ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o |
38 | 38 | ||
39 | ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ | 39 | ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ |
40 | ixgbe_dcb_82599.o ixgbe_dcb_nl.o | 40 | ixgbe_dcb_82599.o ixgbe_dcb_nl.o |
41 | 41 | ||
42 | ixgbe-$(CONFIG_IXGBE_PTP) += ixgbe_ptp.o | ||
43 | ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o | 42 | ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o |
44 | ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o | 43 | ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 30efc9f0f47a..7ff4c4fdcb0d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h | |||
@@ -36,11 +36,9 @@ | |||
36 | #include <linux/aer.h> | 36 | #include <linux/aer.h> |
37 | #include <linux/if_vlan.h> | 37 | #include <linux/if_vlan.h> |
38 | 38 | ||
39 | #ifdef CONFIG_IXGBE_PTP | ||
40 | #include <linux/clocksource.h> | 39 | #include <linux/clocksource.h> |
41 | #include <linux/net_tstamp.h> | 40 | #include <linux/net_tstamp.h> |
42 | #include <linux/ptp_clock_kernel.h> | 41 | #include <linux/ptp_clock_kernel.h> |
43 | #endif /* CONFIG_IXGBE_PTP */ | ||
44 | 42 | ||
45 | #include "ixgbe_type.h" | 43 | #include "ixgbe_type.h" |
46 | #include "ixgbe_common.h" | 44 | #include "ixgbe_common.h" |
@@ -135,6 +133,7 @@ struct vf_data_storage { | |||
135 | u16 tx_rate; | 133 | u16 tx_rate; |
136 | u16 vlan_count; | 134 | u16 vlan_count; |
137 | u8 spoofchk_enabled; | 135 | u8 spoofchk_enabled; |
136 | unsigned int vf_api; | ||
138 | }; | 137 | }; |
139 | 138 | ||
140 | struct vf_macvlans { | 139 | struct vf_macvlans { |
@@ -482,7 +481,7 @@ struct ixgbe_adapter { | |||
482 | #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) | 481 | #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) |
483 | #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8) | 482 | #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8) |
484 | #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9) | 483 | #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9) |
485 | #define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 10) | 484 | #define IXGBE_FLAG2_PTP_ENABLED (u32)(1 << 10) |
486 | #define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) | 485 | #define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) |
487 | 486 | ||
488 | /* Tx fast path data */ | 487 | /* Tx fast path data */ |
@@ -571,7 +570,6 @@ struct ixgbe_adapter { | |||
571 | u32 interrupt_event; | 570 | u32 interrupt_event; |
572 | u32 led_reg; | 571 | u32 led_reg; |
573 | 572 | ||
574 | #ifdef CONFIG_IXGBE_PTP | ||
575 | struct ptp_clock *ptp_clock; | 573 | struct ptp_clock *ptp_clock; |
576 | struct ptp_clock_info ptp_caps; | 574 | struct ptp_clock_info ptp_caps; |
577 | unsigned long last_overflow_check; | 575 | unsigned long last_overflow_check; |
@@ -580,8 +578,6 @@ struct ixgbe_adapter { | |||
580 | struct timecounter tc; | 578 | struct timecounter tc; |
581 | int rx_hwtstamp_filter; | 579 | int rx_hwtstamp_filter; |
582 | u32 base_incval; | 580 | u32 base_incval; |
583 | u32 cycle_speed; | ||
584 | #endif /* CONFIG_IXGBE_PTP */ | ||
585 | 581 | ||
586 | /* SR-IOV */ | 582 | /* SR-IOV */ |
587 | DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); | 583 | DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); |
@@ -600,6 +596,8 @@ struct ixgbe_adapter { | |||
600 | #ifdef CONFIG_DEBUG_FS | 596 | #ifdef CONFIG_DEBUG_FS |
601 | struct dentry *ixgbe_dbg_adapter; | 597 | struct dentry *ixgbe_dbg_adapter; |
602 | #endif /*CONFIG_DEBUG_FS*/ | 598 | #endif /*CONFIG_DEBUG_FS*/ |
599 | |||
600 | u8 default_up; | ||
603 | }; | 601 | }; |
604 | 602 | ||
605 | struct ixgbe_fdir_filter { | 603 | struct ixgbe_fdir_filter { |
@@ -691,6 +689,7 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, | |||
691 | u16 soft_id); | 689 | u16 soft_id); |
692 | extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, | 690 | extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, |
693 | union ixgbe_atr_input *mask); | 691 | union ixgbe_atr_input *mask); |
692 | extern bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); | ||
694 | extern void ixgbe_set_rx_mode(struct net_device *netdev); | 693 | extern void ixgbe_set_rx_mode(struct net_device *netdev); |
695 | #ifdef CONFIG_IXGBE_DCB | 694 | #ifdef CONFIG_IXGBE_DCB |
696 | extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); | 695 | extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); |
@@ -739,7 +738,6 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) | |||
739 | return netdev_get_tx_queue(ring->netdev, ring->queue_index); | 738 | return netdev_get_tx_queue(ring->netdev, ring->queue_index); |
740 | } | 739 | } |
741 | 740 | ||
742 | #ifdef CONFIG_IXGBE_PTP | ||
743 | extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); | 741 | extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); |
744 | extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); | 742 | extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); |
745 | extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); | 743 | extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); |
@@ -751,7 +749,7 @@ extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | |||
751 | extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, | 749 | extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, |
752 | struct ifreq *ifr, int cmd); | 750 | struct ifreq *ifr, int cmd); |
753 | extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); | 751 | extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); |
752 | extern void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); | ||
754 | extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); | 753 | extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); |
755 | #endif /* CONFIG_IXGBE_PTP */ | ||
756 | 754 | ||
757 | #endif /* _IXGBE_H_ */ | 755 | #endif /* _IXGBE_H_ */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 1077cb2b38db..e75f5a4a2a6d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | |||
@@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, | |||
62 | bool autoneg, | 62 | bool autoneg, |
63 | bool autoneg_wait_to_complete); | 63 | bool autoneg_wait_to_complete); |
64 | static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); | 64 | static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); |
65 | static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); | ||
66 | 65 | ||
67 | static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) | 66 | static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) |
68 | { | 67 | { |
@@ -99,9 +98,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) | |||
99 | static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) | 98 | static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) |
100 | { | 99 | { |
101 | s32 ret_val = 0; | 100 | s32 ret_val = 0; |
102 | u32 reg_anlp1 = 0; | ||
103 | u32 i = 0; | ||
104 | u16 list_offset, data_offset, data_value; | 101 | u16 list_offset, data_offset, data_value; |
102 | bool got_lock = false; | ||
105 | 103 | ||
106 | if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { | 104 | if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { |
107 | ixgbe_init_mac_link_ops_82599(hw); | 105 | ixgbe_init_mac_link_ops_82599(hw); |
@@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) | |||
137 | usleep_range(hw->eeprom.semaphore_delay * 1000, | 135 | usleep_range(hw->eeprom.semaphore_delay * 1000, |
138 | hw->eeprom.semaphore_delay * 2000); | 136 | hw->eeprom.semaphore_delay * 2000); |
139 | 137 | ||
140 | /* Now restart DSP by setting Restart_AN and clearing LMS */ | 138 | /* Need SW/FW semaphore around AUTOC writes if LESM on, |
141 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw, | 139 | * likewise reset_pipeline requires lock as it also writes |
142 | IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) | | 140 | * AUTOC. |
143 | IXGBE_AUTOC_AN_RESTART)); | 141 | */ |
144 | 142 | if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { | |
145 | /* Wait for AN to leave state 0 */ | 143 | ret_val = hw->mac.ops.acquire_swfw_sync(hw, |
146 | for (i = 0; i < 10; i++) { | 144 | IXGBE_GSSR_MAC_CSR_SM); |
147 | usleep_range(4000, 8000); | 145 | if (ret_val) |
148 | reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1); | 146 | goto setup_sfp_out; |
149 | if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK) | 147 | |
150 | break; | 148 | got_lock = true; |
149 | } | ||
150 | |||
151 | /* Restart DSP and set SFI mode */ | ||
152 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw, | ||
153 | IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL)); | ||
154 | |||
155 | ret_val = ixgbe_reset_pipeline_82599(hw); | ||
156 | |||
157 | if (got_lock) { | ||
158 | hw->mac.ops.release_swfw_sync(hw, | ||
159 | IXGBE_GSSR_MAC_CSR_SM); | ||
160 | got_lock = false; | ||
151 | } | 161 | } |
152 | if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) { | 162 | |
153 | hw_dbg(hw, "sfp module setup not complete\n"); | 163 | if (ret_val) { |
164 | hw_dbg(hw, " sfp module setup not complete\n"); | ||
154 | ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; | 165 | ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; |
155 | goto setup_sfp_out; | 166 | goto setup_sfp_out; |
156 | } | 167 | } |
157 | |||
158 | /* Restart DSP by setting Restart_AN and return to SFI mode */ | ||
159 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw, | ||
160 | IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL | | ||
161 | IXGBE_AUTOC_AN_RESTART)); | ||
162 | } | 168 | } |
163 | 169 | ||
164 | setup_sfp_out: | 170 | setup_sfp_out: |
@@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, | |||
394 | u32 links_reg; | 400 | u32 links_reg; |
395 | u32 i; | 401 | u32 i; |
396 | s32 status = 0; | 402 | s32 status = 0; |
403 | bool got_lock = false; | ||
404 | |||
405 | if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
406 | status = hw->mac.ops.acquire_swfw_sync(hw, | ||
407 | IXGBE_GSSR_MAC_CSR_SM); | ||
408 | if (status) | ||
409 | goto out; | ||
410 | |||
411 | got_lock = true; | ||
412 | } | ||
397 | 413 | ||
398 | /* Restart link */ | 414 | /* Restart link */ |
399 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 415 | ixgbe_reset_pipeline_82599(hw); |
400 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 416 | |
401 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 417 | if (got_lock) |
418 | hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); | ||
402 | 419 | ||
403 | /* Only poll for autoneg to complete if specified to do so */ | 420 | /* Only poll for autoneg to complete if specified to do so */ |
404 | if (autoneg_wait_to_complete) { | 421 | if (autoneg_wait_to_complete) { |
422 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
405 | if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 423 | if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == |
406 | IXGBE_AUTOC_LMS_KX4_KX_KR || | 424 | IXGBE_AUTOC_LMS_KX4_KX_KR || |
407 | (autoc_reg & IXGBE_AUTOC_LMS_MASK) == | 425 | (autoc_reg & IXGBE_AUTOC_LMS_MASK) == |
@@ -425,6 +443,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, | |||
425 | /* Add delay to filter out noises during initial link setup */ | 443 | /* Add delay to filter out noises during initial link setup */ |
426 | msleep(50); | 444 | msleep(50); |
427 | 445 | ||
446 | out: | ||
428 | return status; | 447 | return status; |
429 | } | 448 | } |
430 | 449 | ||
@@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, | |||
779 | u32 links_reg; | 798 | u32 links_reg; |
780 | u32 i; | 799 | u32 i; |
781 | ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; | 800 | ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; |
801 | bool got_lock = false; | ||
782 | 802 | ||
783 | /* Check to see if speed passed in is supported. */ | 803 | /* Check to see if speed passed in is supported. */ |
784 | status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities, | 804 | status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities, |
@@ -836,9 +856,26 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, | |||
836 | } | 856 | } |
837 | 857 | ||
838 | if (autoc != start_autoc) { | 858 | if (autoc != start_autoc) { |
859 | /* Need SW/FW semaphore around AUTOC writes if LESM is on, | ||
860 | * likewise reset_pipeline requires us to hold this lock as | ||
861 | * it also writes to AUTOC. | ||
862 | */ | ||
863 | if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
864 | status = hw->mac.ops.acquire_swfw_sync(hw, | ||
865 | IXGBE_GSSR_MAC_CSR_SM); | ||
866 | if (status != 0) | ||
867 | goto out; | ||
868 | |||
869 | got_lock = true; | ||
870 | } | ||
871 | |||
839 | /* Restart link */ | 872 | /* Restart link */ |
840 | autoc |= IXGBE_AUTOC_AN_RESTART; | ||
841 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); | 873 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); |
874 | ixgbe_reset_pipeline_82599(hw); | ||
875 | |||
876 | if (got_lock) | ||
877 | hw->mac.ops.release_swfw_sync(hw, | ||
878 | IXGBE_GSSR_MAC_CSR_SM); | ||
842 | 879 | ||
843 | /* Only poll for autoneg to complete if specified to do so */ | 880 | /* Only poll for autoneg to complete if specified to do so */ |
844 | if (autoneg_wait_to_complete) { | 881 | if (autoneg_wait_to_complete) { |
@@ -994,9 +1031,28 @@ mac_reset_top: | |||
994 | hw->mac.orig_autoc2 = autoc2; | 1031 | hw->mac.orig_autoc2 = autoc2; |
995 | hw->mac.orig_link_settings_stored = true; | 1032 | hw->mac.orig_link_settings_stored = true; |
996 | } else { | 1033 | } else { |
997 | if (autoc != hw->mac.orig_autoc) | 1034 | if (autoc != hw->mac.orig_autoc) { |
998 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc | | 1035 | /* Need SW/FW semaphore around AUTOC writes if LESM is |
999 | IXGBE_AUTOC_AN_RESTART)); | 1036 | * on, likewise reset_pipeline requires us to hold |
1037 | * this lock as it also writes to AUTOC. | ||
1038 | */ | ||
1039 | bool got_lock = false; | ||
1040 | if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
1041 | status = hw->mac.ops.acquire_swfw_sync(hw, | ||
1042 | IXGBE_GSSR_MAC_CSR_SM); | ||
1043 | if (status) | ||
1044 | goto reset_hw_out; | ||
1045 | |||
1046 | got_lock = true; | ||
1047 | } | ||
1048 | |||
1049 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); | ||
1050 | ixgbe_reset_pipeline_82599(hw); | ||
1051 | |||
1052 | if (got_lock) | ||
1053 | hw->mac.ops.release_swfw_sync(hw, | ||
1054 | IXGBE_GSSR_MAC_CSR_SM); | ||
1055 | } | ||
1000 | 1056 | ||
1001 | if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != | 1057 | if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != |
1002 | (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { | 1058 | (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { |
@@ -1983,7 +2039,7 @@ fw_version_out: | |||
1983 | * Returns true if the LESM FW module is present and enabled. Otherwise | 2039 | * Returns true if the LESM FW module is present and enabled. Otherwise |
1984 | * returns false. Smart Speed must be disabled if LESM FW module is enabled. | 2040 | * returns false. Smart Speed must be disabled if LESM FW module is enabled. |
1985 | **/ | 2041 | **/ |
1986 | static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) | 2042 | bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) |
1987 | { | 2043 | { |
1988 | bool lesm_enabled = false; | 2044 | bool lesm_enabled = false; |
1989 | u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; | 2045 | u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; |
@@ -2080,6 +2136,50 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, | |||
2080 | return ret_val; | 2136 | return ret_val; |
2081 | } | 2137 | } |
2082 | 2138 | ||
2139 | /** | ||
2140 | * ixgbe_reset_pipeline_82599 - perform pipeline reset | ||
2141 | * | ||
2142 | * @hw: pointer to hardware structure | ||
2143 | * | ||
2144 | * Reset pipeline by asserting Restart_AN together with LMS change to ensure | ||
2145 | * full pipeline reset. Note - We must hold the SW/FW semaphore before writing | ||
2146 | * to AUTOC, so this function assumes the semaphore is held. | ||
2147 | **/ | ||
2148 | s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) | ||
2149 | { | ||
2150 | s32 i, autoc_reg, ret_val; | ||
2151 | s32 anlp1_reg = 0; | ||
2152 | |||
2153 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
2154 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | ||
2155 | |||
2156 | /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */ | ||
2157 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN); | ||
2158 | |||
2159 | /* Wait for AN to leave state 0 */ | ||
2160 | for (i = 0; i < 10; i++) { | ||
2161 | usleep_range(4000, 8000); | ||
2162 | anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); | ||
2163 | if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK) | ||
2164 | break; | ||
2165 | } | ||
2166 | |||
2167 | if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) { | ||
2168 | hw_dbg(hw, "auto negotiation not completed\n"); | ||
2169 | ret_val = IXGBE_ERR_RESET_FAILED; | ||
2170 | goto reset_pipeline_out; | ||
2171 | } | ||
2172 | |||
2173 | ret_val = 0; | ||
2174 | |||
2175 | reset_pipeline_out: | ||
2176 | /* Write AUTOC register with original LMS field and Restart_AN */ | ||
2177 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
2178 | IXGBE_WRITE_FLUSH(hw); | ||
2179 | |||
2180 | return ret_val; | ||
2181 | } | ||
2182 | |||
2083 | static struct ixgbe_mac_operations mac_ops_82599 = { | 2183 | static struct ixgbe_mac_operations mac_ops_82599 = { |
2084 | .init_hw = &ixgbe_init_hw_generic, | 2184 | .init_hw = &ixgbe_init_hw_generic, |
2085 | .reset_hw = &ixgbe_reset_hw_82599, | 2185 | .reset_hw = &ixgbe_reset_hw_82599, |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index dbf37e4a45fd..8f285edb5094 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | |||
@@ -90,6 +90,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw) | |||
90 | s32 ret_val = 0; | 90 | s32 ret_val = 0; |
91 | u32 reg = 0, reg_bp = 0; | 91 | u32 reg = 0, reg_bp = 0; |
92 | u16 reg_cu = 0; | 92 | u16 reg_cu = 0; |
93 | bool got_lock = false; | ||
93 | 94 | ||
94 | /* | 95 | /* |
95 | * Validate the requested mode. Strict IEEE mode does not allow | 96 | * Validate the requested mode. Strict IEEE mode does not allow |
@@ -210,8 +211,29 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw) | |||
210 | * | 211 | * |
211 | */ | 212 | */ |
212 | if (hw->phy.media_type == ixgbe_media_type_backplane) { | 213 | if (hw->phy.media_type == ixgbe_media_type_backplane) { |
213 | reg_bp |= IXGBE_AUTOC_AN_RESTART; | 214 | /* Need the SW/FW semaphore around AUTOC writes if 82599 and |
215 | * LESM is on, likewise reset_pipeline requries the lock as | ||
216 | * it also writes AUTOC. | ||
217 | */ | ||
218 | if ((hw->mac.type == ixgbe_mac_82599EB) && | ||
219 | ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
220 | ret_val = hw->mac.ops.acquire_swfw_sync(hw, | ||
221 | IXGBE_GSSR_MAC_CSR_SM); | ||
222 | if (ret_val) | ||
223 | goto out; | ||
224 | |||
225 | got_lock = true; | ||
226 | } | ||
227 | |||
214 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); | 228 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); |
229 | |||
230 | if (hw->mac.type == ixgbe_mac_82599EB) | ||
231 | ixgbe_reset_pipeline_82599(hw); | ||
232 | |||
233 | if (got_lock) | ||
234 | hw->mac.ops.release_swfw_sync(hw, | ||
235 | IXGBE_GSSR_MAC_CSR_SM); | ||
236 | |||
215 | } else if ((hw->phy.media_type == ixgbe_media_type_copper) && | 237 | } else if ((hw->phy.media_type == ixgbe_media_type_copper) && |
216 | (ixgbe_device_supports_autoneg_fc(hw) == 0)) { | 238 | (ixgbe_device_supports_autoneg_fc(hw) == 0)) { |
217 | hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, | 239 | hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, |
@@ -1778,8 +1800,7 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr) | |||
1778 | else if (IXGBE_IS_BROADCAST(mac_addr)) | 1800 | else if (IXGBE_IS_BROADCAST(mac_addr)) |
1779 | status = IXGBE_ERR_INVALID_MAC_ADDR; | 1801 | status = IXGBE_ERR_INVALID_MAC_ADDR; |
1780 | /* Reject the zero address */ | 1802 | /* Reject the zero address */ |
1781 | else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && | 1803 | else if (is_zero_ether_addr(mac_addr)) |
1782 | mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) | ||
1783 | status = IXGBE_ERR_INVALID_MAC_ADDR; | 1804 | status = IXGBE_ERR_INVALID_MAC_ADDR; |
1784 | 1805 | ||
1785 | return status; | 1806 | return status; |
@@ -2617,6 +2638,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | |||
2617 | bool link_up = false; | 2638 | bool link_up = false; |
2618 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 2639 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); |
2619 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 2640 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); |
2641 | s32 ret_val = 0; | ||
2620 | 2642 | ||
2621 | /* | 2643 | /* |
2622 | * Link must be up to auto-blink the LEDs; | 2644 | * Link must be up to auto-blink the LEDs; |
@@ -2625,10 +2647,28 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | |||
2625 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | 2647 | hw->mac.ops.check_link(hw, &speed, &link_up, false); |
2626 | 2648 | ||
2627 | if (!link_up) { | 2649 | if (!link_up) { |
2650 | /* Need the SW/FW semaphore around AUTOC writes if 82599 and | ||
2651 | * LESM is on. | ||
2652 | */ | ||
2653 | bool got_lock = false; | ||
2654 | |||
2655 | if ((hw->mac.type == ixgbe_mac_82599EB) && | ||
2656 | ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
2657 | ret_val = hw->mac.ops.acquire_swfw_sync(hw, | ||
2658 | IXGBE_GSSR_MAC_CSR_SM); | ||
2659 | if (ret_val) | ||
2660 | goto out; | ||
2661 | |||
2662 | got_lock = true; | ||
2663 | } | ||
2628 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 2664 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; |
2629 | autoc_reg |= IXGBE_AUTOC_FLU; | 2665 | autoc_reg |= IXGBE_AUTOC_FLU; |
2630 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 2666 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); |
2631 | IXGBE_WRITE_FLUSH(hw); | 2667 | IXGBE_WRITE_FLUSH(hw); |
2668 | |||
2669 | if (got_lock) | ||
2670 | hw->mac.ops.release_swfw_sync(hw, | ||
2671 | IXGBE_GSSR_MAC_CSR_SM); | ||
2632 | usleep_range(10000, 20000); | 2672 | usleep_range(10000, 20000); |
2633 | } | 2673 | } |
2634 | 2674 | ||
@@ -2637,7 +2677,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | |||
2637 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 2677 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); |
2638 | IXGBE_WRITE_FLUSH(hw); | 2678 | IXGBE_WRITE_FLUSH(hw); |
2639 | 2679 | ||
2640 | return 0; | 2680 | out: |
2681 | return ret_val; | ||
2641 | } | 2682 | } |
2642 | 2683 | ||
2643 | /** | 2684 | /** |
@@ -2649,18 +2690,40 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) | |||
2649 | { | 2690 | { |
2650 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 2691 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); |
2651 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 2692 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); |
2693 | s32 ret_val = 0; | ||
2694 | bool got_lock = false; | ||
2695 | |||
2696 | /* Need the SW/FW semaphore around AUTOC writes if 82599 and | ||
2697 | * LESM is on. | ||
2698 | */ | ||
2699 | if ((hw->mac.type == ixgbe_mac_82599EB) && | ||
2700 | ixgbe_verify_lesm_fw_enabled_82599(hw)) { | ||
2701 | ret_val = hw->mac.ops.acquire_swfw_sync(hw, | ||
2702 | IXGBE_GSSR_MAC_CSR_SM); | ||
2703 | if (ret_val) | ||
2704 | goto out; | ||
2705 | |||
2706 | got_lock = true; | ||
2707 | } | ||
2652 | 2708 | ||
2653 | autoc_reg &= ~IXGBE_AUTOC_FLU; | 2709 | autoc_reg &= ~IXGBE_AUTOC_FLU; |
2654 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 2710 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; |
2655 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 2711 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); |
2656 | 2712 | ||
2713 | if (hw->mac.type == ixgbe_mac_82599EB) | ||
2714 | ixgbe_reset_pipeline_82599(hw); | ||
2715 | |||
2716 | if (got_lock) | ||
2717 | hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); | ||
2718 | |||
2657 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | 2719 | led_reg &= ~IXGBE_LED_MODE_MASK(index); |
2658 | led_reg &= ~IXGBE_LED_BLINK(index); | 2720 | led_reg &= ~IXGBE_LED_BLINK(index); |
2659 | led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); | 2721 | led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); |
2660 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | 2722 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); |
2661 | IXGBE_WRITE_FLUSH(hw); | 2723 | IXGBE_WRITE_FLUSH(hw); |
2662 | 2724 | ||
2663 | return 0; | 2725 | out: |
2726 | return ret_val; | ||
2664 | } | 2727 | } |
2665 | 2728 | ||
2666 | /** | 2729 | /** |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h index d813d1188c36..587db4728072 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | |||
@@ -107,6 +107,7 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); | |||
107 | 107 | ||
108 | void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, | 108 | void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, |
109 | u32 headroom, int strategy); | 109 | u32 headroom, int strategy); |
110 | s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw); | ||
110 | 111 | ||
111 | #define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8 | 112 | #define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8 |
112 | #define IXGBE_EMC_INTERNAL_DATA 0x00 | 113 | #define IXGBE_EMC_INTERNAL_DATA 0x00 |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 116f0e901bee..a545728e100c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | |||
@@ -887,24 +887,23 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
887 | struct ethtool_ringparam *ring) | 887 | struct ethtool_ringparam *ring) |
888 | { | 888 | { |
889 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 889 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
890 | struct ixgbe_ring *temp_tx_ring, *temp_rx_ring; | 890 | struct ixgbe_ring *temp_ring; |
891 | int i, err = 0; | 891 | int i, err = 0; |
892 | u32 new_rx_count, new_tx_count; | 892 | u32 new_rx_count, new_tx_count; |
893 | bool need_update = false; | ||
894 | 893 | ||
895 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 894 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
896 | return -EINVAL; | 895 | return -EINVAL; |
897 | 896 | ||
898 | new_rx_count = max_t(u32, ring->rx_pending, IXGBE_MIN_RXD); | 897 | new_tx_count = clamp_t(u32, ring->tx_pending, |
899 | new_rx_count = min_t(u32, new_rx_count, IXGBE_MAX_RXD); | 898 | IXGBE_MIN_TXD, IXGBE_MAX_TXD); |
900 | new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); | ||
901 | |||
902 | new_tx_count = max_t(u32, ring->tx_pending, IXGBE_MIN_TXD); | ||
903 | new_tx_count = min_t(u32, new_tx_count, IXGBE_MAX_TXD); | ||
904 | new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); | 899 | new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); |
905 | 900 | ||
906 | if ((new_tx_count == adapter->tx_ring[0]->count) && | 901 | new_rx_count = clamp_t(u32, ring->rx_pending, |
907 | (new_rx_count == adapter->rx_ring[0]->count)) { | 902 | IXGBE_MIN_RXD, IXGBE_MAX_RXD); |
903 | new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); | ||
904 | |||
905 | if ((new_tx_count == adapter->tx_ring_count) && | ||
906 | (new_rx_count == adapter->rx_ring_count)) { | ||
908 | /* nothing to do */ | 907 | /* nothing to do */ |
909 | return 0; | 908 | return 0; |
910 | } | 909 | } |
@@ -922,81 +921,80 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
922 | goto clear_reset; | 921 | goto clear_reset; |
923 | } | 922 | } |
924 | 923 | ||
925 | temp_tx_ring = vmalloc(adapter->num_tx_queues * sizeof(struct ixgbe_ring)); | 924 | /* allocate temporary buffer to store rings in */ |
926 | if (!temp_tx_ring) { | 925 | i = max_t(int, adapter->num_tx_queues, adapter->num_rx_queues); |
926 | temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); | ||
927 | |||
928 | if (!temp_ring) { | ||
927 | err = -ENOMEM; | 929 | err = -ENOMEM; |
928 | goto clear_reset; | 930 | goto clear_reset; |
929 | } | 931 | } |
930 | 932 | ||
933 | ixgbe_down(adapter); | ||
934 | |||
935 | /* | ||
936 | * Setup new Tx resources and free the old Tx resources in that order. | ||
937 | * We can then assign the new resources to the rings via a memcpy. | ||
938 | * The advantage to this approach is that we are guaranteed to still | ||
939 | * have resources even in the case of an allocation failure. | ||
940 | */ | ||
931 | if (new_tx_count != adapter->tx_ring_count) { | 941 | if (new_tx_count != adapter->tx_ring_count) { |
932 | for (i = 0; i < adapter->num_tx_queues; i++) { | 942 | for (i = 0; i < adapter->num_tx_queues; i++) { |
933 | memcpy(&temp_tx_ring[i], adapter->tx_ring[i], | 943 | memcpy(&temp_ring[i], adapter->tx_ring[i], |
934 | sizeof(struct ixgbe_ring)); | 944 | sizeof(struct ixgbe_ring)); |
935 | temp_tx_ring[i].count = new_tx_count; | 945 | |
936 | err = ixgbe_setup_tx_resources(&temp_tx_ring[i]); | 946 | temp_ring[i].count = new_tx_count; |
947 | err = ixgbe_setup_tx_resources(&temp_ring[i]); | ||
937 | if (err) { | 948 | if (err) { |
938 | while (i) { | 949 | while (i) { |
939 | i--; | 950 | i--; |
940 | ixgbe_free_tx_resources(&temp_tx_ring[i]); | 951 | ixgbe_free_tx_resources(&temp_ring[i]); |
941 | } | 952 | } |
942 | goto clear_reset; | 953 | goto err_setup; |
943 | } | 954 | } |
944 | } | 955 | } |
945 | need_update = true; | ||
946 | } | ||
947 | 956 | ||
948 | temp_rx_ring = vmalloc(adapter->num_rx_queues * sizeof(struct ixgbe_ring)); | 957 | for (i = 0; i < adapter->num_tx_queues; i++) { |
949 | if (!temp_rx_ring) { | 958 | ixgbe_free_tx_resources(adapter->tx_ring[i]); |
950 | err = -ENOMEM; | 959 | |
951 | goto err_setup; | 960 | memcpy(adapter->tx_ring[i], &temp_ring[i], |
961 | sizeof(struct ixgbe_ring)); | ||
962 | } | ||
963 | |||
964 | adapter->tx_ring_count = new_tx_count; | ||
952 | } | 965 | } |
953 | 966 | ||
967 | /* Repeat the process for the Rx rings if needed */ | ||
954 | if (new_rx_count != adapter->rx_ring_count) { | 968 | if (new_rx_count != adapter->rx_ring_count) { |
955 | for (i = 0; i < adapter->num_rx_queues; i++) { | 969 | for (i = 0; i < adapter->num_rx_queues; i++) { |
956 | memcpy(&temp_rx_ring[i], adapter->rx_ring[i], | 970 | memcpy(&temp_ring[i], adapter->rx_ring[i], |
957 | sizeof(struct ixgbe_ring)); | 971 | sizeof(struct ixgbe_ring)); |
958 | temp_rx_ring[i].count = new_rx_count; | 972 | |
959 | err = ixgbe_setup_rx_resources(&temp_rx_ring[i]); | 973 | temp_ring[i].count = new_rx_count; |
974 | err = ixgbe_setup_rx_resources(&temp_ring[i]); | ||
960 | if (err) { | 975 | if (err) { |
961 | while (i) { | 976 | while (i) { |
962 | i--; | 977 | i--; |
963 | ixgbe_free_rx_resources(&temp_rx_ring[i]); | 978 | ixgbe_free_rx_resources(&temp_ring[i]); |
964 | } | 979 | } |
965 | goto err_setup; | 980 | goto err_setup; |
966 | } | 981 | } |
982 | |||
967 | } | 983 | } |
968 | need_update = true; | ||
969 | } | ||
970 | 984 | ||
971 | /* if rings need to be updated, here's the place to do it in one shot */ | 985 | for (i = 0; i < adapter->num_rx_queues; i++) { |
972 | if (need_update) { | 986 | ixgbe_free_rx_resources(adapter->rx_ring[i]); |
973 | ixgbe_down(adapter); | ||
974 | 987 | ||
975 | /* tx */ | 988 | memcpy(adapter->rx_ring[i], &temp_ring[i], |
976 | if (new_tx_count != adapter->tx_ring_count) { | 989 | sizeof(struct ixgbe_ring)); |
977 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
978 | ixgbe_free_tx_resources(adapter->tx_ring[i]); | ||
979 | memcpy(adapter->tx_ring[i], &temp_tx_ring[i], | ||
980 | sizeof(struct ixgbe_ring)); | ||
981 | } | ||
982 | adapter->tx_ring_count = new_tx_count; | ||
983 | } | 990 | } |
984 | 991 | ||
985 | /* rx */ | 992 | adapter->rx_ring_count = new_rx_count; |
986 | if (new_rx_count != adapter->rx_ring_count) { | ||
987 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
988 | ixgbe_free_rx_resources(adapter->rx_ring[i]); | ||
989 | memcpy(adapter->rx_ring[i], &temp_rx_ring[i], | ||
990 | sizeof(struct ixgbe_ring)); | ||
991 | } | ||
992 | adapter->rx_ring_count = new_rx_count; | ||
993 | } | ||
994 | ixgbe_up(adapter); | ||
995 | } | 993 | } |
996 | 994 | ||
997 | vfree(temp_rx_ring); | ||
998 | err_setup: | 995 | err_setup: |
999 | vfree(temp_tx_ring); | 996 | ixgbe_up(adapter); |
997 | vfree(temp_ring); | ||
1000 | clear_reset: | 998 | clear_reset: |
1001 | clear_bit(__IXGBE_RESETTING, &adapter->state); | 999 | clear_bit(__IXGBE_RESETTING, &adapter->state); |
1002 | return err; | 1000 | return err; |
@@ -2669,7 +2667,6 @@ static int ixgbe_get_ts_info(struct net_device *dev, | |||
2669 | struct ixgbe_adapter *adapter = netdev_priv(dev); | 2667 | struct ixgbe_adapter *adapter = netdev_priv(dev); |
2670 | 2668 | ||
2671 | switch (adapter->hw.mac.type) { | 2669 | switch (adapter->hw.mac.type) { |
2672 | #ifdef CONFIG_IXGBE_PTP | ||
2673 | case ixgbe_mac_X540: | 2670 | case ixgbe_mac_X540: |
2674 | case ixgbe_mac_82599EB: | 2671 | case ixgbe_mac_82599EB: |
2675 | info->so_timestamping = | 2672 | info->so_timestamping = |
@@ -2695,7 +2692,6 @@ static int ixgbe_get_ts_info(struct net_device *dev, | |||
2695 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | | 2692 | (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | |
2696 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); | 2693 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); |
2697 | break; | 2694 | break; |
2698 | #endif /* CONFIG_IXGBE_PTP */ | ||
2699 | default: | 2695 | default: |
2700 | return ethtool_op_get_ts_info(dev, info); | 2696 | return ethtool_op_get_ts_info(dev, info); |
2701 | break; | 2697 | break; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index ae73ef14fdf3..252850d9a3e0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | |||
@@ -800,6 +800,10 @@ int ixgbe_fcoe_enable(struct net_device *netdev) | |||
800 | return -EINVAL; | 800 | return -EINVAL; |
801 | 801 | ||
802 | e_info(drv, "Enabling FCoE offload features.\n"); | 802 | e_info(drv, "Enabling FCoE offload features.\n"); |
803 | |||
804 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) | ||
805 | e_warn(probe, "Enabling FCoE on PF will disable legacy VFs\n"); | ||
806 | |||
803 | if (netif_running(netdev)) | 807 | if (netif_running(netdev)) |
804 | netdev->netdev_ops->ndo_stop(netdev); | 808 | netdev->netdev_ops->ndo_stop(netdev); |
805 | 809 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index 17ecbcedd548..8c74f739011d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | |||
@@ -802,10 +802,13 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, | |||
802 | /* setup affinity mask and node */ | 802 | /* setup affinity mask and node */ |
803 | if (cpu != -1) | 803 | if (cpu != -1) |
804 | cpumask_set_cpu(cpu, &q_vector->affinity_mask); | 804 | cpumask_set_cpu(cpu, &q_vector->affinity_mask); |
805 | else | ||
806 | cpumask_copy(&q_vector->affinity_mask, cpu_online_mask); | ||
807 | q_vector->numa_node = node; | 805 | q_vector->numa_node = node; |
808 | 806 | ||
807 | #ifdef CONFIG_IXGBE_DCA | ||
808 | /* initialize CPU for DCA */ | ||
809 | q_vector->cpu = -1; | ||
810 | |||
811 | #endif | ||
809 | /* initialize NAPI */ | 812 | /* initialize NAPI */ |
810 | netif_napi_add(adapter->netdev, &q_vector->napi, | 813 | netif_napi_add(adapter->netdev, &q_vector->napi, |
811 | ixgbe_poll, 64); | 814 | ixgbe_poll, 64); |
@@ -821,6 +824,21 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, | |||
821 | /* initialize pointer to rings */ | 824 | /* initialize pointer to rings */ |
822 | ring = q_vector->ring; | 825 | ring = q_vector->ring; |
823 | 826 | ||
827 | /* intialize ITR */ | ||
828 | if (txr_count && !rxr_count) { | ||
829 | /* tx only vector */ | ||
830 | if (adapter->tx_itr_setting == 1) | ||
831 | q_vector->itr = IXGBE_10K_ITR; | ||
832 | else | ||
833 | q_vector->itr = adapter->tx_itr_setting; | ||
834 | } else { | ||
835 | /* rx or rx/tx vector */ | ||
836 | if (adapter->rx_itr_setting == 1) | ||
837 | q_vector->itr = IXGBE_20K_ITR; | ||
838 | else | ||
839 | q_vector->itr = adapter->rx_itr_setting; | ||
840 | } | ||
841 | |||
824 | while (txr_count) { | 842 | while (txr_count) { |
825 | /* assign generic ring traits */ | 843 | /* assign generic ring traits */ |
826 | ring->dev = &adapter->pdev->dev; | 844 | ring->dev = &adapter->pdev->dev; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index fa3d552e1f4a..690535a0322f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/ethtool.h> | 44 | #include <linux/ethtool.h> |
45 | #include <linux/if.h> | 45 | #include <linux/if.h> |
46 | #include <linux/if_vlan.h> | 46 | #include <linux/if_vlan.h> |
47 | #include <linux/if_bridge.h> | ||
47 | #include <linux/prefetch.h> | 48 | #include <linux/prefetch.h> |
48 | #include <scsi/fc/fc_fcoe.h> | 49 | #include <scsi/fc/fc_fcoe.h> |
49 | 50 | ||
@@ -355,13 +356,37 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) | |||
355 | 356 | ||
356 | /* Transmit Descriptor Formats | 357 | /* Transmit Descriptor Formats |
357 | * | 358 | * |
358 | * Advanced Transmit Descriptor | 359 | * 82598 Advanced Transmit Descriptor |
359 | * +--------------------------------------------------------------+ | 360 | * +--------------------------------------------------------------+ |
360 | * 0 | Buffer Address [63:0] | | 361 | * 0 | Buffer Address [63:0] | |
361 | * +--------------------------------------------------------------+ | 362 | * +--------------------------------------------------------------+ |
362 | * 8 | PAYLEN | PORTS | IDX | STA | DCMD |DTYP | RSV | DTALEN | | 363 | * 8 | PAYLEN | POPTS | IDX | STA | DCMD |DTYP | RSV | DTALEN | |
363 | * +--------------------------------------------------------------+ | 364 | * +--------------------------------------------------------------+ |
364 | * 63 46 45 40 39 36 35 32 31 24 23 20 19 0 | 365 | * 63 46 45 40 39 36 35 32 31 24 23 20 19 0 |
366 | * | ||
367 | * 82598 Advanced Transmit Descriptor (Write-Back Format) | ||
368 | * +--------------------------------------------------------------+ | ||
369 | * 0 | RSV [63:0] | | ||
370 | * +--------------------------------------------------------------+ | ||
371 | * 8 | RSV | STA | NXTSEQ | | ||
372 | * +--------------------------------------------------------------+ | ||
373 | * 63 36 35 32 31 0 | ||
374 | * | ||
375 | * 82599+ Advanced Transmit Descriptor | ||
376 | * +--------------------------------------------------------------+ | ||
377 | * 0 | Buffer Address [63:0] | | ||
378 | * +--------------------------------------------------------------+ | ||
379 | * 8 |PAYLEN |POPTS|CC|IDX |STA |DCMD |DTYP |MAC |RSV |DTALEN | | ||
380 | * +--------------------------------------------------------------+ | ||
381 | * 63 46 45 40 39 38 36 35 32 31 24 23 20 19 18 17 16 15 0 | ||
382 | * | ||
383 | * 82599+ Advanced Transmit Descriptor (Write-Back Format) | ||
384 | * +--------------------------------------------------------------+ | ||
385 | * 0 | RSV [63:0] | | ||
386 | * +--------------------------------------------------------------+ | ||
387 | * 8 | RSV | STA | RSV | | ||
388 | * +--------------------------------------------------------------+ | ||
389 | * 63 36 35 32 31 0 | ||
365 | */ | 390 | */ |
366 | 391 | ||
367 | for (n = 0; n < adapter->num_tx_queues; n++) { | 392 | for (n = 0; n < adapter->num_tx_queues; n++) { |
@@ -422,7 +447,9 @@ rx_ring_summary: | |||
422 | 447 | ||
423 | dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); | 448 | dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); |
424 | 449 | ||
425 | /* Advanced Receive Descriptor (Read) Format | 450 | /* Receive Descriptor Formats |
451 | * | ||
452 | * 82598 Advanced Receive Descriptor (Read) Format | ||
426 | * 63 1 0 | 453 | * 63 1 0 |
427 | * +-----------------------------------------------------+ | 454 | * +-----------------------------------------------------+ |
428 | * 0 | Packet Buffer Address [63:1] |A0/NSE| | 455 | * 0 | Packet Buffer Address [63:1] |A0/NSE| |
@@ -431,17 +458,40 @@ rx_ring_summary: | |||
431 | * +-----------------------------------------------------+ | 458 | * +-----------------------------------------------------+ |
432 | * | 459 | * |
433 | * | 460 | * |
434 | * Advanced Receive Descriptor (Write-Back) Format | 461 | * 82598 Advanced Receive Descriptor (Write-Back) Format |
435 | * | 462 | * |
436 | * 63 48 47 32 31 30 21 20 16 15 4 3 0 | 463 | * 63 48 47 32 31 30 21 20 16 15 4 3 0 |
437 | * +------------------------------------------------------+ | 464 | * +------------------------------------------------------+ |
438 | * 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS | | 465 | * 0 | RSS Hash / |SPH| HDR_LEN | RSV |Packet| RSS | |
439 | * | Checksum Ident | | | | Type | Type | | 466 | * | Packet | IP | | | | Type | Type | |
467 | * | Checksum | Ident | | | | | | | ||
440 | * +------------------------------------------------------+ | 468 | * +------------------------------------------------------+ |
441 | * 8 | VLAN Tag | Length | Extended Error | Extended Status | | 469 | * 8 | VLAN Tag | Length | Extended Error | Extended Status | |
442 | * +------------------------------------------------------+ | 470 | * +------------------------------------------------------+ |
443 | * 63 48 47 32 31 20 19 0 | 471 | * 63 48 47 32 31 20 19 0 |
472 | * | ||
473 | * 82599+ Advanced Receive Descriptor (Read) Format | ||
474 | * 63 1 0 | ||
475 | * +-----------------------------------------------------+ | ||
476 | * 0 | Packet Buffer Address [63:1] |A0/NSE| | ||
477 | * +----------------------------------------------+------+ | ||
478 | * 8 | Header Buffer Address [63:1] | DD | | ||
479 | * +-----------------------------------------------------+ | ||
480 | * | ||
481 | * | ||
482 | * 82599+ Advanced Receive Descriptor (Write-Back) Format | ||
483 | * | ||
484 | * 63 48 47 32 31 30 21 20 17 16 4 3 0 | ||
485 | * +------------------------------------------------------+ | ||
486 | * 0 |RSS / Frag Checksum|SPH| HDR_LEN |RSC- |Packet| RSS | | ||
487 | * |/ RTT / PCoE_PARAM | | | CNT | Type | Type | | ||
488 | * |/ Flow Dir Flt ID | | | | | | | ||
489 | * +------------------------------------------------------+ | ||
490 | * 8 | VLAN Tag | Length |Extended Error| Xtnd Status/NEXTP | | ||
491 | * +------------------------------------------------------+ | ||
492 | * 63 48 47 32 31 20 19 0 | ||
444 | */ | 493 | */ |
494 | |||
445 | for (n = 0; n < adapter->num_rx_queues; n++) { | 495 | for (n = 0; n < adapter->num_rx_queues; n++) { |
446 | rx_ring = adapter->rx_ring[n]; | 496 | rx_ring = adapter->rx_ring[n]; |
447 | pr_info("------------------------------------\n"); | 497 | pr_info("------------------------------------\n"); |
@@ -791,10 +841,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, | |||
791 | total_bytes += tx_buffer->bytecount; | 841 | total_bytes += tx_buffer->bytecount; |
792 | total_packets += tx_buffer->gso_segs; | 842 | total_packets += tx_buffer->gso_segs; |
793 | 843 | ||
794 | #ifdef CONFIG_IXGBE_PTP | ||
795 | if (unlikely(tx_buffer->tx_flags & IXGBE_TX_FLAGS_TSTAMP)) | 844 | if (unlikely(tx_buffer->tx_flags & IXGBE_TX_FLAGS_TSTAMP)) |
796 | ixgbe_ptp_tx_hwtstamp(q_vector, tx_buffer->skb); | 845 | ixgbe_ptp_tx_hwtstamp(q_vector, tx_buffer->skb); |
797 | #endif | ||
798 | 846 | ||
799 | /* free the skb */ | 847 | /* free the skb */ |
800 | dev_kfree_skb_any(tx_buffer->skb); | 848 | dev_kfree_skb_any(tx_buffer->skb); |
@@ -1244,6 +1292,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1244 | struct vlan_hdr *vlan; | 1292 | struct vlan_hdr *vlan; |
1245 | /* l3 headers */ | 1293 | /* l3 headers */ |
1246 | struct iphdr *ipv4; | 1294 | struct iphdr *ipv4; |
1295 | struct ipv6hdr *ipv6; | ||
1247 | } hdr; | 1296 | } hdr; |
1248 | __be16 protocol; | 1297 | __be16 protocol; |
1249 | u8 nexthdr = 0; /* default to not TCP */ | 1298 | u8 nexthdr = 0; /* default to not TCP */ |
@@ -1284,6 +1333,13 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1284 | /* record next protocol */ | 1333 | /* record next protocol */ |
1285 | nexthdr = hdr.ipv4->protocol; | 1334 | nexthdr = hdr.ipv4->protocol; |
1286 | hdr.network += hlen; | 1335 | hdr.network += hlen; |
1336 | } else if (protocol == __constant_htons(ETH_P_IPV6)) { | ||
1337 | if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr))) | ||
1338 | return max_len; | ||
1339 | |||
1340 | /* record next protocol */ | ||
1341 | nexthdr = hdr.ipv6->nexthdr; | ||
1342 | hdr.network += sizeof(struct ipv6hdr); | ||
1287 | #ifdef IXGBE_FCOE | 1343 | #ifdef IXGBE_FCOE |
1288 | } else if (protocol == __constant_htons(ETH_P_FCOE)) { | 1344 | } else if (protocol == __constant_htons(ETH_P_FCOE)) { |
1289 | if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) | 1345 | if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) |
@@ -1294,7 +1350,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1294 | return hdr.network - data; | 1350 | return hdr.network - data; |
1295 | } | 1351 | } |
1296 | 1352 | ||
1297 | /* finally sort out TCP */ | 1353 | /* finally sort out TCP/UDP */ |
1298 | if (nexthdr == IPPROTO_TCP) { | 1354 | if (nexthdr == IPPROTO_TCP) { |
1299 | if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) | 1355 | if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) |
1300 | return max_len; | 1356 | return max_len; |
@@ -1307,6 +1363,11 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, | |||
1307 | return hdr.network - data; | 1363 | return hdr.network - data; |
1308 | 1364 | ||
1309 | hdr.network += hlen; | 1365 | hdr.network += hlen; |
1366 | } else if (nexthdr == IPPROTO_UDP) { | ||
1367 | if ((hdr.network - data) > (max_len - sizeof(struct udphdr))) | ||
1368 | return max_len; | ||
1369 | |||
1370 | hdr.network += sizeof(struct udphdr); | ||
1310 | } | 1371 | } |
1311 | 1372 | ||
1312 | /* | 1373 | /* |
@@ -1369,9 +1430,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, | |||
1369 | 1430 | ||
1370 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); | 1431 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); |
1371 | 1432 | ||
1372 | #ifdef CONFIG_IXGBE_PTP | ||
1373 | ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb); | 1433 | ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb); |
1374 | #endif | ||
1375 | 1434 | ||
1376 | if ((dev->features & NETIF_F_HW_VLAN_RX) && | 1435 | if ((dev->features & NETIF_F_HW_VLAN_RX) && |
1377 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { | 1436 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { |
@@ -1781,7 +1840,7 @@ dma_sync: | |||
1781 | **/ | 1840 | **/ |
1782 | static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | 1841 | static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, |
1783 | struct ixgbe_ring *rx_ring, | 1842 | struct ixgbe_ring *rx_ring, |
1784 | int budget) | 1843 | const int budget) |
1785 | { | 1844 | { |
1786 | unsigned int total_rx_bytes = 0, total_rx_packets = 0; | 1845 | unsigned int total_rx_bytes = 0, total_rx_packets = 0; |
1787 | #ifdef IXGBE_FCOE | 1846 | #ifdef IXGBE_FCOE |
@@ -1832,7 +1891,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
1832 | 1891 | ||
1833 | /* probably a little skewed due to removing CRC */ | 1892 | /* probably a little skewed due to removing CRC */ |
1834 | total_rx_bytes += skb->len; | 1893 | total_rx_bytes += skb->len; |
1835 | total_rx_packets++; | ||
1836 | 1894 | ||
1837 | /* populate checksum, timestamp, VLAN, and protocol */ | 1895 | /* populate checksum, timestamp, VLAN, and protocol */ |
1838 | ixgbe_process_skb_fields(rx_ring, rx_desc, skb); | 1896 | ixgbe_process_skb_fields(rx_ring, rx_desc, skb); |
@@ -1865,8 +1923,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
1865 | ixgbe_rx_skb(q_vector, skb); | 1923 | ixgbe_rx_skb(q_vector, skb); |
1866 | 1924 | ||
1867 | /* update budget accounting */ | 1925 | /* update budget accounting */ |
1868 | budget--; | 1926 | total_rx_packets++; |
1869 | } while (likely(budget)); | 1927 | } while (likely(total_rx_packets < budget)); |
1870 | 1928 | ||
1871 | u64_stats_update_begin(&rx_ring->syncp); | 1929 | u64_stats_update_begin(&rx_ring->syncp); |
1872 | rx_ring->stats.packets += total_rx_packets; | 1930 | rx_ring->stats.packets += total_rx_packets; |
@@ -1878,7 +1936,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
1878 | if (cleaned_count) | 1936 | if (cleaned_count) |
1879 | ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); | 1937 | ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); |
1880 | 1938 | ||
1881 | return !!budget; | 1939 | return (total_rx_packets < budget); |
1882 | } | 1940 | } |
1883 | 1941 | ||
1884 | /** | 1942 | /** |
@@ -1914,20 +1972,6 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) | |||
1914 | ixgbe_for_each_ring(ring, q_vector->tx) | 1972 | ixgbe_for_each_ring(ring, q_vector->tx) |
1915 | ixgbe_set_ivar(adapter, 1, ring->reg_idx, v_idx); | 1973 | ixgbe_set_ivar(adapter, 1, ring->reg_idx, v_idx); |
1916 | 1974 | ||
1917 | if (q_vector->tx.ring && !q_vector->rx.ring) { | ||
1918 | /* tx only vector */ | ||
1919 | if (adapter->tx_itr_setting == 1) | ||
1920 | q_vector->itr = IXGBE_10K_ITR; | ||
1921 | else | ||
1922 | q_vector->itr = adapter->tx_itr_setting; | ||
1923 | } else { | ||
1924 | /* rx or rx/tx vector */ | ||
1925 | if (adapter->rx_itr_setting == 1) | ||
1926 | q_vector->itr = IXGBE_20K_ITR; | ||
1927 | else | ||
1928 | q_vector->itr = adapter->rx_itr_setting; | ||
1929 | } | ||
1930 | |||
1931 | ixgbe_write_eitr(q_vector); | 1975 | ixgbe_write_eitr(q_vector); |
1932 | } | 1976 | } |
1933 | 1977 | ||
@@ -2324,10 +2368,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, | |||
2324 | break; | 2368 | break; |
2325 | } | 2369 | } |
2326 | 2370 | ||
2327 | #ifdef CONFIG_IXGBE_PTP | ||
2328 | if (adapter->hw.mac.type == ixgbe_mac_X540) | 2371 | if (adapter->hw.mac.type == ixgbe_mac_X540) |
2329 | mask |= IXGBE_EIMS_TIMESYNC; | 2372 | mask |= IXGBE_EIMS_TIMESYNC; |
2330 | #endif | ||
2331 | 2373 | ||
2332 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && | 2374 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && |
2333 | !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) | 2375 | !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) |
@@ -2393,10 +2435,8 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) | |||
2393 | 2435 | ||
2394 | ixgbe_check_fan_failure(adapter, eicr); | 2436 | ixgbe_check_fan_failure(adapter, eicr); |
2395 | 2437 | ||
2396 | #ifdef CONFIG_IXGBE_PTP | ||
2397 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) | 2438 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) |
2398 | ixgbe_ptp_check_pps_event(adapter, eicr); | 2439 | ixgbe_ptp_check_pps_event(adapter, eicr); |
2399 | #endif | ||
2400 | 2440 | ||
2401 | /* re-enable the original interrupt state, no lsc, no queues */ | 2441 | /* re-enable the original interrupt state, no lsc, no queues */ |
2402 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 2442 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
@@ -2588,10 +2628,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
2588 | } | 2628 | } |
2589 | 2629 | ||
2590 | ixgbe_check_fan_failure(adapter, eicr); | 2630 | ixgbe_check_fan_failure(adapter, eicr); |
2591 | #ifdef CONFIG_IXGBE_PTP | ||
2592 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) | 2631 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) |
2593 | ixgbe_ptp_check_pps_event(adapter, eicr); | 2632 | ixgbe_ptp_check_pps_event(adapter, eicr); |
2594 | #endif | ||
2595 | 2633 | ||
2596 | /* would disable interrupts here but EIAM disabled it */ | 2634 | /* would disable interrupts here but EIAM disabled it */ |
2597 | napi_schedule(&q_vector->napi); | 2635 | napi_schedule(&q_vector->napi); |
@@ -2699,12 +2737,6 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) | |||
2699 | { | 2737 | { |
2700 | struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; | 2738 | struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; |
2701 | 2739 | ||
2702 | /* rx/tx vector */ | ||
2703 | if (adapter->rx_itr_setting == 1) | ||
2704 | q_vector->itr = IXGBE_20K_ITR; | ||
2705 | else | ||
2706 | q_vector->itr = adapter->rx_itr_setting; | ||
2707 | |||
2708 | ixgbe_write_eitr(q_vector); | 2740 | ixgbe_write_eitr(q_vector); |
2709 | 2741 | ||
2710 | ixgbe_set_ivar(adapter, 0, 0, 0); | 2742 | ixgbe_set_ivar(adapter, 0, 0, 0); |
@@ -3211,7 +3243,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) | |||
3211 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), reg_offset - 1); | 3243 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), reg_offset - 1); |
3212 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (~0) << vf_shift); | 3244 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (~0) << vf_shift); |
3213 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), reg_offset - 1); | 3245 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), reg_offset - 1); |
3214 | IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); | ||
3215 | 3246 | ||
3216 | /* Map PF MAC address in RAR Entry 0 to first pool following VFs */ | 3247 | /* Map PF MAC address in RAR Entry 0 to first pool following VFs */ |
3217 | hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0)); | 3248 | hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0)); |
@@ -3234,8 +3265,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) | |||
3234 | 3265 | ||
3235 | IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); | 3266 | IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); |
3236 | 3267 | ||
3237 | /* enable Tx loopback for VF/PF communication */ | ||
3238 | IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); | ||
3239 | 3268 | ||
3240 | /* Enable MAC Anti-Spoofing */ | 3269 | /* Enable MAC Anti-Spoofing */ |
3241 | hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), | 3270 | hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), |
@@ -3263,6 +3292,11 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) | |||
3263 | max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; | 3292 | max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; |
3264 | 3293 | ||
3265 | #endif /* IXGBE_FCOE */ | 3294 | #endif /* IXGBE_FCOE */ |
3295 | |||
3296 | /* adjust max frame to be at least the size of a standard frame */ | ||
3297 | if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN)) | ||
3298 | max_frame = (ETH_FRAME_LEN + ETH_FCS_LEN); | ||
3299 | |||
3266 | mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); | 3300 | mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); |
3267 | if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { | 3301 | if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { |
3268 | mhadd &= ~IXGBE_MHADD_MFS_MASK; | 3302 | mhadd &= ~IXGBE_MHADD_MFS_MASK; |
@@ -3271,9 +3305,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) | |||
3271 | IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); | 3305 | IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); |
3272 | } | 3306 | } |
3273 | 3307 | ||
3274 | /* MHADD will allow an extra 4 bytes past for vlan tagged frames */ | ||
3275 | max_frame += VLAN_HLEN; | ||
3276 | |||
3277 | hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); | 3308 | hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); |
3278 | /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */ | 3309 | /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */ |
3279 | hlreg0 |= IXGBE_HLREG0_JUMBOEN; | 3310 | hlreg0 |= IXGBE_HLREG0_JUMBOEN; |
@@ -4072,11 +4103,8 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
4072 | else | 4103 | else |
4073 | ixgbe_configure_msi_and_legacy(adapter); | 4104 | ixgbe_configure_msi_and_legacy(adapter); |
4074 | 4105 | ||
4075 | /* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */ | 4106 | /* enable the optics for 82599 SFP+ fiber */ |
4076 | if (hw->mac.ops.enable_tx_laser && | 4107 | if (hw->mac.ops.enable_tx_laser) |
4077 | ((hw->phy.multispeed_fiber) || | ||
4078 | ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && | ||
4079 | (hw->mac.type == ixgbe_mac_82599EB)))) | ||
4080 | hw->mac.ops.enable_tx_laser(hw); | 4108 | hw->mac.ops.enable_tx_laser(hw); |
4081 | 4109 | ||
4082 | clear_bit(__IXGBE_DOWN, &adapter->state); | 4110 | clear_bit(__IXGBE_DOWN, &adapter->state); |
@@ -4192,6 +4220,9 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) | |||
4192 | /* update SAN MAC vmdq pool selection */ | 4220 | /* update SAN MAC vmdq pool selection */ |
4193 | if (hw->mac.san_mac_rar_index) | 4221 | if (hw->mac.san_mac_rar_index) |
4194 | hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0)); | 4222 | hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0)); |
4223 | |||
4224 | if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) | ||
4225 | ixgbe_ptp_reset(adapter); | ||
4195 | } | 4226 | } |
4196 | 4227 | ||
4197 | /** | 4228 | /** |
@@ -4393,11 +4424,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
4393 | if (!pci_channel_offline(adapter->pdev)) | 4424 | if (!pci_channel_offline(adapter->pdev)) |
4394 | ixgbe_reset(adapter); | 4425 | ixgbe_reset(adapter); |
4395 | 4426 | ||
4396 | /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ | 4427 | /* power down the optics for 82599 SFP+ fiber */ |
4397 | if (hw->mac.ops.disable_tx_laser && | 4428 | if (hw->mac.ops.disable_tx_laser) |
4398 | ((hw->phy.multispeed_fiber) || | ||
4399 | ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && | ||
4400 | (hw->mac.type == ixgbe_mac_82599EB)))) | ||
4401 | hw->mac.ops.disable_tx_laser(hw); | 4429 | hw->mac.ops.disable_tx_laser(hw); |
4402 | 4430 | ||
4403 | ixgbe_clean_all_tx_rings(adapter); | 4431 | ixgbe_clean_all_tx_rings(adapter); |
@@ -4828,14 +4856,14 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) | |||
4828 | return -EINVAL; | 4856 | return -EINVAL; |
4829 | 4857 | ||
4830 | /* | 4858 | /* |
4831 | * For 82599EB we cannot allow PF to change MTU greater than 1500 | 4859 | * For 82599EB we cannot allow legacy VFs to enable their receive |
4832 | * in SR-IOV mode as it may cause buffer overruns in guest VFs that | 4860 | * paths when MTU greater than 1500 is configured. So display a |
4833 | * don't allocate and chain buffers correctly. | 4861 | * warning that legacy VFs will be disabled. |
4834 | */ | 4862 | */ |
4835 | if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && | 4863 | if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && |
4836 | (adapter->hw.mac.type == ixgbe_mac_82599EB) && | 4864 | (adapter->hw.mac.type == ixgbe_mac_82599EB) && |
4837 | (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) | 4865 | (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) |
4838 | return -EINVAL; | 4866 | e_warn(probe, "Setting MTU > 1500 will disable legacy VFs\n"); |
4839 | 4867 | ||
4840 | e_info(probe, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); | 4868 | e_info(probe, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); |
4841 | 4869 | ||
@@ -4901,6 +4929,8 @@ static int ixgbe_open(struct net_device *netdev) | |||
4901 | if (err) | 4929 | if (err) |
4902 | goto err_set_queues; | 4930 | goto err_set_queues; |
4903 | 4931 | ||
4932 | ixgbe_ptp_init(adapter); | ||
4933 | |||
4904 | ixgbe_up_complete(adapter); | 4934 | ixgbe_up_complete(adapter); |
4905 | 4935 | ||
4906 | return 0; | 4936 | return 0; |
@@ -4932,6 +4962,8 @@ static int ixgbe_close(struct net_device *netdev) | |||
4932 | { | 4962 | { |
4933 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 4963 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
4934 | 4964 | ||
4965 | ixgbe_ptp_stop(adapter); | ||
4966 | |||
4935 | ixgbe_down(adapter); | 4967 | ixgbe_down(adapter); |
4936 | ixgbe_free_irq(adapter); | 4968 | ixgbe_free_irq(adapter); |
4937 | 4969 | ||
@@ -5022,14 +5054,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
5022 | if (wufc) { | 5054 | if (wufc) { |
5023 | ixgbe_set_rx_mode(netdev); | 5055 | ixgbe_set_rx_mode(netdev); |
5024 | 5056 | ||
5025 | /* | 5057 | /* enable the optics for 82599 SFP+ fiber as we can WoL */ |
5026 | * enable the optics for both mult-speed fiber and | 5058 | if (hw->mac.ops.enable_tx_laser) |
5027 | * 82599 SFP+ fiber as we can WoL. | ||
5028 | */ | ||
5029 | if (hw->mac.ops.enable_tx_laser && | ||
5030 | (hw->phy.multispeed_fiber || | ||
5031 | (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && | ||
5032 | hw->mac.type == ixgbe_mac_82599EB))) | ||
5033 | hw->mac.ops.enable_tx_laser(hw); | 5059 | hw->mac.ops.enable_tx_laser(hw); |
5034 | 5060 | ||
5035 | /* turn on all-multi mode if wake on multicast is enabled */ | 5061 | /* turn on all-multi mode if wake on multicast is enabled */ |
@@ -5442,6 +5468,23 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter) | |||
5442 | adapter->link_speed = link_speed; | 5468 | adapter->link_speed = link_speed; |
5443 | } | 5469 | } |
5444 | 5470 | ||
5471 | static void ixgbe_update_default_up(struct ixgbe_adapter *adapter) | ||
5472 | { | ||
5473 | #ifdef CONFIG_IXGBE_DCB | ||
5474 | struct net_device *netdev = adapter->netdev; | ||
5475 | struct dcb_app app = { | ||
5476 | .selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE, | ||
5477 | .protocol = 0, | ||
5478 | }; | ||
5479 | u8 up = 0; | ||
5480 | |||
5481 | if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) | ||
5482 | up = dcb_ieee_getapp_mask(netdev, &app); | ||
5483 | |||
5484 | adapter->default_up = (up > 1) ? (ffs(up) - 1) : 0; | ||
5485 | #endif | ||
5486 | } | ||
5487 | |||
5445 | /** | 5488 | /** |
5446 | * ixgbe_watchdog_link_is_up - update netif_carrier status and | 5489 | * ixgbe_watchdog_link_is_up - update netif_carrier status and |
5447 | * print link up message | 5490 | * print link up message |
@@ -5482,9 +5525,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) | |||
5482 | break; | 5525 | break; |
5483 | } | 5526 | } |
5484 | 5527 | ||
5485 | #ifdef CONFIG_IXGBE_PTP | 5528 | if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) |
5486 | ixgbe_ptp_start_cyclecounter(adapter); | 5529 | ixgbe_ptp_start_cyclecounter(adapter); |
5487 | #endif | ||
5488 | 5530 | ||
5489 | e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", | 5531 | e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", |
5490 | (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? | 5532 | (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? |
@@ -5501,6 +5543,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) | |||
5501 | netif_carrier_on(netdev); | 5543 | netif_carrier_on(netdev); |
5502 | ixgbe_check_vf_rate_limit(adapter); | 5544 | ixgbe_check_vf_rate_limit(adapter); |
5503 | 5545 | ||
5546 | /* update the default user priority for VFs */ | ||
5547 | ixgbe_update_default_up(adapter); | ||
5548 | |||
5504 | /* ping all the active vfs to let them know link has changed */ | 5549 | /* ping all the active vfs to let them know link has changed */ |
5505 | ixgbe_ping_all_vfs(adapter); | 5550 | ixgbe_ping_all_vfs(adapter); |
5506 | } | 5551 | } |
@@ -5526,9 +5571,8 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) | |||
5526 | if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) | 5571 | if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) |
5527 | adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; | 5572 | adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; |
5528 | 5573 | ||
5529 | #ifdef CONFIG_IXGBE_PTP | 5574 | if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) |
5530 | ixgbe_ptp_start_cyclecounter(adapter); | 5575 | ixgbe_ptp_start_cyclecounter(adapter); |
5531 | #endif | ||
5532 | 5576 | ||
5533 | e_info(drv, "NIC Link is Down\n"); | 5577 | e_info(drv, "NIC Link is Down\n"); |
5534 | netif_carrier_off(netdev); | 5578 | netif_carrier_off(netdev); |
@@ -5833,9 +5877,7 @@ static void ixgbe_service_task(struct work_struct *work) | |||
5833 | ixgbe_watchdog_subtask(adapter); | 5877 | ixgbe_watchdog_subtask(adapter); |
5834 | ixgbe_fdir_reinit_subtask(adapter); | 5878 | ixgbe_fdir_reinit_subtask(adapter); |
5835 | ixgbe_check_hang_subtask(adapter); | 5879 | ixgbe_check_hang_subtask(adapter); |
5836 | #ifdef CONFIG_IXGBE_PTP | ||
5837 | ixgbe_ptp_overflow_check(adapter); | 5880 | ixgbe_ptp_overflow_check(adapter); |
5838 | #endif | ||
5839 | 5881 | ||
5840 | ixgbe_service_event_complete(adapter); | 5882 | ixgbe_service_event_complete(adapter); |
5841 | } | 5883 | } |
@@ -5988,10 +6030,8 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags) | |||
5988 | if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN) | 6030 | if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN) |
5989 | cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE); | 6031 | cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE); |
5990 | 6032 | ||
5991 | #ifdef CONFIG_IXGBE_PTP | ||
5992 | if (tx_flags & IXGBE_TX_FLAGS_TSTAMP) | 6033 | if (tx_flags & IXGBE_TX_FLAGS_TSTAMP) |
5993 | cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP); | 6034 | cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP); |
5994 | #endif | ||
5995 | 6035 | ||
5996 | /* set segmentation enable bits for TSO/FSO */ | 6036 | /* set segmentation enable bits for TSO/FSO */ |
5997 | #ifdef IXGBE_FCOE | 6037 | #ifdef IXGBE_FCOE |
@@ -6393,12 +6433,10 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | |||
6393 | 6433 | ||
6394 | skb_tx_timestamp(skb); | 6434 | skb_tx_timestamp(skb); |
6395 | 6435 | ||
6396 | #ifdef CONFIG_IXGBE_PTP | ||
6397 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { | 6436 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { |
6398 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | 6437 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
6399 | tx_flags |= IXGBE_TX_FLAGS_TSTAMP; | 6438 | tx_flags |= IXGBE_TX_FLAGS_TSTAMP; |
6400 | } | 6439 | } |
6401 | #endif | ||
6402 | 6440 | ||
6403 | #ifdef CONFIG_PCI_IOV | 6441 | #ifdef CONFIG_PCI_IOV |
6404 | /* | 6442 | /* |
@@ -6485,6 +6523,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, | |||
6485 | if (skb_pad(skb, 17 - skb->len)) | 6523 | if (skb_pad(skb, 17 - skb->len)) |
6486 | return NETDEV_TX_OK; | 6524 | return NETDEV_TX_OK; |
6487 | skb->len = 17; | 6525 | skb->len = 17; |
6526 | skb_set_tail_pointer(skb, 17); | ||
6488 | } | 6527 | } |
6489 | 6528 | ||
6490 | tx_ring = adapter->tx_ring[skb->queue_mapping]; | 6529 | tx_ring = adapter->tx_ring[skb->queue_mapping]; |
@@ -6547,10 +6586,8 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) | |||
6547 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 6586 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
6548 | 6587 | ||
6549 | switch (cmd) { | 6588 | switch (cmd) { |
6550 | #ifdef CONFIG_IXGBE_PTP | ||
6551 | case SIOCSHWTSTAMP: | 6589 | case SIOCSHWTSTAMP: |
6552 | return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd); | 6590 | return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd); |
6553 | #endif | ||
6554 | default: | 6591 | default: |
6555 | return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); | 6592 | return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); |
6556 | } | 6593 | } |
@@ -6916,7 +6953,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |||
6916 | return -EINVAL; | 6953 | return -EINVAL; |
6917 | } | 6954 | } |
6918 | 6955 | ||
6919 | if (is_unicast_ether_addr(addr)) { | 6956 | if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) { |
6920 | u32 rar_uc_entries = IXGBE_MAX_PF_MACVLANS; | 6957 | u32 rar_uc_entries = IXGBE_MAX_PF_MACVLANS; |
6921 | 6958 | ||
6922 | if (netdev_uc_count(dev) < rar_uc_entries) | 6959 | if (netdev_uc_count(dev) < rar_uc_entries) |
@@ -6974,6 +7011,59 @@ static int ixgbe_ndo_fdb_dump(struct sk_buff *skb, | |||
6974 | return idx; | 7011 | return idx; |
6975 | } | 7012 | } |
6976 | 7013 | ||
7014 | static int ixgbe_ndo_bridge_setlink(struct net_device *dev, | ||
7015 | struct nlmsghdr *nlh) | ||
7016 | { | ||
7017 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
7018 | struct nlattr *attr, *br_spec; | ||
7019 | int rem; | ||
7020 | |||
7021 | if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) | ||
7022 | return -EOPNOTSUPP; | ||
7023 | |||
7024 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); | ||
7025 | |||
7026 | nla_for_each_nested(attr, br_spec, rem) { | ||
7027 | __u16 mode; | ||
7028 | u32 reg = 0; | ||
7029 | |||
7030 | if (nla_type(attr) != IFLA_BRIDGE_MODE) | ||
7031 | continue; | ||
7032 | |||
7033 | mode = nla_get_u16(attr); | ||
7034 | if (mode == BRIDGE_MODE_VEPA) | ||
7035 | reg = 0; | ||
7036 | else if (mode == BRIDGE_MODE_VEB) | ||
7037 | reg = IXGBE_PFDTXGSWC_VT_LBEN; | ||
7038 | else | ||
7039 | return -EINVAL; | ||
7040 | |||
7041 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_PFDTXGSWC, reg); | ||
7042 | |||
7043 | e_info(drv, "enabling bridge mode: %s\n", | ||
7044 | mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB"); | ||
7045 | } | ||
7046 | |||
7047 | return 0; | ||
7048 | } | ||
7049 | |||
7050 | static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | ||
7051 | struct net_device *dev) | ||
7052 | { | ||
7053 | struct ixgbe_adapter *adapter = netdev_priv(dev); | ||
7054 | u16 mode; | ||
7055 | |||
7056 | if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) | ||
7057 | return 0; | ||
7058 | |||
7059 | if (IXGBE_READ_REG(&adapter->hw, IXGBE_PFDTXGSWC) & 1) | ||
7060 | mode = BRIDGE_MODE_VEB; | ||
7061 | else | ||
7062 | mode = BRIDGE_MODE_VEPA; | ||
7063 | |||
7064 | return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode); | ||
7065 | } | ||
7066 | |||
6977 | static const struct net_device_ops ixgbe_netdev_ops = { | 7067 | static const struct net_device_ops ixgbe_netdev_ops = { |
6978 | .ndo_open = ixgbe_open, | 7068 | .ndo_open = ixgbe_open, |
6979 | .ndo_stop = ixgbe_close, | 7069 | .ndo_stop = ixgbe_close, |
@@ -7013,6 +7103,8 @@ static const struct net_device_ops ixgbe_netdev_ops = { | |||
7013 | .ndo_fdb_add = ixgbe_ndo_fdb_add, | 7103 | .ndo_fdb_add = ixgbe_ndo_fdb_add, |
7014 | .ndo_fdb_del = ixgbe_ndo_fdb_del, | 7104 | .ndo_fdb_del = ixgbe_ndo_fdb_del, |
7015 | .ndo_fdb_dump = ixgbe_ndo_fdb_dump, | 7105 | .ndo_fdb_dump = ixgbe_ndo_fdb_dump, |
7106 | .ndo_bridge_setlink = ixgbe_ndo_bridge_setlink, | ||
7107 | .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink, | ||
7016 | }; | 7108 | }; |
7017 | 7109 | ||
7018 | /** | 7110 | /** |
@@ -7042,6 +7134,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, | |||
7042 | break; | 7134 | break; |
7043 | case IXGBE_SUBDEV_ID_82599_SFP: | 7135 | case IXGBE_SUBDEV_ID_82599_SFP: |
7044 | case IXGBE_SUBDEV_ID_82599_RNDC: | 7136 | case IXGBE_SUBDEV_ID_82599_RNDC: |
7137 | case IXGBE_SUBDEV_ID_82599_ECNA_DP: | ||
7045 | is_wol_supported = 1; | 7138 | is_wol_supported = 1; |
7046 | break; | 7139 | break; |
7047 | } | 7140 | } |
@@ -7364,10 +7457,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7364 | 7457 | ||
7365 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | 7458 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); |
7366 | 7459 | ||
7367 | #ifdef CONFIG_IXGBE_PTP | ||
7368 | ixgbe_ptp_init(adapter); | ||
7369 | #endif /* CONFIG_IXGBE_PTP*/ | ||
7370 | |||
7371 | /* save off EEPROM version number */ | 7460 | /* save off EEPROM version number */ |
7372 | hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); | 7461 | hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); |
7373 | hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); | 7462 | hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); |
@@ -7420,11 +7509,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
7420 | if (err) | 7509 | if (err) |
7421 | goto err_register; | 7510 | goto err_register; |
7422 | 7511 | ||
7423 | /* power down the optics for multispeed fiber and 82599 SFP+ fiber */ | 7512 | /* power down the optics for 82599 SFP+ fiber */ |
7424 | if (hw->mac.ops.disable_tx_laser && | 7513 | if (hw->mac.ops.disable_tx_laser) |
7425 | ((hw->phy.multispeed_fiber) || | ||
7426 | ((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) && | ||
7427 | (hw->mac.type == ixgbe_mac_82599EB)))) | ||
7428 | hw->mac.ops.disable_tx_laser(hw); | 7514 | hw->mac.ops.disable_tx_laser(hw); |
7429 | 7515 | ||
7430 | /* carrier off reporting is important to ethtool even BEFORE open */ | 7516 | /* carrier off reporting is important to ethtool even BEFORE open */ |
@@ -7505,9 +7591,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) | |||
7505 | set_bit(__IXGBE_DOWN, &adapter->state); | 7591 | set_bit(__IXGBE_DOWN, &adapter->state); |
7506 | cancel_work_sync(&adapter->service_task); | 7592 | cancel_work_sync(&adapter->service_task); |
7507 | 7593 | ||
7508 | #ifdef CONFIG_IXGBE_PTP | ||
7509 | ixgbe_ptp_stop(adapter); | ||
7510 | #endif | ||
7511 | 7594 | ||
7512 | #ifdef CONFIG_IXGBE_DCA | 7595 | #ifdef CONFIG_IXGBE_DCA |
7513 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { | 7596 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h index 310bdd961075..42dd65e6ac97 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | |||
@@ -62,12 +62,39 @@ | |||
62 | /* bits 23:16 are used for exra info for certain messages */ | 62 | /* bits 23:16 are used for exra info for certain messages */ |
63 | #define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT) | 63 | #define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT) |
64 | 64 | ||
65 | /* definitions to support mailbox API version negotiation */ | ||
66 | |||
67 | /* | ||
68 | * Each element denotes a version of the API; existing numbers may not | ||
69 | * change; any additions must go at the end | ||
70 | */ | ||
71 | enum ixgbe_pfvf_api_rev { | ||
72 | ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ | ||
73 | ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ | ||
74 | ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ | ||
75 | /* This value should always be last */ | ||
76 | ixgbe_mbox_api_unknown, /* indicates that API version is not known */ | ||
77 | }; | ||
78 | |||
79 | /* mailbox API, legacy requests */ | ||
65 | #define IXGBE_VF_RESET 0x01 /* VF requests reset */ | 80 | #define IXGBE_VF_RESET 0x01 /* VF requests reset */ |
66 | #define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */ | 81 | #define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */ |
67 | #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ | 82 | #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ |
68 | #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ | 83 | #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ |
69 | #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ | 84 | |
70 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ | 85 | /* mailbox API, version 1.0 VF requests */ |
86 | #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ | ||
87 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ | ||
88 | #define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ | ||
89 | |||
90 | /* mailbox API, version 1.1 VF requests */ | ||
91 | #define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */ | ||
92 | |||
93 | /* GET_QUEUES return data indices within the mailbox */ | ||
94 | #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ | ||
95 | #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ | ||
96 | #define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */ | ||
97 | #define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */ | ||
71 | 98 | ||
72 | /* length of permanent address message returned from PF */ | 99 | /* length of permanent address message returned from PF */ |
73 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 | 100 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index d9291316ee9f..01d99af0b9ba 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -387,6 +387,15 @@ void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) | |||
387 | struct ixgbe_hw *hw = &adapter->hw; | 387 | struct ixgbe_hw *hw = &adapter->hw; |
388 | struct ptp_clock_event event; | 388 | struct ptp_clock_event event; |
389 | 389 | ||
390 | event.type = PTP_CLOCK_PPS; | ||
391 | |||
392 | /* this check is necessary in case the interrupt was enabled via some | ||
393 | * alternative means (ex. debug_fs). Better to check here than | ||
394 | * everywhere that calls this function. | ||
395 | */ | ||
396 | if (!adapter->ptp_clock) | ||
397 | return; | ||
398 | |||
390 | switch (hw->mac.type) { | 399 | switch (hw->mac.type) { |
391 | case ixgbe_mac_X540: | 400 | case ixgbe_mac_X540: |
392 | ptp_clock_event(adapter->ptp_clock, &event); | 401 | ptp_clock_event(adapter->ptp_clock, &event); |
@@ -411,7 +420,7 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) | |||
411 | unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies; | 420 | unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies; |
412 | struct timespec ts; | 421 | struct timespec ts; |
413 | 422 | ||
414 | if ((adapter->flags2 & IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED) && | 423 | if ((adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) && |
415 | (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) { | 424 | (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) { |
416 | ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); | 425 | ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); |
417 | adapter->last_overflow_check = jiffies; | 426 | adapter->last_overflow_check = jiffies; |
@@ -554,12 +563,14 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | |||
554 | adapter = q_vector->adapter; | 563 | adapter = q_vector->adapter; |
555 | hw = &adapter->hw; | 564 | hw = &adapter->hw; |
556 | 565 | ||
566 | if (likely(!ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter))) | ||
567 | return; | ||
568 | |||
557 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | 569 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
558 | 570 | ||
559 | /* Check if we have a valid timestamp and make sure the skb should | 571 | /* Check if we have a valid timestamp and make sure the skb should |
560 | * have been timestamped */ | 572 | * have been timestamped */ |
561 | if (likely(!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID) || | 573 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) |
562 | !ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter))) | ||
563 | return; | 574 | return; |
564 | 575 | ||
565 | /* | 576 | /* |
@@ -759,58 +770,20 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, | |||
759 | * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw | 770 | * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw |
760 | * @adapter: pointer to the adapter structure | 771 | * @adapter: pointer to the adapter structure |
761 | * | 772 | * |
762 | * this function initializes the timecounter and cyclecounter | 773 | * This function should be called to set the proper values for the TIMINCA |
763 | * structures for use in generated a ns counter from the arbitrary | 774 | * register and tell the cyclecounter structure what the tick rate of SYSTIME |
764 | * fixed point cycles registers in the hardware. | 775 | * is. It does not directly modify SYSTIME registers or the timecounter |
765 | * | 776 | * structure. It should be called whenever a new TIMINCA value is necessary, |
766 | * A change in link speed impacts the frequency of the DMA clock on | 777 | * such as during initialization or when the link speed changes. |
767 | * the device, which is used to generate the cycle counter | ||
768 | * registers. Therefor this function is called whenever the link speed | ||
769 | * changes. | ||
770 | * | ||
771 | * This function also turns on the SDP pin for clock out feature (X540 | ||
772 | * only), because this is where the shift is first calculated. | ||
773 | */ | 778 | */ |
774 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | 779 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) |
775 | { | 780 | { |
776 | struct ixgbe_hw *hw = &adapter->hw; | 781 | struct ixgbe_hw *hw = &adapter->hw; |
777 | u32 incval = 0; | 782 | u32 incval = 0; |
778 | u32 timinca = 0; | ||
779 | u32 shift = 0; | 783 | u32 shift = 0; |
780 | u32 cycle_speed; | ||
781 | unsigned long flags; | 784 | unsigned long flags; |
782 | 785 | ||
783 | /** | 786 | /** |
784 | * Determine what speed we need to set the cyclecounter | ||
785 | * for. It should be different for 100Mb, 1Gb, and 10Gb. Treat | ||
786 | * unknown speeds as 10Gb. (Hence why we can't just copy the | ||
787 | * link_speed. | ||
788 | */ | ||
789 | switch (adapter->link_speed) { | ||
790 | case IXGBE_LINK_SPEED_100_FULL: | ||
791 | case IXGBE_LINK_SPEED_1GB_FULL: | ||
792 | case IXGBE_LINK_SPEED_10GB_FULL: | ||
793 | cycle_speed = adapter->link_speed; | ||
794 | break; | ||
795 | default: | ||
796 | /* cycle speed should be 10Gb when there is no link */ | ||
797 | cycle_speed = IXGBE_LINK_SPEED_10GB_FULL; | ||
798 | break; | ||
799 | } | ||
800 | |||
801 | /* | ||
802 | * grab the current TIMINCA value from the register so that it can be | ||
803 | * double checked. If the register value has been cleared, it must be | ||
804 | * reset to the correct value for generating a cyclecounter. If | ||
805 | * TIMINCA is zero, the SYSTIME registers do not increment at all. | ||
806 | */ | ||
807 | timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); | ||
808 | |||
809 | /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ | ||
810 | if (adapter->cycle_speed == cycle_speed && timinca) | ||
811 | return; | ||
812 | |||
813 | /** | ||
814 | * Scale the NIC cycle counter by a large factor so that | 787 | * Scale the NIC cycle counter by a large factor so that |
815 | * relatively small corrections to the frequency can be added | 788 | * relatively small corrections to the frequency can be added |
816 | * or subtracted. The drawbacks of a large factor include | 789 | * or subtracted. The drawbacks of a large factor include |
@@ -819,8 +792,12 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
819 | * to nanoseconds using only a multiplier and a right-shift, | 792 | * to nanoseconds using only a multiplier and a right-shift, |
820 | * and (c) the value must fit within the timinca register space | 793 | * and (c) the value must fit within the timinca register space |
821 | * => math based on internal DMA clock rate and available bits | 794 | * => math based on internal DMA clock rate and available bits |
795 | * | ||
796 | * Note that when there is no link, internal DMA clock is same as when | ||
797 | * link speed is 10Gb. Set the registers correctly even when link is | ||
798 | * down to preserve the clock setting | ||
822 | */ | 799 | */ |
823 | switch (cycle_speed) { | 800 | switch (adapter->link_speed) { |
824 | case IXGBE_LINK_SPEED_100_FULL: | 801 | case IXGBE_LINK_SPEED_100_FULL: |
825 | incval = IXGBE_INCVAL_100; | 802 | incval = IXGBE_INCVAL_100; |
826 | shift = IXGBE_INCVAL_SHIFT_100; | 803 | shift = IXGBE_INCVAL_SHIFT_100; |
@@ -830,6 +807,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
830 | shift = IXGBE_INCVAL_SHIFT_1GB; | 807 | shift = IXGBE_INCVAL_SHIFT_1GB; |
831 | break; | 808 | break; |
832 | case IXGBE_LINK_SPEED_10GB_FULL: | 809 | case IXGBE_LINK_SPEED_10GB_FULL: |
810 | default: | ||
833 | incval = IXGBE_INCVAL_10GB; | 811 | incval = IXGBE_INCVAL_10GB; |
834 | shift = IXGBE_INCVAL_SHIFT_10GB; | 812 | shift = IXGBE_INCVAL_SHIFT_10GB; |
835 | break; | 813 | break; |
@@ -857,18 +835,11 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
857 | return; | 835 | return; |
858 | } | 836 | } |
859 | 837 | ||
860 | /* reset the system time registers */ | 838 | /* update the base incval used to calculate frequency adjustment */ |
861 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); | ||
862 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); | ||
863 | IXGBE_WRITE_FLUSH(hw); | ||
864 | |||
865 | /* store the new cycle speed */ | ||
866 | adapter->cycle_speed = cycle_speed; | ||
867 | |||
868 | ACCESS_ONCE(adapter->base_incval) = incval; | 839 | ACCESS_ONCE(adapter->base_incval) = incval; |
869 | smp_mb(); | 840 | smp_mb(); |
870 | 841 | ||
871 | /* grab the ptp lock */ | 842 | /* need lock to prevent incorrect read while modifying cyclecounter */ |
872 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | 843 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
873 | 844 | ||
874 | memset(&adapter->cc, 0, sizeof(adapter->cc)); | 845 | memset(&adapter->cc, 0, sizeof(adapter->cc)); |
@@ -877,6 +848,31 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
877 | adapter->cc.shift = shift; | 848 | adapter->cc.shift = shift; |
878 | adapter->cc.mult = 1; | 849 | adapter->cc.mult = 1; |
879 | 850 | ||
851 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | ||
852 | } | ||
853 | |||
854 | /** | ||
855 | * ixgbe_ptp_reset | ||
856 | * @adapter: the ixgbe private board structure | ||
857 | * | ||
858 | * When the MAC resets, all timesync features are reset. This function should be | ||
859 | * called to re-enable the PTP clock structure. It will re-init the timecounter | ||
860 | * structure based on the kernel time as well as setup the cycle counter data. | ||
861 | */ | ||
862 | void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) | ||
863 | { | ||
864 | struct ixgbe_hw *hw = &adapter->hw; | ||
865 | unsigned long flags; | ||
866 | |||
867 | /* set SYSTIME registers to 0 just in case */ | ||
868 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); | ||
869 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); | ||
870 | IXGBE_WRITE_FLUSH(hw); | ||
871 | |||
872 | ixgbe_ptp_start_cyclecounter(adapter); | ||
873 | |||
874 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | ||
875 | |||
880 | /* reset the ns time counter */ | 876 | /* reset the ns time counter */ |
881 | timecounter_init(&adapter->tc, &adapter->cc, | 877 | timecounter_init(&adapter->tc, &adapter->cc, |
882 | ktime_to_ns(ktime_get_real())); | 878 | ktime_to_ns(ktime_get_real())); |
@@ -904,7 +900,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
904 | 900 | ||
905 | switch (adapter->hw.mac.type) { | 901 | switch (adapter->hw.mac.type) { |
906 | case ixgbe_mac_X540: | 902 | case ixgbe_mac_X540: |
907 | snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); | 903 | snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); |
908 | adapter->ptp_caps.owner = THIS_MODULE; | 904 | adapter->ptp_caps.owner = THIS_MODULE; |
909 | adapter->ptp_caps.max_adj = 250000000; | 905 | adapter->ptp_caps.max_adj = 250000000; |
910 | adapter->ptp_caps.n_alarm = 0; | 906 | adapter->ptp_caps.n_alarm = 0; |
@@ -918,7 +914,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
918 | adapter->ptp_caps.enable = ixgbe_ptp_enable; | 914 | adapter->ptp_caps.enable = ixgbe_ptp_enable; |
919 | break; | 915 | break; |
920 | case ixgbe_mac_82599EB: | 916 | case ixgbe_mac_82599EB: |
921 | snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); | 917 | snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); |
922 | adapter->ptp_caps.owner = THIS_MODULE; | 918 | adapter->ptp_caps.owner = THIS_MODULE; |
923 | adapter->ptp_caps.max_adj = 250000000; | 919 | adapter->ptp_caps.max_adj = 250000000; |
924 | adapter->ptp_caps.n_alarm = 0; | 920 | adapter->ptp_caps.n_alarm = 0; |
@@ -942,11 +938,6 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
942 | 938 | ||
943 | spin_lock_init(&adapter->tmreg_lock); | 939 | spin_lock_init(&adapter->tmreg_lock); |
944 | 940 | ||
945 | ixgbe_ptp_start_cyclecounter(adapter); | ||
946 | |||
947 | /* (Re)start the overflow check */ | ||
948 | adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; | ||
949 | |||
950 | adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, | 941 | adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, |
951 | &adapter->pdev->dev); | 942 | &adapter->pdev->dev); |
952 | if (IS_ERR(adapter->ptp_clock)) { | 943 | if (IS_ERR(adapter->ptp_clock)) { |
@@ -955,6 +946,11 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
955 | } else | 946 | } else |
956 | e_dev_info("registered PHC device on %s\n", netdev->name); | 947 | e_dev_info("registered PHC device on %s\n", netdev->name); |
957 | 948 | ||
949 | ixgbe_ptp_reset(adapter); | ||
950 | |||
951 | /* set the flag that PTP has been enabled */ | ||
952 | adapter->flags2 |= IXGBE_FLAG2_PTP_ENABLED; | ||
953 | |||
958 | return; | 954 | return; |
959 | } | 955 | } |
960 | 956 | ||
@@ -967,7 +963,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
967 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) | 963 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) |
968 | { | 964 | { |
969 | /* stop the overflow check task */ | 965 | /* stop the overflow check task */ |
970 | adapter->flags2 &= ~(IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED | | 966 | adapter->flags2 &= ~(IXGBE_FLAG2_PTP_ENABLED | |
971 | IXGBE_FLAG2_PTP_PPS_ENABLED); | 967 | IXGBE_FLAG2_PTP_PPS_ENABLED); |
972 | 968 | ||
973 | ixgbe_ptp_setup_sdp(adapter); | 969 | ixgbe_ptp_setup_sdp(adapter); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index dce48bf64d96..4993642d1ce1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | |||
@@ -117,6 +117,9 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | /* Initialize default switching mode VEB */ | ||
121 | IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); | ||
122 | |||
120 | /* If call to enable VFs succeeded then allocate memory | 123 | /* If call to enable VFs succeeded then allocate memory |
121 | * for per VF control structures. | 124 | * for per VF control structures. |
122 | */ | 125 | */ |
@@ -150,16 +153,6 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, | |||
150 | adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE | | 153 | adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE | |
151 | IXGBE_FLAG2_RSC_ENABLED); | 154 | IXGBE_FLAG2_RSC_ENABLED); |
152 | 155 | ||
153 | #ifdef IXGBE_FCOE | ||
154 | /* | ||
155 | * When SR-IOV is enabled 82599 cannot support jumbo frames | ||
156 | * so we must disable FCoE because we cannot support FCoE MTU. | ||
157 | */ | ||
158 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | ||
159 | adapter->flags &= ~(IXGBE_FLAG_FCOE_ENABLED | | ||
160 | IXGBE_FLAG_FCOE_CAPABLE); | ||
161 | #endif | ||
162 | |||
163 | /* enable spoof checking for all VFs */ | 156 | /* enable spoof checking for all VFs */ |
164 | for (i = 0; i < adapter->num_vfs; i++) | 157 | for (i = 0; i < adapter->num_vfs; i++) |
165 | adapter->vfinfo[i].spoofchk_enabled = true; | 158 | adapter->vfinfo[i].spoofchk_enabled = true; |
@@ -265,8 +258,11 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) | |||
265 | } | 258 | } |
266 | 259 | ||
267 | static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, | 260 | static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, |
268 | int entries, u16 *hash_list, u32 vf) | 261 | u32 *msgbuf, u32 vf) |
269 | { | 262 | { |
263 | int entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | ||
264 | >> IXGBE_VT_MSGINFO_SHIFT; | ||
265 | u16 *hash_list = (u16 *)&msgbuf[1]; | ||
270 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | 266 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; |
271 | struct ixgbe_hw *hw = &adapter->hw; | 267 | struct ixgbe_hw *hw = &adapter->hw; |
272 | int i; | 268 | int i; |
@@ -353,31 +349,89 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, | |||
353 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); | 349 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); |
354 | } | 350 | } |
355 | 351 | ||
356 | static void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf) | 352 | static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) |
357 | { | 353 | { |
358 | struct ixgbe_hw *hw = &adapter->hw; | 354 | struct ixgbe_hw *hw = &adapter->hw; |
359 | int new_mtu = msgbuf[1]; | 355 | int max_frame = msgbuf[1]; |
360 | u32 max_frs; | 356 | u32 max_frs; |
361 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | ||
362 | 357 | ||
363 | /* Only X540 supports jumbo frames in IOV mode */ | 358 | /* |
364 | if (adapter->hw.mac.type != ixgbe_mac_X540) | 359 | * For 82599EB we have to keep all PFs and VFs operating with |
365 | return; | 360 | * the same max_frame value in order to avoid sending an oversize |
361 | * frame to a VF. In order to guarantee this is handled correctly | ||
362 | * for all cases we have several special exceptions to take into | ||
363 | * account before we can enable the VF for receive | ||
364 | */ | ||
365 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
366 | struct net_device *dev = adapter->netdev; | ||
367 | int pf_max_frame = dev->mtu + ETH_HLEN; | ||
368 | u32 reg_offset, vf_shift, vfre; | ||
369 | s32 err = 0; | ||
370 | |||
371 | #ifdef CONFIG_FCOE | ||
372 | if (dev->features & NETIF_F_FCOE_MTU) | ||
373 | pf_max_frame = max_t(int, pf_max_frame, | ||
374 | IXGBE_FCOE_JUMBO_FRAME_SIZE); | ||
375 | |||
376 | #endif /* CONFIG_FCOE */ | ||
377 | switch (adapter->vfinfo[vf].vf_api) { | ||
378 | case ixgbe_mbox_api_11: | ||
379 | /* | ||
380 | * Version 1.1 supports jumbo frames on VFs if PF has | ||
381 | * jumbo frames enabled which means legacy VFs are | ||
382 | * disabled | ||
383 | */ | ||
384 | if (pf_max_frame > ETH_FRAME_LEN) | ||
385 | break; | ||
386 | default: | ||
387 | /* | ||
388 | * If the PF or VF are running w/ jumbo frames enabled | ||
389 | * we need to shut down the VF Rx path as we cannot | ||
390 | * support jumbo frames on legacy VFs | ||
391 | */ | ||
392 | if ((pf_max_frame > ETH_FRAME_LEN) || | ||
393 | (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN))) | ||
394 | err = -EINVAL; | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | /* determine VF receive enable location */ | ||
399 | vf_shift = vf % 32; | ||
400 | reg_offset = vf / 32; | ||
401 | |||
402 | /* enable or disable receive depending on error */ | ||
403 | vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); | ||
404 | if (err) | ||
405 | vfre &= ~(1 << vf_shift); | ||
406 | else | ||
407 | vfre |= 1 << vf_shift; | ||
408 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), vfre); | ||
409 | |||
410 | if (err) { | ||
411 | e_err(drv, "VF max_frame %d out of range\n", max_frame); | ||
412 | return err; | ||
413 | } | ||
414 | } | ||
366 | 415 | ||
367 | /* MTU < 68 is an error and causes problems on some kernels */ | 416 | /* MTU < 68 is an error and causes problems on some kernels */ |
368 | if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) { | 417 | if (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE) { |
369 | e_err(drv, "VF mtu %d out of range\n", new_mtu); | 418 | e_err(drv, "VF max_frame %d out of range\n", max_frame); |
370 | return; | 419 | return -EINVAL; |
371 | } | 420 | } |
372 | 421 | ||
373 | max_frs = (IXGBE_READ_REG(hw, IXGBE_MAXFRS) & | 422 | /* pull current max frame size from hardware */ |
374 | IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; | 423 | max_frs = IXGBE_READ_REG(hw, IXGBE_MAXFRS); |
375 | if (max_frs < new_mtu) { | 424 | max_frs &= IXGBE_MHADD_MFS_MASK; |
376 | max_frs = new_mtu << IXGBE_MHADD_MFS_SHIFT; | 425 | max_frs >>= IXGBE_MHADD_MFS_SHIFT; |
426 | |||
427 | if (max_frs < max_frame) { | ||
428 | max_frs = max_frame << IXGBE_MHADD_MFS_SHIFT; | ||
377 | IXGBE_WRITE_REG(hw, IXGBE_MAXFRS, max_frs); | 429 | IXGBE_WRITE_REG(hw, IXGBE_MAXFRS, max_frs); |
378 | } | 430 | } |
379 | 431 | ||
380 | e_info(hw, "VF requests change max MTU to %d\n", new_mtu); | 432 | e_info(hw, "VF requests change max MTU to %d\n", max_frame); |
433 | |||
434 | return 0; | ||
381 | } | 435 | } |
382 | 436 | ||
383 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | 437 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) |
@@ -392,35 +446,47 @@ static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | |||
392 | IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); | 446 | IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); |
393 | } | 447 | } |
394 | 448 | ||
395 | static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf) | 449 | static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, |
450 | u16 vid, u16 qos, u32 vf) | ||
396 | { | 451 | { |
397 | struct ixgbe_hw *hw = &adapter->hw; | 452 | struct ixgbe_hw *hw = &adapter->hw; |
453 | u32 vmvir = vid | (qos << VLAN_PRIO_SHIFT) | IXGBE_VMVIR_VLANA_DEFAULT; | ||
398 | 454 | ||
399 | if (vid) | 455 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), vmvir); |
400 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), | ||
401 | (vid | IXGBE_VMVIR_VLANA_DEFAULT)); | ||
402 | else | ||
403 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); | ||
404 | } | 456 | } |
405 | 457 | ||
458 | static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf) | ||
459 | { | ||
460 | struct ixgbe_hw *hw = &adapter->hw; | ||
461 | |||
462 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); | ||
463 | } | ||
406 | static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) | 464 | static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) |
407 | { | 465 | { |
408 | struct ixgbe_hw *hw = &adapter->hw; | 466 | struct ixgbe_hw *hw = &adapter->hw; |
467 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | ||
409 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); | 468 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); |
469 | u8 num_tcs = netdev_get_num_tc(adapter->netdev); | ||
470 | |||
471 | /* add PF assigned VLAN or VLAN 0 */ | ||
472 | ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf); | ||
410 | 473 | ||
411 | /* reset offloads to defaults */ | 474 | /* reset offloads to defaults */ |
412 | if (adapter->vfinfo[vf].pf_vlan) { | 475 | ixgbe_set_vmolr(hw, vf, !vfinfo->pf_vlan); |
413 | ixgbe_set_vf_vlan(adapter, true, | 476 | |
414 | adapter->vfinfo[vf].pf_vlan, vf); | 477 | /* set outgoing tags for VFs */ |
415 | ixgbe_set_vmvir(adapter, | 478 | if (!vfinfo->pf_vlan && !vfinfo->pf_qos && !num_tcs) { |
416 | (adapter->vfinfo[vf].pf_vlan | | 479 | ixgbe_clear_vmvir(adapter, vf); |
417 | (adapter->vfinfo[vf].pf_qos << | ||
418 | VLAN_PRIO_SHIFT)), vf); | ||
419 | ixgbe_set_vmolr(hw, vf, false); | ||
420 | } else { | 480 | } else { |
421 | ixgbe_set_vf_vlan(adapter, true, 0, vf); | 481 | if (vfinfo->pf_qos || !num_tcs) |
422 | ixgbe_set_vmvir(adapter, 0, vf); | 482 | ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, |
423 | ixgbe_set_vmolr(hw, vf, true); | 483 | vfinfo->pf_qos, vf); |
484 | else | ||
485 | ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, | ||
486 | adapter->default_up, vf); | ||
487 | |||
488 | if (vfinfo->spoofchk_enabled) | ||
489 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); | ||
424 | } | 490 | } |
425 | 491 | ||
426 | /* reset multicast table array for vf */ | 492 | /* reset multicast table array for vf */ |
@@ -430,6 +496,9 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) | |||
430 | ixgbe_set_rx_mode(adapter->netdev); | 496 | ixgbe_set_rx_mode(adapter->netdev); |
431 | 497 | ||
432 | hw->mac.ops.clear_rar(hw, rar_entry); | 498 | hw->mac.ops.clear_rar(hw, rar_entry); |
499 | |||
500 | /* reset VF api back to unknown */ | ||
501 | adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10; | ||
433 | } | 502 | } |
434 | 503 | ||
435 | static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, | 504 | static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, |
@@ -521,30 +590,221 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) | |||
521 | return 0; | 590 | return 0; |
522 | } | 591 | } |
523 | 592 | ||
524 | static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) | 593 | static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) |
525 | { | 594 | { |
526 | struct ixgbe_hw *hw = &adapter->hw; | 595 | struct ixgbe_hw *hw = &adapter->hw; |
527 | u32 reg; | 596 | unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; |
597 | u32 reg, msgbuf[4]; | ||
528 | u32 reg_offset, vf_shift; | 598 | u32 reg_offset, vf_shift; |
599 | u8 *addr = (u8 *)(&msgbuf[1]); | ||
600 | |||
601 | e_info(probe, "VF Reset msg received from vf %d\n", vf); | ||
602 | |||
603 | /* reset the filters for the device */ | ||
604 | ixgbe_vf_reset_event(adapter, vf); | ||
605 | |||
606 | /* set vf mac address */ | ||
607 | ixgbe_set_vf_mac(adapter, vf, vf_mac); | ||
529 | 608 | ||
530 | vf_shift = vf % 32; | 609 | vf_shift = vf % 32; |
531 | reg_offset = vf / 32; | 610 | reg_offset = vf / 32; |
532 | 611 | ||
533 | /* enable transmit and receive for vf */ | 612 | /* enable transmit for vf */ |
534 | reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); | 613 | reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); |
535 | reg |= (reg | (1 << vf_shift)); | 614 | reg |= 1 << vf_shift; |
536 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); | 615 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); |
537 | 616 | ||
617 | /* enable receive for vf */ | ||
538 | reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); | 618 | reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); |
539 | reg |= (reg | (1 << vf_shift)); | 619 | reg |= 1 << vf_shift; |
620 | /* | ||
621 | * The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs. | ||
622 | * For more info take a look at ixgbe_set_vf_lpe | ||
623 | */ | ||
624 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
625 | struct net_device *dev = adapter->netdev; | ||
626 | int pf_max_frame = dev->mtu + ETH_HLEN; | ||
627 | |||
628 | #ifdef CONFIG_FCOE | ||
629 | if (dev->features & NETIF_F_FCOE_MTU) | ||
630 | pf_max_frame = max_t(int, pf_max_frame, | ||
631 | IXGBE_FCOE_JUMBO_FRAME_SIZE); | ||
632 | |||
633 | #endif /* CONFIG_FCOE */ | ||
634 | if (pf_max_frame > ETH_FRAME_LEN) | ||
635 | reg &= ~(1 << vf_shift); | ||
636 | } | ||
540 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); | 637 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); |
541 | 638 | ||
639 | /* enable VF mailbox for further messages */ | ||
640 | adapter->vfinfo[vf].clear_to_send = true; | ||
641 | |||
542 | /* Enable counting of spoofed packets in the SSVPC register */ | 642 | /* Enable counting of spoofed packets in the SSVPC register */ |
543 | reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset)); | 643 | reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset)); |
544 | reg |= (1 << vf_shift); | 644 | reg |= (1 << vf_shift); |
545 | IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg); | 645 | IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg); |
546 | 646 | ||
547 | ixgbe_vf_reset_event(adapter, vf); | 647 | /* reply to reset with ack and vf mac address */ |
648 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; | ||
649 | memcpy(addr, vf_mac, ETH_ALEN); | ||
650 | |||
651 | /* | ||
652 | * Piggyback the multicast filter type so VF can compute the | ||
653 | * correct vectors | ||
654 | */ | ||
655 | msgbuf[3] = hw->mac.mc_filter_type; | ||
656 | ixgbe_write_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN, vf); | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, | ||
662 | u32 *msgbuf, u32 vf) | ||
663 | { | ||
664 | u8 *new_mac = ((u8 *)(&msgbuf[1])); | ||
665 | |||
666 | if (!is_valid_ether_addr(new_mac)) { | ||
667 | e_warn(drv, "VF %d attempted to set invalid mac\n", vf); | ||
668 | return -1; | ||
669 | } | ||
670 | |||
671 | if (adapter->vfinfo[vf].pf_set_mac && | ||
672 | memcmp(adapter->vfinfo[vf].vf_mac_addresses, new_mac, | ||
673 | ETH_ALEN)) { | ||
674 | e_warn(drv, | ||
675 | "VF %d attempted to override administratively set MAC address\n" | ||
676 | "Reload the VF driver to resume operations\n", | ||
677 | vf); | ||
678 | return -1; | ||
679 | } | ||
680 | |||
681 | return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0; | ||
682 | } | ||
683 | |||
684 | static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, | ||
685 | u32 *msgbuf, u32 vf) | ||
686 | { | ||
687 | struct ixgbe_hw *hw = &adapter->hw; | ||
688 | int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; | ||
689 | int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); | ||
690 | int err; | ||
691 | u8 tcs = netdev_get_num_tc(adapter->netdev); | ||
692 | |||
693 | if (adapter->vfinfo[vf].pf_vlan || tcs) { | ||
694 | e_warn(drv, | ||
695 | "VF %d attempted to override administratively set VLAN configuration\n" | ||
696 | "Reload the VF driver to resume operations\n", | ||
697 | vf); | ||
698 | return -1; | ||
699 | } | ||
700 | |||
701 | if (add) | ||
702 | adapter->vfinfo[vf].vlan_count++; | ||
703 | else if (adapter->vfinfo[vf].vlan_count) | ||
704 | adapter->vfinfo[vf].vlan_count--; | ||
705 | |||
706 | err = ixgbe_set_vf_vlan(adapter, add, vid, vf); | ||
707 | if (!err && adapter->vfinfo[vf].spoofchk_enabled) | ||
708 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); | ||
709 | |||
710 | return err; | ||
711 | } | ||
712 | |||
713 | static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter, | ||
714 | u32 *msgbuf, u32 vf) | ||
715 | { | ||
716 | u8 *new_mac = ((u8 *)(&msgbuf[1])); | ||
717 | int index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> | ||
718 | IXGBE_VT_MSGINFO_SHIFT; | ||
719 | int err; | ||
720 | |||
721 | if (adapter->vfinfo[vf].pf_set_mac && index > 0) { | ||
722 | e_warn(drv, | ||
723 | "VF %d requested MACVLAN filter but is administratively denied\n", | ||
724 | vf); | ||
725 | return -1; | ||
726 | } | ||
727 | |||
728 | /* An non-zero index indicates the VF is setting a filter */ | ||
729 | if (index) { | ||
730 | if (!is_valid_ether_addr(new_mac)) { | ||
731 | e_warn(drv, "VF %d attempted to set invalid mac\n", vf); | ||
732 | return -1; | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * If the VF is allowed to set MAC filters then turn off | ||
737 | * anti-spoofing to avoid false positives. | ||
738 | */ | ||
739 | if (adapter->vfinfo[vf].spoofchk_enabled) | ||
740 | ixgbe_ndo_set_vf_spoofchk(adapter->netdev, vf, false); | ||
741 | } | ||
742 | |||
743 | err = ixgbe_set_vf_macvlan(adapter, vf, index, new_mac); | ||
744 | if (err == -ENOSPC) | ||
745 | e_warn(drv, | ||
746 | "VF %d has requested a MACVLAN filter but there is no space for it\n", | ||
747 | vf); | ||
748 | |||
749 | return err < 0; | ||
750 | } | ||
751 | |||
752 | static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter, | ||
753 | u32 *msgbuf, u32 vf) | ||
754 | { | ||
755 | int api = msgbuf[1]; | ||
756 | |||
757 | switch (api) { | ||
758 | case ixgbe_mbox_api_10: | ||
759 | case ixgbe_mbox_api_11: | ||
760 | adapter->vfinfo[vf].vf_api = api; | ||
761 | return 0; | ||
762 | default: | ||
763 | break; | ||
764 | } | ||
765 | |||
766 | e_info(drv, "VF %d requested invalid api version %u\n", vf, api); | ||
767 | |||
768 | return -1; | ||
769 | } | ||
770 | |||
771 | static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter, | ||
772 | u32 *msgbuf, u32 vf) | ||
773 | { | ||
774 | struct net_device *dev = adapter->netdev; | ||
775 | struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; | ||
776 | unsigned int default_tc = 0; | ||
777 | u8 num_tcs = netdev_get_num_tc(dev); | ||
778 | |||
779 | /* verify the PF is supporting the correct APIs */ | ||
780 | switch (adapter->vfinfo[vf].vf_api) { | ||
781 | case ixgbe_mbox_api_20: | ||
782 | case ixgbe_mbox_api_11: | ||
783 | break; | ||
784 | default: | ||
785 | return -1; | ||
786 | } | ||
787 | |||
788 | /* only allow 1 Tx queue for bandwidth limiting */ | ||
789 | msgbuf[IXGBE_VF_TX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask); | ||
790 | msgbuf[IXGBE_VF_RX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask); | ||
791 | |||
792 | /* if TCs > 1 determine which TC belongs to default user priority */ | ||
793 | if (num_tcs > 1) | ||
794 | default_tc = netdev_get_prio_tc_map(dev, adapter->default_up); | ||
795 | |||
796 | /* notify VF of need for VLAN tag stripping, and correct queue */ | ||
797 | if (num_tcs) | ||
798 | msgbuf[IXGBE_VF_TRANS_VLAN] = num_tcs; | ||
799 | else if (adapter->vfinfo[vf].pf_vlan || adapter->vfinfo[vf].pf_qos) | ||
800 | msgbuf[IXGBE_VF_TRANS_VLAN] = 1; | ||
801 | else | ||
802 | msgbuf[IXGBE_VF_TRANS_VLAN] = 0; | ||
803 | |||
804 | /* notify VF of default queue */ | ||
805 | msgbuf[IXGBE_VF_DEF_QUEUE] = default_tc; | ||
806 | |||
807 | return 0; | ||
548 | } | 808 | } |
549 | 809 | ||
550 | static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | 810 | static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) |
@@ -553,10 +813,6 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
553 | u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; | 813 | u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; |
554 | struct ixgbe_hw *hw = &adapter->hw; | 814 | struct ixgbe_hw *hw = &adapter->hw; |
555 | s32 retval; | 815 | s32 retval; |
556 | int entries; | ||
557 | u16 *hash_list; | ||
558 | int add, vid, index; | ||
559 | u8 *new_mac; | ||
560 | 816 | ||
561 | retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); | 817 | retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); |
562 | 818 | ||
@@ -572,39 +828,13 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
572 | /* flush the ack before we write any messages back */ | 828 | /* flush the ack before we write any messages back */ |
573 | IXGBE_WRITE_FLUSH(hw); | 829 | IXGBE_WRITE_FLUSH(hw); |
574 | 830 | ||
831 | if (msgbuf[0] == IXGBE_VF_RESET) | ||
832 | return ixgbe_vf_reset_msg(adapter, vf); | ||
833 | |||
575 | /* | 834 | /* |
576 | * until the vf completes a virtual function reset it should not be | 835 | * until the vf completes a virtual function reset it should not be |
577 | * allowed to start any configuration. | 836 | * allowed to start any configuration. |
578 | */ | 837 | */ |
579 | |||
580 | if (msgbuf[0] == IXGBE_VF_RESET) { | ||
581 | unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; | ||
582 | new_mac = (u8 *)(&msgbuf[1]); | ||
583 | e_info(probe, "VF Reset msg received from vf %d\n", vf); | ||
584 | adapter->vfinfo[vf].clear_to_send = false; | ||
585 | ixgbe_vf_reset_msg(adapter, vf); | ||
586 | adapter->vfinfo[vf].clear_to_send = true; | ||
587 | |||
588 | if (is_valid_ether_addr(new_mac) && | ||
589 | !adapter->vfinfo[vf].pf_set_mac) | ||
590 | ixgbe_set_vf_mac(adapter, vf, vf_mac); | ||
591 | else | ||
592 | ixgbe_set_vf_mac(adapter, | ||
593 | vf, adapter->vfinfo[vf].vf_mac_addresses); | ||
594 | |||
595 | /* reply to reset with ack and vf mac address */ | ||
596 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; | ||
597 | memcpy(new_mac, vf_mac, ETH_ALEN); | ||
598 | /* | ||
599 | * Piggyback the multicast filter type so VF can compute the | ||
600 | * correct vectors | ||
601 | */ | ||
602 | msgbuf[3] = hw->mac.mc_filter_type; | ||
603 | ixgbe_write_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN, vf); | ||
604 | |||
605 | return retval; | ||
606 | } | ||
607 | |||
608 | if (!adapter->vfinfo[vf].clear_to_send) { | 838 | if (!adapter->vfinfo[vf].clear_to_send) { |
609 | msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK; | 839 | msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK; |
610 | ixgbe_write_mbx(hw, msgbuf, 1, vf); | 840 | ixgbe_write_mbx(hw, msgbuf, 1, vf); |
@@ -613,70 +843,25 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
613 | 843 | ||
614 | switch ((msgbuf[0] & 0xFFFF)) { | 844 | switch ((msgbuf[0] & 0xFFFF)) { |
615 | case IXGBE_VF_SET_MAC_ADDR: | 845 | case IXGBE_VF_SET_MAC_ADDR: |
616 | new_mac = ((u8 *)(&msgbuf[1])); | 846 | retval = ixgbe_set_vf_mac_addr(adapter, msgbuf, vf); |
617 | if (is_valid_ether_addr(new_mac) && | ||
618 | !adapter->vfinfo[vf].pf_set_mac) { | ||
619 | ixgbe_set_vf_mac(adapter, vf, new_mac); | ||
620 | } else if (memcmp(adapter->vfinfo[vf].vf_mac_addresses, | ||
621 | new_mac, ETH_ALEN)) { | ||
622 | e_warn(drv, "VF %d attempted to override " | ||
623 | "administratively set MAC address\nReload " | ||
624 | "the VF driver to resume operations\n", vf); | ||
625 | retval = -1; | ||
626 | } | ||
627 | break; | 847 | break; |
628 | case IXGBE_VF_SET_MULTICAST: | 848 | case IXGBE_VF_SET_MULTICAST: |
629 | entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | 849 | retval = ixgbe_set_vf_multicasts(adapter, msgbuf, vf); |
630 | >> IXGBE_VT_MSGINFO_SHIFT; | ||
631 | hash_list = (u16 *)&msgbuf[1]; | ||
632 | retval = ixgbe_set_vf_multicasts(adapter, entries, | ||
633 | hash_list, vf); | ||
634 | break; | ||
635 | case IXGBE_VF_SET_LPE: | ||
636 | ixgbe_set_vf_lpe(adapter, msgbuf); | ||
637 | break; | 850 | break; |
638 | case IXGBE_VF_SET_VLAN: | 851 | case IXGBE_VF_SET_VLAN: |
639 | add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | 852 | retval = ixgbe_set_vf_vlan_msg(adapter, msgbuf, vf); |
640 | >> IXGBE_VT_MSGINFO_SHIFT; | 853 | break; |
641 | vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); | 854 | case IXGBE_VF_SET_LPE: |
642 | if (adapter->vfinfo[vf].pf_vlan) { | 855 | retval = ixgbe_set_vf_lpe(adapter, msgbuf, vf); |
643 | e_warn(drv, "VF %d attempted to override " | ||
644 | "administratively set VLAN configuration\n" | ||
645 | "Reload the VF driver to resume operations\n", | ||
646 | vf); | ||
647 | retval = -1; | ||
648 | } else { | ||
649 | if (add) | ||
650 | adapter->vfinfo[vf].vlan_count++; | ||
651 | else if (adapter->vfinfo[vf].vlan_count) | ||
652 | adapter->vfinfo[vf].vlan_count--; | ||
653 | retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); | ||
654 | if (!retval && adapter->vfinfo[vf].spoofchk_enabled) | ||
655 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); | ||
656 | } | ||
657 | break; | 856 | break; |
658 | case IXGBE_VF_SET_MACVLAN: | 857 | case IXGBE_VF_SET_MACVLAN: |
659 | index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> | 858 | retval = ixgbe_set_vf_macvlan_msg(adapter, msgbuf, vf); |
660 | IXGBE_VT_MSGINFO_SHIFT; | 859 | break; |
661 | if (adapter->vfinfo[vf].pf_set_mac && index > 0) { | 860 | case IXGBE_VF_API_NEGOTIATE: |
662 | e_warn(drv, "VF %d requested MACVLAN filter but is " | 861 | retval = ixgbe_negotiate_vf_api(adapter, msgbuf, vf); |
663 | "administratively denied\n", vf); | 862 | break; |
664 | retval = -1; | 863 | case IXGBE_VF_GET_QUEUES: |
665 | break; | 864 | retval = ixgbe_get_vf_queues(adapter, msgbuf, vf); |
666 | } | ||
667 | /* | ||
668 | * If the VF is allowed to set MAC filters then turn off | ||
669 | * anti-spoofing to avoid false positives. An index | ||
670 | * greater than 0 will indicate the VF is setting a | ||
671 | * macvlan MAC filter. | ||
672 | */ | ||
673 | if (index > 0 && adapter->vfinfo[vf].spoofchk_enabled) | ||
674 | ixgbe_ndo_set_vf_spoofchk(adapter->netdev, vf, false); | ||
675 | retval = ixgbe_set_vf_macvlan(adapter, vf, index, | ||
676 | (unsigned char *)(&msgbuf[1])); | ||
677 | if (retval == -ENOSPC) | ||
678 | e_warn(drv, "VF %d has requested a MACVLAN filter " | ||
679 | "but there is no space for it\n", vf); | ||
680 | break; | 865 | break; |
681 | default: | 866 | default: |
682 | e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); | 867 | e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); |
@@ -692,7 +877,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
692 | 877 | ||
693 | msgbuf[0] |= IXGBE_VT_MSGTYPE_CTS; | 878 | msgbuf[0] |= IXGBE_VT_MSGTYPE_CTS; |
694 | 879 | ||
695 | ixgbe_write_mbx(hw, msgbuf, 1, vf); | 880 | ixgbe_write_mbx(hw, msgbuf, mbx_size, vf); |
696 | 881 | ||
697 | return retval; | 882 | return retval; |
698 | } | 883 | } |
@@ -783,7 +968,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) | |||
783 | err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); | 968 | err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); |
784 | if (err) | 969 | if (err) |
785 | goto out; | 970 | goto out; |
786 | ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); | 971 | ixgbe_set_vmvir(adapter, vlan, qos, vf); |
787 | ixgbe_set_vmolr(hw, vf, false); | 972 | ixgbe_set_vmolr(hw, vf, false); |
788 | if (adapter->vfinfo[vf].spoofchk_enabled) | 973 | if (adapter->vfinfo[vf].spoofchk_enabled) |
789 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); | 974 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); |
@@ -803,7 +988,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) | |||
803 | } else { | 988 | } else { |
804 | err = ixgbe_set_vf_vlan(adapter, false, | 989 | err = ixgbe_set_vf_vlan(adapter, false, |
805 | adapter->vfinfo[vf].pf_vlan, vf); | 990 | adapter->vfinfo[vf].pf_vlan, vf); |
806 | ixgbe_set_vmvir(adapter, vlan, vf); | 991 | ixgbe_clear_vmvir(adapter, vf); |
807 | ixgbe_set_vmolr(hw, vf, true); | 992 | ixgbe_set_vmolr(hw, vf, true); |
808 | hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); | 993 | hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); |
809 | if (adapter->vfinfo[vf].vlan_count) | 994 | if (adapter->vfinfo[vf].vlan_count) |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 0722f3368092..21915e20399a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | |||
@@ -56,6 +56,7 @@ | |||
56 | #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 | 56 | #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 |
57 | #define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 | 57 | #define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72 |
58 | #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 | 58 | #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 |
59 | #define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470 | ||
59 | #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 | 60 | #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 |
60 | #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D | 61 | #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D |
61 | #define IXGBE_DEV_ID_82599EN_SFP 0x1557 | 62 | #define IXGBE_DEV_ID_82599EN_SFP 0x1557 |
diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h index da17ccf5c09d..3147795bd135 100644 --- a/drivers/net/ethernet/intel/ixgbevf/defines.h +++ b/drivers/net/ethernet/intel/ixgbevf/defines.h | |||
@@ -33,8 +33,11 @@ | |||
33 | #define IXGBE_DEV_ID_X540_VF 0x1515 | 33 | #define IXGBE_DEV_ID_X540_VF 0x1515 |
34 | 34 | ||
35 | #define IXGBE_VF_IRQ_CLEAR_MASK 7 | 35 | #define IXGBE_VF_IRQ_CLEAR_MASK 7 |
36 | #define IXGBE_VF_MAX_TX_QUEUES 1 | 36 | #define IXGBE_VF_MAX_TX_QUEUES 8 |
37 | #define IXGBE_VF_MAX_RX_QUEUES 1 | 37 | #define IXGBE_VF_MAX_RX_QUEUES 8 |
38 | |||
39 | /* DCB define */ | ||
40 | #define IXGBE_VF_MAX_TRAFFIC_CLASS 8 | ||
38 | 41 | ||
39 | /* Link speed */ | 42 | /* Link speed */ |
40 | typedef u32 ixgbe_link_speed; | 43 | typedef u32 ixgbe_link_speed; |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 4a9c9c285685..2323ccd211c0 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -89,8 +89,8 @@ struct ixgbevf_ring { | |||
89 | /* How many Rx Buffers do we bundle into one write to the hardware ? */ | 89 | /* How many Rx Buffers do we bundle into one write to the hardware ? */ |
90 | #define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ | 90 | #define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ |
91 | 91 | ||
92 | #define MAX_RX_QUEUES 1 | 92 | #define MAX_RX_QUEUES IXGBE_VF_MAX_RX_QUEUES |
93 | #define MAX_TX_QUEUES 1 | 93 | #define MAX_TX_QUEUES IXGBE_VF_MAX_TX_QUEUES |
94 | 94 | ||
95 | #define IXGBEVF_DEFAULT_TXD 1024 | 95 | #define IXGBEVF_DEFAULT_TXD 1024 |
96 | #define IXGBEVF_DEFAULT_RXD 512 | 96 | #define IXGBEVF_DEFAULT_RXD 512 |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index de1ad506665d..f3d3947ae962 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -58,7 +58,7 @@ const char ixgbevf_driver_name[] = "ixgbevf"; | |||
58 | static const char ixgbevf_driver_string[] = | 58 | static const char ixgbevf_driver_string[] = |
59 | "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; | 59 | "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; |
60 | 60 | ||
61 | #define DRV_VERSION "2.6.0-k" | 61 | #define DRV_VERSION "2.7.12-k" |
62 | const char ixgbevf_driver_version[] = DRV_VERSION; | 62 | const char ixgbevf_driver_version[] = DRV_VERSION; |
63 | static char ixgbevf_copyright[] = | 63 | static char ixgbevf_copyright[] = |
64 | "Copyright (c) 2009 - 2012 Intel Corporation."; | 64 | "Copyright (c) 2009 - 2012 Intel Corporation."; |
@@ -99,6 +99,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | |||
99 | 99 | ||
100 | /* forward decls */ | 100 | /* forward decls */ |
101 | static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); | 101 | static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); |
102 | static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter); | ||
102 | 103 | ||
103 | static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, | 104 | static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, |
104 | struct ixgbevf_ring *rx_ring, | 105 | struct ixgbevf_ring *rx_ring, |
@@ -358,6 +359,12 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, | |||
358 | bi->dma = dma_map_single(&pdev->dev, skb->data, | 359 | bi->dma = dma_map_single(&pdev->dev, skb->data, |
359 | rx_ring->rx_buf_len, | 360 | rx_ring->rx_buf_len, |
360 | DMA_FROM_DEVICE); | 361 | DMA_FROM_DEVICE); |
362 | if (dma_mapping_error(&pdev->dev, bi->dma)) { | ||
363 | dev_kfree_skb(skb); | ||
364 | bi->skb = NULL; | ||
365 | dev_err(&pdev->dev, "RX DMA map failed\n"); | ||
366 | break; | ||
367 | } | ||
361 | } | 368 | } |
362 | rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); | 369 | rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); |
363 | 370 | ||
@@ -471,6 +478,16 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, | |||
471 | } | 478 | } |
472 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); | 479 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); |
473 | 480 | ||
481 | /* Workaround hardware that can't do proper VEPA multicast | ||
482 | * source pruning. | ||
483 | */ | ||
484 | if ((skb->pkt_type & (PACKET_BROADCAST | PACKET_MULTICAST)) && | ||
485 | !(compare_ether_addr(adapter->netdev->dev_addr, | ||
486 | eth_hdr(skb)->h_source))) { | ||
487 | dev_kfree_skb_irq(skb); | ||
488 | goto next_desc; | ||
489 | } | ||
490 | |||
474 | ixgbevf_receive_skb(q_vector, skb, staterr, rx_desc); | 491 | ixgbevf_receive_skb(q_vector, skb, staterr, rx_desc); |
475 | 492 | ||
476 | next_desc: | 493 | next_desc: |
@@ -1131,12 +1148,12 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
1131 | if (!hw->mac.ops.set_vfta) | 1148 | if (!hw->mac.ops.set_vfta) |
1132 | return -EOPNOTSUPP; | 1149 | return -EOPNOTSUPP; |
1133 | 1150 | ||
1134 | spin_lock(&adapter->mbx_lock); | 1151 | spin_lock_bh(&adapter->mbx_lock); |
1135 | 1152 | ||
1136 | /* add VID to filter table */ | 1153 | /* add VID to filter table */ |
1137 | err = hw->mac.ops.set_vfta(hw, vid, 0, true); | 1154 | err = hw->mac.ops.set_vfta(hw, vid, 0, true); |
1138 | 1155 | ||
1139 | spin_unlock(&adapter->mbx_lock); | 1156 | spin_unlock_bh(&adapter->mbx_lock); |
1140 | 1157 | ||
1141 | /* translate error return types so error makes sense */ | 1158 | /* translate error return types so error makes sense */ |
1142 | if (err == IXGBE_ERR_MBX) | 1159 | if (err == IXGBE_ERR_MBX) |
@@ -1156,13 +1173,13 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
1156 | struct ixgbe_hw *hw = &adapter->hw; | 1173 | struct ixgbe_hw *hw = &adapter->hw; |
1157 | int err = -EOPNOTSUPP; | 1174 | int err = -EOPNOTSUPP; |
1158 | 1175 | ||
1159 | spin_lock(&adapter->mbx_lock); | 1176 | spin_lock_bh(&adapter->mbx_lock); |
1160 | 1177 | ||
1161 | /* remove VID from filter table */ | 1178 | /* remove VID from filter table */ |
1162 | if (hw->mac.ops.set_vfta) | 1179 | if (hw->mac.ops.set_vfta) |
1163 | err = hw->mac.ops.set_vfta(hw, vid, 0, false); | 1180 | err = hw->mac.ops.set_vfta(hw, vid, 0, false); |
1164 | 1181 | ||
1165 | spin_unlock(&adapter->mbx_lock); | 1182 | spin_unlock_bh(&adapter->mbx_lock); |
1166 | 1183 | ||
1167 | clear_bit(vid, adapter->active_vlans); | 1184 | clear_bit(vid, adapter->active_vlans); |
1168 | 1185 | ||
@@ -1218,7 +1235,7 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) | |||
1218 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1235 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1219 | struct ixgbe_hw *hw = &adapter->hw; | 1236 | struct ixgbe_hw *hw = &adapter->hw; |
1220 | 1237 | ||
1221 | spin_lock(&adapter->mbx_lock); | 1238 | spin_lock_bh(&adapter->mbx_lock); |
1222 | 1239 | ||
1223 | /* reprogram multicast list */ | 1240 | /* reprogram multicast list */ |
1224 | if (hw->mac.ops.update_mc_addr_list) | 1241 | if (hw->mac.ops.update_mc_addr_list) |
@@ -1226,7 +1243,7 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) | |||
1226 | 1243 | ||
1227 | ixgbevf_write_uc_addr_list(netdev); | 1244 | ixgbevf_write_uc_addr_list(netdev); |
1228 | 1245 | ||
1229 | spin_unlock(&adapter->mbx_lock); | 1246 | spin_unlock_bh(&adapter->mbx_lock); |
1230 | } | 1247 | } |
1231 | 1248 | ||
1232 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) | 1249 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) |
@@ -1335,11 +1352,12 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) | |||
1335 | static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) | 1352 | static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) |
1336 | { | 1353 | { |
1337 | struct ixgbe_hw *hw = &adapter->hw; | 1354 | struct ixgbe_hw *hw = &adapter->hw; |
1338 | int api[] = { ixgbe_mbox_api_10, | 1355 | int api[] = { ixgbe_mbox_api_11, |
1356 | ixgbe_mbox_api_10, | ||
1339 | ixgbe_mbox_api_unknown }; | 1357 | ixgbe_mbox_api_unknown }; |
1340 | int err = 0, idx = 0; | 1358 | int err = 0, idx = 0; |
1341 | 1359 | ||
1342 | spin_lock(&adapter->mbx_lock); | 1360 | spin_lock_bh(&adapter->mbx_lock); |
1343 | 1361 | ||
1344 | while (api[idx] != ixgbe_mbox_api_unknown) { | 1362 | while (api[idx] != ixgbe_mbox_api_unknown) { |
1345 | err = ixgbevf_negotiate_api_version(hw, api[idx]); | 1363 | err = ixgbevf_negotiate_api_version(hw, api[idx]); |
@@ -1348,7 +1366,7 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter) | |||
1348 | idx++; | 1366 | idx++; |
1349 | } | 1367 | } |
1350 | 1368 | ||
1351 | spin_unlock(&adapter->mbx_lock); | 1369 | spin_unlock_bh(&adapter->mbx_lock); |
1352 | } | 1370 | } |
1353 | 1371 | ||
1354 | static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | 1372 | static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) |
@@ -1389,7 +1407,7 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1389 | 1407 | ||
1390 | ixgbevf_configure_msix(adapter); | 1408 | ixgbevf_configure_msix(adapter); |
1391 | 1409 | ||
1392 | spin_lock(&adapter->mbx_lock); | 1410 | spin_lock_bh(&adapter->mbx_lock); |
1393 | 1411 | ||
1394 | if (hw->mac.ops.set_rar) { | 1412 | if (hw->mac.ops.set_rar) { |
1395 | if (is_valid_ether_addr(hw->mac.addr)) | 1413 | if (is_valid_ether_addr(hw->mac.addr)) |
@@ -1398,7 +1416,7 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1398 | hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0); | 1416 | hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0); |
1399 | } | 1417 | } |
1400 | 1418 | ||
1401 | spin_unlock(&adapter->mbx_lock); | 1419 | spin_unlock_bh(&adapter->mbx_lock); |
1402 | 1420 | ||
1403 | clear_bit(__IXGBEVF_DOWN, &adapter->state); | 1421 | clear_bit(__IXGBEVF_DOWN, &adapter->state); |
1404 | ixgbevf_napi_enable_all(adapter); | 1422 | ixgbevf_napi_enable_all(adapter); |
@@ -1413,12 +1431,87 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1413 | mod_timer(&adapter->watchdog_timer, jiffies); | 1431 | mod_timer(&adapter->watchdog_timer, jiffies); |
1414 | } | 1432 | } |
1415 | 1433 | ||
1434 | static int ixgbevf_reset_queues(struct ixgbevf_adapter *adapter) | ||
1435 | { | ||
1436 | struct ixgbe_hw *hw = &adapter->hw; | ||
1437 | struct ixgbevf_ring *rx_ring; | ||
1438 | unsigned int def_q = 0; | ||
1439 | unsigned int num_tcs = 0; | ||
1440 | unsigned int num_rx_queues = 1; | ||
1441 | int err, i; | ||
1442 | |||
1443 | spin_lock_bh(&adapter->mbx_lock); | ||
1444 | |||
1445 | /* fetch queue configuration from the PF */ | ||
1446 | err = ixgbevf_get_queues(hw, &num_tcs, &def_q); | ||
1447 | |||
1448 | spin_unlock_bh(&adapter->mbx_lock); | ||
1449 | |||
1450 | if (err) | ||
1451 | return err; | ||
1452 | |||
1453 | if (num_tcs > 1) { | ||
1454 | /* update default Tx ring register index */ | ||
1455 | adapter->tx_ring[0].reg_idx = def_q; | ||
1456 | |||
1457 | /* we need as many queues as traffic classes */ | ||
1458 | num_rx_queues = num_tcs; | ||
1459 | } | ||
1460 | |||
1461 | /* nothing to do if we have the correct number of queues */ | ||
1462 | if (adapter->num_rx_queues == num_rx_queues) | ||
1463 | return 0; | ||
1464 | |||
1465 | /* allocate new rings */ | ||
1466 | rx_ring = kcalloc(num_rx_queues, | ||
1467 | sizeof(struct ixgbevf_ring), GFP_KERNEL); | ||
1468 | if (!rx_ring) | ||
1469 | return -ENOMEM; | ||
1470 | |||
1471 | /* setup ring fields */ | ||
1472 | for (i = 0; i < num_rx_queues; i++) { | ||
1473 | rx_ring[i].count = adapter->rx_ring_count; | ||
1474 | rx_ring[i].queue_index = i; | ||
1475 | rx_ring[i].reg_idx = i; | ||
1476 | rx_ring[i].dev = &adapter->pdev->dev; | ||
1477 | rx_ring[i].netdev = adapter->netdev; | ||
1478 | |||
1479 | /* allocate resources on the ring */ | ||
1480 | err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); | ||
1481 | if (err) { | ||
1482 | while (i) { | ||
1483 | i--; | ||
1484 | ixgbevf_free_rx_resources(adapter, &rx_ring[i]); | ||
1485 | } | ||
1486 | kfree(rx_ring); | ||
1487 | return err; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | /* free the existing rings and queues */ | ||
1492 | ixgbevf_free_all_rx_resources(adapter); | ||
1493 | adapter->num_rx_queues = 0; | ||
1494 | kfree(adapter->rx_ring); | ||
1495 | |||
1496 | /* move new rings into position on the adapter struct */ | ||
1497 | adapter->rx_ring = rx_ring; | ||
1498 | adapter->num_rx_queues = num_rx_queues; | ||
1499 | |||
1500 | /* reset ring to vector mapping */ | ||
1501 | ixgbevf_reset_q_vectors(adapter); | ||
1502 | ixgbevf_map_rings_to_vectors(adapter); | ||
1503 | |||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1416 | void ixgbevf_up(struct ixgbevf_adapter *adapter) | 1507 | void ixgbevf_up(struct ixgbevf_adapter *adapter) |
1417 | { | 1508 | { |
1418 | struct ixgbe_hw *hw = &adapter->hw; | 1509 | struct ixgbe_hw *hw = &adapter->hw; |
1419 | 1510 | ||
1420 | ixgbevf_negotiate_api(adapter); | 1511 | ixgbevf_negotiate_api(adapter); |
1421 | 1512 | ||
1513 | ixgbevf_reset_queues(adapter); | ||
1514 | |||
1422 | ixgbevf_configure(adapter); | 1515 | ixgbevf_configure(adapter); |
1423 | 1516 | ||
1424 | ixgbevf_up_complete(adapter); | 1517 | ixgbevf_up_complete(adapter); |
@@ -1611,14 +1704,14 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) | |||
1611 | struct ixgbe_hw *hw = &adapter->hw; | 1704 | struct ixgbe_hw *hw = &adapter->hw; |
1612 | struct net_device *netdev = adapter->netdev; | 1705 | struct net_device *netdev = adapter->netdev; |
1613 | 1706 | ||
1614 | spin_lock(&adapter->mbx_lock); | 1707 | spin_lock_bh(&adapter->mbx_lock); |
1615 | 1708 | ||
1616 | if (hw->mac.ops.reset_hw(hw)) | 1709 | if (hw->mac.ops.reset_hw(hw)) |
1617 | hw_dbg(hw, "PF still resetting\n"); | 1710 | hw_dbg(hw, "PF still resetting\n"); |
1618 | else | 1711 | else |
1619 | hw->mac.ops.init_hw(hw); | 1712 | hw->mac.ops.init_hw(hw); |
1620 | 1713 | ||
1621 | spin_unlock(&adapter->mbx_lock); | 1714 | spin_unlock_bh(&adapter->mbx_lock); |
1622 | 1715 | ||
1623 | if (is_valid_ether_addr(adapter->hw.mac.addr)) { | 1716 | if (is_valid_ether_addr(adapter->hw.mac.addr)) { |
1624 | memcpy(netdev->dev_addr, adapter->hw.mac.addr, | 1717 | memcpy(netdev->dev_addr, adapter->hw.mac.addr, |
@@ -1717,6 +1810,7 @@ static int ixgbevf_alloc_queues(struct ixgbevf_adapter *adapter) | |||
1717 | for (i = 0; i < adapter->num_tx_queues; i++) { | 1810 | for (i = 0; i < adapter->num_tx_queues; i++) { |
1718 | adapter->tx_ring[i].count = adapter->tx_ring_count; | 1811 | adapter->tx_ring[i].count = adapter->tx_ring_count; |
1719 | adapter->tx_ring[i].queue_index = i; | 1812 | adapter->tx_ring[i].queue_index = i; |
1813 | /* reg_idx may be remapped later by DCB config */ | ||
1720 | adapter->tx_ring[i].reg_idx = i; | 1814 | adapter->tx_ring[i].reg_idx = i; |
1721 | adapter->tx_ring[i].dev = &adapter->pdev->dev; | 1815 | adapter->tx_ring[i].dev = &adapter->pdev->dev; |
1722 | adapter->tx_ring[i].netdev = adapter->netdev; | 1816 | adapter->tx_ring[i].netdev = adapter->netdev; |
@@ -1834,18 +1928,13 @@ err_out: | |||
1834 | **/ | 1928 | **/ |
1835 | static void ixgbevf_free_q_vectors(struct ixgbevf_adapter *adapter) | 1929 | static void ixgbevf_free_q_vectors(struct ixgbevf_adapter *adapter) |
1836 | { | 1930 | { |
1837 | int q_idx, num_q_vectors; | 1931 | int q_idx, num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; |
1838 | int napi_vectors; | ||
1839 | |||
1840 | num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; | ||
1841 | napi_vectors = adapter->num_rx_queues; | ||
1842 | 1932 | ||
1843 | for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { | 1933 | for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { |
1844 | struct ixgbevf_q_vector *q_vector = adapter->q_vector[q_idx]; | 1934 | struct ixgbevf_q_vector *q_vector = adapter->q_vector[q_idx]; |
1845 | 1935 | ||
1846 | adapter->q_vector[q_idx] = NULL; | 1936 | adapter->q_vector[q_idx] = NULL; |
1847 | if (q_idx < napi_vectors) | 1937 | netif_napi_del(&q_vector->napi); |
1848 | netif_napi_del(&q_vector->napi); | ||
1849 | kfree(q_vector); | 1938 | kfree(q_vector); |
1850 | } | 1939 | } |
1851 | } | 1940 | } |
@@ -1950,8 +2039,11 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) | |||
1950 | hw->subsystem_device_id = pdev->subsystem_device; | 2039 | hw->subsystem_device_id = pdev->subsystem_device; |
1951 | 2040 | ||
1952 | hw->mbx.ops.init_params(hw); | 2041 | hw->mbx.ops.init_params(hw); |
1953 | hw->mac.max_tx_queues = MAX_TX_QUEUES; | 2042 | |
1954 | hw->mac.max_rx_queues = MAX_RX_QUEUES; | 2043 | /* assume legacy case in which PF would only give VF 2 queues */ |
2044 | hw->mac.max_tx_queues = 2; | ||
2045 | hw->mac.max_rx_queues = 2; | ||
2046 | |||
1955 | err = hw->mac.ops.reset_hw(hw); | 2047 | err = hw->mac.ops.reset_hw(hw); |
1956 | if (err) { | 2048 | if (err) { |
1957 | dev_info(&pdev->dev, | 2049 | dev_info(&pdev->dev, |
@@ -2113,12 +2205,12 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2113 | if (hw->mac.ops.check_link) { | 2205 | if (hw->mac.ops.check_link) { |
2114 | s32 need_reset; | 2206 | s32 need_reset; |
2115 | 2207 | ||
2116 | spin_lock(&adapter->mbx_lock); | 2208 | spin_lock_bh(&adapter->mbx_lock); |
2117 | 2209 | ||
2118 | need_reset = hw->mac.ops.check_link(hw, &link_speed, | 2210 | need_reset = hw->mac.ops.check_link(hw, &link_speed, |
2119 | &link_up, false); | 2211 | &link_up, false); |
2120 | 2212 | ||
2121 | spin_unlock(&adapter->mbx_lock); | 2213 | spin_unlock_bh(&adapter->mbx_lock); |
2122 | 2214 | ||
2123 | if (need_reset) { | 2215 | if (need_reset) { |
2124 | adapter->link_up = link_up; | 2216 | adapter->link_up = link_up; |
@@ -2377,6 +2469,63 @@ static void ixgbevf_free_all_rx_resources(struct ixgbevf_adapter *adapter) | |||
2377 | &adapter->rx_ring[i]); | 2469 | &adapter->rx_ring[i]); |
2378 | } | 2470 | } |
2379 | 2471 | ||
2472 | static int ixgbevf_setup_queues(struct ixgbevf_adapter *adapter) | ||
2473 | { | ||
2474 | struct ixgbe_hw *hw = &adapter->hw; | ||
2475 | struct ixgbevf_ring *rx_ring; | ||
2476 | unsigned int def_q = 0; | ||
2477 | unsigned int num_tcs = 0; | ||
2478 | unsigned int num_rx_queues = 1; | ||
2479 | int err, i; | ||
2480 | |||
2481 | spin_lock_bh(&adapter->mbx_lock); | ||
2482 | |||
2483 | /* fetch queue configuration from the PF */ | ||
2484 | err = ixgbevf_get_queues(hw, &num_tcs, &def_q); | ||
2485 | |||
2486 | spin_unlock_bh(&adapter->mbx_lock); | ||
2487 | |||
2488 | if (err) | ||
2489 | return err; | ||
2490 | |||
2491 | if (num_tcs > 1) { | ||
2492 | /* update default Tx ring register index */ | ||
2493 | adapter->tx_ring[0].reg_idx = def_q; | ||
2494 | |||
2495 | /* we need as many queues as traffic classes */ | ||
2496 | num_rx_queues = num_tcs; | ||
2497 | } | ||
2498 | |||
2499 | /* nothing to do if we have the correct number of queues */ | ||
2500 | if (adapter->num_rx_queues == num_rx_queues) | ||
2501 | return 0; | ||
2502 | |||
2503 | /* allocate new rings */ | ||
2504 | rx_ring = kcalloc(num_rx_queues, | ||
2505 | sizeof(struct ixgbevf_ring), GFP_KERNEL); | ||
2506 | if (!rx_ring) | ||
2507 | return -ENOMEM; | ||
2508 | |||
2509 | /* setup ring fields */ | ||
2510 | for (i = 0; i < num_rx_queues; i++) { | ||
2511 | rx_ring[i].count = adapter->rx_ring_count; | ||
2512 | rx_ring[i].queue_index = i; | ||
2513 | rx_ring[i].reg_idx = i; | ||
2514 | rx_ring[i].dev = &adapter->pdev->dev; | ||
2515 | rx_ring[i].netdev = adapter->netdev; | ||
2516 | } | ||
2517 | |||
2518 | /* free the existing ring and queues */ | ||
2519 | adapter->num_rx_queues = 0; | ||
2520 | kfree(adapter->rx_ring); | ||
2521 | |||
2522 | /* move new rings into position on the adapter struct */ | ||
2523 | adapter->rx_ring = rx_ring; | ||
2524 | adapter->num_rx_queues = num_rx_queues; | ||
2525 | |||
2526 | return 0; | ||
2527 | } | ||
2528 | |||
2380 | /** | 2529 | /** |
2381 | * ixgbevf_open - Called when a network interface is made active | 2530 | * ixgbevf_open - Called when a network interface is made active |
2382 | * @netdev: network interface device structure | 2531 | * @netdev: network interface device structure |
@@ -2413,6 +2562,11 @@ static int ixgbevf_open(struct net_device *netdev) | |||
2413 | 2562 | ||
2414 | ixgbevf_negotiate_api(adapter); | 2563 | ixgbevf_negotiate_api(adapter); |
2415 | 2564 | ||
2565 | /* setup queue reg_idx and Rx queue count */ | ||
2566 | err = ixgbevf_setup_queues(adapter); | ||
2567 | if (err) | ||
2568 | goto err_setup_queues; | ||
2569 | |||
2416 | /* allocate transmit descriptors */ | 2570 | /* allocate transmit descriptors */ |
2417 | err = ixgbevf_setup_all_tx_resources(adapter); | 2571 | err = ixgbevf_setup_all_tx_resources(adapter); |
2418 | if (err) | 2572 | if (err) |
@@ -2451,6 +2605,7 @@ err_setup_rx: | |||
2451 | ixgbevf_free_all_rx_resources(adapter); | 2605 | ixgbevf_free_all_rx_resources(adapter); |
2452 | err_setup_tx: | 2606 | err_setup_tx: |
2453 | ixgbevf_free_all_tx_resources(adapter); | 2607 | ixgbevf_free_all_tx_resources(adapter); |
2608 | err_setup_queues: | ||
2454 | ixgbevf_reset(adapter); | 2609 | ixgbevf_reset(adapter); |
2455 | 2610 | ||
2456 | err_setup_reset: | 2611 | err_setup_reset: |
@@ -2678,10 +2833,10 @@ static int ixgbevf_tx_map(struct ixgbevf_ring *tx_ring, | |||
2678 | tx_buffer_info->dma = | 2833 | tx_buffer_info->dma = |
2679 | skb_frag_dma_map(tx_ring->dev, frag, | 2834 | skb_frag_dma_map(tx_ring->dev, frag, |
2680 | offset, size, DMA_TO_DEVICE); | 2835 | offset, size, DMA_TO_DEVICE); |
2681 | tx_buffer_info->mapped_as_page = true; | ||
2682 | if (dma_mapping_error(tx_ring->dev, | 2836 | if (dma_mapping_error(tx_ring->dev, |
2683 | tx_buffer_info->dma)) | 2837 | tx_buffer_info->dma)) |
2684 | goto dma_error; | 2838 | goto dma_error; |
2839 | tx_buffer_info->mapped_as_page = true; | ||
2685 | tx_buffer_info->next_to_watch = i; | 2840 | tx_buffer_info->next_to_watch = i; |
2686 | 2841 | ||
2687 | len -= size; | 2842 | len -= size; |
@@ -2823,6 +2978,11 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2823 | #if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD | 2978 | #if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD |
2824 | unsigned short f; | 2979 | unsigned short f; |
2825 | #endif | 2980 | #endif |
2981 | u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL); | ||
2982 | if (!dst_mac || is_link_local_ether_addr(dst_mac)) { | ||
2983 | dev_kfree_skb(skb); | ||
2984 | return NETDEV_TX_OK; | ||
2985 | } | ||
2826 | 2986 | ||
2827 | tx_ring = &adapter->tx_ring[r_idx]; | 2987 | tx_ring = &adapter->tx_ring[r_idx]; |
2828 | 2988 | ||
@@ -2902,12 +3062,12 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) | |||
2902 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 3062 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
2903 | memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); | 3063 | memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); |
2904 | 3064 | ||
2905 | spin_lock(&adapter->mbx_lock); | 3065 | spin_lock_bh(&adapter->mbx_lock); |
2906 | 3066 | ||
2907 | if (hw->mac.ops.set_rar) | 3067 | if (hw->mac.ops.set_rar) |
2908 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); | 3068 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); |
2909 | 3069 | ||
2910 | spin_unlock(&adapter->mbx_lock); | 3070 | spin_unlock_bh(&adapter->mbx_lock); |
2911 | 3071 | ||
2912 | return 0; | 3072 | return 0; |
2913 | } | 3073 | } |
@@ -2925,8 +3085,15 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) | |||
2925 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | 3085 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; |
2926 | int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; | 3086 | int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; |
2927 | 3087 | ||
2928 | if (adapter->hw.mac.type == ixgbe_mac_X540_vf) | 3088 | switch (adapter->hw.api_version) { |
3089 | case ixgbe_mbox_api_11: | ||
2929 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; | 3090 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; |
3091 | break; | ||
3092 | default: | ||
3093 | if (adapter->hw.mac.type == ixgbe_mac_X540_vf) | ||
3094 | max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; | ||
3095 | break; | ||
3096 | } | ||
2930 | 3097 | ||
2931 | /* MTU < 68 is an error and causes problems on some kernels */ | 3098 | /* MTU < 68 is an error and causes problems on some kernels */ |
2932 | if ((new_mtu < 68) || (max_frame > max_possible_frame)) | 3099 | if ((new_mtu < 68) || (max_frame > max_possible_frame)) |
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h index 946ce86f337f..0bc30058ff82 100644 --- a/drivers/net/ethernet/intel/ixgbevf/mbx.h +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h | |||
@@ -85,6 +85,7 @@ | |||
85 | enum ixgbe_pfvf_api_rev { | 85 | enum ixgbe_pfvf_api_rev { |
86 | ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ | 86 | ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */ |
87 | ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ | 87 | ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */ |
88 | ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */ | ||
88 | /* This value should always be last */ | 89 | /* This value should always be last */ |
89 | ixgbe_mbox_api_unknown, /* indicates that API version is not known */ | 90 | ixgbe_mbox_api_unknown, /* indicates that API version is not known */ |
90 | }; | 91 | }; |
@@ -100,6 +101,15 @@ enum ixgbe_pfvf_api_rev { | |||
100 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ | 101 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ |
101 | #define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ | 102 | #define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */ |
102 | 103 | ||
104 | /* mailbox API, version 1.1 VF requests */ | ||
105 | #define IXGBE_VF_GET_QUEUE 0x09 /* get queue configuration */ | ||
106 | |||
107 | /* GET_QUEUES return data indices within the mailbox */ | ||
108 | #define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */ | ||
109 | #define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */ | ||
110 | #define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */ | ||
111 | #define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */ | ||
112 | |||
103 | /* length of permanent address message returned from PF */ | 113 | /* length of permanent address message returned from PF */ |
104 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 | 114 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 |
105 | /* word in permanent address message with the current multicast type */ | 115 | /* word in permanent address message with the current multicast type */ |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index 0c7447e6fcc8..0c94557b53df 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c | |||
@@ -331,6 +331,9 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, | |||
331 | netdev_for_each_mc_addr(ha, netdev) { | 331 | netdev_for_each_mc_addr(ha, netdev) { |
332 | if (i == cnt) | 332 | if (i == cnt) |
333 | break; | 333 | break; |
334 | if (is_link_local_ether_addr(ha->addr)) | ||
335 | continue; | ||
336 | |||
334 | vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); | 337 | vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); |
335 | } | 338 | } |
336 | 339 | ||
@@ -513,6 +516,64 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) | |||
513 | return err; | 516 | return err; |
514 | } | 517 | } |
515 | 518 | ||
519 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||
520 | unsigned int *default_tc) | ||
521 | { | ||
522 | int err; | ||
523 | u32 msg[5]; | ||
524 | |||
525 | /* do nothing if API doesn't support ixgbevf_get_queues */ | ||
526 | switch (hw->api_version) { | ||
527 | case ixgbe_mbox_api_11: | ||
528 | break; | ||
529 | default: | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | /* Fetch queue configuration from the PF */ | ||
534 | msg[0] = IXGBE_VF_GET_QUEUE; | ||
535 | msg[1] = msg[2] = msg[3] = msg[4] = 0; | ||
536 | err = hw->mbx.ops.write_posted(hw, msg, 5); | ||
537 | |||
538 | if (!err) | ||
539 | err = hw->mbx.ops.read_posted(hw, msg, 5); | ||
540 | |||
541 | if (!err) { | ||
542 | msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||
543 | |||
544 | /* | ||
545 | * if we we didn't get an ACK there must have been | ||
546 | * some sort of mailbox error so we should treat it | ||
547 | * as such | ||
548 | */ | ||
549 | if (msg[0] != (IXGBE_VF_GET_QUEUE | IXGBE_VT_MSGTYPE_ACK)) | ||
550 | return IXGBE_ERR_MBX; | ||
551 | |||
552 | /* record and validate values from message */ | ||
553 | hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES]; | ||
554 | if (hw->mac.max_tx_queues == 0 || | ||
555 | hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES) | ||
556 | hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES; | ||
557 | |||
558 | hw->mac.max_rx_queues = msg[IXGBE_VF_RX_QUEUES]; | ||
559 | if (hw->mac.max_rx_queues == 0 || | ||
560 | hw->mac.max_rx_queues > IXGBE_VF_MAX_RX_QUEUES) | ||
561 | hw->mac.max_rx_queues = IXGBE_VF_MAX_RX_QUEUES; | ||
562 | |||
563 | *num_tcs = msg[IXGBE_VF_TRANS_VLAN]; | ||
564 | /* in case of unknown state assume we cannot tag frames */ | ||
565 | if (*num_tcs > hw->mac.max_rx_queues) | ||
566 | *num_tcs = 1; | ||
567 | |||
568 | *default_tc = msg[IXGBE_VF_DEF_QUEUE]; | ||
569 | /* default to queue 0 on out-of-bounds queue number */ | ||
570 | if (*default_tc >= hw->mac.max_tx_queues) | ||
571 | *default_tc = 0; | ||
572 | } | ||
573 | |||
574 | return err; | ||
575 | } | ||
576 | |||
516 | static const struct ixgbe_mac_operations ixgbevf_mac_ops = { | 577 | static const struct ixgbe_mac_operations ixgbevf_mac_ops = { |
517 | .init_hw = ixgbevf_init_hw_vf, | 578 | .init_hw = ixgbevf_init_hw_vf, |
518 | .reset_hw = ixgbevf_reset_hw_vf, | 579 | .reset_hw = ixgbevf_reset_hw_vf, |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h index 47f11a584d8c..7b1f502d1716 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h | |||
@@ -174,5 +174,7 @@ struct ixgbevf_info { | |||
174 | 174 | ||
175 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); | 175 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); |
176 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); | 176 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); |
177 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||
178 | unsigned int *default_tc); | ||
177 | #endif /* __IXGBE_VF_H__ */ | 179 | #endif /* __IXGBE_VF_H__ */ |
178 | 180 | ||
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 59489722e898..10d678d3dd01 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c | |||
@@ -1131,7 +1131,7 @@ static int pxa168_eth_open(struct net_device *dev) | |||
1131 | err = request_irq(dev->irq, pxa168_eth_int_handler, | 1131 | err = request_irq(dev->irq, pxa168_eth_int_handler, |
1132 | IRQF_DISABLED, dev->name, dev); | 1132 | IRQF_DISABLED, dev->name, dev); |
1133 | if (err) { | 1133 | if (err) { |
1134 | dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n"); | 1134 | dev_err(&dev->dev, "can't assign irq\n"); |
1135 | return -EAGAIN; | 1135 | return -EAGAIN; |
1136 | } | 1136 | } |
1137 | pep->rx_resource_err = 0; | 1137 | pep->rx_resource_err = 0; |
@@ -1201,9 +1201,8 @@ static int pxa168_eth_change_mtu(struct net_device *dev, int mtu) | |||
1201 | */ | 1201 | */ |
1202 | pxa168_eth_stop(dev); | 1202 | pxa168_eth_stop(dev); |
1203 | if (pxa168_eth_open(dev)) { | 1203 | if (pxa168_eth_open(dev)) { |
1204 | dev_printk(KERN_ERR, &dev->dev, | 1204 | dev_err(&dev->dev, |
1205 | "fatal error on re-opening device after " | 1205 | "fatal error on re-opening device after MTU change\n"); |
1206 | "MTU change\n"); | ||
1207 | } | 1206 | } |
1208 | 1207 | ||
1209 | return 0; | 1208 | return 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index edd9cb8d3e1d..2b23ca21b320 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -870,7 +870,7 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) | |||
870 | /* If we haven't received a specific coalescing setting | 870 | /* If we haven't received a specific coalescing setting |
871 | * (module param), we set the moderation parameters as follows: | 871 | * (module param), we set the moderation parameters as follows: |
872 | * - moder_cnt is set to the number of mtu sized packets to | 872 | * - moder_cnt is set to the number of mtu sized packets to |
873 | * satisfy our coelsing target. | 873 | * satisfy our coalescing target. |
874 | * - moder_time is set to a fixed value. | 874 | * - moder_time is set to a fixed value. |
875 | */ | 875 | */ |
876 | priv->rx_frames = MLX4_EN_RX_COAL_TARGET; | 876 | priv->rx_frames = MLX4_EN_RX_COAL_TARGET; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 9d27e42264e2..8a5e70d68894 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -126,7 +126,7 @@ enum { | |||
126 | #define MLX4_EN_RX_COAL_TIME 0x10 | 126 | #define MLX4_EN_RX_COAL_TIME 0x10 |
127 | 127 | ||
128 | #define MLX4_EN_TX_COAL_PKTS 16 | 128 | #define MLX4_EN_TX_COAL_PKTS 16 |
129 | #define MLX4_EN_TX_COAL_TIME 0x80 | 129 | #define MLX4_EN_TX_COAL_TIME 0x10 |
130 | 130 | ||
131 | #define MLX4_EN_RX_RATE_LOW 400000 | 131 | #define MLX4_EN_RX_RATE_LOW 400000 |
132 | #define MLX4_EN_RX_COAL_TIME_LOW 0 | 132 | #define MLX4_EN_RX_COAL_TIME_LOW 0 |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e558edd1cb6c..e4ba868e232c 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
@@ -7251,18 +7251,7 @@ static struct pci_driver pci_device_driver = { | |||
7251 | .remove = pcidev_exit | 7251 | .remove = pcidev_exit |
7252 | }; | 7252 | }; |
7253 | 7253 | ||
7254 | static int __init ksz884x_init_module(void) | 7254 | module_pci_driver(pci_device_driver); |
7255 | { | ||
7256 | return pci_register_driver(&pci_device_driver); | ||
7257 | } | ||
7258 | |||
7259 | static void __exit ksz884x_cleanup_module(void) | ||
7260 | { | ||
7261 | pci_unregister_driver(&pci_device_driver); | ||
7262 | } | ||
7263 | |||
7264 | module_init(ksz884x_init_module); | ||
7265 | module_exit(ksz884x_cleanup_module); | ||
7266 | 7255 | ||
7267 | MODULE_DESCRIPTION("KSZ8841/2 PCI network driver"); | 7256 | MODULE_DESCRIPTION("KSZ8841/2 PCI network driver"); |
7268 | MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>"); | 7257 | MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>"); |
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index de50547c187d..c98decb19ce8 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c | |||
@@ -8239,7 +8239,8 @@ static int __init s2io_starter(void) | |||
8239 | 8239 | ||
8240 | /** | 8240 | /** |
8241 | * s2io_closer - Cleanup routine for the driver | 8241 | * s2io_closer - Cleanup routine for the driver |
8242 | * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. | 8242 | * Description: This function is the cleanup routine for the driver. It |
8243 | * unregisters the driver. | ||
8243 | */ | 8244 | */ |
8244 | 8245 | ||
8245 | static __exit void s2io_closer(void) | 8246 | static __exit void s2io_closer(void) |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig index 5296cc8d3cba..00bc4fc968c7 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig +++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig | |||
@@ -20,19 +20,3 @@ config PCH_GBE | |||
20 | purpose use. | 20 | purpose use. |
21 | ML7223/ML7831 is companion chip for Intel Atom E6xx series. | 21 | ML7223/ML7831 is companion chip for Intel Atom E6xx series. |
22 | ML7223/ML7831 is completely compatible for Intel EG20T PCH. | 22 | ML7223/ML7831 is completely compatible for Intel EG20T PCH. |
23 | |||
24 | if PCH_GBE | ||
25 | |||
26 | config PCH_PTP | ||
27 | bool "PCH PTP clock support" | ||
28 | default n | ||
29 | depends on EXPERIMENTAL | ||
30 | select PPS | ||
31 | select PTP_1588_CLOCK | ||
32 | select PTP_1588_CLOCK_PCH | ||
33 | ---help--- | ||
34 | Say Y here if you want to use Precision Time Protocol (PTP) in the | ||
35 | driver. PTP is a method to precisely synchronize distributed clocks | ||
36 | over Ethernet networks. | ||
37 | |||
38 | endif # PCH_GBE | ||
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h index b07311eaa693..7fb7e178c74e 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h | |||
@@ -649,7 +649,6 @@ extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, | |||
649 | extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, | 649 | extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, |
650 | struct pch_gbe_rx_ring *rx_ring); | 650 | struct pch_gbe_rx_ring *rx_ring); |
651 | extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); | 651 | extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); |
652 | #ifdef CONFIG_PCH_PTP | ||
653 | extern u32 pch_ch_control_read(struct pci_dev *pdev); | 652 | extern u32 pch_ch_control_read(struct pci_dev *pdev); |
654 | extern void pch_ch_control_write(struct pci_dev *pdev, u32 val); | 653 | extern void pch_ch_control_write(struct pci_dev *pdev, u32 val); |
655 | extern u32 pch_ch_event_read(struct pci_dev *pdev); | 654 | extern u32 pch_ch_event_read(struct pci_dev *pdev); |
@@ -659,7 +658,6 @@ extern u32 pch_src_uuid_hi_read(struct pci_dev *pdev); | |||
659 | extern u64 pch_rx_snap_read(struct pci_dev *pdev); | 658 | extern u64 pch_rx_snap_read(struct pci_dev *pdev); |
660 | extern u64 pch_tx_snap_read(struct pci_dev *pdev); | 659 | extern u64 pch_tx_snap_read(struct pci_dev *pdev); |
661 | extern int pch_set_station_address(u8 *addr, struct pci_dev *pdev); | 660 | extern int pch_set_station_address(u8 *addr, struct pci_dev *pdev); |
662 | #endif | ||
663 | 661 | ||
664 | /* pch_gbe_param.c */ | 662 | /* pch_gbe_param.c */ |
665 | extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); | 663 | extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 4c4fe5b1a29a..39ab4d09faaa 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | |||
@@ -21,10 +21,8 @@ | |||
21 | #include "pch_gbe.h" | 21 | #include "pch_gbe.h" |
22 | #include "pch_gbe_api.h" | 22 | #include "pch_gbe_api.h" |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #ifdef CONFIG_PCH_PTP | ||
25 | #include <linux/net_tstamp.h> | 24 | #include <linux/net_tstamp.h> |
26 | #include <linux/ptp_classify.h> | 25 | #include <linux/ptp_classify.h> |
27 | #endif | ||
28 | 26 | ||
29 | #define DRV_VERSION "1.01" | 27 | #define DRV_VERSION "1.01" |
30 | const char pch_driver_version[] = DRV_VERSION; | 28 | const char pch_driver_version[] = DRV_VERSION; |
@@ -98,7 +96,6 @@ const char pch_driver_version[] = DRV_VERSION; | |||
98 | 96 | ||
99 | #define PCH_GBE_INT_DISABLE_ALL 0 | 97 | #define PCH_GBE_INT_DISABLE_ALL 0 |
100 | 98 | ||
101 | #ifdef CONFIG_PCH_PTP | ||
102 | /* Macros for ieee1588 */ | 99 | /* Macros for ieee1588 */ |
103 | /* 0x40 Time Synchronization Channel Control Register Bits */ | 100 | /* 0x40 Time Synchronization Channel Control Register Bits */ |
104 | #define MASTER_MODE (1<<0) | 101 | #define MASTER_MODE (1<<0) |
@@ -113,7 +110,6 @@ const char pch_driver_version[] = DRV_VERSION; | |||
113 | 110 | ||
114 | #define PTP_L4_MULTICAST_SA "01:00:5e:00:01:81" | 111 | #define PTP_L4_MULTICAST_SA "01:00:5e:00:01:81" |
115 | #define PTP_L2_MULTICAST_SA "01:1b:19:00:00:00" | 112 | #define PTP_L2_MULTICAST_SA "01:1b:19:00:00:00" |
116 | #endif | ||
117 | 113 | ||
118 | static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; | 114 | static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; |
119 | 115 | ||
@@ -122,7 +118,6 @@ static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, | |||
122 | int data); | 118 | int data); |
123 | static void pch_gbe_set_multi(struct net_device *netdev); | 119 | static void pch_gbe_set_multi(struct net_device *netdev); |
124 | 120 | ||
125 | #ifdef CONFIG_PCH_PTP | ||
126 | static struct sock_filter ptp_filter[] = { | 121 | static struct sock_filter ptp_filter[] = { |
127 | PTP_FILTER | 122 | PTP_FILTER |
128 | }; | 123 | }; |
@@ -291,7 +286,6 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
291 | 286 | ||
292 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | 287 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; |
293 | } | 288 | } |
294 | #endif | ||
295 | 289 | ||
296 | inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) | 290 | inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) |
297 | { | 291 | { |
@@ -1244,9 +1238,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, | |||
1244 | (int)sizeof(struct pch_gbe_tx_desc) * ring_num, | 1238 | (int)sizeof(struct pch_gbe_tx_desc) * ring_num, |
1245 | &hw->reg->TX_DSC_SW_P); | 1239 | &hw->reg->TX_DSC_SW_P); |
1246 | 1240 | ||
1247 | #ifdef CONFIG_PCH_PTP | ||
1248 | pch_tx_timestamp(adapter, skb); | 1241 | pch_tx_timestamp(adapter, skb); |
1249 | #endif | ||
1250 | 1242 | ||
1251 | dev_kfree_skb_any(skb); | 1243 | dev_kfree_skb_any(skb); |
1252 | } | 1244 | } |
@@ -1730,9 +1722,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
1730 | /* Write meta date of skb */ | 1722 | /* Write meta date of skb */ |
1731 | skb_put(skb, length); | 1723 | skb_put(skb, length); |
1732 | 1724 | ||
1733 | #ifdef CONFIG_PCH_PTP | ||
1734 | pch_rx_timestamp(adapter, skb); | 1725 | pch_rx_timestamp(adapter, skb); |
1735 | #endif | ||
1736 | 1726 | ||
1737 | skb->protocol = eth_type_trans(skb, netdev); | 1727 | skb->protocol = eth_type_trans(skb, netdev); |
1738 | if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) | 1728 | if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) |
@@ -2334,10 +2324,8 @@ static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
2334 | 2324 | ||
2335 | pr_debug("cmd : 0x%04x\n", cmd); | 2325 | pr_debug("cmd : 0x%04x\n", cmd); |
2336 | 2326 | ||
2337 | #ifdef CONFIG_PCH_PTP | ||
2338 | if (cmd == SIOCSHWTSTAMP) | 2327 | if (cmd == SIOCSHWTSTAMP) |
2339 | return hwtstamp_ioctl(netdev, ifr, cmd); | 2328 | return hwtstamp_ioctl(netdev, ifr, cmd); |
2340 | #endif | ||
2341 | 2329 | ||
2342 | return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); | 2330 | return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); |
2343 | } | 2331 | } |
@@ -2623,14 +2611,12 @@ static int pch_gbe_probe(struct pci_dev *pdev, | |||
2623 | goto err_free_netdev; | 2611 | goto err_free_netdev; |
2624 | } | 2612 | } |
2625 | 2613 | ||
2626 | #ifdef CONFIG_PCH_PTP | ||
2627 | adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number, | 2614 | adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number, |
2628 | PCI_DEVFN(12, 4)); | 2615 | PCI_DEVFN(12, 4)); |
2629 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | 2616 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { |
2630 | pr_err("Bad ptp filter\n"); | 2617 | pr_err("Bad ptp filter\n"); |
2631 | return -EINVAL; | 2618 | return -EINVAL; |
2632 | } | 2619 | } |
2633 | #endif | ||
2634 | 2620 | ||
2635 | netdev->netdev_ops = &pch_gbe_netdev_ops; | 2621 | netdev->netdev_ops = &pch_gbe_netdev_ops; |
2636 | netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; | 2622 | netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 10468e7932dd..4ca2c196c98a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | |||
@@ -218,7 +218,7 @@ skip: | |||
218 | check_sfp_module = netif_running(dev) && | 218 | check_sfp_module = netif_running(dev) && |
219 | adapter->has_link_events; | 219 | adapter->has_link_events; |
220 | } else { | 220 | } else { |
221 | ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); | 221 | ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); |
222 | ecmd->advertising |= | 222 | ecmd->advertising |= |
223 | (ADVERTISED_TP | ADVERTISED_Autoneg); | 223 | (ADVERTISED_TP | ADVERTISED_Autoneg); |
224 | ecmd->port = PORT_TP; | 224 | ecmd->port = PORT_TP; |
@@ -381,7 +381,7 @@ static u32 netxen_nic_test_link(struct net_device *dev) | |||
381 | 381 | ||
382 | static int | 382 | static int |
383 | netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | 383 | netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, |
384 | u8 * bytes) | 384 | u8 *bytes) |
385 | { | 385 | { |
386 | struct netxen_adapter *adapter = netdev_priv(dev); | 386 | struct netxen_adapter *adapter = netdev_priv(dev); |
387 | int offset; | 387 | int offset; |
@@ -488,6 +488,8 @@ netxen_nic_get_pauseparam(struct net_device *dev, | |||
488 | __u32 val; | 488 | __u32 val; |
489 | int port = adapter->physical_port; | 489 | int port = adapter->physical_port; |
490 | 490 | ||
491 | pause->autoneg = 0; | ||
492 | |||
491 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 493 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { |
492 | if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) | 494 | if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) |
493 | return; | 495 | return; |
@@ -496,19 +498,19 @@ netxen_nic_get_pauseparam(struct net_device *dev, | |||
496 | pause->rx_pause = netxen_gb_get_rx_flowctl(val); | 498 | pause->rx_pause = netxen_gb_get_rx_flowctl(val); |
497 | val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); | 499 | val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); |
498 | switch (port) { | 500 | switch (port) { |
499 | case 0: | 501 | case 0: |
500 | pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); | 502 | pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); |
501 | break; | 503 | break; |
502 | case 1: | 504 | case 1: |
503 | pause->tx_pause = !(netxen_gb_get_gb1_mask(val)); | 505 | pause->tx_pause = !(netxen_gb_get_gb1_mask(val)); |
504 | break; | 506 | break; |
505 | case 2: | 507 | case 2: |
506 | pause->tx_pause = !(netxen_gb_get_gb2_mask(val)); | 508 | pause->tx_pause = !(netxen_gb_get_gb2_mask(val)); |
507 | break; | 509 | break; |
508 | case 3: | 510 | case 3: |
509 | default: | 511 | default: |
510 | pause->tx_pause = !(netxen_gb_get_gb3_mask(val)); | 512 | pause->tx_pause = !(netxen_gb_get_gb3_mask(val)); |
511 | break; | 513 | break; |
512 | } | 514 | } |
513 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { | 515 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { |
514 | if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS)) | 516 | if ((port < 0) || (port >= NETXEN_NIU_MAX_XG_PORTS)) |
@@ -532,6 +534,11 @@ netxen_nic_set_pauseparam(struct net_device *dev, | |||
532 | struct netxen_adapter *adapter = netdev_priv(dev); | 534 | struct netxen_adapter *adapter = netdev_priv(dev); |
533 | __u32 val; | 535 | __u32 val; |
534 | int port = adapter->physical_port; | 536 | int port = adapter->physical_port; |
537 | |||
538 | /* not supported */ | ||
539 | if (pause->autoneg) | ||
540 | return -EINVAL; | ||
541 | |||
535 | /* read mode */ | 542 | /* read mode */ |
536 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 543 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { |
537 | if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) | 544 | if ((port < 0) || (port >= NETXEN_NIU_MAX_GBE_PORTS)) |
@@ -549,31 +556,31 @@ netxen_nic_set_pauseparam(struct net_device *dev, | |||
549 | /* set autoneg */ | 556 | /* set autoneg */ |
550 | val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); | 557 | val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); |
551 | switch (port) { | 558 | switch (port) { |
552 | case 0: | 559 | case 0: |
553 | if (pause->tx_pause) | 560 | if (pause->tx_pause) |
554 | netxen_gb_unset_gb0_mask(val); | 561 | netxen_gb_unset_gb0_mask(val); |
555 | else | 562 | else |
556 | netxen_gb_set_gb0_mask(val); | 563 | netxen_gb_set_gb0_mask(val); |
557 | break; | 564 | break; |
558 | case 1: | 565 | case 1: |
559 | if (pause->tx_pause) | 566 | if (pause->tx_pause) |
560 | netxen_gb_unset_gb1_mask(val); | 567 | netxen_gb_unset_gb1_mask(val); |
561 | else | 568 | else |
562 | netxen_gb_set_gb1_mask(val); | 569 | netxen_gb_set_gb1_mask(val); |
563 | break; | 570 | break; |
564 | case 2: | 571 | case 2: |
565 | if (pause->tx_pause) | 572 | if (pause->tx_pause) |
566 | netxen_gb_unset_gb2_mask(val); | 573 | netxen_gb_unset_gb2_mask(val); |
567 | else | 574 | else |
568 | netxen_gb_set_gb2_mask(val); | 575 | netxen_gb_set_gb2_mask(val); |
569 | break; | 576 | break; |
570 | case 3: | 577 | case 3: |
571 | default: | 578 | default: |
572 | if (pause->tx_pause) | 579 | if (pause->tx_pause) |
573 | netxen_gb_unset_gb3_mask(val); | 580 | netxen_gb_unset_gb3_mask(val); |
574 | else | 581 | else |
575 | netxen_gb_set_gb3_mask(val); | 582 | netxen_gb_set_gb3_mask(val); |
576 | break; | 583 | break; |
577 | } | 584 | } |
578 | NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); | 585 | NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); |
579 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { | 586 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { |
@@ -636,7 +643,7 @@ static int netxen_get_sset_count(struct net_device *dev, int sset) | |||
636 | 643 | ||
637 | static void | 644 | static void |
638 | netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, | 645 | netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, |
639 | u64 * data) | 646 | u64 *data) |
640 | { | 647 | { |
641 | memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN); | 648 | memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN); |
642 | if ((data[0] = netxen_nic_reg_test(dev))) | 649 | if ((data[0] = netxen_nic_reg_test(dev))) |
@@ -647,7 +654,7 @@ netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, | |||
647 | } | 654 | } |
648 | 655 | ||
649 | static void | 656 | static void |
650 | netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data) | 657 | netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
651 | { | 658 | { |
652 | int index; | 659 | int index; |
653 | 660 | ||
@@ -668,7 +675,7 @@ netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data) | |||
668 | 675 | ||
669 | static void | 676 | static void |
670 | netxen_nic_get_ethtool_stats(struct net_device *dev, | 677 | netxen_nic_get_ethtool_stats(struct net_device *dev, |
671 | struct ethtool_stats *stats, u64 * data) | 678 | struct ethtool_stats *stats, u64 *data) |
672 | { | 679 | { |
673 | struct netxen_adapter *adapter = netdev_priv(dev); | 680 | struct netxen_adapter *adapter = netdev_priv(dev); |
674 | int index; | 681 | int index; |
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 6407d0d77e81..12d1f2470d5c 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c | |||
@@ -1920,7 +1920,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, | |||
1920 | { | 1920 | { |
1921 | struct ql_tx_buf_cb *tx_cb; | 1921 | struct ql_tx_buf_cb *tx_cb; |
1922 | int i; | 1922 | int i; |
1923 | int retval = 0; | ||
1924 | 1923 | ||
1925 | if (mac_rsp->flags & OB_MAC_IOCB_RSP_S) { | 1924 | if (mac_rsp->flags & OB_MAC_IOCB_RSP_S) { |
1926 | netdev_warn(qdev->ndev, | 1925 | netdev_warn(qdev->ndev, |
@@ -1935,7 +1934,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, | |||
1935 | "Frame too short to be legal, frame not sent\n"); | 1934 | "Frame too short to be legal, frame not sent\n"); |
1936 | 1935 | ||
1937 | qdev->ndev->stats.tx_errors++; | 1936 | qdev->ndev->stats.tx_errors++; |
1938 | retval = -EIO; | ||
1939 | goto frame_not_sent; | 1937 | goto frame_not_sent; |
1940 | } | 1938 | } |
1941 | 1939 | ||
@@ -1944,7 +1942,6 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, | |||
1944 | mac_rsp->transaction_id); | 1942 | mac_rsp->transaction_id); |
1945 | 1943 | ||
1946 | qdev->ndev->stats.tx_errors++; | 1944 | qdev->ndev->stats.tx_errors++; |
1947 | retval = -EIO; | ||
1948 | goto invalid_seg_count; | 1945 | goto invalid_seg_count; |
1949 | } | 1946 | } |
1950 | 1947 | ||
@@ -3958,15 +3955,4 @@ static struct pci_driver ql3xxx_driver = { | |||
3958 | .remove = __devexit_p(ql3xxx_remove), | 3955 | .remove = __devexit_p(ql3xxx_remove), |
3959 | }; | 3956 | }; |
3960 | 3957 | ||
3961 | static int __init ql3xxx_init_module(void) | 3958 | module_pci_driver(ql3xxx_driver); |
3962 | { | ||
3963 | return pci_register_driver(&ql3xxx_driver); | ||
3964 | } | ||
3965 | |||
3966 | static void __exit ql3xxx_exit(void) | ||
3967 | { | ||
3968 | pci_unregister_driver(&ql3xxx_driver); | ||
3969 | } | ||
3970 | |||
3971 | module_init(ql3xxx_init_module); | ||
3972 | module_exit(ql3xxx_exit); | ||
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c index 58185b604b72..10093f0c4c0f 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c | |||
@@ -86,7 +86,7 @@ exit: | |||
86 | } | 86 | } |
87 | 87 | ||
88 | /* Read out the SERDES registers */ | 88 | /* Read out the SERDES registers */ |
89 | static int ql_read_serdes_reg(struct ql_adapter *qdev, u32 reg, u32 * data) | 89 | static int ql_read_serdes_reg(struct ql_adapter *qdev, u32 reg, u32 *data) |
90 | { | 90 | { |
91 | int status; | 91 | int status; |
92 | 92 | ||
@@ -364,7 +364,7 @@ exit: | |||
364 | /* Read the 400 xgmac control/statistics registers | 364 | /* Read the 400 xgmac control/statistics registers |
365 | * skipping unused locations. | 365 | * skipping unused locations. |
366 | */ | 366 | */ |
367 | static int ql_get_xgmac_regs(struct ql_adapter *qdev, u32 * buf, | 367 | static int ql_get_xgmac_regs(struct ql_adapter *qdev, u32 *buf, |
368 | unsigned int other_function) | 368 | unsigned int other_function) |
369 | { | 369 | { |
370 | int status = 0; | 370 | int status = 0; |
@@ -405,7 +405,7 @@ static int ql_get_xgmac_regs(struct ql_adapter *qdev, u32 * buf, | |||
405 | return status; | 405 | return status; |
406 | } | 406 | } |
407 | 407 | ||
408 | static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf) | 408 | static int ql_get_ets_regs(struct ql_adapter *qdev, u32 *buf) |
409 | { | 409 | { |
410 | int status = 0; | 410 | int status = 0; |
411 | int i; | 411 | int i; |
@@ -423,7 +423,7 @@ static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf) | |||
423 | return status; | 423 | return status; |
424 | } | 424 | } |
425 | 425 | ||
426 | static void ql_get_intr_states(struct ql_adapter *qdev, u32 * buf) | 426 | static void ql_get_intr_states(struct ql_adapter *qdev, u32 *buf) |
427 | { | 427 | { |
428 | int i; | 428 | int i; |
429 | 429 | ||
@@ -434,7 +434,7 @@ static void ql_get_intr_states(struct ql_adapter *qdev, u32 * buf) | |||
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | static int ql_get_cam_entries(struct ql_adapter *qdev, u32 * buf) | 437 | static int ql_get_cam_entries(struct ql_adapter *qdev, u32 *buf) |
438 | { | 438 | { |
439 | int i, status; | 439 | int i, status; |
440 | u32 value[3]; | 440 | u32 value[3]; |
@@ -471,7 +471,7 @@ err: | |||
471 | return status; | 471 | return status; |
472 | } | 472 | } |
473 | 473 | ||
474 | static int ql_get_routing_entries(struct ql_adapter *qdev, u32 * buf) | 474 | static int ql_get_routing_entries(struct ql_adapter *qdev, u32 *buf) |
475 | { | 475 | { |
476 | int status; | 476 | int status; |
477 | u32 value, i; | 477 | u32 value, i; |
@@ -496,7 +496,7 @@ err: | |||
496 | } | 496 | } |
497 | 497 | ||
498 | /* Read the MPI Processor shadow registers */ | 498 | /* Read the MPI Processor shadow registers */ |
499 | static int ql_get_mpi_shadow_regs(struct ql_adapter *qdev, u32 * buf) | 499 | static int ql_get_mpi_shadow_regs(struct ql_adapter *qdev, u32 *buf) |
500 | { | 500 | { |
501 | u32 i; | 501 | u32 i; |
502 | int status; | 502 | int status; |
@@ -515,7 +515,7 @@ end: | |||
515 | } | 515 | } |
516 | 516 | ||
517 | /* Read the MPI Processor core registers */ | 517 | /* Read the MPI Processor core registers */ |
518 | static int ql_get_mpi_regs(struct ql_adapter *qdev, u32 * buf, | 518 | static int ql_get_mpi_regs(struct ql_adapter *qdev, u32 *buf, |
519 | u32 offset, u32 count) | 519 | u32 offset, u32 count) |
520 | { | 520 | { |
521 | int i, status = 0; | 521 | int i, status = 0; |
diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c index e02f04d7f3ad..9f2d416de750 100644 --- a/drivers/net/ethernet/realtek/atp.c +++ b/drivers/net/ethernet/realtek/atp.c | |||
@@ -175,8 +175,7 @@ struct net_local { | |||
175 | unsigned int tx_unit_busy:1; | 175 | unsigned int tx_unit_busy:1; |
176 | unsigned char re_tx, /* Number of packet retransmissions. */ | 176 | unsigned char re_tx, /* Number of packet retransmissions. */ |
177 | addr_mode, /* Current Rx filter e.g. promiscuous, etc. */ | 177 | addr_mode, /* Current Rx filter e.g. promiscuous, etc. */ |
178 | pac_cnt_in_tx_buf, | 178 | pac_cnt_in_tx_buf; |
179 | chip_type; | ||
180 | }; | 179 | }; |
181 | 180 | ||
182 | /* This code, written by wwc@super.org, resets the adapter every | 181 | /* This code, written by wwc@super.org, resets the adapter every |
@@ -339,7 +338,6 @@ static int __init atp_probe1(long ioaddr) | |||
339 | write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); | 338 | write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); |
340 | 339 | ||
341 | lp = netdev_priv(dev); | 340 | lp = netdev_priv(dev); |
342 | lp->chip_type = RTL8002; | ||
343 | lp->addr_mode = CMR2h_Normal; | 341 | lp->addr_mode = CMR2h_Normal; |
344 | spin_lock_init(&lp->lock); | 342 | spin_lock_init(&lp->lock); |
345 | 343 | ||
@@ -852,7 +850,7 @@ net_close(struct net_device *dev) | |||
852 | * Set or clear the multicast filter for this adapter. | 850 | * Set or clear the multicast filter for this adapter. |
853 | */ | 851 | */ |
854 | 852 | ||
855 | static void set_rx_mode_8002(struct net_device *dev) | 853 | static void set_rx_mode(struct net_device *dev) |
856 | { | 854 | { |
857 | struct net_local *lp = netdev_priv(dev); | 855 | struct net_local *lp = netdev_priv(dev); |
858 | long ioaddr = dev->base_addr; | 856 | long ioaddr = dev->base_addr; |
@@ -864,58 +862,6 @@ static void set_rx_mode_8002(struct net_device *dev) | |||
864 | write_reg_high(ioaddr, CMR2, lp->addr_mode); | 862 | write_reg_high(ioaddr, CMR2, lp->addr_mode); |
865 | } | 863 | } |
866 | 864 | ||
867 | static void set_rx_mode_8012(struct net_device *dev) | ||
868 | { | ||
869 | struct net_local *lp = netdev_priv(dev); | ||
870 | long ioaddr = dev->base_addr; | ||
871 | unsigned char new_mode, mc_filter[8]; /* Multicast hash filter */ | ||
872 | int i; | ||
873 | |||
874 | if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ | ||
875 | new_mode = CMR2h_PROMISC; | ||
876 | } else if ((netdev_mc_count(dev) > 1000) || | ||
877 | (dev->flags & IFF_ALLMULTI)) { | ||
878 | /* Too many to filter perfectly -- accept all multicasts. */ | ||
879 | memset(mc_filter, 0xff, sizeof(mc_filter)); | ||
880 | new_mode = CMR2h_Normal; | ||
881 | } else { | ||
882 | struct netdev_hw_addr *ha; | ||
883 | |||
884 | memset(mc_filter, 0, sizeof(mc_filter)); | ||
885 | netdev_for_each_mc_addr(ha, dev) { | ||
886 | int filterbit = ether_crc_le(ETH_ALEN, ha->addr) & 0x3f; | ||
887 | mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); | ||
888 | } | ||
889 | new_mode = CMR2h_Normal; | ||
890 | } | ||
891 | lp->addr_mode = new_mode; | ||
892 | write_reg(ioaddr, CMR2, CMR2_IRQOUT | 0x04); /* Switch to page 1. */ | ||
893 | for (i = 0; i < 8; i++) | ||
894 | write_reg_byte(ioaddr, i, mc_filter[i]); | ||
895 | if (net_debug > 2 || 1) { | ||
896 | lp->addr_mode = 1; | ||
897 | printk(KERN_DEBUG "%s: Mode %d, setting multicast filter to", | ||
898 | dev->name, lp->addr_mode); | ||
899 | for (i = 0; i < 8; i++) | ||
900 | printk(" %2.2x", mc_filter[i]); | ||
901 | printk(".\n"); | ||
902 | } | ||
903 | |||
904 | write_reg_high(ioaddr, CMR2, lp->addr_mode); | ||
905 | write_reg(ioaddr, CMR2, CMR2_IRQOUT); /* Switch back to page 0 */ | ||
906 | } | ||
907 | |||
908 | static void set_rx_mode(struct net_device *dev) | ||
909 | { | ||
910 | struct net_local *lp = netdev_priv(dev); | ||
911 | |||
912 | if (lp->chip_type == RTL8002) | ||
913 | return set_rx_mode_8002(dev); | ||
914 | else | ||
915 | return set_rx_mode_8012(dev); | ||
916 | } | ||
917 | |||
918 | |||
919 | static int __init atp_init_module(void) { | 865 | static int __init atp_init_module(void) { |
920 | if (debug) /* Emit version even if no cards detected. */ | 866 | if (debug) /* Emit version even if no cards detected. */ |
921 | printk(KERN_INFO "%s", version); | 867 | printk(KERN_INFO "%s", version); |
diff --git a/drivers/net/ethernet/realtek/atp.h b/drivers/net/ethernet/realtek/atp.h index 0edc642c2c2f..040b13739947 100644 --- a/drivers/net/ethernet/realtek/atp.h +++ b/drivers/net/ethernet/realtek/atp.h | |||
@@ -16,8 +16,6 @@ struct rx_header { | |||
16 | #define PAR_STATUS 1 | 16 | #define PAR_STATUS 1 |
17 | #define PAR_CONTROL 2 | 17 | #define PAR_CONTROL 2 |
18 | 18 | ||
19 | enum chip_type { RTL8002, RTL8012 }; | ||
20 | |||
21 | #define Ctrl_LNibRead 0x08 /* LP_PSELECP */ | 19 | #define Ctrl_LNibRead 0x08 /* LP_PSELECP */ |
22 | #define Ctrl_HNibRead 0 | 20 | #define Ctrl_HNibRead 0 |
23 | #define Ctrl_LNibWrite 0x08 /* LP_PSELECP */ | 21 | #define Ctrl_LNibWrite 0x08 /* LP_PSELECP */ |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 927aa33d4349..50a55fb10368 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -78,7 +78,6 @@ static const int multicast_filter_limit = 32; | |||
78 | 78 | ||
79 | #define MAX_READ_REQUEST_SHIFT 12 | 79 | #define MAX_READ_REQUEST_SHIFT 12 |
80 | #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ | 80 | #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ |
81 | #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ | ||
82 | #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ | 81 | #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ |
83 | 82 | ||
84 | #define R8169_REGS_SIZE 256 | 83 | #define R8169_REGS_SIZE 256 |
@@ -456,6 +455,7 @@ enum rtl8168_registers { | |||
456 | #define PWM_EN (1 << 22) | 455 | #define PWM_EN (1 << 22) |
457 | #define RXDV_GATED_EN (1 << 19) | 456 | #define RXDV_GATED_EN (1 << 19) |
458 | #define EARLY_TALLY_EN (1 << 16) | 457 | #define EARLY_TALLY_EN (1 << 16) |
458 | #define FORCE_CLK (1 << 15) /* force clock request */ | ||
459 | }; | 459 | }; |
460 | 460 | ||
461 | enum rtl_register_content { | 461 | enum rtl_register_content { |
@@ -519,6 +519,7 @@ enum rtl_register_content { | |||
519 | PMEnable = (1 << 0), /* Power Management Enable */ | 519 | PMEnable = (1 << 0), /* Power Management Enable */ |
520 | 520 | ||
521 | /* Config2 register p. 25 */ | 521 | /* Config2 register p. 25 */ |
522 | ClkReqEn = (1 << 7), /* Clock Request Enable */ | ||
522 | MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ | 523 | MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ |
523 | PCI_Clock_66MHz = 0x01, | 524 | PCI_Clock_66MHz = 0x01, |
524 | PCI_Clock_33MHz = 0x00, | 525 | PCI_Clock_33MHz = 0x00, |
@@ -539,6 +540,7 @@ enum rtl_register_content { | |||
539 | Spi_en = (1 << 3), | 540 | Spi_en = (1 << 3), |
540 | LanWake = (1 << 1), /* LanWake enable/disable */ | 541 | LanWake = (1 << 1), /* LanWake enable/disable */ |
541 | PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ | 542 | PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ |
543 | ASPM_en = (1 << 0), /* ASPM enable */ | ||
542 | 544 | ||
543 | /* TBICSR p.28 */ | 545 | /* TBICSR p.28 */ |
544 | TBIReset = 0x80000000, | 546 | TBIReset = 0x80000000, |
@@ -687,6 +689,7 @@ enum features { | |||
687 | RTL_FEATURE_WOL = (1 << 0), | 689 | RTL_FEATURE_WOL = (1 << 0), |
688 | RTL_FEATURE_MSI = (1 << 1), | 690 | RTL_FEATURE_MSI = (1 << 1), |
689 | RTL_FEATURE_GMII = (1 << 2), | 691 | RTL_FEATURE_GMII = (1 << 2), |
692 | RTL_FEATURE_FW_LOADED = (1 << 3), | ||
690 | }; | 693 | }; |
691 | 694 | ||
692 | struct rtl8169_counters { | 695 | struct rtl8169_counters { |
@@ -2394,8 +2397,10 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) | |||
2394 | struct rtl_fw *rtl_fw = tp->rtl_fw; | 2397 | struct rtl_fw *rtl_fw = tp->rtl_fw; |
2395 | 2398 | ||
2396 | /* TODO: release firmware once rtl_phy_write_fw signals failures. */ | 2399 | /* TODO: release firmware once rtl_phy_write_fw signals failures. */ |
2397 | if (!IS_ERR_OR_NULL(rtl_fw)) | 2400 | if (!IS_ERR_OR_NULL(rtl_fw)) { |
2398 | rtl_phy_write_fw(tp, rtl_fw); | 2401 | rtl_phy_write_fw(tp, rtl_fw); |
2402 | tp->features |= RTL_FEATURE_FW_LOADED; | ||
2403 | } | ||
2399 | } | 2404 | } |
2400 | 2405 | ||
2401 | static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) | 2406 | static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) |
@@ -2406,6 +2411,31 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) | |||
2406 | rtl_apply_firmware(tp); | 2411 | rtl_apply_firmware(tp); |
2407 | } | 2412 | } |
2408 | 2413 | ||
2414 | static void r810x_aldps_disable(struct rtl8169_private *tp) | ||
2415 | { | ||
2416 | rtl_writephy(tp, 0x1f, 0x0000); | ||
2417 | rtl_writephy(tp, 0x18, 0x0310); | ||
2418 | msleep(100); | ||
2419 | } | ||
2420 | |||
2421 | static void r810x_aldps_enable(struct rtl8169_private *tp) | ||
2422 | { | ||
2423 | if (!(tp->features & RTL_FEATURE_FW_LOADED)) | ||
2424 | return; | ||
2425 | |||
2426 | rtl_writephy(tp, 0x1f, 0x0000); | ||
2427 | rtl_writephy(tp, 0x18, 0x8310); | ||
2428 | } | ||
2429 | |||
2430 | static void r8168_aldps_enable_1(struct rtl8169_private *tp) | ||
2431 | { | ||
2432 | if (!(tp->features & RTL_FEATURE_FW_LOADED)) | ||
2433 | return; | ||
2434 | |||
2435 | rtl_writephy(tp, 0x1f, 0x0000); | ||
2436 | rtl_w1w0_phy(tp, 0x15, 0x1000, 0x0000); | ||
2437 | } | ||
2438 | |||
2409 | static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) | 2439 | static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) |
2410 | { | 2440 | { |
2411 | static const struct phy_reg phy_reg_init[] = { | 2441 | static const struct phy_reg phy_reg_init[] = { |
@@ -3178,6 +3208,8 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) | |||
3178 | rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); | 3208 | rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); |
3179 | rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); | 3209 | rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); |
3180 | rtl_writephy(tp, 0x1f, 0x0000); | 3210 | rtl_writephy(tp, 0x1f, 0x0000); |
3211 | |||
3212 | r8168_aldps_enable_1(tp); | ||
3181 | } | 3213 | } |
3182 | 3214 | ||
3183 | static void rtl8168f_hw_phy_config(struct rtl8169_private *tp) | 3215 | static void rtl8168f_hw_phy_config(struct rtl8169_private *tp) |
@@ -3250,6 +3282,8 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp) | |||
3250 | rtl_writephy(tp, 0x05, 0x8b85); | 3282 | rtl_writephy(tp, 0x05, 0x8b85); |
3251 | rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000); | 3283 | rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000); |
3252 | rtl_writephy(tp, 0x1f, 0x0000); | 3284 | rtl_writephy(tp, 0x1f, 0x0000); |
3285 | |||
3286 | r8168_aldps_enable_1(tp); | ||
3253 | } | 3287 | } |
3254 | 3288 | ||
3255 | static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) | 3289 | static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) |
@@ -3257,6 +3291,8 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) | |||
3257 | rtl_apply_firmware(tp); | 3291 | rtl_apply_firmware(tp); |
3258 | 3292 | ||
3259 | rtl8168f_hw_phy_config(tp); | 3293 | rtl8168f_hw_phy_config(tp); |
3294 | |||
3295 | r8168_aldps_enable_1(tp); | ||
3260 | } | 3296 | } |
3261 | 3297 | ||
3262 | static void rtl8411_hw_phy_config(struct rtl8169_private *tp) | 3298 | static void rtl8411_hw_phy_config(struct rtl8169_private *tp) |
@@ -3354,6 +3390,8 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) | |||
3354 | rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); | 3390 | rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001); |
3355 | rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); | 3391 | rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400); |
3356 | rtl_writephy(tp, 0x1f, 0x0000); | 3392 | rtl_writephy(tp, 0x1f, 0x0000); |
3393 | |||
3394 | r8168_aldps_enable_1(tp); | ||
3357 | } | 3395 | } |
3358 | 3396 | ||
3359 | static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) | 3397 | static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) |
@@ -3439,21 +3477,19 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) | |||
3439 | }; | 3477 | }; |
3440 | 3478 | ||
3441 | /* Disable ALDPS before ram code */ | 3479 | /* Disable ALDPS before ram code */ |
3442 | rtl_writephy(tp, 0x1f, 0x0000); | 3480 | r810x_aldps_disable(tp); |
3443 | rtl_writephy(tp, 0x18, 0x0310); | ||
3444 | msleep(100); | ||
3445 | 3481 | ||
3446 | rtl_apply_firmware(tp); | 3482 | rtl_apply_firmware(tp); |
3447 | 3483 | ||
3448 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 3484 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
3485 | |||
3486 | r810x_aldps_enable(tp); | ||
3449 | } | 3487 | } |
3450 | 3488 | ||
3451 | static void rtl8402_hw_phy_config(struct rtl8169_private *tp) | 3489 | static void rtl8402_hw_phy_config(struct rtl8169_private *tp) |
3452 | { | 3490 | { |
3453 | /* Disable ALDPS before setting firmware */ | 3491 | /* Disable ALDPS before setting firmware */ |
3454 | rtl_writephy(tp, 0x1f, 0x0000); | 3492 | r810x_aldps_disable(tp); |
3455 | rtl_writephy(tp, 0x18, 0x0310); | ||
3456 | msleep(20); | ||
3457 | 3493 | ||
3458 | rtl_apply_firmware(tp); | 3494 | rtl_apply_firmware(tp); |
3459 | 3495 | ||
@@ -3463,6 +3499,8 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) | |||
3463 | rtl_writephy(tp, 0x10, 0x401f); | 3499 | rtl_writephy(tp, 0x10, 0x401f); |
3464 | rtl_writephy(tp, 0x19, 0x7030); | 3500 | rtl_writephy(tp, 0x19, 0x7030); |
3465 | rtl_writephy(tp, 0x1f, 0x0000); | 3501 | rtl_writephy(tp, 0x1f, 0x0000); |
3502 | |||
3503 | r810x_aldps_enable(tp); | ||
3466 | } | 3504 | } |
3467 | 3505 | ||
3468 | static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) | 3506 | static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) |
@@ -3475,9 +3513,7 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) | |||
3475 | }; | 3513 | }; |
3476 | 3514 | ||
3477 | /* Disable ALDPS before ram code */ | 3515 | /* Disable ALDPS before ram code */ |
3478 | rtl_writephy(tp, 0x1f, 0x0000); | 3516 | r810x_aldps_disable(tp); |
3479 | rtl_writephy(tp, 0x18, 0x0310); | ||
3480 | msleep(100); | ||
3481 | 3517 | ||
3482 | rtl_apply_firmware(tp); | 3518 | rtl_apply_firmware(tp); |
3483 | 3519 | ||
@@ -3485,6 +3521,8 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) | |||
3485 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 3521 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
3486 | 3522 | ||
3487 | rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); | 3523 | rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); |
3524 | |||
3525 | r810x_aldps_enable(tp); | ||
3488 | } | 3526 | } |
3489 | 3527 | ||
3490 | static void rtl_hw_phy_config(struct net_device *dev) | 3528 | static void rtl_hw_phy_config(struct net_device *dev) |
@@ -5015,8 +5053,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) | |||
5015 | 5053 | ||
5016 | RTL_W8(MaxTxPacketSize, EarlySize); | 5054 | RTL_W8(MaxTxPacketSize, EarlySize); |
5017 | 5055 | ||
5018 | rtl_disable_clock_request(pdev); | ||
5019 | |||
5020 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); | 5056 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); |
5021 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); | 5057 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); |
5022 | 5058 | ||
@@ -5025,7 +5061,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) | |||
5025 | 5061 | ||
5026 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); | 5062 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); |
5027 | RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); | 5063 | RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); |
5028 | RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); | 5064 | RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); |
5065 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5029 | } | 5066 | } |
5030 | 5067 | ||
5031 | static void rtl_hw_start_8168f(struct rtl8169_private *tp) | 5068 | static void rtl_hw_start_8168f(struct rtl8169_private *tp) |
@@ -5050,13 +5087,12 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp) | |||
5050 | 5087 | ||
5051 | RTL_W8(MaxTxPacketSize, EarlySize); | 5088 | RTL_W8(MaxTxPacketSize, EarlySize); |
5052 | 5089 | ||
5053 | rtl_disable_clock_request(pdev); | ||
5054 | |||
5055 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); | 5090 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); |
5056 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); | 5091 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); |
5057 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); | 5092 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); |
5058 | RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); | 5093 | RTL_W32(MISC, RTL_R32(MISC) | PWM_EN | FORCE_CLK); |
5059 | RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); | 5094 | RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); |
5095 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5060 | } | 5096 | } |
5061 | 5097 | ||
5062 | static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) | 5098 | static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) |
@@ -5113,8 +5149,10 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) | |||
5113 | rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); | 5149 | rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); |
5114 | 5150 | ||
5115 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 5151 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
5116 | RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); | 5152 | RTL_W32(MISC, (RTL_R32(MISC) | FORCE_CLK) & ~RXDV_GATED_EN); |
5117 | RTL_W8(MaxTxPacketSize, EarlySize); | 5153 | RTL_W8(MaxTxPacketSize, EarlySize); |
5154 | RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); | ||
5155 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5118 | 5156 | ||
5119 | rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); | 5157 | rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); |
5120 | rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); | 5158 | rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); |
@@ -5330,6 +5368,9 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) | |||
5330 | 5368 | ||
5331 | RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); | 5369 | RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); |
5332 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); | 5370 | RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); |
5371 | RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); | ||
5372 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5373 | RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); | ||
5333 | 5374 | ||
5334 | rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); | 5375 | rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); |
5335 | } | 5376 | } |
@@ -5355,6 +5396,9 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) | |||
5355 | 5396 | ||
5356 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); | 5397 | RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); |
5357 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); | 5398 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); |
5399 | RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); | ||
5400 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5401 | RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); | ||
5358 | 5402 | ||
5359 | rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); | 5403 | rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); |
5360 | 5404 | ||
@@ -5376,7 +5420,10 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp) | |||
5376 | /* Force LAN exit from ASPM if Rx/Tx are not idle */ | 5420 | /* Force LAN exit from ASPM if Rx/Tx are not idle */ |
5377 | RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); | 5421 | RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); |
5378 | 5422 | ||
5379 | RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); | 5423 | RTL_W32(MISC, |
5424 | (RTL_R32(MISC) | DISABLE_LAN_EN | FORCE_CLK) & ~EARLY_TALLY_EN); | ||
5425 | RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); | ||
5426 | RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); | ||
5380 | RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); | 5427 | RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); |
5381 | RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); | 5428 | RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); |
5382 | } | 5429 | } |
@@ -6992,15 +7039,4 @@ static struct pci_driver rtl8169_pci_driver = { | |||
6992 | .driver.pm = RTL8169_PM_OPS, | 7039 | .driver.pm = RTL8169_PM_OPS, |
6993 | }; | 7040 | }; |
6994 | 7041 | ||
6995 | static int __init rtl8169_init_module(void) | 7042 | module_pci_driver(rtl8169_pci_driver); |
6996 | { | ||
6997 | return pci_register_driver(&rtl8169_pci_driver); | ||
6998 | } | ||
6999 | |||
7000 | static void __exit rtl8169_cleanup_module(void) | ||
7001 | { | ||
7002 | pci_unregister_driver(&rtl8169_pci_driver); | ||
7003 | } | ||
7004 | |||
7005 | module_init(rtl8169_init_module); | ||
7006 | module_exit(rtl8169_cleanup_module); | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c8bfea0524dd..3d705862bd7d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -2286,7 +2286,7 @@ static int sh_mdio_init(struct net_device *ndev, int id, | |||
2286 | for (i = 0; i < PHY_MAX_ADDR; i++) | 2286 | for (i = 0; i < PHY_MAX_ADDR; i++) |
2287 | mdp->mii_bus->irq[i] = PHY_POLL; | 2287 | mdp->mii_bus->irq[i] = PHY_POLL; |
2288 | 2288 | ||
2289 | /* regist mdio bus */ | 2289 | /* register mdio bus */ |
2290 | ret = mdiobus_register(mdp->mii_bus); | 2290 | ret = mdiobus_register(mdp->mii_bus); |
2291 | if (ret) | 2291 | if (ret) |
2292 | goto out_free_irq; | 2292 | goto out_free_irq; |
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 25906c1d1b15..3ab2c4289a47 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig | |||
@@ -5,6 +5,7 @@ config SFC | |||
5 | select CRC32 | 5 | select CRC32 |
6 | select I2C | 6 | select I2C |
7 | select I2C_ALGOBIT | 7 | select I2C_ALGOBIT |
8 | select PTP_1588_CLOCK | ||
8 | ---help--- | 9 | ---help--- |
9 | This driver supports 10-gigabit Ethernet cards based on | 10 | This driver supports 10-gigabit Ethernet cards based on |
10 | the Solarflare SFC4000 and SFC9000-family controllers. | 11 | the Solarflare SFC4000 and SFC9000-family controllers. |
@@ -34,10 +35,3 @@ config SFC_SRIOV | |||
34 | This enables support for the SFC9000 I/O Virtualization | 35 | This enables support for the SFC9000 I/O Virtualization |
35 | features, allowing accelerated network performance in | 36 | features, allowing accelerated network performance in |
36 | virtualized environments. | 37 | virtualized environments. |
37 | config SFC_PTP | ||
38 | bool "Solarflare SFC9000-family PTP support" | ||
39 | depends on SFC && PTP_1588_CLOCK && !(SFC=y && PTP_1588_CLOCK=m) | ||
40 | default y | ||
41 | ---help--- | ||
42 | This enables support for the Precision Time Protocol (PTP) | ||
43 | on SFC9000-family NICs | ||
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index e11f2ecf69d9..945bf06e69ef 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile | |||
@@ -2,9 +2,8 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ | |||
2 | falcon_xmac.o mcdi_mac.o \ | 2 | falcon_xmac.o mcdi_mac.o \ |
3 | selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ | 3 | selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ |
4 | tenxpress.o txc43128_phy.o falcon_boards.o \ | 4 | tenxpress.o txc43128_phy.o falcon_boards.o \ |
5 | mcdi.o mcdi_phy.o mcdi_mon.o | 5 | mcdi.o mcdi_phy.o mcdi_mon.o ptp.o |
6 | sfc-$(CONFIG_SFC_MTD) += mtd.o | 6 | sfc-$(CONFIG_SFC_MTD) += mtd.o |
7 | sfc-$(CONFIG_SFC_SRIOV) += siena_sriov.o | 7 | sfc-$(CONFIG_SFC_SRIOV) += siena_sriov.o |
8 | sfc-$(CONFIG_SFC_PTP) += ptp.o | ||
9 | 8 | ||
10 | obj-$(CONFIG_SFC) += sfc.o | 9 | obj-$(CONFIG_SFC) += sfc.o |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 576a31091165..2487f582ab04 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -868,9 +868,7 @@ struct efx_nic { | |||
868 | struct work_struct peer_work; | 868 | struct work_struct peer_work; |
869 | #endif | 869 | #endif |
870 | 870 | ||
871 | #ifdef CONFIG_SFC_PTP | ||
872 | struct efx_ptp_data *ptp_data; | 871 | struct efx_ptp_data *ptp_data; |
873 | #endif | ||
874 | 872 | ||
875 | /* The following fields may be written more often */ | 873 | /* The following fields may be written more often */ |
876 | 874 | ||
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 438cef11f727..7a9647a3c565 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
@@ -252,7 +252,6 @@ extern int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf, | |||
252 | bool spoofchk); | 252 | bool spoofchk); |
253 | 253 | ||
254 | struct ethtool_ts_info; | 254 | struct ethtool_ts_info; |
255 | #ifdef CONFIG_SFC_PTP | ||
256 | extern void efx_ptp_probe(struct efx_nic *efx); | 255 | extern void efx_ptp_probe(struct efx_nic *efx); |
257 | extern int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd); | 256 | extern int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd); |
258 | extern int efx_ptp_get_ts_info(struct net_device *net_dev, | 257 | extern int efx_ptp_get_ts_info(struct net_device *net_dev, |
@@ -260,31 +259,6 @@ extern int efx_ptp_get_ts_info(struct net_device *net_dev, | |||
260 | extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 259 | extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
261 | extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 260 | extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
262 | extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); | 261 | extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); |
263 | #else | ||
264 | static inline void efx_ptp_probe(struct efx_nic *efx) {} | ||
265 | static inline int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd) | ||
266 | { | ||
267 | return -EOPNOTSUPP; | ||
268 | } | ||
269 | static inline int efx_ptp_get_ts_info(struct net_device *net_dev, | ||
270 | struct ethtool_ts_info *ts_info) | ||
271 | { | ||
272 | ts_info->so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | | ||
273 | SOF_TIMESTAMPING_RX_SOFTWARE); | ||
274 | ts_info->phc_index = -1; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | static inline bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) | ||
279 | { | ||
280 | return false; | ||
281 | } | ||
282 | static inline int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) | ||
283 | { | ||
284 | return NETDEV_TX_OK; | ||
285 | } | ||
286 | static inline void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) {} | ||
287 | #endif | ||
288 | 262 | ||
289 | extern const struct efx_nic_type falcon_a1_nic_type; | 263 | extern const struct efx_nic_type falcon_a1_nic_type; |
290 | extern const struct efx_nic_type falcon_b0_nic_type; | 264 | extern const struct efx_nic_type falcon_b0_nic_type; |
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index 2c41894d5472..48fcb5e3bd3d 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig | |||
@@ -60,6 +60,14 @@ config TI_CPSW | |||
60 | To compile this driver as a module, choose M here: the module | 60 | To compile this driver as a module, choose M here: the module |
61 | will be called cpsw. | 61 | will be called cpsw. |
62 | 62 | ||
63 | config TI_CPTS | ||
64 | boolean "TI Common Platform Time Sync (CPTS) Support" | ||
65 | select PTP_1588_CLOCK | ||
66 | ---help--- | ||
67 | This driver supports the Common Platform Time Sync unit of | ||
68 | the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4 | ||
69 | and Layer 2 packets, and the driver offers a PTP Hardware Clock. | ||
70 | |||
63 | config TLAN | 71 | config TLAN |
64 | tristate "TI ThunderLAN support" | 72 | tristate "TI ThunderLAN support" |
65 | depends on (PCI || EISA) | 73 | depends on (PCI || EISA) |
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile index 91bd8bba78ff..c65148e8aa1d 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile | |||
@@ -8,4 +8,4 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o | |||
8 | obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o | 8 | obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o |
9 | obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o | 9 | obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o |
10 | obj-$(CONFIG_TI_CPSW) += ti_cpsw.o | 10 | obj-$(CONFIG_TI_CPSW) += ti_cpsw.o |
11 | ti_cpsw-y := cpsw_ale.o cpsw.o | 11 | ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index df55e2403746..7654a62ab75e 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/if_ether.h> | 24 | #include <linux/if_ether.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/net_tstamp.h> | ||
27 | #include <linux/phy.h> | 28 | #include <linux/phy.h> |
28 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <linux/platform_data/cpsw.h> | 36 | #include <linux/platform_data/cpsw.h> |
36 | 37 | ||
37 | #include "cpsw_ale.h" | 38 | #include "cpsw_ale.h" |
39 | #include "cpts.h" | ||
38 | #include "davinci_cpdma.h" | 40 | #include "davinci_cpdma.h" |
39 | 41 | ||
40 | #define CPSW_DEBUG (NETIF_MSG_HW | NETIF_MSG_WOL | \ | 42 | #define CPSW_DEBUG (NETIF_MSG_HW | NETIF_MSG_WOL | \ |
@@ -70,10 +72,14 @@ do { \ | |||
70 | dev_notice(priv->dev, format, ## __VA_ARGS__); \ | 72 | dev_notice(priv->dev, format, ## __VA_ARGS__); \ |
71 | } while (0) | 73 | } while (0) |
72 | 74 | ||
75 | #define ALE_ALL_PORTS 0x7 | ||
76 | |||
73 | #define CPSW_MAJOR_VERSION(reg) (reg >> 8 & 0x7) | 77 | #define CPSW_MAJOR_VERSION(reg) (reg >> 8 & 0x7) |
74 | #define CPSW_MINOR_VERSION(reg) (reg & 0xff) | 78 | #define CPSW_MINOR_VERSION(reg) (reg & 0xff) |
75 | #define CPSW_RTL_VERSION(reg) ((reg >> 11) & 0x1f) | 79 | #define CPSW_RTL_VERSION(reg) ((reg >> 11) & 0x1f) |
76 | 80 | ||
81 | #define CPSW_VERSION_1 0x19010a | ||
82 | #define CPSW_VERSION_2 0x19010c | ||
77 | #define CPDMA_RXTHRESH 0x0c0 | 83 | #define CPDMA_RXTHRESH 0x0c0 |
78 | #define CPDMA_RXFREE 0x0e0 | 84 | #define CPDMA_RXFREE 0x0e0 |
79 | #define CPDMA_TXHDP 0x00 | 85 | #define CPDMA_TXHDP 0x00 |
@@ -129,7 +135,7 @@ static int rx_packet_max = CPSW_MAX_PACKET_SIZE; | |||
129 | module_param(rx_packet_max, int, 0); | 135 | module_param(rx_packet_max, int, 0); |
130 | MODULE_PARM_DESC(rx_packet_max, "maximum receive packet size (bytes)"); | 136 | MODULE_PARM_DESC(rx_packet_max, "maximum receive packet size (bytes)"); |
131 | 137 | ||
132 | struct cpsw_ss_regs { | 138 | struct cpsw_wr_regs { |
133 | u32 id_ver; | 139 | u32 id_ver; |
134 | u32 soft_reset; | 140 | u32 soft_reset; |
135 | u32 control; | 141 | u32 control; |
@@ -140,26 +146,98 @@ struct cpsw_ss_regs { | |||
140 | u32 misc_en; | 146 | u32 misc_en; |
141 | }; | 147 | }; |
142 | 148 | ||
143 | struct cpsw_regs { | 149 | struct cpsw_ss_regs { |
144 | u32 id_ver; | 150 | u32 id_ver; |
145 | u32 control; | 151 | u32 control; |
146 | u32 soft_reset; | 152 | u32 soft_reset; |
147 | u32 stat_port_en; | 153 | u32 stat_port_en; |
148 | u32 ptype; | 154 | u32 ptype; |
155 | u32 soft_idle; | ||
156 | u32 thru_rate; | ||
157 | u32 gap_thresh; | ||
158 | u32 tx_start_wds; | ||
159 | u32 flow_control; | ||
160 | u32 vlan_ltype; | ||
161 | u32 ts_ltype; | ||
162 | u32 dlr_ltype; | ||
149 | }; | 163 | }; |
150 | 164 | ||
151 | struct cpsw_slave_regs { | 165 | /* CPSW_PORT_V1 */ |
152 | u32 max_blks; | 166 | #define CPSW1_MAX_BLKS 0x00 /* Maximum FIFO Blocks */ |
153 | u32 blk_cnt; | 167 | #define CPSW1_BLK_CNT 0x04 /* FIFO Block Usage Count (Read Only) */ |
154 | u32 flow_thresh; | 168 | #define CPSW1_TX_IN_CTL 0x08 /* Transmit FIFO Control */ |
155 | u32 port_vlan; | 169 | #define CPSW1_PORT_VLAN 0x0c /* VLAN Register */ |
156 | u32 tx_pri_map; | 170 | #define CPSW1_TX_PRI_MAP 0x10 /* Tx Header Priority to Switch Pri Mapping */ |
157 | u32 ts_ctl; | 171 | #define CPSW1_TS_CTL 0x14 /* Time Sync Control */ |
158 | u32 ts_seq_ltype; | 172 | #define CPSW1_TS_SEQ_LTYPE 0x18 /* Time Sync Sequence ID Offset and Msg Type */ |
159 | u32 ts_vlan; | 173 | #define CPSW1_TS_VLAN 0x1c /* Time Sync VLAN1 and VLAN2 */ |
160 | u32 sa_lo; | 174 | |
161 | u32 sa_hi; | 175 | /* CPSW_PORT_V2 */ |
162 | }; | 176 | #define CPSW2_CONTROL 0x00 /* Control Register */ |
177 | #define CPSW2_MAX_BLKS 0x08 /* Maximum FIFO Blocks */ | ||
178 | #define CPSW2_BLK_CNT 0x0c /* FIFO Block Usage Count (Read Only) */ | ||
179 | #define CPSW2_TX_IN_CTL 0x10 /* Transmit FIFO Control */ | ||
180 | #define CPSW2_PORT_VLAN 0x14 /* VLAN Register */ | ||
181 | #define CPSW2_TX_PRI_MAP 0x18 /* Tx Header Priority to Switch Pri Mapping */ | ||
182 | #define CPSW2_TS_SEQ_MTYPE 0x1c /* Time Sync Sequence ID Offset and Msg Type */ | ||
183 | |||
184 | /* CPSW_PORT_V1 and V2 */ | ||
185 | #define SA_LO 0x20 /* CPGMAC_SL Source Address Low */ | ||
186 | #define SA_HI 0x24 /* CPGMAC_SL Source Address High */ | ||
187 | #define SEND_PERCENT 0x28 /* Transmit Queue Send Percentages */ | ||
188 | |||
189 | /* CPSW_PORT_V2 only */ | ||
190 | #define RX_DSCP_PRI_MAP0 0x30 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
191 | #define RX_DSCP_PRI_MAP1 0x34 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
192 | #define RX_DSCP_PRI_MAP2 0x38 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
193 | #define RX_DSCP_PRI_MAP3 0x3c /* Rx DSCP Priority to Rx Packet Mapping */ | ||
194 | #define RX_DSCP_PRI_MAP4 0x40 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
195 | #define RX_DSCP_PRI_MAP5 0x44 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
196 | #define RX_DSCP_PRI_MAP6 0x48 /* Rx DSCP Priority to Rx Packet Mapping */ | ||
197 | #define RX_DSCP_PRI_MAP7 0x4c /* Rx DSCP Priority to Rx Packet Mapping */ | ||
198 | |||
199 | /* Bit definitions for the CPSW2_CONTROL register */ | ||
200 | #define PASS_PRI_TAGGED (1<<24) /* Pass Priority Tagged */ | ||
201 | #define VLAN_LTYPE2_EN (1<<21) /* VLAN LTYPE 2 enable */ | ||
202 | #define VLAN_LTYPE1_EN (1<<20) /* VLAN LTYPE 1 enable */ | ||
203 | #define DSCP_PRI_EN (1<<16) /* DSCP Priority Enable */ | ||
204 | #define TS_320 (1<<14) /* Time Sync Dest Port 320 enable */ | ||
205 | #define TS_319 (1<<13) /* Time Sync Dest Port 319 enable */ | ||
206 | #define TS_132 (1<<12) /* Time Sync Dest IP Addr 132 enable */ | ||
207 | #define TS_131 (1<<11) /* Time Sync Dest IP Addr 131 enable */ | ||
208 | #define TS_130 (1<<10) /* Time Sync Dest IP Addr 130 enable */ | ||
209 | #define TS_129 (1<<9) /* Time Sync Dest IP Addr 129 enable */ | ||
210 | #define TS_BIT8 (1<<8) /* ts_ttl_nonzero? */ | ||
211 | #define TS_ANNEX_D_EN (1<<4) /* Time Sync Annex D enable */ | ||
212 | #define TS_LTYPE2_EN (1<<3) /* Time Sync LTYPE 2 enable */ | ||
213 | #define TS_LTYPE1_EN (1<<2) /* Time Sync LTYPE 1 enable */ | ||
214 | #define TS_TX_EN (1<<1) /* Time Sync Transmit Enable */ | ||
215 | #define TS_RX_EN (1<<0) /* Time Sync Receive Enable */ | ||
216 | |||
217 | #define CTRL_TS_BITS \ | ||
218 | (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 | TS_BIT8 | \ | ||
219 | TS_ANNEX_D_EN | TS_LTYPE1_EN) | ||
220 | |||
221 | #define CTRL_ALL_TS_MASK (CTRL_TS_BITS | TS_TX_EN | TS_RX_EN) | ||
222 | #define CTRL_TX_TS_BITS (CTRL_TS_BITS | TS_TX_EN) | ||
223 | #define CTRL_RX_TS_BITS (CTRL_TS_BITS | TS_RX_EN) | ||
224 | |||
225 | /* Bit definitions for the CPSW2_TS_SEQ_MTYPE register */ | ||
226 | #define TS_SEQ_ID_OFFSET_SHIFT (16) /* Time Sync Sequence ID Offset */ | ||
227 | #define TS_SEQ_ID_OFFSET_MASK (0x3f) | ||
228 | #define TS_MSG_TYPE_EN_SHIFT (0) /* Time Sync Message Type Enable */ | ||
229 | #define TS_MSG_TYPE_EN_MASK (0xffff) | ||
230 | |||
231 | /* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */ | ||
232 | #define EVENT_MSG_BITS ((1<<0) | (1<<1) | (1<<2) | (1<<3)) | ||
233 | |||
234 | /* Bit definitions for the CPSW1_TS_CTL register */ | ||
235 | #define CPSW_V1_TS_RX_EN BIT(0) | ||
236 | #define CPSW_V1_TS_TX_EN BIT(4) | ||
237 | #define CPSW_V1_MSG_TYPE_OFS 16 | ||
238 | |||
239 | /* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */ | ||
240 | #define CPSW_V1_SEQ_ID_OFS_SHIFT 16 | ||
163 | 241 | ||
164 | struct cpsw_host_regs { | 242 | struct cpsw_host_regs { |
165 | u32 max_blks; | 243 | u32 max_blks; |
@@ -185,7 +263,7 @@ struct cpsw_sliver_regs { | |||
185 | }; | 263 | }; |
186 | 264 | ||
187 | struct cpsw_slave { | 265 | struct cpsw_slave { |
188 | struct cpsw_slave_regs __iomem *regs; | 266 | void __iomem *regs; |
189 | struct cpsw_sliver_regs __iomem *sliver; | 267 | struct cpsw_sliver_regs __iomem *sliver; |
190 | int slave_num; | 268 | int slave_num; |
191 | u32 mac_control; | 269 | u32 mac_control; |
@@ -193,19 +271,30 @@ struct cpsw_slave { | |||
193 | struct phy_device *phy; | 271 | struct phy_device *phy; |
194 | }; | 272 | }; |
195 | 273 | ||
274 | static inline u32 slave_read(struct cpsw_slave *slave, u32 offset) | ||
275 | { | ||
276 | return __raw_readl(slave->regs + offset); | ||
277 | } | ||
278 | |||
279 | static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) | ||
280 | { | ||
281 | __raw_writel(val, slave->regs + offset); | ||
282 | } | ||
283 | |||
196 | struct cpsw_priv { | 284 | struct cpsw_priv { |
197 | spinlock_t lock; | 285 | spinlock_t lock; |
198 | struct platform_device *pdev; | 286 | struct platform_device *pdev; |
199 | struct net_device *ndev; | 287 | struct net_device *ndev; |
200 | struct resource *cpsw_res; | 288 | struct resource *cpsw_res; |
201 | struct resource *cpsw_ss_res; | 289 | struct resource *cpsw_wr_res; |
202 | struct napi_struct napi; | 290 | struct napi_struct napi; |
203 | struct device *dev; | 291 | struct device *dev; |
204 | struct cpsw_platform_data data; | 292 | struct cpsw_platform_data data; |
205 | struct cpsw_regs __iomem *regs; | 293 | struct cpsw_ss_regs __iomem *regs; |
206 | struct cpsw_ss_regs __iomem *ss_regs; | 294 | struct cpsw_wr_regs __iomem *wr_regs; |
207 | struct cpsw_host_regs __iomem *host_port_regs; | 295 | struct cpsw_host_regs __iomem *host_port_regs; |
208 | u32 msg_enable; | 296 | u32 msg_enable; |
297 | u32 version; | ||
209 | struct net_device_stats stats; | 298 | struct net_device_stats stats; |
210 | int rx_packet_max; | 299 | int rx_packet_max; |
211 | int host_port; | 300 | int host_port; |
@@ -218,6 +307,7 @@ struct cpsw_priv { | |||
218 | /* snapshot of IRQ numbers */ | 307 | /* snapshot of IRQ numbers */ |
219 | u32 irqs_table[4]; | 308 | u32 irqs_table[4]; |
220 | u32 num_irqs; | 309 | u32 num_irqs; |
310 | struct cpts cpts; | ||
221 | }; | 311 | }; |
222 | 312 | ||
223 | #define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi) | 313 | #define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi) |
@@ -228,10 +318,34 @@ struct cpsw_priv { | |||
228 | (func)((priv)->slaves + idx, ##arg); \ | 318 | (func)((priv)->slaves + idx, ##arg); \ |
229 | } while (0) | 319 | } while (0) |
230 | 320 | ||
321 | static void cpsw_ndo_set_rx_mode(struct net_device *ndev) | ||
322 | { | ||
323 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
324 | |||
325 | if (ndev->flags & IFF_PROMISC) { | ||
326 | /* Enable promiscuous mode */ | ||
327 | dev_err(priv->dev, "Ignoring Promiscuous mode\n"); | ||
328 | return; | ||
329 | } | ||
330 | |||
331 | /* Clear all mcast from ALE */ | ||
332 | cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); | ||
333 | |||
334 | if (!netdev_mc_empty(ndev)) { | ||
335 | struct netdev_hw_addr *ha; | ||
336 | |||
337 | /* program multicast address list into ALE register */ | ||
338 | netdev_for_each_mc_addr(ha, ndev) { | ||
339 | cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr, | ||
340 | ALE_ALL_PORTS << priv->host_port, 0, 0); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | |||
231 | static void cpsw_intr_enable(struct cpsw_priv *priv) | 345 | static void cpsw_intr_enable(struct cpsw_priv *priv) |
232 | { | 346 | { |
233 | __raw_writel(0xFF, &priv->ss_regs->tx_en); | 347 | __raw_writel(0xFF, &priv->wr_regs->tx_en); |
234 | __raw_writel(0xFF, &priv->ss_regs->rx_en); | 348 | __raw_writel(0xFF, &priv->wr_regs->rx_en); |
235 | 349 | ||
236 | cpdma_ctlr_int_ctrl(priv->dma, true); | 350 | cpdma_ctlr_int_ctrl(priv->dma, true); |
237 | return; | 351 | return; |
@@ -239,8 +353,8 @@ static void cpsw_intr_enable(struct cpsw_priv *priv) | |||
239 | 353 | ||
240 | static void cpsw_intr_disable(struct cpsw_priv *priv) | 354 | static void cpsw_intr_disable(struct cpsw_priv *priv) |
241 | { | 355 | { |
242 | __raw_writel(0, &priv->ss_regs->tx_en); | 356 | __raw_writel(0, &priv->wr_regs->tx_en); |
243 | __raw_writel(0, &priv->ss_regs->rx_en); | 357 | __raw_writel(0, &priv->wr_regs->rx_en); |
244 | 358 | ||
245 | cpdma_ctlr_int_ctrl(priv->dma, false); | 359 | cpdma_ctlr_int_ctrl(priv->dma, false); |
246 | return; | 360 | return; |
@@ -254,6 +368,7 @@ void cpsw_tx_handler(void *token, int len, int status) | |||
254 | 368 | ||
255 | if (unlikely(netif_queue_stopped(ndev))) | 369 | if (unlikely(netif_queue_stopped(ndev))) |
256 | netif_start_queue(ndev); | 370 | netif_start_queue(ndev); |
371 | cpts_tx_timestamp(&priv->cpts, skb); | ||
257 | priv->stats.tx_packets++; | 372 | priv->stats.tx_packets++; |
258 | priv->stats.tx_bytes += len; | 373 | priv->stats.tx_bytes += len; |
259 | dev_kfree_skb_any(skb); | 374 | dev_kfree_skb_any(skb); |
@@ -274,6 +389,7 @@ void cpsw_rx_handler(void *token, int len, int status) | |||
274 | } | 389 | } |
275 | if (likely(status >= 0)) { | 390 | if (likely(status >= 0)) { |
276 | skb_put(skb, len); | 391 | skb_put(skb, len); |
392 | cpts_rx_timestamp(&priv->cpts, skb); | ||
277 | skb->protocol = eth_type_trans(skb, ndev); | 393 | skb->protocol = eth_type_trans(skb, ndev); |
278 | netif_receive_skb(skb); | 394 | netif_receive_skb(skb); |
279 | priv->stats.rx_bytes += len; | 395 | priv->stats.rx_bytes += len; |
@@ -359,8 +475,8 @@ static inline void soft_reset(const char *module, void __iomem *reg) | |||
359 | static void cpsw_set_slave_mac(struct cpsw_slave *slave, | 475 | static void cpsw_set_slave_mac(struct cpsw_slave *slave, |
360 | struct cpsw_priv *priv) | 476 | struct cpsw_priv *priv) |
361 | { | 477 | { |
362 | __raw_writel(mac_hi(priv->mac_addr), &slave->regs->sa_hi); | 478 | slave_write(slave, mac_hi(priv->mac_addr), SA_HI); |
363 | __raw_writel(mac_lo(priv->mac_addr), &slave->regs->sa_lo); | 479 | slave_write(slave, mac_lo(priv->mac_addr), SA_LO); |
364 | } | 480 | } |
365 | 481 | ||
366 | static void _cpsw_adjust_link(struct cpsw_slave *slave, | 482 | static void _cpsw_adjust_link(struct cpsw_slave *slave, |
@@ -446,7 +562,15 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) | |||
446 | 562 | ||
447 | /* setup priority mapping */ | 563 | /* setup priority mapping */ |
448 | __raw_writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map); | 564 | __raw_writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map); |
449 | __raw_writel(TX_PRIORITY_MAPPING, &slave->regs->tx_pri_map); | 565 | |
566 | switch (priv->version) { | ||
567 | case CPSW_VERSION_1: | ||
568 | slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP); | ||
569 | break; | ||
570 | case CPSW_VERSION_2: | ||
571 | slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP); | ||
572 | break; | ||
573 | } | ||
450 | 574 | ||
451 | /* setup max packet size, and mac address */ | 575 | /* setup max packet size, and mac address */ |
452 | __raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen); | 576 | __raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen); |
@@ -506,6 +630,7 @@ static int cpsw_ndo_open(struct net_device *ndev) | |||
506 | pm_runtime_get_sync(&priv->pdev->dev); | 630 | pm_runtime_get_sync(&priv->pdev->dev); |
507 | 631 | ||
508 | reg = __raw_readl(&priv->regs->id_ver); | 632 | reg = __raw_readl(&priv->regs->id_ver); |
633 | priv->version = reg; | ||
509 | 634 | ||
510 | dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", | 635 | dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", |
511 | CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), | 636 | CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), |
@@ -592,6 +717,11 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, | |||
592 | return NETDEV_TX_OK; | 717 | return NETDEV_TX_OK; |
593 | } | 718 | } |
594 | 719 | ||
720 | if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && priv->cpts.tx_enable) | ||
721 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
722 | |||
723 | skb_tx_timestamp(skb); | ||
724 | |||
595 | ret = cpdma_chan_submit(priv->txch, skb, skb->data, | 725 | ret = cpdma_chan_submit(priv->txch, skb, skb->data, |
596 | skb->len, GFP_KERNEL); | 726 | skb->len, GFP_KERNEL); |
597 | if (unlikely(ret != 0)) { | 727 | if (unlikely(ret != 0)) { |
@@ -629,6 +759,130 @@ static void cpsw_ndo_change_rx_flags(struct net_device *ndev, int flags) | |||
629 | dev_err(&ndev->dev, "multicast traffic cannot be filtered!\n"); | 759 | dev_err(&ndev->dev, "multicast traffic cannot be filtered!\n"); |
630 | } | 760 | } |
631 | 761 | ||
762 | #ifdef CONFIG_TI_CPTS | ||
763 | |||
764 | static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) | ||
765 | { | ||
766 | struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave]; | ||
767 | u32 ts_en, seq_id; | ||
768 | |||
769 | if (!priv->cpts.tx_enable && !priv->cpts.rx_enable) { | ||
770 | slave_write(slave, 0, CPSW1_TS_CTL); | ||
771 | return; | ||
772 | } | ||
773 | |||
774 | seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588; | ||
775 | ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS; | ||
776 | |||
777 | if (priv->cpts.tx_enable) | ||
778 | ts_en |= CPSW_V1_TS_TX_EN; | ||
779 | |||
780 | if (priv->cpts.rx_enable) | ||
781 | ts_en |= CPSW_V1_TS_RX_EN; | ||
782 | |||
783 | slave_write(slave, ts_en, CPSW1_TS_CTL); | ||
784 | slave_write(slave, seq_id, CPSW1_TS_SEQ_LTYPE); | ||
785 | } | ||
786 | |||
787 | static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) | ||
788 | { | ||
789 | struct cpsw_slave *slave = &priv->slaves[priv->data.cpts_active_slave]; | ||
790 | u32 ctrl, mtype; | ||
791 | |||
792 | ctrl = slave_read(slave, CPSW2_CONTROL); | ||
793 | ctrl &= ~CTRL_ALL_TS_MASK; | ||
794 | |||
795 | if (priv->cpts.tx_enable) | ||
796 | ctrl |= CTRL_TX_TS_BITS; | ||
797 | |||
798 | if (priv->cpts.rx_enable) | ||
799 | ctrl |= CTRL_RX_TS_BITS; | ||
800 | |||
801 | mtype = (30 << TS_SEQ_ID_OFFSET_SHIFT) | EVENT_MSG_BITS; | ||
802 | |||
803 | slave_write(slave, mtype, CPSW2_TS_SEQ_MTYPE); | ||
804 | slave_write(slave, ctrl, CPSW2_CONTROL); | ||
805 | __raw_writel(ETH_P_1588, &priv->regs->ts_ltype); | ||
806 | } | ||
807 | |||
808 | static int cpsw_hwtstamp_ioctl(struct cpsw_priv *priv, struct ifreq *ifr) | ||
809 | { | ||
810 | struct cpts *cpts = &priv->cpts; | ||
811 | struct hwtstamp_config cfg; | ||
812 | |||
813 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) | ||
814 | return -EFAULT; | ||
815 | |||
816 | /* reserved for future extensions */ | ||
817 | if (cfg.flags) | ||
818 | return -EINVAL; | ||
819 | |||
820 | switch (cfg.tx_type) { | ||
821 | case HWTSTAMP_TX_OFF: | ||
822 | cpts->tx_enable = 0; | ||
823 | break; | ||
824 | case HWTSTAMP_TX_ON: | ||
825 | cpts->tx_enable = 1; | ||
826 | break; | ||
827 | default: | ||
828 | return -ERANGE; | ||
829 | } | ||
830 | |||
831 | switch (cfg.rx_filter) { | ||
832 | case HWTSTAMP_FILTER_NONE: | ||
833 | cpts->rx_enable = 0; | ||
834 | break; | ||
835 | case HWTSTAMP_FILTER_ALL: | ||
836 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
837 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
838 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
839 | return -ERANGE; | ||
840 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
841 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
842 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
843 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
844 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
845 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
846 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
847 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
848 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
849 | cpts->rx_enable = 1; | ||
850 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | ||
851 | break; | ||
852 | default: | ||
853 | return -ERANGE; | ||
854 | } | ||
855 | |||
856 | switch (priv->version) { | ||
857 | case CPSW_VERSION_1: | ||
858 | cpsw_hwtstamp_v1(priv); | ||
859 | break; | ||
860 | case CPSW_VERSION_2: | ||
861 | cpsw_hwtstamp_v2(priv); | ||
862 | break; | ||
863 | default: | ||
864 | return -ENOTSUPP; | ||
865 | } | ||
866 | |||
867 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | ||
868 | } | ||
869 | |||
870 | #endif /*CONFIG_TI_CPTS*/ | ||
871 | |||
872 | static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
873 | { | ||
874 | struct cpsw_priv *priv = netdev_priv(dev); | ||
875 | |||
876 | if (!netif_running(dev)) | ||
877 | return -EINVAL; | ||
878 | |||
879 | #ifdef CONFIG_TI_CPTS | ||
880 | if (cmd == SIOCSHWTSTAMP) | ||
881 | return cpsw_hwtstamp_ioctl(priv, req); | ||
882 | #endif | ||
883 | return -ENOTSUPP; | ||
884 | } | ||
885 | |||
632 | static void cpsw_ndo_tx_timeout(struct net_device *ndev) | 886 | static void cpsw_ndo_tx_timeout(struct net_device *ndev) |
633 | { | 887 | { |
634 | struct cpsw_priv *priv = netdev_priv(ndev); | 888 | struct cpsw_priv *priv = netdev_priv(ndev); |
@@ -669,10 +923,12 @@ static const struct net_device_ops cpsw_netdev_ops = { | |||
669 | .ndo_stop = cpsw_ndo_stop, | 923 | .ndo_stop = cpsw_ndo_stop, |
670 | .ndo_start_xmit = cpsw_ndo_start_xmit, | 924 | .ndo_start_xmit = cpsw_ndo_start_xmit, |
671 | .ndo_change_rx_flags = cpsw_ndo_change_rx_flags, | 925 | .ndo_change_rx_flags = cpsw_ndo_change_rx_flags, |
926 | .ndo_do_ioctl = cpsw_ndo_ioctl, | ||
672 | .ndo_validate_addr = eth_validate_addr, | 927 | .ndo_validate_addr = eth_validate_addr, |
673 | .ndo_change_mtu = eth_change_mtu, | 928 | .ndo_change_mtu = eth_change_mtu, |
674 | .ndo_tx_timeout = cpsw_ndo_tx_timeout, | 929 | .ndo_tx_timeout = cpsw_ndo_tx_timeout, |
675 | .ndo_get_stats = cpsw_ndo_get_stats, | 930 | .ndo_get_stats = cpsw_ndo_get_stats, |
931 | .ndo_set_rx_mode = cpsw_ndo_set_rx_mode, | ||
676 | #ifdef CONFIG_NET_POLL_CONTROLLER | 932 | #ifdef CONFIG_NET_POLL_CONTROLLER |
677 | .ndo_poll_controller = cpsw_ndo_poll_controller, | 933 | .ndo_poll_controller = cpsw_ndo_poll_controller, |
678 | #endif | 934 | #endif |
@@ -699,11 +955,44 @@ static void cpsw_set_msglevel(struct net_device *ndev, u32 value) | |||
699 | priv->msg_enable = value; | 955 | priv->msg_enable = value; |
700 | } | 956 | } |
701 | 957 | ||
958 | static int cpsw_get_ts_info(struct net_device *ndev, | ||
959 | struct ethtool_ts_info *info) | ||
960 | { | ||
961 | #ifdef CONFIG_TI_CPTS | ||
962 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
963 | |||
964 | info->so_timestamping = | ||
965 | SOF_TIMESTAMPING_TX_HARDWARE | | ||
966 | SOF_TIMESTAMPING_TX_SOFTWARE | | ||
967 | SOF_TIMESTAMPING_RX_HARDWARE | | ||
968 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
969 | SOF_TIMESTAMPING_SOFTWARE | | ||
970 | SOF_TIMESTAMPING_RAW_HARDWARE; | ||
971 | info->phc_index = priv->cpts.phc_index; | ||
972 | info->tx_types = | ||
973 | (1 << HWTSTAMP_TX_OFF) | | ||
974 | (1 << HWTSTAMP_TX_ON); | ||
975 | info->rx_filters = | ||
976 | (1 << HWTSTAMP_FILTER_NONE) | | ||
977 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); | ||
978 | #else | ||
979 | info->so_timestamping = | ||
980 | SOF_TIMESTAMPING_TX_SOFTWARE | | ||
981 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
982 | SOF_TIMESTAMPING_SOFTWARE; | ||
983 | info->phc_index = -1; | ||
984 | info->tx_types = 0; | ||
985 | info->rx_filters = 0; | ||
986 | #endif | ||
987 | return 0; | ||
988 | } | ||
989 | |||
702 | static const struct ethtool_ops cpsw_ethtool_ops = { | 990 | static const struct ethtool_ops cpsw_ethtool_ops = { |
703 | .get_drvinfo = cpsw_get_drvinfo, | 991 | .get_drvinfo = cpsw_get_drvinfo, |
704 | .get_msglevel = cpsw_get_msglevel, | 992 | .get_msglevel = cpsw_get_msglevel, |
705 | .set_msglevel = cpsw_set_msglevel, | 993 | .set_msglevel = cpsw_set_msglevel, |
706 | .get_link = ethtool_op_get_link, | 994 | .get_link = ethtool_op_get_link, |
995 | .get_ts_info = cpsw_get_ts_info, | ||
707 | }; | 996 | }; |
708 | 997 | ||
709 | static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) | 998 | static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) |
@@ -734,6 +1023,27 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
734 | } | 1023 | } |
735 | data->slaves = prop; | 1024 | data->slaves = prop; |
736 | 1025 | ||
1026 | if (of_property_read_u32(node, "cpts_active_slave", &prop)) { | ||
1027 | pr_err("Missing cpts_active_slave property in the DT.\n"); | ||
1028 | ret = -EINVAL; | ||
1029 | goto error_ret; | ||
1030 | } | ||
1031 | data->cpts_active_slave = prop; | ||
1032 | |||
1033 | if (of_property_read_u32(node, "cpts_clock_mult", &prop)) { | ||
1034 | pr_err("Missing cpts_clock_mult property in the DT.\n"); | ||
1035 | ret = -EINVAL; | ||
1036 | goto error_ret; | ||
1037 | } | ||
1038 | data->cpts_clock_mult = prop; | ||
1039 | |||
1040 | if (of_property_read_u32(node, "cpts_clock_shift", &prop)) { | ||
1041 | pr_err("Missing cpts_clock_shift property in the DT.\n"); | ||
1042 | ret = -EINVAL; | ||
1043 | goto error_ret; | ||
1044 | } | ||
1045 | data->cpts_clock_shift = prop; | ||
1046 | |||
737 | data->slave_data = kzalloc(sizeof(struct cpsw_slave_data) * | 1047 | data->slave_data = kzalloc(sizeof(struct cpsw_slave_data) * |
738 | data->slaves, GFP_KERNEL); | 1048 | data->slaves, GFP_KERNEL); |
739 | if (!data->slave_data) { | 1049 | if (!data->slave_data) { |
@@ -799,6 +1109,13 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
799 | } | 1109 | } |
800 | data->hw_stats_reg_ofs = prop; | 1110 | data->hw_stats_reg_ofs = prop; |
801 | 1111 | ||
1112 | if (of_property_read_u32(node, "cpts_reg_ofs", &prop)) { | ||
1113 | pr_err("Missing cpts_reg_ofs property in the DT.\n"); | ||
1114 | ret = -EINVAL; | ||
1115 | goto error_ret; | ||
1116 | } | ||
1117 | data->cpts_reg_ofs = prop; | ||
1118 | |||
802 | if (of_property_read_u32(node, "bd_ram_ofs", &prop)) { | 1119 | if (of_property_read_u32(node, "bd_ram_ofs", &prop)) { |
803 | pr_err("Missing bd_ram_ofs property in the DT.\n"); | 1120 | pr_err("Missing bd_ram_ofs property in the DT.\n"); |
804 | ret = -EINVAL; | 1121 | ret = -EINVAL; |
@@ -935,14 +1252,12 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
935 | ret = -ENOENT; | 1252 | ret = -ENOENT; |
936 | goto clean_clk_ret; | 1253 | goto clean_clk_ret; |
937 | } | 1254 | } |
938 | |||
939 | if (!request_mem_region(priv->cpsw_res->start, | 1255 | if (!request_mem_region(priv->cpsw_res->start, |
940 | resource_size(priv->cpsw_res), ndev->name)) { | 1256 | resource_size(priv->cpsw_res), ndev->name)) { |
941 | dev_err(priv->dev, "failed request i/o region\n"); | 1257 | dev_err(priv->dev, "failed request i/o region\n"); |
942 | ret = -ENXIO; | 1258 | ret = -ENXIO; |
943 | goto clean_clk_ret; | 1259 | goto clean_clk_ret; |
944 | } | 1260 | } |
945 | |||
946 | regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); | 1261 | regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); |
947 | if (!regs) { | 1262 | if (!regs) { |
948 | dev_err(priv->dev, "unable to map i/o region\n"); | 1263 | dev_err(priv->dev, "unable to map i/o region\n"); |
@@ -951,28 +1266,27 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
951 | priv->regs = regs; | 1266 | priv->regs = regs; |
952 | priv->host_port = data->host_port_num; | 1267 | priv->host_port = data->host_port_num; |
953 | priv->host_port_regs = regs + data->host_port_reg_ofs; | 1268 | priv->host_port_regs = regs + data->host_port_reg_ofs; |
1269 | priv->cpts.reg = regs + data->cpts_reg_ofs; | ||
954 | 1270 | ||
955 | priv->cpsw_ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1271 | priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
956 | if (!priv->cpsw_ss_res) { | 1272 | if (!priv->cpsw_wr_res) { |
957 | dev_err(priv->dev, "error getting i/o resource\n"); | 1273 | dev_err(priv->dev, "error getting i/o resource\n"); |
958 | ret = -ENOENT; | 1274 | ret = -ENOENT; |
959 | goto clean_clk_ret; | 1275 | goto clean_iomap_ret; |
960 | } | 1276 | } |
961 | 1277 | if (!request_mem_region(priv->cpsw_wr_res->start, | |
962 | if (!request_mem_region(priv->cpsw_ss_res->start, | 1278 | resource_size(priv->cpsw_wr_res), ndev->name)) { |
963 | resource_size(priv->cpsw_ss_res), ndev->name)) { | ||
964 | dev_err(priv->dev, "failed request i/o region\n"); | 1279 | dev_err(priv->dev, "failed request i/o region\n"); |
965 | ret = -ENXIO; | 1280 | ret = -ENXIO; |
966 | goto clean_clk_ret; | 1281 | goto clean_iomap_ret; |
967 | } | 1282 | } |
968 | 1283 | regs = ioremap(priv->cpsw_wr_res->start, | |
969 | regs = ioremap(priv->cpsw_ss_res->start, | 1284 | resource_size(priv->cpsw_wr_res)); |
970 | resource_size(priv->cpsw_ss_res)); | ||
971 | if (!regs) { | 1285 | if (!regs) { |
972 | dev_err(priv->dev, "unable to map i/o region\n"); | 1286 | dev_err(priv->dev, "unable to map i/o region\n"); |
973 | goto clean_cpsw_ss_iores_ret; | 1287 | goto clean_cpsw_wr_iores_ret; |
974 | } | 1288 | } |
975 | priv->ss_regs = regs; | 1289 | priv->wr_regs = regs; |
976 | 1290 | ||
977 | for_each_slave(priv, cpsw_slave_init, priv); | 1291 | for_each_slave(priv, cpsw_slave_init, priv); |
978 | 1292 | ||
@@ -1008,7 +1322,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
1008 | if (!priv->dma) { | 1322 | if (!priv->dma) { |
1009 | dev_err(priv->dev, "error initializing dma\n"); | 1323 | dev_err(priv->dev, "error initializing dma\n"); |
1010 | ret = -ENOMEM; | 1324 | ret = -ENOMEM; |
1011 | goto clean_iomap_ret; | 1325 | goto clean_wr_iomap_ret; |
1012 | } | 1326 | } |
1013 | 1327 | ||
1014 | priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), | 1328 | priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), |
@@ -1072,6 +1386,10 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
1072 | goto clean_irq_ret; | 1386 | goto clean_irq_ret; |
1073 | } | 1387 | } |
1074 | 1388 | ||
1389 | if (cpts_register(&pdev->dev, &priv->cpts, | ||
1390 | data->cpts_clock_mult, data->cpts_clock_shift)) | ||
1391 | dev_err(priv->dev, "error registering cpts device\n"); | ||
1392 | |||
1075 | cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n", | 1393 | cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n", |
1076 | priv->cpsw_res->start, ndev->irq); | 1394 | priv->cpsw_res->start, ndev->irq); |
1077 | 1395 | ||
@@ -1085,11 +1403,13 @@ clean_dma_ret: | |||
1085 | cpdma_chan_destroy(priv->txch); | 1403 | cpdma_chan_destroy(priv->txch); |
1086 | cpdma_chan_destroy(priv->rxch); | 1404 | cpdma_chan_destroy(priv->rxch); |
1087 | cpdma_ctlr_destroy(priv->dma); | 1405 | cpdma_ctlr_destroy(priv->dma); |
1406 | clean_wr_iomap_ret: | ||
1407 | iounmap(priv->wr_regs); | ||
1408 | clean_cpsw_wr_iores_ret: | ||
1409 | release_mem_region(priv->cpsw_wr_res->start, | ||
1410 | resource_size(priv->cpsw_wr_res)); | ||
1088 | clean_iomap_ret: | 1411 | clean_iomap_ret: |
1089 | iounmap(priv->regs); | 1412 | iounmap(priv->regs); |
1090 | clean_cpsw_ss_iores_ret: | ||
1091 | release_mem_region(priv->cpsw_ss_res->start, | ||
1092 | resource_size(priv->cpsw_ss_res)); | ||
1093 | clean_cpsw_iores_ret: | 1413 | clean_cpsw_iores_ret: |
1094 | release_mem_region(priv->cpsw_res->start, | 1414 | release_mem_region(priv->cpsw_res->start, |
1095 | resource_size(priv->cpsw_res)); | 1415 | resource_size(priv->cpsw_res)); |
@@ -1111,6 +1431,7 @@ static int __devexit cpsw_remove(struct platform_device *pdev) | |||
1111 | pr_info("removing device"); | 1431 | pr_info("removing device"); |
1112 | platform_set_drvdata(pdev, NULL); | 1432 | platform_set_drvdata(pdev, NULL); |
1113 | 1433 | ||
1434 | cpts_unregister(&priv->cpts); | ||
1114 | free_irq(ndev->irq, priv); | 1435 | free_irq(ndev->irq, priv); |
1115 | cpsw_ale_destroy(priv->ale); | 1436 | cpsw_ale_destroy(priv->ale); |
1116 | cpdma_chan_destroy(priv->txch); | 1437 | cpdma_chan_destroy(priv->txch); |
@@ -1119,8 +1440,9 @@ static int __devexit cpsw_remove(struct platform_device *pdev) | |||
1119 | iounmap(priv->regs); | 1440 | iounmap(priv->regs); |
1120 | release_mem_region(priv->cpsw_res->start, | 1441 | release_mem_region(priv->cpsw_res->start, |
1121 | resource_size(priv->cpsw_res)); | 1442 | resource_size(priv->cpsw_res)); |
1122 | release_mem_region(priv->cpsw_ss_res->start, | 1443 | iounmap(priv->wr_regs); |
1123 | resource_size(priv->cpsw_ss_res)); | 1444 | release_mem_region(priv->cpsw_wr_res->start, |
1445 | resource_size(priv->cpsw_wr_res)); | ||
1124 | pm_runtime_disable(&pdev->dev); | 1446 | pm_runtime_disable(&pdev->dev); |
1125 | clk_put(priv->clk); | 1447 | clk_put(priv->clk); |
1126 | kfree(priv->slaves); | 1448 | kfree(priv->slaves); |
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index ca0d48a7e508..0e9ccc2cf91f 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/stat.h> | 21 | #include <linux/stat.h> |
22 | #include <linux/sysfs.h> | 22 | #include <linux/sysfs.h> |
23 | #include <linux/etherdevice.h> | ||
23 | 24 | ||
24 | #include "cpsw_ale.h" | 25 | #include "cpsw_ale.h" |
25 | 26 | ||
@@ -211,10 +212,34 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, | |||
211 | mask &= ~port_mask; | 212 | mask &= ~port_mask; |
212 | 213 | ||
213 | /* free if only remaining port is host port */ | 214 | /* free if only remaining port is host port */ |
214 | if (mask == BIT(ale->params.ale_ports)) | 215 | if (mask) |
215 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | ||
216 | else | ||
217 | cpsw_ale_set_port_mask(ale_entry, mask); | 216 | cpsw_ale_set_port_mask(ale_entry, mask); |
217 | else | ||
218 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | ||
219 | } | ||
220 | |||
221 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | ||
222 | { | ||
223 | u32 ale_entry[ALE_ENTRY_WORDS]; | ||
224 | int ret, idx; | ||
225 | |||
226 | for (idx = 0; idx < ale->params.ale_entries; idx++) { | ||
227 | cpsw_ale_read(ale, idx, ale_entry); | ||
228 | ret = cpsw_ale_get_entry_type(ale_entry); | ||
229 | if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) | ||
230 | continue; | ||
231 | |||
232 | if (cpsw_ale_get_mcast(ale_entry)) { | ||
233 | u8 addr[6]; | ||
234 | |||
235 | cpsw_ale_get_addr(ale_entry, addr); | ||
236 | if (!is_broadcast_ether_addr(addr)) | ||
237 | cpsw_ale_flush_mcast(ale, ale_entry, port_mask); | ||
238 | } | ||
239 | |||
240 | cpsw_ale_write(ale, idx, ale_entry); | ||
241 | } | ||
242 | return 0; | ||
218 | } | 243 | } |
219 | 244 | ||
220 | static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry, | 245 | static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry, |
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index a95b37beb02d..2bd09cbce522 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h | |||
@@ -80,6 +80,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale); | |||
80 | 80 | ||
81 | int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout); | 81 | int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout); |
82 | int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); | 82 | int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); |
83 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask); | ||
83 | int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags); | 84 | int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags); |
84 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port); | 85 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port); |
85 | int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, | 86 | int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, |
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c new file mode 100644 index 000000000000..337766738eca --- /dev/null +++ b/drivers/net/ethernet/ti/cpts.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * TI Common Platform Time Sync | ||
3 | * | ||
4 | * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/if.h> | ||
22 | #include <linux/hrtimer.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/net_tstamp.h> | ||
25 | #include <linux/ptp_classify.h> | ||
26 | #include <linux/time.h> | ||
27 | #include <linux/uaccess.h> | ||
28 | #include <linux/workqueue.h> | ||
29 | |||
30 | #include <plat/clock.h> | ||
31 | |||
32 | #include "cpts.h" | ||
33 | |||
34 | #ifdef CONFIG_TI_CPTS | ||
35 | |||
36 | static struct sock_filter ptp_filter[] = { | ||
37 | PTP_FILTER | ||
38 | }; | ||
39 | |||
40 | #define cpts_read32(c, r) __raw_readl(&c->reg->r) | ||
41 | #define cpts_write32(c, v, r) __raw_writel(v, &c->reg->r) | ||
42 | |||
43 | static int event_expired(struct cpts_event *event) | ||
44 | { | ||
45 | return time_after(jiffies, event->tmo); | ||
46 | } | ||
47 | |||
48 | static int event_type(struct cpts_event *event) | ||
49 | { | ||
50 | return (event->high >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | ||
51 | } | ||
52 | |||
53 | static int cpts_fifo_pop(struct cpts *cpts, u32 *high, u32 *low) | ||
54 | { | ||
55 | u32 r = cpts_read32(cpts, intstat_raw); | ||
56 | |||
57 | if (r & TS_PEND_RAW) { | ||
58 | *high = cpts_read32(cpts, event_high); | ||
59 | *low = cpts_read32(cpts, event_low); | ||
60 | cpts_write32(cpts, EVENT_POP, event_pop); | ||
61 | return 0; | ||
62 | } | ||
63 | return -1; | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * Returns zero if matching event type was found. | ||
68 | */ | ||
69 | static int cpts_fifo_read(struct cpts *cpts, int match) | ||
70 | { | ||
71 | int i, type = -1; | ||
72 | u32 hi, lo; | ||
73 | struct cpts_event *event; | ||
74 | |||
75 | for (i = 0; i < CPTS_FIFO_DEPTH; i++) { | ||
76 | if (cpts_fifo_pop(cpts, &hi, &lo)) | ||
77 | break; | ||
78 | if (list_empty(&cpts->pool)) { | ||
79 | pr_err("cpts: event pool is empty\n"); | ||
80 | return -1; | ||
81 | } | ||
82 | event = list_first_entry(&cpts->pool, struct cpts_event, list); | ||
83 | event->tmo = jiffies + 2; | ||
84 | event->high = hi; | ||
85 | event->low = lo; | ||
86 | type = event_type(event); | ||
87 | switch (type) { | ||
88 | case CPTS_EV_PUSH: | ||
89 | case CPTS_EV_RX: | ||
90 | case CPTS_EV_TX: | ||
91 | list_del_init(&event->list); | ||
92 | list_add_tail(&event->list, &cpts->events); | ||
93 | break; | ||
94 | case CPTS_EV_ROLL: | ||
95 | case CPTS_EV_HALF: | ||
96 | case CPTS_EV_HW: | ||
97 | break; | ||
98 | default: | ||
99 | pr_err("cpts: unkown event type\n"); | ||
100 | break; | ||
101 | } | ||
102 | if (type == match) | ||
103 | break; | ||
104 | } | ||
105 | return type == match ? 0 : -1; | ||
106 | } | ||
107 | |||
108 | static cycle_t cpts_systim_read(const struct cyclecounter *cc) | ||
109 | { | ||
110 | u64 val = 0; | ||
111 | struct cpts_event *event; | ||
112 | struct list_head *this, *next; | ||
113 | struct cpts *cpts = container_of(cc, struct cpts, cc); | ||
114 | |||
115 | cpts_write32(cpts, TS_PUSH, ts_push); | ||
116 | if (cpts_fifo_read(cpts, CPTS_EV_PUSH)) | ||
117 | pr_err("cpts: unable to obtain a time stamp\n"); | ||
118 | |||
119 | list_for_each_safe(this, next, &cpts->events) { | ||
120 | event = list_entry(this, struct cpts_event, list); | ||
121 | if (event_type(event) == CPTS_EV_PUSH) { | ||
122 | list_del_init(&event->list); | ||
123 | list_add(&event->list, &cpts->pool); | ||
124 | val = event->low; | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | return val; | ||
130 | } | ||
131 | |||
132 | /* PTP clock operations */ | ||
133 | |||
134 | static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | ||
135 | { | ||
136 | u64 adj; | ||
137 | u32 diff, mult; | ||
138 | int neg_adj = 0; | ||
139 | unsigned long flags; | ||
140 | struct cpts *cpts = container_of(ptp, struct cpts, info); | ||
141 | |||
142 | if (ppb < 0) { | ||
143 | neg_adj = 1; | ||
144 | ppb = -ppb; | ||
145 | } | ||
146 | mult = cpts->cc_mult; | ||
147 | adj = mult; | ||
148 | adj *= ppb; | ||
149 | diff = div_u64(adj, 1000000000ULL); | ||
150 | |||
151 | spin_lock_irqsave(&cpts->lock, flags); | ||
152 | |||
153 | timecounter_read(&cpts->tc); | ||
154 | |||
155 | cpts->cc.mult = neg_adj ? mult - diff : mult + diff; | ||
156 | |||
157 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int cpts_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | ||
163 | { | ||
164 | s64 now; | ||
165 | unsigned long flags; | ||
166 | struct cpts *cpts = container_of(ptp, struct cpts, info); | ||
167 | |||
168 | spin_lock_irqsave(&cpts->lock, flags); | ||
169 | now = timecounter_read(&cpts->tc); | ||
170 | now += delta; | ||
171 | timecounter_init(&cpts->tc, &cpts->cc, now); | ||
172 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int cpts_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | ||
178 | { | ||
179 | u64 ns; | ||
180 | u32 remainder; | ||
181 | unsigned long flags; | ||
182 | struct cpts *cpts = container_of(ptp, struct cpts, info); | ||
183 | |||
184 | spin_lock_irqsave(&cpts->lock, flags); | ||
185 | ns = timecounter_read(&cpts->tc); | ||
186 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
187 | |||
188 | ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); | ||
189 | ts->tv_nsec = remainder; | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int cpts_ptp_settime(struct ptp_clock_info *ptp, | ||
195 | const struct timespec *ts) | ||
196 | { | ||
197 | u64 ns; | ||
198 | unsigned long flags; | ||
199 | struct cpts *cpts = container_of(ptp, struct cpts, info); | ||
200 | |||
201 | ns = ts->tv_sec * 1000000000ULL; | ||
202 | ns += ts->tv_nsec; | ||
203 | |||
204 | spin_lock_irqsave(&cpts->lock, flags); | ||
205 | timecounter_init(&cpts->tc, &cpts->cc, ns); | ||
206 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static int cpts_ptp_enable(struct ptp_clock_info *ptp, | ||
212 | struct ptp_clock_request *rq, int on) | ||
213 | { | ||
214 | return -EOPNOTSUPP; | ||
215 | } | ||
216 | |||
217 | static struct ptp_clock_info cpts_info = { | ||
218 | .owner = THIS_MODULE, | ||
219 | .name = "CTPS timer", | ||
220 | .max_adj = 1000000, | ||
221 | .n_ext_ts = 0, | ||
222 | .pps = 0, | ||
223 | .adjfreq = cpts_ptp_adjfreq, | ||
224 | .adjtime = cpts_ptp_adjtime, | ||
225 | .gettime = cpts_ptp_gettime, | ||
226 | .settime = cpts_ptp_settime, | ||
227 | .enable = cpts_ptp_enable, | ||
228 | }; | ||
229 | |||
230 | static void cpts_overflow_check(struct work_struct *work) | ||
231 | { | ||
232 | struct timespec ts; | ||
233 | struct cpts *cpts = container_of(work, struct cpts, overflow_work.work); | ||
234 | |||
235 | cpts_write32(cpts, CPTS_EN, control); | ||
236 | cpts_write32(cpts, TS_PEND_EN, int_enable); | ||
237 | cpts_ptp_gettime(&cpts->info, &ts); | ||
238 | pr_debug("cpts overflow check at %ld.%09lu\n", ts.tv_sec, ts.tv_nsec); | ||
239 | schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD); | ||
240 | } | ||
241 | |||
242 | #define CPTS_REF_CLOCK_NAME "cpsw_cpts_rft_clk" | ||
243 | |||
244 | static void cpts_clk_init(struct cpts *cpts) | ||
245 | { | ||
246 | cpts->refclk = clk_get(NULL, CPTS_REF_CLOCK_NAME); | ||
247 | if (IS_ERR(cpts->refclk)) { | ||
248 | pr_err("Failed to clk_get %s\n", CPTS_REF_CLOCK_NAME); | ||
249 | cpts->refclk = NULL; | ||
250 | return; | ||
251 | } | ||
252 | clk_enable(cpts->refclk); | ||
253 | cpts->freq = cpts->refclk->recalc(cpts->refclk); | ||
254 | } | ||
255 | |||
256 | static void cpts_clk_release(struct cpts *cpts) | ||
257 | { | ||
258 | clk_disable(cpts->refclk); | ||
259 | clk_put(cpts->refclk); | ||
260 | } | ||
261 | |||
262 | static int cpts_match(struct sk_buff *skb, unsigned int ptp_class, | ||
263 | u16 ts_seqid, u8 ts_msgtype) | ||
264 | { | ||
265 | u16 *seqid; | ||
266 | unsigned int offset; | ||
267 | u8 *msgtype, *data = skb->data; | ||
268 | |||
269 | switch (ptp_class) { | ||
270 | case PTP_CLASS_V1_IPV4: | ||
271 | case PTP_CLASS_V2_IPV4: | ||
272 | offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN; | ||
273 | break; | ||
274 | case PTP_CLASS_V1_IPV6: | ||
275 | case PTP_CLASS_V2_IPV6: | ||
276 | offset = OFF_PTP6; | ||
277 | break; | ||
278 | case PTP_CLASS_V2_L2: | ||
279 | offset = ETH_HLEN; | ||
280 | break; | ||
281 | case PTP_CLASS_V2_VLAN: | ||
282 | offset = ETH_HLEN + VLAN_HLEN; | ||
283 | break; | ||
284 | default: | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid)) | ||
289 | return 0; | ||
290 | |||
291 | if (unlikely(ptp_class & PTP_CLASS_V1)) | ||
292 | msgtype = data + offset + OFF_PTP_CONTROL; | ||
293 | else | ||
294 | msgtype = data + offset; | ||
295 | |||
296 | seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); | ||
297 | |||
298 | return (ts_msgtype == (*msgtype & 0xf) && ts_seqid == ntohs(*seqid)); | ||
299 | } | ||
300 | |||
301 | static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type) | ||
302 | { | ||
303 | u64 ns = 0; | ||
304 | struct cpts_event *event; | ||
305 | struct list_head *this, *next; | ||
306 | unsigned int class = sk_run_filter(skb, ptp_filter); | ||
307 | unsigned long flags; | ||
308 | u16 seqid; | ||
309 | u8 mtype; | ||
310 | |||
311 | if (class == PTP_CLASS_NONE) | ||
312 | return 0; | ||
313 | |||
314 | spin_lock_irqsave(&cpts->lock, flags); | ||
315 | cpts_fifo_read(cpts, CPTS_EV_PUSH); | ||
316 | list_for_each_safe(this, next, &cpts->events) { | ||
317 | event = list_entry(this, struct cpts_event, list); | ||
318 | if (event_expired(event)) { | ||
319 | list_del_init(&event->list); | ||
320 | list_add(&event->list, &cpts->pool); | ||
321 | continue; | ||
322 | } | ||
323 | mtype = (event->high >> MESSAGE_TYPE_SHIFT) & MESSAGE_TYPE_MASK; | ||
324 | seqid = (event->high >> SEQUENCE_ID_SHIFT) & SEQUENCE_ID_MASK; | ||
325 | if (ev_type == event_type(event) && | ||
326 | cpts_match(skb, class, seqid, mtype)) { | ||
327 | ns = timecounter_cyc2time(&cpts->tc, event->low); | ||
328 | list_del_init(&event->list); | ||
329 | list_add(&event->list, &cpts->pool); | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
334 | |||
335 | return ns; | ||
336 | } | ||
337 | |||
338 | void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb) | ||
339 | { | ||
340 | u64 ns; | ||
341 | struct skb_shared_hwtstamps *ssh; | ||
342 | |||
343 | if (!cpts->rx_enable) | ||
344 | return; | ||
345 | ns = cpts_find_ts(cpts, skb, CPTS_EV_RX); | ||
346 | if (!ns) | ||
347 | return; | ||
348 | ssh = skb_hwtstamps(skb); | ||
349 | memset(ssh, 0, sizeof(*ssh)); | ||
350 | ssh->hwtstamp = ns_to_ktime(ns); | ||
351 | } | ||
352 | |||
353 | void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb) | ||
354 | { | ||
355 | u64 ns; | ||
356 | struct skb_shared_hwtstamps ssh; | ||
357 | |||
358 | if (!(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) | ||
359 | return; | ||
360 | ns = cpts_find_ts(cpts, skb, CPTS_EV_TX); | ||
361 | if (!ns) | ||
362 | return; | ||
363 | memset(&ssh, 0, sizeof(ssh)); | ||
364 | ssh.hwtstamp = ns_to_ktime(ns); | ||
365 | skb_tstamp_tx(skb, &ssh); | ||
366 | } | ||
367 | |||
368 | #endif /*CONFIG_TI_CPTS*/ | ||
369 | |||
370 | int cpts_register(struct device *dev, struct cpts *cpts, | ||
371 | u32 mult, u32 shift) | ||
372 | { | ||
373 | #ifdef CONFIG_TI_CPTS | ||
374 | int err, i; | ||
375 | unsigned long flags; | ||
376 | |||
377 | if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) { | ||
378 | pr_err("cpts: bad ptp filter\n"); | ||
379 | return -EINVAL; | ||
380 | } | ||
381 | cpts->info = cpts_info; | ||
382 | cpts->clock = ptp_clock_register(&cpts->info, dev); | ||
383 | if (IS_ERR(cpts->clock)) { | ||
384 | err = PTR_ERR(cpts->clock); | ||
385 | cpts->clock = NULL; | ||
386 | return err; | ||
387 | } | ||
388 | spin_lock_init(&cpts->lock); | ||
389 | |||
390 | cpts->cc.read = cpts_systim_read; | ||
391 | cpts->cc.mask = CLOCKSOURCE_MASK(32); | ||
392 | cpts->cc_mult = mult; | ||
393 | cpts->cc.mult = mult; | ||
394 | cpts->cc.shift = shift; | ||
395 | |||
396 | INIT_LIST_HEAD(&cpts->events); | ||
397 | INIT_LIST_HEAD(&cpts->pool); | ||
398 | for (i = 0; i < CPTS_MAX_EVENTS; i++) | ||
399 | list_add(&cpts->pool_data[i].list, &cpts->pool); | ||
400 | |||
401 | cpts_clk_init(cpts); | ||
402 | cpts_write32(cpts, CPTS_EN, control); | ||
403 | cpts_write32(cpts, TS_PEND_EN, int_enable); | ||
404 | |||
405 | spin_lock_irqsave(&cpts->lock, flags); | ||
406 | timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real())); | ||
407 | spin_unlock_irqrestore(&cpts->lock, flags); | ||
408 | |||
409 | INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check); | ||
410 | schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD); | ||
411 | |||
412 | cpts->phc_index = ptp_clock_index(cpts->clock); | ||
413 | #endif | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | void cpts_unregister(struct cpts *cpts) | ||
418 | { | ||
419 | #ifdef CONFIG_TI_CPTS | ||
420 | if (cpts->clock) { | ||
421 | ptp_clock_unregister(cpts->clock); | ||
422 | cancel_delayed_work_sync(&cpts->overflow_work); | ||
423 | } | ||
424 | if (cpts->refclk) | ||
425 | cpts_clk_release(cpts); | ||
426 | #endif | ||
427 | } | ||
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h new file mode 100644 index 000000000000..e1bba3a496b2 --- /dev/null +++ b/drivers/net/ethernet/ti/cpts.h | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * TI Common Platform Time Sync | ||
3 | * | ||
4 | * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #ifndef _TI_CPTS_H_ | ||
21 | #define _TI_CPTS_H_ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | #include <linux/clocksource.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/ptp_clock_kernel.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | |||
31 | struct cpsw_cpts { | ||
32 | u32 idver; /* Identification and version */ | ||
33 | u32 control; /* Time sync control */ | ||
34 | u32 res1; | ||
35 | u32 ts_push; /* Time stamp event push */ | ||
36 | u32 ts_load_val; /* Time stamp load value */ | ||
37 | u32 ts_load_en; /* Time stamp load enable */ | ||
38 | u32 res2[2]; | ||
39 | u32 intstat_raw; /* Time sync interrupt status raw */ | ||
40 | u32 intstat_masked; /* Time sync interrupt status masked */ | ||
41 | u32 int_enable; /* Time sync interrupt enable */ | ||
42 | u32 res3; | ||
43 | u32 event_pop; /* Event interrupt pop */ | ||
44 | u32 event_low; /* 32 Bit Event Time Stamp */ | ||
45 | u32 event_high; /* Event Type Fields */ | ||
46 | }; | ||
47 | |||
48 | /* Bit definitions for the IDVER register */ | ||
49 | #define TX_IDENT_SHIFT (16) /* TX Identification Value */ | ||
50 | #define TX_IDENT_MASK (0xffff) | ||
51 | #define RTL_VER_SHIFT (11) /* RTL Version Value */ | ||
52 | #define RTL_VER_MASK (0x1f) | ||
53 | #define MAJOR_VER_SHIFT (8) /* Major Version Value */ | ||
54 | #define MAJOR_VER_MASK (0x7) | ||
55 | #define MINOR_VER_SHIFT (0) /* Minor Version Value */ | ||
56 | #define MINOR_VER_MASK (0xff) | ||
57 | |||
58 | /* Bit definitions for the CONTROL register */ | ||
59 | #define HW4_TS_PUSH_EN (1<<11) /* Hardware push 4 enable */ | ||
60 | #define HW3_TS_PUSH_EN (1<<10) /* Hardware push 3 enable */ | ||
61 | #define HW2_TS_PUSH_EN (1<<9) /* Hardware push 2 enable */ | ||
62 | #define HW1_TS_PUSH_EN (1<<8) /* Hardware push 1 enable */ | ||
63 | #define INT_TEST (1<<1) /* Interrupt Test */ | ||
64 | #define CPTS_EN (1<<0) /* Time Sync Enable */ | ||
65 | |||
66 | /* | ||
67 | * Definitions for the single bit resisters: | ||
68 | * TS_PUSH TS_LOAD_EN INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP | ||
69 | */ | ||
70 | #define TS_PUSH (1<<0) /* Time stamp event push */ | ||
71 | #define TS_LOAD_EN (1<<0) /* Time Stamp Load */ | ||
72 | #define TS_PEND_RAW (1<<0) /* int read (before enable) */ | ||
73 | #define TS_PEND (1<<0) /* masked interrupt read (after enable) */ | ||
74 | #define TS_PEND_EN (1<<0) /* masked interrupt enable */ | ||
75 | #define EVENT_POP (1<<0) /* writing discards one event */ | ||
76 | |||
77 | /* Bit definitions for the EVENT_HIGH register */ | ||
78 | #define PORT_NUMBER_SHIFT (24) /* Indicates Ethernet port or HW pin */ | ||
79 | #define PORT_NUMBER_MASK (0x1f) | ||
80 | #define EVENT_TYPE_SHIFT (20) /* Time sync event type */ | ||
81 | #define EVENT_TYPE_MASK (0xf) | ||
82 | #define MESSAGE_TYPE_SHIFT (16) /* PTP message type */ | ||
83 | #define MESSAGE_TYPE_MASK (0xf) | ||
84 | #define SEQUENCE_ID_SHIFT (0) /* PTP message sequence ID */ | ||
85 | #define SEQUENCE_ID_MASK (0xffff) | ||
86 | |||
87 | enum { | ||
88 | CPTS_EV_PUSH, /* Time Stamp Push Event */ | ||
89 | CPTS_EV_ROLL, /* Time Stamp Rollover Event */ | ||
90 | CPTS_EV_HALF, /* Time Stamp Half Rollover Event */ | ||
91 | CPTS_EV_HW, /* Hardware Time Stamp Push Event */ | ||
92 | CPTS_EV_RX, /* Ethernet Receive Event */ | ||
93 | CPTS_EV_TX, /* Ethernet Transmit Event */ | ||
94 | }; | ||
95 | |||
96 | /* This covers any input clock up to about 500 MHz. */ | ||
97 | #define CPTS_OVERFLOW_PERIOD (HZ * 8) | ||
98 | |||
99 | #define CPTS_FIFO_DEPTH 16 | ||
100 | #define CPTS_MAX_EVENTS 32 | ||
101 | |||
102 | struct cpts_event { | ||
103 | struct list_head list; | ||
104 | unsigned long tmo; | ||
105 | u32 high; | ||
106 | u32 low; | ||
107 | }; | ||
108 | |||
109 | struct cpts { | ||
110 | struct cpsw_cpts __iomem *reg; | ||
111 | int tx_enable; | ||
112 | int rx_enable; | ||
113 | #ifdef CONFIG_TI_CPTS | ||
114 | struct ptp_clock_info info; | ||
115 | struct ptp_clock *clock; | ||
116 | spinlock_t lock; /* protects time registers */ | ||
117 | u32 cc_mult; /* for the nominal frequency */ | ||
118 | struct cyclecounter cc; | ||
119 | struct timecounter tc; | ||
120 | struct delayed_work overflow_work; | ||
121 | int phc_index; | ||
122 | struct clk *refclk; | ||
123 | unsigned long freq; | ||
124 | struct list_head events; | ||
125 | struct list_head pool; | ||
126 | struct cpts_event pool_data[CPTS_MAX_EVENTS]; | ||
127 | #endif | ||
128 | }; | ||
129 | |||
130 | #ifdef CONFIG_TI_CPTS | ||
131 | extern void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb); | ||
132 | extern void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb); | ||
133 | #else | ||
134 | static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb) | ||
135 | { | ||
136 | } | ||
137 | static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb) | ||
138 | { | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | extern int cpts_register(struct device *dev, struct cpts *cpts, | ||
143 | u32 mult, u32 shift); | ||
144 | extern void cpts_unregister(struct cpts *cpts); | ||
145 | |||
146 | #endif | ||
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 928148cc3220..7fdeb528133d 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -363,11 +363,6 @@ static void rndis_filter_receive_data(struct rndis_device *dev, | |||
363 | 363 | ||
364 | rndis_pkt = &msg->msg.pkt; | 364 | rndis_pkt = &msg->msg.pkt; |
365 | 365 | ||
366 | /* | ||
367 | * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this | ||
368 | * netvsc packet (ie TotalDataBufferLength != MessageLength) | ||
369 | */ | ||
370 | |||
371 | /* Remove the rndis header and pass it back up the stack */ | 366 | /* Remove the rndis header and pass it back up the stack */ |
372 | data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; | 367 | data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; |
373 | 368 | ||
diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c index 4b746d9bd8e7..945360a99cb4 100644 --- a/drivers/net/irda/sh_irda.c +++ b/drivers/net/irda/sh_irda.c | |||
@@ -33,11 +33,7 @@ | |||
33 | 33 | ||
34 | #define DRIVER_NAME "sh_irda" | 34 | #define DRIVER_NAME "sh_irda" |
35 | 35 | ||
36 | #if defined(CONFIG_ARCH_SH7367) || defined(CONFIG_ARCH_SH7377) | ||
37 | #define __IRDARAM_LEN 0x13FF | ||
38 | #else | ||
39 | #define __IRDARAM_LEN 0x1039 | 36 | #define __IRDARAM_LEN 0x1039 |
40 | #endif | ||
41 | 37 | ||
42 | #define IRTMR 0x1F00 /* Transfer mode */ | 38 | #define IRTMR 0x1F00 /* Transfer mode */ |
43 | #define IRCFR 0x1F02 /* Configuration */ | 39 | #define IRCFR 0x1F02 /* Configuration */ |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index b3321129a83c..6989ebe2bc79 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -56,6 +56,10 @@ static char config[MAX_PARAM_LENGTH]; | |||
56 | module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0); | 56 | module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0); |
57 | MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]"); | 57 | MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]"); |
58 | 58 | ||
59 | static bool oops_only = false; | ||
60 | module_param(oops_only, bool, 0600); | ||
61 | MODULE_PARM_DESC(oops_only, "Only log oops messages"); | ||
62 | |||
59 | #ifndef MODULE | 63 | #ifndef MODULE |
60 | static int __init option_setup(char *opt) | 64 | static int __init option_setup(char *opt) |
61 | { | 65 | { |
@@ -683,6 +687,8 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
683 | struct netconsole_target *nt; | 687 | struct netconsole_target *nt; |
684 | const char *tmp; | 688 | const char *tmp; |
685 | 689 | ||
690 | if (oops_only && !oops_in_progress) | ||
691 | return; | ||
686 | /* Avoid taking lock and disabling interrupts unnecessarily */ | 692 | /* Avoid taking lock and disabling interrupts unnecessarily */ |
687 | if (list_empty(&target_list)) | 693 | if (list_empty(&target_list)) |
688 | return; | 694 | return; |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index c1ef3000ea60..044b5326459f 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -431,10 +431,24 @@ static struct dev_pm_ops mdio_bus_pm_ops = { | |||
431 | 431 | ||
432 | #endif /* CONFIG_PM */ | 432 | #endif /* CONFIG_PM */ |
433 | 433 | ||
434 | static ssize_t | ||
435 | phy_id_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
436 | { | ||
437 | struct phy_device *phydev = to_phy_device(dev); | ||
438 | |||
439 | return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id); | ||
440 | } | ||
441 | |||
442 | static struct device_attribute mdio_dev_attrs[] = { | ||
443 | __ATTR_RO(phy_id), | ||
444 | __ATTR_NULL | ||
445 | }; | ||
446 | |||
434 | struct bus_type mdio_bus_type = { | 447 | struct bus_type mdio_bus_type = { |
435 | .name = "mdio_bus", | 448 | .name = "mdio_bus", |
436 | .match = mdio_bus_match, | 449 | .match = mdio_bus_match, |
437 | .pm = MDIO_BUS_PM_OPS, | 450 | .pm = MDIO_BUS_PM_OPS, |
451 | .dev_attrs = mdio_dev_attrs, | ||
438 | }; | 452 | }; |
439 | EXPORT_SYMBOL(mdio_bus_type); | 453 | EXPORT_SYMBOL(mdio_bus_type); |
440 | 454 | ||
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index eb3f5cefeba3..0b2706abe3e3 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
@@ -1034,7 +1034,7 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1034 | return err; | 1034 | return err; |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | struct rtnl_link_stats64* | 1037 | static struct rtnl_link_stats64* |
1038 | ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) | 1038 | ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) |
1039 | { | 1039 | { |
1040 | struct ppp *ppp = netdev_priv(dev); | 1040 | struct ppp *ppp = netdev_priv(dev); |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 0873cdcf39be..b44d7b79cddc 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -68,7 +68,6 @@ | |||
68 | #include <net/netns/generic.h> | 68 | #include <net/netns/generic.h> |
69 | #include <net/rtnetlink.h> | 69 | #include <net/rtnetlink.h> |
70 | #include <net/sock.h> | 70 | #include <net/sock.h> |
71 | #include <net/cls_cgroup.h> | ||
72 | 71 | ||
73 | #include <asm/uaccess.h> | 72 | #include <asm/uaccess.h> |
74 | 73 | ||
@@ -110,16 +109,56 @@ struct tap_filter { | |||
110 | unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; | 109 | unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; |
111 | }; | 110 | }; |
112 | 111 | ||
112 | /* 1024 is probably a high enough limit: modern hypervisors seem to support on | ||
113 | * the order of 100-200 CPUs so this leaves us some breathing space if we want | ||
114 | * to match a queue per guest CPU. | ||
115 | */ | ||
116 | #define MAX_TAP_QUEUES 1024 | ||
117 | |||
118 | #define TUN_FLOW_EXPIRE (3 * HZ) | ||
119 | |||
120 | /* A tun_file connects an open character device to a tuntap netdevice. It | ||
121 | * also contains all socket related strctures (except sock_fprog and tap_filter) | ||
122 | * to serve as one transmit queue for tuntap device. The sock_fprog and | ||
123 | * tap_filter were kept in tun_struct since they were used for filtering for the | ||
124 | * netdevice not for a specific queue (at least I didn't see the reqirement for | ||
125 | * this). | ||
126 | * | ||
127 | * RCU usage: | ||
128 | * The tun_file and tun_struct are loosely coupled, the pointer from on to the | ||
129 | * other can only be read while rcu_read_lock or rtnl_lock is held. | ||
130 | */ | ||
113 | struct tun_file { | 131 | struct tun_file { |
114 | atomic_t count; | 132 | struct sock sk; |
115 | struct tun_struct *tun; | 133 | struct socket socket; |
134 | struct socket_wq wq; | ||
135 | struct tun_struct __rcu *tun; | ||
116 | struct net *net; | 136 | struct net *net; |
137 | struct fasync_struct *fasync; | ||
138 | /* only used for fasnyc */ | ||
139 | unsigned int flags; | ||
140 | u16 queue_index; | ||
141 | }; | ||
142 | |||
143 | struct tun_flow_entry { | ||
144 | struct hlist_node hash_link; | ||
145 | struct rcu_head rcu; | ||
146 | struct tun_struct *tun; | ||
147 | |||
148 | u32 rxhash; | ||
149 | int queue_index; | ||
150 | unsigned long updated; | ||
117 | }; | 151 | }; |
118 | 152 | ||
119 | struct tun_sock; | 153 | #define TUN_NUM_FLOW_ENTRIES 1024 |
120 | 154 | ||
155 | /* Since the socket were moved to tun_file, to preserve the behavior of persist | ||
156 | * device, socket fileter, sndbuf and vnet header size were restore when the | ||
157 | * file were attached to a persist device. | ||
158 | */ | ||
121 | struct tun_struct { | 159 | struct tun_struct { |
122 | struct tun_file *tfile; | 160 | struct tun_file __rcu *tfiles[MAX_TAP_QUEUES]; |
161 | unsigned int numqueues; | ||
123 | unsigned int flags; | 162 | unsigned int flags; |
124 | kuid_t owner; | 163 | kuid_t owner; |
125 | kgid_t group; | 164 | kgid_t group; |
@@ -128,88 +167,351 @@ struct tun_struct { | |||
128 | netdev_features_t set_features; | 167 | netdev_features_t set_features; |
129 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ | 168 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ |
130 | NETIF_F_TSO6|NETIF_F_UFO) | 169 | NETIF_F_TSO6|NETIF_F_UFO) |
131 | struct fasync_struct *fasync; | ||
132 | |||
133 | struct tap_filter txflt; | ||
134 | struct socket socket; | ||
135 | struct socket_wq wq; | ||
136 | 170 | ||
137 | int vnet_hdr_sz; | 171 | int vnet_hdr_sz; |
138 | 172 | int sndbuf; | |
173 | struct tap_filter txflt; | ||
174 | struct sock_fprog fprog; | ||
175 | /* protected by rtnl lock */ | ||
176 | bool filter_attached; | ||
139 | #ifdef TUN_DEBUG | 177 | #ifdef TUN_DEBUG |
140 | int debug; | 178 | int debug; |
141 | #endif | 179 | #endif |
180 | spinlock_t lock; | ||
181 | struct kmem_cache *flow_cache; | ||
182 | struct hlist_head flows[TUN_NUM_FLOW_ENTRIES]; | ||
183 | struct timer_list flow_gc_timer; | ||
184 | unsigned long ageing_time; | ||
142 | }; | 185 | }; |
143 | 186 | ||
144 | struct tun_sock { | 187 | static inline u32 tun_hashfn(u32 rxhash) |
145 | struct sock sk; | 188 | { |
146 | struct tun_struct *tun; | 189 | return rxhash & 0x3ff; |
147 | }; | 190 | } |
148 | 191 | ||
149 | static inline struct tun_sock *tun_sk(struct sock *sk) | 192 | static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash) |
150 | { | 193 | { |
151 | return container_of(sk, struct tun_sock, sk); | 194 | struct tun_flow_entry *e; |
195 | struct hlist_node *n; | ||
196 | |||
197 | hlist_for_each_entry_rcu(e, n, head, hash_link) { | ||
198 | if (e->rxhash == rxhash) | ||
199 | return e; | ||
200 | } | ||
201 | return NULL; | ||
152 | } | 202 | } |
153 | 203 | ||
154 | static int tun_attach(struct tun_struct *tun, struct file *file) | 204 | static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, |
205 | struct hlist_head *head, | ||
206 | u32 rxhash, u16 queue_index) | ||
155 | { | 207 | { |
156 | struct tun_file *tfile = file->private_data; | 208 | struct tun_flow_entry *e = kmem_cache_alloc(tun->flow_cache, |
157 | int err; | 209 | GFP_ATOMIC); |
210 | if (e) { | ||
211 | tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", | ||
212 | rxhash, queue_index); | ||
213 | e->updated = jiffies; | ||
214 | e->rxhash = rxhash; | ||
215 | e->queue_index = queue_index; | ||
216 | e->tun = tun; | ||
217 | hlist_add_head_rcu(&e->hash_link, head); | ||
218 | } | ||
219 | return e; | ||
220 | } | ||
158 | 221 | ||
159 | ASSERT_RTNL(); | 222 | static void tun_flow_free(struct rcu_head *head) |
223 | { | ||
224 | struct tun_flow_entry *e | ||
225 | = container_of(head, struct tun_flow_entry, rcu); | ||
226 | kmem_cache_free(e->tun->flow_cache, e); | ||
227 | } | ||
160 | 228 | ||
161 | netif_tx_lock_bh(tun->dev); | 229 | static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) |
230 | { | ||
231 | tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", | ||
232 | e->rxhash, e->queue_index); | ||
233 | hlist_del_rcu(&e->hash_link); | ||
234 | call_rcu(&e->rcu, tun_flow_free); | ||
235 | } | ||
162 | 236 | ||
163 | err = -EINVAL; | 237 | static void tun_flow_flush(struct tun_struct *tun) |
164 | if (tfile->tun) | 238 | { |
165 | goto out; | 239 | int i; |
166 | 240 | ||
167 | err = -EBUSY; | 241 | spin_lock_bh(&tun->lock); |
168 | if (tun->tfile) | 242 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { |
169 | goto out; | 243 | struct tun_flow_entry *e; |
244 | struct hlist_node *h, *n; | ||
170 | 245 | ||
171 | err = 0; | 246 | hlist_for_each_entry_safe(e, h, n, &tun->flows[i], hash_link) |
172 | tfile->tun = tun; | 247 | tun_flow_delete(tun, e); |
173 | tun->tfile = tfile; | 248 | } |
174 | tun->socket.file = file; | 249 | spin_unlock_bh(&tun->lock); |
175 | netif_carrier_on(tun->dev); | 250 | } |
176 | dev_hold(tun->dev); | ||
177 | sock_hold(tun->socket.sk); | ||
178 | atomic_inc(&tfile->count); | ||
179 | 251 | ||
180 | out: | 252 | static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index) |
181 | netif_tx_unlock_bh(tun->dev); | 253 | { |
182 | return err; | 254 | int i; |
255 | |||
256 | spin_lock_bh(&tun->lock); | ||
257 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { | ||
258 | struct tun_flow_entry *e; | ||
259 | struct hlist_node *h, *n; | ||
260 | |||
261 | hlist_for_each_entry_safe(e, h, n, &tun->flows[i], hash_link) { | ||
262 | if (e->queue_index == queue_index) | ||
263 | tun_flow_delete(tun, e); | ||
264 | } | ||
265 | } | ||
266 | spin_unlock_bh(&tun->lock); | ||
183 | } | 267 | } |
184 | 268 | ||
185 | static void __tun_detach(struct tun_struct *tun) | 269 | static void tun_flow_cleanup(unsigned long data) |
186 | { | 270 | { |
187 | /* Detach from net device */ | 271 | struct tun_struct *tun = (struct tun_struct *)data; |
188 | netif_tx_lock_bh(tun->dev); | 272 | unsigned long delay = tun->ageing_time; |
189 | netif_carrier_off(tun->dev); | 273 | unsigned long next_timer = jiffies + delay; |
190 | tun->tfile = NULL; | 274 | unsigned long count = 0; |
191 | netif_tx_unlock_bh(tun->dev); | 275 | int i; |
192 | 276 | ||
193 | /* Drop read queue */ | 277 | tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); |
194 | skb_queue_purge(&tun->socket.sk->sk_receive_queue); | 278 | |
279 | spin_lock_bh(&tun->lock); | ||
280 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { | ||
281 | struct tun_flow_entry *e; | ||
282 | struct hlist_node *h, *n; | ||
283 | |||
284 | hlist_for_each_entry_safe(e, h, n, &tun->flows[i], hash_link) { | ||
285 | unsigned long this_timer; | ||
286 | count++; | ||
287 | this_timer = e->updated + delay; | ||
288 | if (time_before_eq(this_timer, jiffies)) | ||
289 | tun_flow_delete(tun, e); | ||
290 | else if (time_before(this_timer, next_timer)) | ||
291 | next_timer = this_timer; | ||
292 | } | ||
293 | } | ||
195 | 294 | ||
196 | /* Drop the extra count on the net device */ | 295 | if (count) |
197 | dev_put(tun->dev); | 296 | mod_timer(&tun->flow_gc_timer, round_jiffies_up(next_timer)); |
297 | spin_unlock_bh(&tun->lock); | ||
298 | } | ||
299 | |||
300 | static void tun_flow_update(struct tun_struct *tun, struct sk_buff *skb, | ||
301 | u16 queue_index) | ||
302 | { | ||
303 | struct hlist_head *head; | ||
304 | struct tun_flow_entry *e; | ||
305 | unsigned long delay = tun->ageing_time; | ||
306 | u32 rxhash = skb_get_rxhash(skb); | ||
307 | |||
308 | if (!rxhash) | ||
309 | return; | ||
310 | else | ||
311 | head = &tun->flows[tun_hashfn(rxhash)]; | ||
312 | |||
313 | rcu_read_lock(); | ||
314 | |||
315 | if (tun->numqueues == 1) | ||
316 | goto unlock; | ||
317 | |||
318 | e = tun_flow_find(head, rxhash); | ||
319 | if (likely(e)) { | ||
320 | /* TODO: keep queueing to old queue until it's empty? */ | ||
321 | e->queue_index = queue_index; | ||
322 | e->updated = jiffies; | ||
323 | } else { | ||
324 | spin_lock_bh(&tun->lock); | ||
325 | if (!tun_flow_find(head, rxhash)) | ||
326 | tun_flow_create(tun, head, rxhash, queue_index); | ||
327 | |||
328 | if (!timer_pending(&tun->flow_gc_timer)) | ||
329 | mod_timer(&tun->flow_gc_timer, | ||
330 | round_jiffies_up(jiffies + delay)); | ||
331 | spin_unlock_bh(&tun->lock); | ||
332 | } | ||
333 | |||
334 | unlock: | ||
335 | rcu_read_unlock(); | ||
336 | } | ||
337 | |||
338 | /* We try to identify a flow through its rxhash first. The reason that | ||
339 | * we do not check rxq no. is becuase some cards(e.g 82599), chooses | ||
340 | * the rxq based on the txq where the last packet of the flow comes. As | ||
341 | * the userspace application move between processors, we may get a | ||
342 | * different rxq no. here. If we could not get rxhash, then we would | ||
343 | * hope the rxq no. may help here. | ||
344 | */ | ||
345 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
346 | { | ||
347 | struct tun_struct *tun = netdev_priv(dev); | ||
348 | struct tun_flow_entry *e; | ||
349 | u32 txq = 0; | ||
350 | u32 numqueues = 0; | ||
351 | |||
352 | rcu_read_lock(); | ||
353 | numqueues = tun->numqueues; | ||
354 | |||
355 | txq = skb_get_rxhash(skb); | ||
356 | if (txq) { | ||
357 | e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); | ||
358 | if (e) | ||
359 | txq = e->queue_index; | ||
360 | else | ||
361 | /* use multiply and shift instead of expensive divide */ | ||
362 | txq = ((u64)txq * numqueues) >> 32; | ||
363 | } else if (likely(skb_rx_queue_recorded(skb))) { | ||
364 | txq = skb_get_rx_queue(skb); | ||
365 | while (unlikely(txq >= numqueues)) | ||
366 | txq -= numqueues; | ||
367 | } | ||
368 | |||
369 | rcu_read_unlock(); | ||
370 | return txq; | ||
371 | } | ||
372 | |||
373 | static inline bool tun_not_capable(struct tun_struct *tun) | ||
374 | { | ||
375 | const struct cred *cred = current_cred(); | ||
376 | |||
377 | return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || | ||
378 | (gid_valid(tun->group) && !in_egroup_p(tun->group))) && | ||
379 | !capable(CAP_NET_ADMIN); | ||
380 | } | ||
381 | |||
382 | static void tun_set_real_num_queues(struct tun_struct *tun) | ||
383 | { | ||
384 | netif_set_real_num_tx_queues(tun->dev, tun->numqueues); | ||
385 | netif_set_real_num_rx_queues(tun->dev, tun->numqueues); | ||
386 | } | ||
387 | |||
388 | static void __tun_detach(struct tun_file *tfile, bool clean) | ||
389 | { | ||
390 | struct tun_file *ntfile; | ||
391 | struct tun_struct *tun; | ||
392 | struct net_device *dev; | ||
393 | |||
394 | tun = rcu_dereference_protected(tfile->tun, | ||
395 | lockdep_rtnl_is_held()); | ||
396 | if (tun) { | ||
397 | u16 index = tfile->queue_index; | ||
398 | BUG_ON(index >= tun->numqueues); | ||
399 | dev = tun->dev; | ||
400 | |||
401 | rcu_assign_pointer(tun->tfiles[index], | ||
402 | tun->tfiles[tun->numqueues - 1]); | ||
403 | rcu_assign_pointer(tfile->tun, NULL); | ||
404 | ntfile = rcu_dereference_protected(tun->tfiles[index], | ||
405 | lockdep_rtnl_is_held()); | ||
406 | ntfile->queue_index = index; | ||
407 | |||
408 | --tun->numqueues; | ||
409 | sock_put(&tfile->sk); | ||
410 | |||
411 | synchronize_net(); | ||
412 | tun_flow_delete_by_queue(tun, tun->numqueues + 1); | ||
413 | /* Drop read queue */ | ||
414 | skb_queue_purge(&tfile->sk.sk_receive_queue); | ||
415 | tun_set_real_num_queues(tun); | ||
416 | |||
417 | if (tun->numqueues == 0 && !(tun->flags & TUN_PERSIST)) | ||
418 | if (dev->reg_state == NETREG_REGISTERED) | ||
419 | unregister_netdevice(dev); | ||
420 | } | ||
421 | |||
422 | if (clean) { | ||
423 | BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, | ||
424 | &tfile->socket.flags)); | ||
425 | sk_release_kernel(&tfile->sk); | ||
426 | } | ||
198 | } | 427 | } |
199 | 428 | ||
200 | static void tun_detach(struct tun_struct *tun) | 429 | static void tun_detach(struct tun_file *tfile, bool clean) |
201 | { | 430 | { |
202 | rtnl_lock(); | 431 | rtnl_lock(); |
203 | __tun_detach(tun); | 432 | __tun_detach(tfile, clean); |
204 | rtnl_unlock(); | 433 | rtnl_unlock(); |
205 | } | 434 | } |
206 | 435 | ||
436 | static void tun_detach_all(struct net_device *dev) | ||
437 | { | ||
438 | struct tun_struct *tun = netdev_priv(dev); | ||
439 | struct tun_file *tfile; | ||
440 | int i, n = tun->numqueues; | ||
441 | |||
442 | for (i = 0; i < n; i++) { | ||
443 | tfile = rcu_dereference_protected(tun->tfiles[i], | ||
444 | lockdep_rtnl_is_held()); | ||
445 | BUG_ON(!tfile); | ||
446 | wake_up_all(&tfile->wq.wait); | ||
447 | rcu_assign_pointer(tfile->tun, NULL); | ||
448 | --tun->numqueues; | ||
449 | } | ||
450 | BUG_ON(tun->numqueues != 0); | ||
451 | |||
452 | synchronize_net(); | ||
453 | for (i = 0; i < n; i++) { | ||
454 | tfile = rcu_dereference_protected(tun->tfiles[i], | ||
455 | lockdep_rtnl_is_held()); | ||
456 | /* Drop read queue */ | ||
457 | skb_queue_purge(&tfile->sk.sk_receive_queue); | ||
458 | sock_put(&tfile->sk); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | static int tun_attach(struct tun_struct *tun, struct file *file) | ||
463 | { | ||
464 | struct tun_file *tfile = file->private_data; | ||
465 | int err; | ||
466 | |||
467 | err = -EINVAL; | ||
468 | if (rcu_dereference_protected(tfile->tun, lockdep_rtnl_is_held())) | ||
469 | goto out; | ||
470 | |||
471 | err = -EBUSY; | ||
472 | if (!(tun->flags & TUN_TAP_MQ) && tun->numqueues == 1) | ||
473 | goto out; | ||
474 | |||
475 | err = -E2BIG; | ||
476 | if (tun->numqueues == MAX_TAP_QUEUES) | ||
477 | goto out; | ||
478 | |||
479 | err = 0; | ||
480 | |||
481 | /* Re-attach the filter to presist device */ | ||
482 | if (tun->filter_attached == true) { | ||
483 | err = sk_attach_filter(&tun->fprog, tfile->socket.sk); | ||
484 | if (!err) | ||
485 | goto out; | ||
486 | } | ||
487 | tfile->queue_index = tun->numqueues; | ||
488 | rcu_assign_pointer(tfile->tun, tun); | ||
489 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | ||
490 | sock_hold(&tfile->sk); | ||
491 | tun->numqueues++; | ||
492 | |||
493 | tun_set_real_num_queues(tun); | ||
494 | |||
495 | if (tun->numqueues == 1) | ||
496 | netif_carrier_on(tun->dev); | ||
497 | |||
498 | /* device is allowed to go away first, so no need to hold extra | ||
499 | * refcnt. | ||
500 | */ | ||
501 | |||
502 | out: | ||
503 | return err; | ||
504 | } | ||
505 | |||
207 | static struct tun_struct *__tun_get(struct tun_file *tfile) | 506 | static struct tun_struct *__tun_get(struct tun_file *tfile) |
208 | { | 507 | { |
209 | struct tun_struct *tun = NULL; | 508 | struct tun_struct *tun; |
210 | 509 | ||
211 | if (atomic_inc_not_zero(&tfile->count)) | 510 | rcu_read_lock(); |
212 | tun = tfile->tun; | 511 | tun = rcu_dereference(tfile->tun); |
512 | if (tun) | ||
513 | dev_hold(tun->dev); | ||
514 | rcu_read_unlock(); | ||
213 | 515 | ||
214 | return tun; | 516 | return tun; |
215 | } | 517 | } |
@@ -221,10 +523,7 @@ static struct tun_struct *tun_get(struct file *file) | |||
221 | 523 | ||
222 | static void tun_put(struct tun_struct *tun) | 524 | static void tun_put(struct tun_struct *tun) |
223 | { | 525 | { |
224 | struct tun_file *tfile = tun->tfile; | 526 | dev_put(tun->dev); |
225 | |||
226 | if (atomic_dec_and_test(&tfile->count)) | ||
227 | tun_detach(tfile->tun); | ||
228 | } | 527 | } |
229 | 528 | ||
230 | /* TAP filtering */ | 529 | /* TAP filtering */ |
@@ -344,38 +643,20 @@ static const struct ethtool_ops tun_ethtool_ops; | |||
344 | /* Net device detach from fd. */ | 643 | /* Net device detach from fd. */ |
345 | static void tun_net_uninit(struct net_device *dev) | 644 | static void tun_net_uninit(struct net_device *dev) |
346 | { | 645 | { |
347 | struct tun_struct *tun = netdev_priv(dev); | 646 | tun_detach_all(dev); |
348 | struct tun_file *tfile = tun->tfile; | ||
349 | |||
350 | /* Inform the methods they need to stop using the dev. | ||
351 | */ | ||
352 | if (tfile) { | ||
353 | wake_up_all(&tun->wq.wait); | ||
354 | if (atomic_dec_and_test(&tfile->count)) | ||
355 | __tun_detach(tun); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | static void tun_free_netdev(struct net_device *dev) | ||
360 | { | ||
361 | struct tun_struct *tun = netdev_priv(dev); | ||
362 | |||
363 | BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags)); | ||
364 | |||
365 | sk_release_kernel(tun->socket.sk); | ||
366 | } | 647 | } |
367 | 648 | ||
368 | /* Net device open. */ | 649 | /* Net device open. */ |
369 | static int tun_net_open(struct net_device *dev) | 650 | static int tun_net_open(struct net_device *dev) |
370 | { | 651 | { |
371 | netif_start_queue(dev); | 652 | netif_tx_start_all_queues(dev); |
372 | return 0; | 653 | return 0; |
373 | } | 654 | } |
374 | 655 | ||
375 | /* Net device close. */ | 656 | /* Net device close. */ |
376 | static int tun_net_close(struct net_device *dev) | 657 | static int tun_net_close(struct net_device *dev) |
377 | { | 658 | { |
378 | netif_stop_queue(dev); | 659 | netif_tx_stop_all_queues(dev); |
379 | return 0; | 660 | return 0; |
380 | } | 661 | } |
381 | 662 | ||
@@ -383,28 +664,39 @@ static int tun_net_close(struct net_device *dev) | |||
383 | static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | 664 | static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) |
384 | { | 665 | { |
385 | struct tun_struct *tun = netdev_priv(dev); | 666 | struct tun_struct *tun = netdev_priv(dev); |
667 | int txq = skb->queue_mapping; | ||
668 | struct tun_file *tfile; | ||
386 | 669 | ||
387 | tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); | 670 | rcu_read_lock(); |
671 | tfile = rcu_dereference(tun->tfiles[txq]); | ||
388 | 672 | ||
389 | /* Drop packet if interface is not attached */ | 673 | /* Drop packet if interface is not attached */ |
390 | if (!tun->tfile) | 674 | if (txq >= tun->numqueues) |
391 | goto drop; | 675 | goto drop; |
392 | 676 | ||
677 | tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); | ||
678 | |||
679 | BUG_ON(!tfile); | ||
680 | |||
393 | /* Drop if the filter does not like it. | 681 | /* Drop if the filter does not like it. |
394 | * This is a noop if the filter is disabled. | 682 | * This is a noop if the filter is disabled. |
395 | * Filter can be enabled only for the TAP devices. */ | 683 | * Filter can be enabled only for the TAP devices. */ |
396 | if (!check_filter(&tun->txflt, skb)) | 684 | if (!check_filter(&tun->txflt, skb)) |
397 | goto drop; | 685 | goto drop; |
398 | 686 | ||
399 | if (tun->socket.sk->sk_filter && | 687 | if (tfile->socket.sk->sk_filter && |
400 | sk_filter(tun->socket.sk, skb)) | 688 | sk_filter(tfile->socket.sk, skb)) |
401 | goto drop; | 689 | goto drop; |
402 | 690 | ||
403 | if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) { | 691 | /* Limit the number of packets queued by divining txq length with the |
692 | * number of queues. | ||
693 | */ | ||
694 | if (skb_queue_len(&tfile->socket.sk->sk_receive_queue) | ||
695 | >= dev->tx_queue_len / tun->numqueues){ | ||
404 | if (!(tun->flags & TUN_ONE_QUEUE)) { | 696 | if (!(tun->flags & TUN_ONE_QUEUE)) { |
405 | /* Normal queueing mode. */ | 697 | /* Normal queueing mode. */ |
406 | /* Packet scheduler handles dropping of further packets. */ | 698 | /* Packet scheduler handles dropping of further packets. */ |
407 | netif_stop_queue(dev); | 699 | netif_stop_subqueue(dev, txq); |
408 | 700 | ||
409 | /* We won't see all dropped packets individually, so overrun | 701 | /* We won't see all dropped packets individually, so overrun |
410 | * error is more appropriate. */ | 702 | * error is more appropriate. */ |
@@ -423,18 +715,22 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
423 | skb_orphan(skb); | 715 | skb_orphan(skb); |
424 | 716 | ||
425 | /* Enqueue packet */ | 717 | /* Enqueue packet */ |
426 | skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); | 718 | skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb); |
427 | 719 | ||
428 | /* Notify and wake up reader process */ | 720 | /* Notify and wake up reader process */ |
429 | if (tun->flags & TUN_FASYNC) | 721 | if (tfile->flags & TUN_FASYNC) |
430 | kill_fasync(&tun->fasync, SIGIO, POLL_IN); | 722 | kill_fasync(&tfile->fasync, SIGIO, POLL_IN); |
431 | wake_up_interruptible_poll(&tun->wq.wait, POLLIN | | 723 | wake_up_interruptible_poll(&tfile->wq.wait, POLLIN | |
432 | POLLRDNORM | POLLRDBAND); | 724 | POLLRDNORM | POLLRDBAND); |
725 | |||
726 | rcu_read_unlock(); | ||
433 | return NETDEV_TX_OK; | 727 | return NETDEV_TX_OK; |
434 | 728 | ||
435 | drop: | 729 | drop: |
436 | dev->stats.tx_dropped++; | 730 | dev->stats.tx_dropped++; |
731 | skb_tx_error(skb); | ||
437 | kfree_skb(skb); | 732 | kfree_skb(skb); |
733 | rcu_read_unlock(); | ||
438 | return NETDEV_TX_OK; | 734 | return NETDEV_TX_OK; |
439 | } | 735 | } |
440 | 736 | ||
@@ -490,6 +786,7 @@ static const struct net_device_ops tun_netdev_ops = { | |||
490 | .ndo_start_xmit = tun_net_xmit, | 786 | .ndo_start_xmit = tun_net_xmit, |
491 | .ndo_change_mtu = tun_net_change_mtu, | 787 | .ndo_change_mtu = tun_net_change_mtu, |
492 | .ndo_fix_features = tun_net_fix_features, | 788 | .ndo_fix_features = tun_net_fix_features, |
789 | .ndo_select_queue = tun_select_queue, | ||
493 | #ifdef CONFIG_NET_POLL_CONTROLLER | 790 | #ifdef CONFIG_NET_POLL_CONTROLLER |
494 | .ndo_poll_controller = tun_poll_controller, | 791 | .ndo_poll_controller = tun_poll_controller, |
495 | #endif | 792 | #endif |
@@ -505,11 +802,43 @@ static const struct net_device_ops tap_netdev_ops = { | |||
505 | .ndo_set_rx_mode = tun_net_mclist, | 802 | .ndo_set_rx_mode = tun_net_mclist, |
506 | .ndo_set_mac_address = eth_mac_addr, | 803 | .ndo_set_mac_address = eth_mac_addr, |
507 | .ndo_validate_addr = eth_validate_addr, | 804 | .ndo_validate_addr = eth_validate_addr, |
805 | .ndo_select_queue = tun_select_queue, | ||
508 | #ifdef CONFIG_NET_POLL_CONTROLLER | 806 | #ifdef CONFIG_NET_POLL_CONTROLLER |
509 | .ndo_poll_controller = tun_poll_controller, | 807 | .ndo_poll_controller = tun_poll_controller, |
510 | #endif | 808 | #endif |
511 | }; | 809 | }; |
512 | 810 | ||
811 | static int tun_flow_init(struct tun_struct *tun) | ||
812 | { | ||
813 | int i; | ||
814 | |||
815 | tun->flow_cache = kmem_cache_create("tun_flow_cache", | ||
816 | sizeof(struct tun_flow_entry), 0, 0, | ||
817 | NULL); | ||
818 | if (!tun->flow_cache) | ||
819 | return -ENOMEM; | ||
820 | |||
821 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) | ||
822 | INIT_HLIST_HEAD(&tun->flows[i]); | ||
823 | |||
824 | tun->ageing_time = TUN_FLOW_EXPIRE; | ||
825 | setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun); | ||
826 | mod_timer(&tun->flow_gc_timer, | ||
827 | round_jiffies_up(jiffies + tun->ageing_time)); | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static void tun_flow_uninit(struct tun_struct *tun) | ||
833 | { | ||
834 | del_timer_sync(&tun->flow_gc_timer); | ||
835 | tun_flow_flush(tun); | ||
836 | |||
837 | /* Wait for completion of call_rcu()'s */ | ||
838 | rcu_barrier(); | ||
839 | kmem_cache_destroy(tun->flow_cache); | ||
840 | } | ||
841 | |||
513 | /* Initialize net device. */ | 842 | /* Initialize net device. */ |
514 | static void tun_net_init(struct net_device *dev) | 843 | static void tun_net_init(struct net_device *dev) |
515 | { | 844 | { |
@@ -546,7 +875,7 @@ static void tun_net_init(struct net_device *dev) | |||
546 | /* Character device part */ | 875 | /* Character device part */ |
547 | 876 | ||
548 | /* Poll */ | 877 | /* Poll */ |
549 | static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | 878 | static unsigned int tun_chr_poll(struct file *file, poll_table *wait) |
550 | { | 879 | { |
551 | struct tun_file *tfile = file->private_data; | 880 | struct tun_file *tfile = file->private_data; |
552 | struct tun_struct *tun = __tun_get(tfile); | 881 | struct tun_struct *tun = __tun_get(tfile); |
@@ -556,11 +885,11 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | |||
556 | if (!tun) | 885 | if (!tun) |
557 | return POLLERR; | 886 | return POLLERR; |
558 | 887 | ||
559 | sk = tun->socket.sk; | 888 | sk = tfile->socket.sk; |
560 | 889 | ||
561 | tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); | 890 | tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); |
562 | 891 | ||
563 | poll_wait(file, &tun->wq.wait, wait); | 892 | poll_wait(file, &tfile->wq.wait, wait); |
564 | 893 | ||
565 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 894 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
566 | mask |= POLLIN | POLLRDNORM; | 895 | mask |= POLLIN | POLLRDNORM; |
@@ -579,16 +908,14 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | |||
579 | 908 | ||
580 | /* prepad is the amount to reserve at front. len is length after that. | 909 | /* prepad is the amount to reserve at front. len is length after that. |
581 | * linear is a hint as to how much to copy (usually headers). */ | 910 | * linear is a hint as to how much to copy (usually headers). */ |
582 | static struct sk_buff *tun_alloc_skb(struct tun_struct *tun, | 911 | static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, |
583 | size_t prepad, size_t len, | 912 | size_t prepad, size_t len, |
584 | size_t linear, int noblock) | 913 | size_t linear, int noblock) |
585 | { | 914 | { |
586 | struct sock *sk = tun->socket.sk; | 915 | struct sock *sk = tfile->socket.sk; |
587 | struct sk_buff *skb; | 916 | struct sk_buff *skb; |
588 | int err; | 917 | int err; |
589 | 918 | ||
590 | sock_update_classid(sk); | ||
591 | |||
592 | /* Under a page? Don't bother with paged skb. */ | 919 | /* Under a page? Don't bother with paged skb. */ |
593 | if (prepad + len < PAGE_SIZE || !linear) | 920 | if (prepad + len < PAGE_SIZE || !linear) |
594 | linear = len; | 921 | linear = len; |
@@ -685,9 +1012,9 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
685 | } | 1012 | } |
686 | 1013 | ||
687 | /* Get packet from user space buffer */ | 1014 | /* Get packet from user space buffer */ |
688 | static ssize_t tun_get_user(struct tun_struct *tun, void *msg_control, | 1015 | static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, |
689 | const struct iovec *iv, size_t total_len, | 1016 | void *msg_control, const struct iovec *iv, |
690 | size_t count, int noblock) | 1017 | size_t total_len, size_t count, int noblock) |
691 | { | 1018 | { |
692 | struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; | 1019 | struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; |
693 | struct sk_buff *skb; | 1020 | struct sk_buff *skb; |
@@ -757,7 +1084,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, void *msg_control, | |||
757 | } else | 1084 | } else |
758 | copylen = len; | 1085 | copylen = len; |
759 | 1086 | ||
760 | skb = tun_alloc_skb(tun, align, copylen, gso.hdr_len, noblock); | 1087 | skb = tun_alloc_skb(tfile, align, copylen, gso.hdr_len, noblock); |
761 | if (IS_ERR(skb)) { | 1088 | if (IS_ERR(skb)) { |
762 | if (PTR_ERR(skb) != -EAGAIN) | 1089 | if (PTR_ERR(skb) != -EAGAIN) |
763 | tun->dev->stats.rx_dropped++; | 1090 | tun->dev->stats.rx_dropped++; |
@@ -854,6 +1181,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, void *msg_control, | |||
854 | tun->dev->stats.rx_packets++; | 1181 | tun->dev->stats.rx_packets++; |
855 | tun->dev->stats.rx_bytes += len; | 1182 | tun->dev->stats.rx_bytes += len; |
856 | 1183 | ||
1184 | tun_flow_update(tun, skb, tfile->queue_index); | ||
857 | return total_len; | 1185 | return total_len; |
858 | } | 1186 | } |
859 | 1187 | ||
@@ -862,6 +1190,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, | |||
862 | { | 1190 | { |
863 | struct file *file = iocb->ki_filp; | 1191 | struct file *file = iocb->ki_filp; |
864 | struct tun_struct *tun = tun_get(file); | 1192 | struct tun_struct *tun = tun_get(file); |
1193 | struct tun_file *tfile = file->private_data; | ||
865 | ssize_t result; | 1194 | ssize_t result; |
866 | 1195 | ||
867 | if (!tun) | 1196 | if (!tun) |
@@ -869,8 +1198,8 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, | |||
869 | 1198 | ||
870 | tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); | 1199 | tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); |
871 | 1200 | ||
872 | result = tun_get_user(tun, NULL, iv, iov_length(iv, count), count, | 1201 | result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count), |
873 | file->f_flags & O_NONBLOCK); | 1202 | count, file->f_flags & O_NONBLOCK); |
874 | 1203 | ||
875 | tun_put(tun); | 1204 | tun_put(tun); |
876 | return result; | 1205 | return result; |
@@ -878,6 +1207,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, | |||
878 | 1207 | ||
879 | /* Put packet to the user space buffer */ | 1208 | /* Put packet to the user space buffer */ |
880 | static ssize_t tun_put_user(struct tun_struct *tun, | 1209 | static ssize_t tun_put_user(struct tun_struct *tun, |
1210 | struct tun_file *tfile, | ||
881 | struct sk_buff *skb, | 1211 | struct sk_buff *skb, |
882 | const struct iovec *iv, int len) | 1212 | const struct iovec *iv, int len) |
883 | { | 1213 | { |
@@ -957,7 +1287,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
957 | return total; | 1287 | return total; |
958 | } | 1288 | } |
959 | 1289 | ||
960 | static ssize_t tun_do_read(struct tun_struct *tun, | 1290 | static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, |
961 | struct kiocb *iocb, const struct iovec *iv, | 1291 | struct kiocb *iocb, const struct iovec *iv, |
962 | ssize_t len, int noblock) | 1292 | ssize_t len, int noblock) |
963 | { | 1293 | { |
@@ -968,12 +1298,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, | |||
968 | tun_debug(KERN_INFO, tun, "tun_chr_read\n"); | 1298 | tun_debug(KERN_INFO, tun, "tun_chr_read\n"); |
969 | 1299 | ||
970 | if (unlikely(!noblock)) | 1300 | if (unlikely(!noblock)) |
971 | add_wait_queue(&tun->wq.wait, &wait); | 1301 | add_wait_queue(&tfile->wq.wait, &wait); |
972 | while (len) { | 1302 | while (len) { |
973 | current->state = TASK_INTERRUPTIBLE; | 1303 | current->state = TASK_INTERRUPTIBLE; |
974 | 1304 | ||
975 | /* Read frames from the queue */ | 1305 | /* Read frames from the queue */ |
976 | if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) { | 1306 | if (!(skb = skb_dequeue(&tfile->socket.sk->sk_receive_queue))) { |
977 | if (noblock) { | 1307 | if (noblock) { |
978 | ret = -EAGAIN; | 1308 | ret = -EAGAIN; |
979 | break; | 1309 | break; |
@@ -991,16 +1321,16 @@ static ssize_t tun_do_read(struct tun_struct *tun, | |||
991 | schedule(); | 1321 | schedule(); |
992 | continue; | 1322 | continue; |
993 | } | 1323 | } |
994 | netif_wake_queue(tun->dev); | 1324 | netif_wake_subqueue(tun->dev, tfile->queue_index); |
995 | 1325 | ||
996 | ret = tun_put_user(tun, skb, iv, len); | 1326 | ret = tun_put_user(tun, tfile, skb, iv, len); |
997 | kfree_skb(skb); | 1327 | kfree_skb(skb); |
998 | break; | 1328 | break; |
999 | } | 1329 | } |
1000 | 1330 | ||
1001 | current->state = TASK_RUNNING; | 1331 | current->state = TASK_RUNNING; |
1002 | if (unlikely(!noblock)) | 1332 | if (unlikely(!noblock)) |
1003 | remove_wait_queue(&tun->wq.wait, &wait); | 1333 | remove_wait_queue(&tfile->wq.wait, &wait); |
1004 | 1334 | ||
1005 | return ret; | 1335 | return ret; |
1006 | } | 1336 | } |
@@ -1021,13 +1351,22 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
1021 | goto out; | 1351 | goto out; |
1022 | } | 1352 | } |
1023 | 1353 | ||
1024 | ret = tun_do_read(tun, iocb, iv, len, file->f_flags & O_NONBLOCK); | 1354 | ret = tun_do_read(tun, tfile, iocb, iv, len, |
1355 | file->f_flags & O_NONBLOCK); | ||
1025 | ret = min_t(ssize_t, ret, len); | 1356 | ret = min_t(ssize_t, ret, len); |
1026 | out: | 1357 | out: |
1027 | tun_put(tun); | 1358 | tun_put(tun); |
1028 | return ret; | 1359 | return ret; |
1029 | } | 1360 | } |
1030 | 1361 | ||
1362 | static void tun_free_netdev(struct net_device *dev) | ||
1363 | { | ||
1364 | struct tun_struct *tun = netdev_priv(dev); | ||
1365 | |||
1366 | tun_flow_uninit(tun); | ||
1367 | free_netdev(dev); | ||
1368 | } | ||
1369 | |||
1031 | static void tun_setup(struct net_device *dev) | 1370 | static void tun_setup(struct net_device *dev) |
1032 | { | 1371 | { |
1033 | struct tun_struct *tun = netdev_priv(dev); | 1372 | struct tun_struct *tun = netdev_priv(dev); |
@@ -1056,7 +1395,7 @@ static struct rtnl_link_ops tun_link_ops __read_mostly = { | |||
1056 | 1395 | ||
1057 | static void tun_sock_write_space(struct sock *sk) | 1396 | static void tun_sock_write_space(struct sock *sk) |
1058 | { | 1397 | { |
1059 | struct tun_struct *tun; | 1398 | struct tun_file *tfile; |
1060 | wait_queue_head_t *wqueue; | 1399 | wait_queue_head_t *wqueue; |
1061 | 1400 | ||
1062 | if (!sock_writeable(sk)) | 1401 | if (!sock_writeable(sk)) |
@@ -1070,37 +1409,46 @@ static void tun_sock_write_space(struct sock *sk) | |||
1070 | wake_up_interruptible_sync_poll(wqueue, POLLOUT | | 1409 | wake_up_interruptible_sync_poll(wqueue, POLLOUT | |
1071 | POLLWRNORM | POLLWRBAND); | 1410 | POLLWRNORM | POLLWRBAND); |
1072 | 1411 | ||
1073 | tun = tun_sk(sk)->tun; | 1412 | tfile = container_of(sk, struct tun_file, sk); |
1074 | kill_fasync(&tun->fasync, SIGIO, POLL_OUT); | 1413 | kill_fasync(&tfile->fasync, SIGIO, POLL_OUT); |
1075 | } | ||
1076 | |||
1077 | static void tun_sock_destruct(struct sock *sk) | ||
1078 | { | ||
1079 | free_netdev(tun_sk(sk)->tun->dev); | ||
1080 | } | 1414 | } |
1081 | 1415 | ||
1082 | static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, | 1416 | static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, |
1083 | struct msghdr *m, size_t total_len) | 1417 | struct msghdr *m, size_t total_len) |
1084 | { | 1418 | { |
1085 | struct tun_struct *tun = container_of(sock, struct tun_struct, socket); | 1419 | int ret; |
1086 | return tun_get_user(tun, m->msg_control, m->msg_iov, total_len, | 1420 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); |
1087 | m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); | 1421 | struct tun_struct *tun = __tun_get(tfile); |
1422 | |||
1423 | if (!tun) | ||
1424 | return -EBADFD; | ||
1425 | ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len, | ||
1426 | m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); | ||
1427 | tun_put(tun); | ||
1428 | return ret; | ||
1088 | } | 1429 | } |
1089 | 1430 | ||
1431 | |||
1090 | static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, | 1432 | static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, |
1091 | struct msghdr *m, size_t total_len, | 1433 | struct msghdr *m, size_t total_len, |
1092 | int flags) | 1434 | int flags) |
1093 | { | 1435 | { |
1094 | struct tun_struct *tun = container_of(sock, struct tun_struct, socket); | 1436 | struct tun_file *tfile = container_of(sock, struct tun_file, socket); |
1437 | struct tun_struct *tun = __tun_get(tfile); | ||
1095 | int ret; | 1438 | int ret; |
1439 | |||
1440 | if (!tun) | ||
1441 | return -EBADFD; | ||
1442 | |||
1096 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) | 1443 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) |
1097 | return -EINVAL; | 1444 | return -EINVAL; |
1098 | ret = tun_do_read(tun, iocb, m->msg_iov, total_len, | 1445 | ret = tun_do_read(tun, tfile, iocb, m->msg_iov, total_len, |
1099 | flags & MSG_DONTWAIT); | 1446 | flags & MSG_DONTWAIT); |
1100 | if (ret > total_len) { | 1447 | if (ret > total_len) { |
1101 | m->msg_flags |= MSG_TRUNC; | 1448 | m->msg_flags |= MSG_TRUNC; |
1102 | ret = flags & MSG_TRUNC ? ret : total_len; | 1449 | ret = flags & MSG_TRUNC ? ret : total_len; |
1103 | } | 1450 | } |
1451 | tun_put(tun); | ||
1104 | return ret; | 1452 | return ret; |
1105 | } | 1453 | } |
1106 | 1454 | ||
@@ -1121,7 +1469,7 @@ static const struct proto_ops tun_socket_ops = { | |||
1121 | static struct proto tun_proto = { | 1469 | static struct proto tun_proto = { |
1122 | .name = "tun", | 1470 | .name = "tun", |
1123 | .owner = THIS_MODULE, | 1471 | .owner = THIS_MODULE, |
1124 | .obj_size = sizeof(struct tun_sock), | 1472 | .obj_size = sizeof(struct tun_file), |
1125 | }; | 1473 | }; |
1126 | 1474 | ||
1127 | static int tun_flags(struct tun_struct *tun) | 1475 | static int tun_flags(struct tun_struct *tun) |
@@ -1142,6 +1490,9 @@ static int tun_flags(struct tun_struct *tun) | |||
1142 | if (tun->flags & TUN_VNET_HDR) | 1490 | if (tun->flags & TUN_VNET_HDR) |
1143 | flags |= IFF_VNET_HDR; | 1491 | flags |= IFF_VNET_HDR; |
1144 | 1492 | ||
1493 | if (tun->flags & TUN_TAP_MQ) | ||
1494 | flags |= IFF_MULTI_QUEUE; | ||
1495 | |||
1145 | return flags; | 1496 | return flags; |
1146 | } | 1497 | } |
1147 | 1498 | ||
@@ -1178,15 +1529,13 @@ static DEVICE_ATTR(group, 0444, tun_show_group, NULL); | |||
1178 | 1529 | ||
1179 | static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | 1530 | static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) |
1180 | { | 1531 | { |
1181 | struct sock *sk; | ||
1182 | struct tun_struct *tun; | 1532 | struct tun_struct *tun; |
1533 | struct tun_file *tfile = file->private_data; | ||
1183 | struct net_device *dev; | 1534 | struct net_device *dev; |
1184 | int err; | 1535 | int err; |
1185 | 1536 | ||
1186 | dev = __dev_get_by_name(net, ifr->ifr_name); | 1537 | dev = __dev_get_by_name(net, ifr->ifr_name); |
1187 | if (dev) { | 1538 | if (dev) { |
1188 | const struct cred *cred = current_cred(); | ||
1189 | |||
1190 | if (ifr->ifr_flags & IFF_TUN_EXCL) | 1539 | if (ifr->ifr_flags & IFF_TUN_EXCL) |
1191 | return -EBUSY; | 1540 | return -EBUSY; |
1192 | if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) | 1541 | if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) |
@@ -1196,11 +1545,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1196 | else | 1545 | else |
1197 | return -EINVAL; | 1546 | return -EINVAL; |
1198 | 1547 | ||
1199 | if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || | 1548 | if (tun_not_capable(tun)) |
1200 | (gid_valid(tun->group) && !in_egroup_p(tun->group))) && | ||
1201 | !capable(CAP_NET_ADMIN)) | ||
1202 | return -EPERM; | 1549 | return -EPERM; |
1203 | err = security_tun_dev_attach(tun->socket.sk); | 1550 | err = security_tun_dev_attach(tfile->socket.sk); |
1204 | if (err < 0) | 1551 | if (err < 0) |
1205 | return err; | 1552 | return err; |
1206 | 1553 | ||
@@ -1233,8 +1580,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1233 | if (*ifr->ifr_name) | 1580 | if (*ifr->ifr_name) |
1234 | name = ifr->ifr_name; | 1581 | name = ifr->ifr_name; |
1235 | 1582 | ||
1236 | dev = alloc_netdev(sizeof(struct tun_struct), name, | 1583 | dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, |
1237 | tun_setup); | 1584 | tun_setup, |
1585 | MAX_TAP_QUEUES, MAX_TAP_QUEUES); | ||
1238 | if (!dev) | 1586 | if (!dev) |
1239 | return -ENOMEM; | 1587 | return -ENOMEM; |
1240 | 1588 | ||
@@ -1246,46 +1594,35 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1246 | tun->flags = flags; | 1594 | tun->flags = flags; |
1247 | tun->txflt.count = 0; | 1595 | tun->txflt.count = 0; |
1248 | tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); | 1596 | tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); |
1249 | set_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags); | ||
1250 | |||
1251 | err = -ENOMEM; | ||
1252 | sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto); | ||
1253 | if (!sk) | ||
1254 | goto err_free_dev; | ||
1255 | 1597 | ||
1256 | sk_change_net(sk, net); | 1598 | tun->filter_attached = false; |
1257 | tun->socket.wq = &tun->wq; | 1599 | tun->sndbuf = tfile->socket.sk->sk_sndbuf; |
1258 | init_waitqueue_head(&tun->wq.wait); | ||
1259 | tun->socket.ops = &tun_socket_ops; | ||
1260 | sock_init_data(&tun->socket, sk); | ||
1261 | sk->sk_write_space = tun_sock_write_space; | ||
1262 | sk->sk_sndbuf = INT_MAX; | ||
1263 | sock_set_flag(sk, SOCK_ZEROCOPY); | ||
1264 | 1600 | ||
1265 | tun_sk(sk)->tun = tun; | 1601 | spin_lock_init(&tun->lock); |
1266 | 1602 | ||
1267 | security_tun_dev_post_create(sk); | 1603 | security_tun_dev_post_create(&tfile->sk); |
1268 | 1604 | ||
1269 | tun_net_init(dev); | 1605 | tun_net_init(dev); |
1270 | 1606 | ||
1607 | if (tun_flow_init(tun)) | ||
1608 | goto err_free_dev; | ||
1609 | |||
1271 | dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | | 1610 | dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | |
1272 | TUN_USER_FEATURES; | 1611 | TUN_USER_FEATURES; |
1273 | dev->features = dev->hw_features; | 1612 | dev->features = dev->hw_features; |
1274 | 1613 | ||
1275 | err = register_netdevice(tun->dev); | 1614 | err = register_netdevice(tun->dev); |
1276 | if (err < 0) | 1615 | if (err < 0) |
1277 | goto err_free_sk; | 1616 | goto err_free_dev; |
1278 | 1617 | ||
1279 | if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || | 1618 | if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || |
1280 | device_create_file(&tun->dev->dev, &dev_attr_owner) || | 1619 | device_create_file(&tun->dev->dev, &dev_attr_owner) || |
1281 | device_create_file(&tun->dev->dev, &dev_attr_group)) | 1620 | device_create_file(&tun->dev->dev, &dev_attr_group)) |
1282 | pr_err("Failed to create tun sysfs files\n"); | 1621 | pr_err("Failed to create tun sysfs files\n"); |
1283 | 1622 | ||
1284 | sk->sk_destruct = tun_sock_destruct; | ||
1285 | |||
1286 | err = tun_attach(tun, file); | 1623 | err = tun_attach(tun, file); |
1287 | if (err < 0) | 1624 | if (err < 0) |
1288 | goto failed; | 1625 | goto err_free_dev; |
1289 | } | 1626 | } |
1290 | 1627 | ||
1291 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); | 1628 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); |
@@ -1305,20 +1642,22 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1305 | else | 1642 | else |
1306 | tun->flags &= ~TUN_VNET_HDR; | 1643 | tun->flags &= ~TUN_VNET_HDR; |
1307 | 1644 | ||
1645 | if (ifr->ifr_flags & IFF_MULTI_QUEUE) | ||
1646 | tun->flags |= TUN_TAP_MQ; | ||
1647 | else | ||
1648 | tun->flags &= ~TUN_TAP_MQ; | ||
1649 | |||
1308 | /* Make sure persistent devices do not get stuck in | 1650 | /* Make sure persistent devices do not get stuck in |
1309 | * xoff state. | 1651 | * xoff state. |
1310 | */ | 1652 | */ |
1311 | if (netif_running(tun->dev)) | 1653 | if (netif_running(tun->dev)) |
1312 | netif_wake_queue(tun->dev); | 1654 | netif_tx_wake_all_queues(tun->dev); |
1313 | 1655 | ||
1314 | strcpy(ifr->ifr_name, tun->dev->name); | 1656 | strcpy(ifr->ifr_name, tun->dev->name); |
1315 | return 0; | 1657 | return 0; |
1316 | 1658 | ||
1317 | err_free_sk: | ||
1318 | tun_free_netdev(dev); | ||
1319 | err_free_dev: | 1659 | err_free_dev: |
1320 | free_netdev(dev); | 1660 | free_netdev(dev); |
1321 | failed: | ||
1322 | return err; | 1661 | return err; |
1323 | } | 1662 | } |
1324 | 1663 | ||
@@ -1373,13 +1712,91 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) | |||
1373 | return 0; | 1712 | return 0; |
1374 | } | 1713 | } |
1375 | 1714 | ||
1715 | static void tun_detach_filter(struct tun_struct *tun, int n) | ||
1716 | { | ||
1717 | int i; | ||
1718 | struct tun_file *tfile; | ||
1719 | |||
1720 | for (i = 0; i < n; i++) { | ||
1721 | tfile = rcu_dereference_protected(tun->tfiles[i], | ||
1722 | lockdep_rtnl_is_held()); | ||
1723 | sk_detach_filter(tfile->socket.sk); | ||
1724 | } | ||
1725 | |||
1726 | tun->filter_attached = false; | ||
1727 | } | ||
1728 | |||
1729 | static int tun_attach_filter(struct tun_struct *tun) | ||
1730 | { | ||
1731 | int i, ret = 0; | ||
1732 | struct tun_file *tfile; | ||
1733 | |||
1734 | for (i = 0; i < tun->numqueues; i++) { | ||
1735 | tfile = rcu_dereference_protected(tun->tfiles[i], | ||
1736 | lockdep_rtnl_is_held()); | ||
1737 | ret = sk_attach_filter(&tun->fprog, tfile->socket.sk); | ||
1738 | if (ret) { | ||
1739 | tun_detach_filter(tun, i); | ||
1740 | return ret; | ||
1741 | } | ||
1742 | } | ||
1743 | |||
1744 | tun->filter_attached = true; | ||
1745 | return ret; | ||
1746 | } | ||
1747 | |||
1748 | static void tun_set_sndbuf(struct tun_struct *tun) | ||
1749 | { | ||
1750 | struct tun_file *tfile; | ||
1751 | int i; | ||
1752 | |||
1753 | for (i = 0; i < tun->numqueues; i++) { | ||
1754 | tfile = rcu_dereference_protected(tun->tfiles[i], | ||
1755 | lockdep_rtnl_is_held()); | ||
1756 | tfile->socket.sk->sk_sndbuf = tun->sndbuf; | ||
1757 | } | ||
1758 | } | ||
1759 | |||
1760 | static int tun_set_queue(struct file *file, struct ifreq *ifr) | ||
1761 | { | ||
1762 | struct tun_file *tfile = file->private_data; | ||
1763 | struct tun_struct *tun; | ||
1764 | struct net_device *dev; | ||
1765 | int ret = 0; | ||
1766 | |||
1767 | rtnl_lock(); | ||
1768 | |||
1769 | if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { | ||
1770 | dev = __dev_get_by_name(tfile->net, ifr->ifr_name); | ||
1771 | if (!dev) { | ||
1772 | ret = -EINVAL; | ||
1773 | goto unlock; | ||
1774 | } | ||
1775 | |||
1776 | tun = netdev_priv(dev); | ||
1777 | if (dev->netdev_ops != &tap_netdev_ops && | ||
1778 | dev->netdev_ops != &tun_netdev_ops) | ||
1779 | ret = -EINVAL; | ||
1780 | else if (tun_not_capable(tun)) | ||
1781 | ret = -EPERM; | ||
1782 | else | ||
1783 | ret = tun_attach(tun, file); | ||
1784 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) | ||
1785 | __tun_detach(tfile, false); | ||
1786 | else | ||
1787 | ret = -EINVAL; | ||
1788 | |||
1789 | unlock: | ||
1790 | rtnl_unlock(); | ||
1791 | return ret; | ||
1792 | } | ||
1793 | |||
1376 | static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | 1794 | static long __tun_chr_ioctl(struct file *file, unsigned int cmd, |
1377 | unsigned long arg, int ifreq_len) | 1795 | unsigned long arg, int ifreq_len) |
1378 | { | 1796 | { |
1379 | struct tun_file *tfile = file->private_data; | 1797 | struct tun_file *tfile = file->private_data; |
1380 | struct tun_struct *tun; | 1798 | struct tun_struct *tun; |
1381 | void __user* argp = (void __user*)arg; | 1799 | void __user* argp = (void __user*)arg; |
1382 | struct sock_fprog fprog; | ||
1383 | struct ifreq ifr; | 1800 | struct ifreq ifr; |
1384 | kuid_t owner; | 1801 | kuid_t owner; |
1385 | kgid_t group; | 1802 | kgid_t group; |
@@ -1387,7 +1804,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1387 | int vnet_hdr_sz; | 1804 | int vnet_hdr_sz; |
1388 | int ret; | 1805 | int ret; |
1389 | 1806 | ||
1390 | if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) { | 1807 | if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { |
1391 | if (copy_from_user(&ifr, argp, ifreq_len)) | 1808 | if (copy_from_user(&ifr, argp, ifreq_len)) |
1392 | return -EFAULT; | 1809 | return -EFAULT; |
1393 | } else { | 1810 | } else { |
@@ -1398,10 +1815,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1398 | * This is needed because we never checked for invalid flags on | 1815 | * This is needed because we never checked for invalid flags on |
1399 | * TUNSETIFF. */ | 1816 | * TUNSETIFF. */ |
1400 | return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | | 1817 | return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | |
1401 | IFF_VNET_HDR, | 1818 | IFF_VNET_HDR | IFF_MULTI_QUEUE, |
1402 | (unsigned int __user*)argp); | 1819 | (unsigned int __user*)argp); |
1403 | } | 1820 | } else if (cmd == TUNSETQUEUE) |
1821 | return tun_set_queue(file, &ifr); | ||
1404 | 1822 | ||
1823 | ret = 0; | ||
1405 | rtnl_lock(); | 1824 | rtnl_lock(); |
1406 | 1825 | ||
1407 | tun = __tun_get(tfile); | 1826 | tun = __tun_get(tfile); |
@@ -1422,7 +1841,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1422 | if (!tun) | 1841 | if (!tun) |
1423 | goto unlock; | 1842 | goto unlock; |
1424 | 1843 | ||
1425 | tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %d\n", cmd); | 1844 | tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %u\n", cmd); |
1426 | 1845 | ||
1427 | ret = 0; | 1846 | ret = 0; |
1428 | switch (cmd) { | 1847 | switch (cmd) { |
@@ -1444,11 +1863,16 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1444 | break; | 1863 | break; |
1445 | 1864 | ||
1446 | case TUNSETPERSIST: | 1865 | case TUNSETPERSIST: |
1447 | /* Disable/Enable persist mode */ | 1866 | /* Disable/Enable persist mode. Keep an extra reference to the |
1448 | if (arg) | 1867 | * module to prevent the module being unprobed. |
1868 | */ | ||
1869 | if (arg) { | ||
1449 | tun->flags |= TUN_PERSIST; | 1870 | tun->flags |= TUN_PERSIST; |
1450 | else | 1871 | __module_get(THIS_MODULE); |
1872 | } else { | ||
1451 | tun->flags &= ~TUN_PERSIST; | 1873 | tun->flags &= ~TUN_PERSIST; |
1874 | module_put(THIS_MODULE); | ||
1875 | } | ||
1452 | 1876 | ||
1453 | tun_debug(KERN_INFO, tun, "persist %s\n", | 1877 | tun_debug(KERN_INFO, tun, "persist %s\n", |
1454 | arg ? "enabled" : "disabled"); | 1878 | arg ? "enabled" : "disabled"); |
@@ -1462,7 +1886,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1462 | break; | 1886 | break; |
1463 | } | 1887 | } |
1464 | tun->owner = owner; | 1888 | tun->owner = owner; |
1465 | tun_debug(KERN_INFO, tun, "owner set to %d\n", | 1889 | tun_debug(KERN_INFO, tun, "owner set to %u\n", |
1466 | from_kuid(&init_user_ns, tun->owner)); | 1890 | from_kuid(&init_user_ns, tun->owner)); |
1467 | break; | 1891 | break; |
1468 | 1892 | ||
@@ -1474,7 +1898,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1474 | break; | 1898 | break; |
1475 | } | 1899 | } |
1476 | tun->group = group; | 1900 | tun->group = group; |
1477 | tun_debug(KERN_INFO, tun, "group set to %d\n", | 1901 | tun_debug(KERN_INFO, tun, "group set to %u\n", |
1478 | from_kgid(&init_user_ns, tun->group)); | 1902 | from_kgid(&init_user_ns, tun->group)); |
1479 | break; | 1903 | break; |
1480 | 1904 | ||
@@ -1526,7 +1950,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1526 | break; | 1950 | break; |
1527 | 1951 | ||
1528 | case TUNGETSNDBUF: | 1952 | case TUNGETSNDBUF: |
1529 | sndbuf = tun->socket.sk->sk_sndbuf; | 1953 | sndbuf = tfile->socket.sk->sk_sndbuf; |
1530 | if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) | 1954 | if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) |
1531 | ret = -EFAULT; | 1955 | ret = -EFAULT; |
1532 | break; | 1956 | break; |
@@ -1537,7 +1961,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1537 | break; | 1961 | break; |
1538 | } | 1962 | } |
1539 | 1963 | ||
1540 | tun->socket.sk->sk_sndbuf = sndbuf; | 1964 | tun->sndbuf = sndbuf; |
1965 | tun_set_sndbuf(tun); | ||
1541 | break; | 1966 | break; |
1542 | 1967 | ||
1543 | case TUNGETVNETHDRSZ: | 1968 | case TUNGETVNETHDRSZ: |
@@ -1565,10 +1990,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1565 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) | 1990 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) |
1566 | break; | 1991 | break; |
1567 | ret = -EFAULT; | 1992 | ret = -EFAULT; |
1568 | if (copy_from_user(&fprog, argp, sizeof(fprog))) | 1993 | if (copy_from_user(&tun->fprog, argp, sizeof(tun->fprog))) |
1569 | break; | 1994 | break; |
1570 | 1995 | ||
1571 | ret = sk_attach_filter(&fprog, tun->socket.sk); | 1996 | ret = tun_attach_filter(tun); |
1572 | break; | 1997 | break; |
1573 | 1998 | ||
1574 | case TUNDETACHFILTER: | 1999 | case TUNDETACHFILTER: |
@@ -1576,7 +2001,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1576 | ret = -EINVAL; | 2001 | ret = -EINVAL; |
1577 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) | 2002 | if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) |
1578 | break; | 2003 | break; |
1579 | ret = sk_detach_filter(tun->socket.sk); | 2004 | ret = 0; |
2005 | tun_detach_filter(tun, tun->numqueues); | ||
1580 | break; | 2006 | break; |
1581 | 2007 | ||
1582 | default: | 2008 | default: |
@@ -1628,27 +2054,21 @@ static long tun_chr_compat_ioctl(struct file *file, | |||
1628 | 2054 | ||
1629 | static int tun_chr_fasync(int fd, struct file *file, int on) | 2055 | static int tun_chr_fasync(int fd, struct file *file, int on) |
1630 | { | 2056 | { |
1631 | struct tun_struct *tun = tun_get(file); | 2057 | struct tun_file *tfile = file->private_data; |
1632 | int ret; | 2058 | int ret; |
1633 | 2059 | ||
1634 | if (!tun) | 2060 | if ((ret = fasync_helper(fd, file, on, &tfile->fasync)) < 0) |
1635 | return -EBADFD; | ||
1636 | |||
1637 | tun_debug(KERN_INFO, tun, "tun_chr_fasync %d\n", on); | ||
1638 | |||
1639 | if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0) | ||
1640 | goto out; | 2061 | goto out; |
1641 | 2062 | ||
1642 | if (on) { | 2063 | if (on) { |
1643 | ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); | 2064 | ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); |
1644 | if (ret) | 2065 | if (ret) |
1645 | goto out; | 2066 | goto out; |
1646 | tun->flags |= TUN_FASYNC; | 2067 | tfile->flags |= TUN_FASYNC; |
1647 | } else | 2068 | } else |
1648 | tun->flags &= ~TUN_FASYNC; | 2069 | tfile->flags &= ~TUN_FASYNC; |
1649 | ret = 0; | 2070 | ret = 0; |
1650 | out: | 2071 | out: |
1651 | tun_put(tun); | ||
1652 | return ret; | 2072 | return ret; |
1653 | } | 2073 | } |
1654 | 2074 | ||
@@ -1658,44 +2078,39 @@ static int tun_chr_open(struct inode *inode, struct file * file) | |||
1658 | 2078 | ||
1659 | DBG1(KERN_INFO, "tunX: tun_chr_open\n"); | 2079 | DBG1(KERN_INFO, "tunX: tun_chr_open\n"); |
1660 | 2080 | ||
1661 | tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); | 2081 | tfile = (struct tun_file *)sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, |
2082 | &tun_proto); | ||
1662 | if (!tfile) | 2083 | if (!tfile) |
1663 | return -ENOMEM; | 2084 | return -ENOMEM; |
1664 | atomic_set(&tfile->count, 0); | 2085 | rcu_assign_pointer(tfile->tun, NULL); |
1665 | tfile->tun = NULL; | ||
1666 | tfile->net = get_net(current->nsproxy->net_ns); | 2086 | tfile->net = get_net(current->nsproxy->net_ns); |
2087 | tfile->flags = 0; | ||
2088 | |||
2089 | rcu_assign_pointer(tfile->socket.wq, &tfile->wq); | ||
2090 | init_waitqueue_head(&tfile->wq.wait); | ||
2091 | |||
2092 | tfile->socket.file = file; | ||
2093 | tfile->socket.ops = &tun_socket_ops; | ||
2094 | |||
2095 | sock_init_data(&tfile->socket, &tfile->sk); | ||
2096 | sk_change_net(&tfile->sk, tfile->net); | ||
2097 | |||
2098 | tfile->sk.sk_write_space = tun_sock_write_space; | ||
2099 | tfile->sk.sk_sndbuf = INT_MAX; | ||
2100 | |||
1667 | file->private_data = tfile; | 2101 | file->private_data = tfile; |
2102 | set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags); | ||
2103 | |||
1668 | return 0; | 2104 | return 0; |
1669 | } | 2105 | } |
1670 | 2106 | ||
1671 | static int tun_chr_close(struct inode *inode, struct file *file) | 2107 | static int tun_chr_close(struct inode *inode, struct file *file) |
1672 | { | 2108 | { |
1673 | struct tun_file *tfile = file->private_data; | 2109 | struct tun_file *tfile = file->private_data; |
1674 | struct tun_struct *tun; | 2110 | struct net *net = tfile->net; |
1675 | 2111 | ||
1676 | tun = __tun_get(tfile); | 2112 | tun_detach(tfile, true); |
1677 | if (tun) { | 2113 | put_net(net); |
1678 | struct net_device *dev = tun->dev; | ||
1679 | |||
1680 | tun_debug(KERN_INFO, tun, "tun_chr_close\n"); | ||
1681 | |||
1682 | __tun_detach(tun); | ||
1683 | |||
1684 | /* If desirable, unregister the netdevice. */ | ||
1685 | if (!(tun->flags & TUN_PERSIST)) { | ||
1686 | rtnl_lock(); | ||
1687 | if (dev->reg_state == NETREG_REGISTERED) | ||
1688 | unregister_netdevice(dev); | ||
1689 | rtnl_unlock(); | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1693 | tun = tfile->tun; | ||
1694 | if (tun) | ||
1695 | sock_put(tun->socket.sk); | ||
1696 | |||
1697 | put_net(tfile->net); | ||
1698 | kfree(tfile); | ||
1699 | 2114 | ||
1700 | return 0; | 2115 | return 0; |
1701 | } | 2116 | } |
@@ -1822,14 +2237,13 @@ static void tun_cleanup(void) | |||
1822 | * holding a reference to the file for as long as the socket is in use. */ | 2237 | * holding a reference to the file for as long as the socket is in use. */ |
1823 | struct socket *tun_get_socket(struct file *file) | 2238 | struct socket *tun_get_socket(struct file *file) |
1824 | { | 2239 | { |
1825 | struct tun_struct *tun; | 2240 | struct tun_file *tfile; |
1826 | if (file->f_op != &tun_fops) | 2241 | if (file->f_op != &tun_fops) |
1827 | return ERR_PTR(-EINVAL); | 2242 | return ERR_PTR(-EINVAL); |
1828 | tun = tun_get(file); | 2243 | tfile = file->private_data; |
1829 | if (!tun) | 2244 | if (!tfile) |
1830 | return ERR_PTR(-EBADFD); | 2245 | return ERR_PTR(-EBADFD); |
1831 | tun_put(tun); | 2246 | return &tfile->socket; |
1832 | return &tun->socket; | ||
1833 | } | 2247 | } |
1834 | EXPORT_SYMBOL_GPL(tun_get_socket); | 2248 | EXPORT_SYMBOL_GPL(tun_get_socket); |
1835 | 2249 | ||
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index c1ae76968f47..ef976215b649 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -219,6 +219,24 @@ config USB_NET_CDC_NCM | |||
219 | * ST-Ericsson M343 HSPA Mobile Broadband Modem (reference design) | 219 | * ST-Ericsson M343 HSPA Mobile Broadband Modem (reference design) |
220 | * Ericsson F5521gw Mobile Broadband Module | 220 | * Ericsson F5521gw Mobile Broadband Module |
221 | 221 | ||
222 | config USB_NET_CDC_MBIM | ||
223 | tristate "CDC MBIM support" | ||
224 | depends on USB_USBNET | ||
225 | select USB_WDM | ||
226 | select USB_NET_CDC_NCM | ||
227 | help | ||
228 | This driver provides support for CDC MBIM (Mobile Broadband | ||
229 | Interface Model) devices. The CDC MBIM specification is | ||
230 | available from <http://www.usb.org/>. | ||
231 | |||
232 | MBIM devices require configuration using the management | ||
233 | protocol defined by the MBIM specification. This driver | ||
234 | provides unfiltered access to the MBIM control channel | ||
235 | through the associated /dev/cdc-wdmx character device. | ||
236 | |||
237 | To compile this driver as a module, choose M here: the | ||
238 | module will be called cdc_mbim. | ||
239 | |||
222 | config USB_NET_DM9601 | 240 | config USB_NET_DM9601 |
223 | tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" | 241 | tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" |
224 | depends on USB_USBNET | 242 | depends on USB_USBNET |
@@ -230,6 +248,8 @@ config USB_NET_DM9601 | |||
230 | config USB_NET_SMSC75XX | 248 | config USB_NET_SMSC75XX |
231 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | 249 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" |
232 | depends on USB_USBNET | 250 | depends on USB_USBNET |
251 | select BITREVERSE | ||
252 | select CRC16 | ||
233 | select CRC32 | 253 | select CRC32 |
234 | help | 254 | help |
235 | This option adds support for SMSC LAN95XX based USB 2.0 | 255 | This option adds support for SMSC LAN95XX based USB 2.0 |
@@ -238,6 +258,8 @@ config USB_NET_SMSC75XX | |||
238 | config USB_NET_SMSC95XX | 258 | config USB_NET_SMSC95XX |
239 | tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" | 259 | tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" |
240 | depends on USB_USBNET | 260 | depends on USB_USBNET |
261 | select BITREVERSE | ||
262 | select CRC16 | ||
241 | select CRC32 | 263 | select CRC32 |
242 | help | 264 | help |
243 | This option adds support for SMSC LAN95XX based USB 2.0 | 265 | This option adds support for SMSC LAN95XX based USB 2.0 |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index bf063008c1af..478691326f37 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -31,4 +31,5 @@ obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o | |||
31 | obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o | 31 | obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o |
32 | obj-$(CONFIG_USB_VL600) += lg-vl600.o | 32 | obj-$(CONFIG_USB_VL600) += lg-vl600.o |
33 | obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o | 33 | obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o |
34 | obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o | ||
34 | 35 | ||
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 774d9ce2dafc..50d167330d38 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c | |||
@@ -25,121 +25,30 @@ | |||
25 | int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 25 | int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
26 | u16 size, void *data) | 26 | u16 size, void *data) |
27 | { | 27 | { |
28 | void *buf; | 28 | int ret; |
29 | int err = -ENOMEM; | 29 | ret = usbnet_read_cmd(dev, cmd, |
30 | 30 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
31 | netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", | 31 | value, index, data, size); |
32 | cmd, value, index, size); | ||
33 | |||
34 | buf = kmalloc(size, GFP_KERNEL); | ||
35 | if (!buf) | ||
36 | goto out; | ||
37 | |||
38 | err = usb_control_msg( | ||
39 | dev->udev, | ||
40 | usb_rcvctrlpipe(dev->udev, 0), | ||
41 | cmd, | ||
42 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
43 | value, | ||
44 | index, | ||
45 | buf, | ||
46 | size, | ||
47 | USB_CTRL_GET_TIMEOUT); | ||
48 | if (err == size) | ||
49 | memcpy(data, buf, size); | ||
50 | else if (err >= 0) | ||
51 | err = -EINVAL; | ||
52 | kfree(buf); | ||
53 | 32 | ||
54 | out: | 33 | if (ret != size && ret >= 0) |
55 | return err; | 34 | return -EINVAL; |
35 | return ret; | ||
56 | } | 36 | } |
57 | 37 | ||
58 | int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 38 | int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
59 | u16 size, void *data) | 39 | u16 size, void *data) |
60 | { | 40 | { |
61 | void *buf = NULL; | 41 | return usbnet_write_cmd(dev, cmd, |
62 | int err = -ENOMEM; | 42 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
63 | 43 | value, index, data, size); | |
64 | netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", | ||
65 | cmd, value, index, size); | ||
66 | |||
67 | if (data) { | ||
68 | buf = kmemdup(data, size, GFP_KERNEL); | ||
69 | if (!buf) | ||
70 | goto out; | ||
71 | } | ||
72 | |||
73 | err = usb_control_msg( | ||
74 | dev->udev, | ||
75 | usb_sndctrlpipe(dev->udev, 0), | ||
76 | cmd, | ||
77 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
78 | value, | ||
79 | index, | ||
80 | buf, | ||
81 | size, | ||
82 | USB_CTRL_SET_TIMEOUT); | ||
83 | kfree(buf); | ||
84 | |||
85 | out: | ||
86 | return err; | ||
87 | } | ||
88 | |||
89 | static void asix_async_cmd_callback(struct urb *urb) | ||
90 | { | ||
91 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
92 | int status = urb->status; | ||
93 | |||
94 | if (status < 0) | ||
95 | printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", | ||
96 | status); | ||
97 | |||
98 | kfree(req); | ||
99 | usb_free_urb(urb); | ||
100 | } | 44 | } |
101 | 45 | ||
102 | void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 46 | void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
103 | u16 size, void *data) | 47 | u16 size, void *data) |
104 | { | 48 | { |
105 | struct usb_ctrlrequest *req; | 49 | usbnet_write_cmd_async(dev, cmd, |
106 | int status; | 50 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
107 | struct urb *urb; | 51 | value, index, data, size); |
108 | |||
109 | netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", | ||
110 | cmd, value, index, size); | ||
111 | |||
112 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
113 | if (!urb) { | ||
114 | netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); | ||
119 | if (!req) { | ||
120 | netdev_err(dev->net, "Failed to allocate memory for control request\n"); | ||
121 | usb_free_urb(urb); | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | ||
126 | req->bRequest = cmd; | ||
127 | req->wValue = cpu_to_le16(value); | ||
128 | req->wIndex = cpu_to_le16(index); | ||
129 | req->wLength = cpu_to_le16(size); | ||
130 | |||
131 | usb_fill_control_urb(urb, dev->udev, | ||
132 | usb_sndctrlpipe(dev->udev, 0), | ||
133 | (void *)req, data, size, | ||
134 | asix_async_cmd_callback, req); | ||
135 | |||
136 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
137 | if (status < 0) { | ||
138 | netdev_err(dev->net, "Error submitting the control message: status=%d\n", | ||
139 | status); | ||
140 | kfree(req); | ||
141 | usb_free_urb(urb); | ||
142 | } | ||
143 | } | 52 | } |
144 | 53 | ||
145 | int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 54 | int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c new file mode 100644 index 000000000000..42f51c71ec1f --- /dev/null +++ b/drivers/net/usb/cdc_mbim.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Smith Micro Software, Inc. | ||
3 | * Copyright (c) 2012 Bjørn Mork <bjorn@mork.no> | ||
4 | * | ||
5 | * This driver is based on and reuse most of cdc_ncm, which is | ||
6 | * Copyright (C) ST-Ericsson 2010-2012 | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/ethtool.h> | ||
16 | #include <linux/if_vlan.h> | ||
17 | #include <linux/ip.h> | ||
18 | #include <linux/mii.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/cdc.h> | ||
21 | #include <linux/usb/usbnet.h> | ||
22 | #include <linux/usb/cdc-wdm.h> | ||
23 | #include <linux/usb/cdc_ncm.h> | ||
24 | |||
25 | /* driver specific data - must match cdc_ncm usage */ | ||
26 | struct cdc_mbim_state { | ||
27 | struct cdc_ncm_ctx *ctx; | ||
28 | atomic_t pmcount; | ||
29 | struct usb_driver *subdriver; | ||
30 | struct usb_interface *control; | ||
31 | struct usb_interface *data; | ||
32 | }; | ||
33 | |||
34 | /* using a counter to merge subdriver requests with our own into a combined state */ | ||
35 | static int cdc_mbim_manage_power(struct usbnet *dev, int on) | ||
36 | { | ||
37 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
38 | int rv = 0; | ||
39 | |||
40 | dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); | ||
41 | |||
42 | if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { | ||
43 | /* need autopm_get/put here to ensure the usbcore sees the new value */ | ||
44 | rv = usb_autopm_get_interface(dev->intf); | ||
45 | if (rv < 0) | ||
46 | goto err; | ||
47 | dev->intf->needs_remote_wakeup = on; | ||
48 | usb_autopm_put_interface(dev->intf); | ||
49 | } | ||
50 | err: | ||
51 | return rv; | ||
52 | } | ||
53 | |||
54 | static int cdc_mbim_wdm_manage_power(struct usb_interface *intf, int status) | ||
55 | { | ||
56 | struct usbnet *dev = usb_get_intfdata(intf); | ||
57 | |||
58 | /* can be called while disconnecting */ | ||
59 | if (!dev) | ||
60 | return 0; | ||
61 | |||
62 | return cdc_mbim_manage_power(dev, status); | ||
63 | } | ||
64 | |||
65 | |||
66 | static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) | ||
67 | { | ||
68 | struct cdc_ncm_ctx *ctx; | ||
69 | struct usb_driver *subdriver = ERR_PTR(-ENODEV); | ||
70 | int ret = -ENODEV; | ||
71 | u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM; | ||
72 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
73 | |||
74 | /* see if interface supports MBIM alternate setting */ | ||
75 | if (intf->num_altsetting == 2) { | ||
76 | if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) | ||
77 | usb_set_interface(dev->udev, | ||
78 | intf->cur_altsetting->desc.bInterfaceNumber, | ||
79 | CDC_NCM_COMM_ALTSETTING_MBIM); | ||
80 | data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM; | ||
81 | } | ||
82 | |||
83 | /* Probably NCM, defer for cdc_ncm_bind */ | ||
84 | if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) | ||
85 | goto err; | ||
86 | |||
87 | ret = cdc_ncm_bind_common(dev, intf, data_altsetting); | ||
88 | if (ret) | ||
89 | goto err; | ||
90 | |||
91 | ctx = info->ctx; | ||
92 | |||
93 | /* The MBIM descriptor and the status endpoint are required */ | ||
94 | if (ctx->mbim_desc && dev->status) | ||
95 | subdriver = usb_cdc_wdm_register(ctx->control, | ||
96 | &dev->status->desc, | ||
97 | le16_to_cpu(ctx->mbim_desc->wMaxControlMessage), | ||
98 | cdc_mbim_wdm_manage_power); | ||
99 | if (IS_ERR(subdriver)) { | ||
100 | ret = PTR_ERR(subdriver); | ||
101 | cdc_ncm_unbind(dev, intf); | ||
102 | goto err; | ||
103 | } | ||
104 | |||
105 | /* can't let usbnet use the interrupt endpoint */ | ||
106 | dev->status = NULL; | ||
107 | info->subdriver = subdriver; | ||
108 | |||
109 | /* MBIM cannot do ARP */ | ||
110 | dev->net->flags |= IFF_NOARP; | ||
111 | |||
112 | /* no need to put the VLAN tci in the packet headers */ | ||
113 | dev->net->features |= NETIF_F_HW_VLAN_TX; | ||
114 | err: | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf) | ||
119 | { | ||
120 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
121 | struct cdc_ncm_ctx *ctx = info->ctx; | ||
122 | |||
123 | /* disconnect subdriver from control interface */ | ||
124 | if (info->subdriver && info->subdriver->disconnect) | ||
125 | info->subdriver->disconnect(ctx->control); | ||
126 | info->subdriver = NULL; | ||
127 | |||
128 | /* let NCM unbind clean up both control and data interface */ | ||
129 | cdc_ncm_unbind(dev, intf); | ||
130 | } | ||
131 | |||
132 | |||
133 | static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | ||
134 | { | ||
135 | struct sk_buff *skb_out; | ||
136 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
137 | struct cdc_ncm_ctx *ctx = info->ctx; | ||
138 | __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); | ||
139 | u16 tci = 0; | ||
140 | u8 *c; | ||
141 | |||
142 | if (!ctx) | ||
143 | goto error; | ||
144 | |||
145 | if (skb) { | ||
146 | if (skb->len <= sizeof(ETH_HLEN)) | ||
147 | goto error; | ||
148 | |||
149 | /* mapping VLANs to MBIM sessions: | ||
150 | * no tag => IPS session <0> | ||
151 | * 1 - 255 => IPS session <vlanid> | ||
152 | * 256 - 511 => DSS session <vlanid - 256> | ||
153 | * 512 - 4095 => unsupported, drop | ||
154 | */ | ||
155 | vlan_get_tag(skb, &tci); | ||
156 | |||
157 | switch (tci & 0x0f00) { | ||
158 | case 0x0000: /* VLAN ID 0 - 255 */ | ||
159 | /* verify that datagram is IPv4 or IPv6 */ | ||
160 | skb_reset_mac_header(skb); | ||
161 | switch (eth_hdr(skb)->h_proto) { | ||
162 | case htons(ETH_P_IP): | ||
163 | case htons(ETH_P_IPV6): | ||
164 | break; | ||
165 | default: | ||
166 | goto error; | ||
167 | } | ||
168 | c = (u8 *)&sign; | ||
169 | c[3] = tci; | ||
170 | break; | ||
171 | case 0x0100: /* VLAN ID 256 - 511 */ | ||
172 | sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN); | ||
173 | c = (u8 *)&sign; | ||
174 | c[3] = tci; | ||
175 | break; | ||
176 | default: | ||
177 | netif_err(dev, tx_err, dev->net, | ||
178 | "unsupported tci=0x%04x\n", tci); | ||
179 | goto error; | ||
180 | } | ||
181 | skb_pull(skb, ETH_HLEN); | ||
182 | } | ||
183 | |||
184 | spin_lock_bh(&ctx->mtx); | ||
185 | skb_out = cdc_ncm_fill_tx_frame(ctx, skb, sign); | ||
186 | spin_unlock_bh(&ctx->mtx); | ||
187 | return skb_out; | ||
188 | |||
189 | error: | ||
190 | if (skb) | ||
191 | dev_kfree_skb_any(skb); | ||
192 | |||
193 | return NULL; | ||
194 | } | ||
195 | |||
196 | static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci) | ||
197 | { | ||
198 | __be16 proto = htons(ETH_P_802_3); | ||
199 | struct sk_buff *skb = NULL; | ||
200 | |||
201 | if (tci < 256) { /* IPS session? */ | ||
202 | if (len < sizeof(struct iphdr)) | ||
203 | goto err; | ||
204 | |||
205 | switch (*buf & 0xf0) { | ||
206 | case 0x40: | ||
207 | proto = htons(ETH_P_IP); | ||
208 | break; | ||
209 | case 0x60: | ||
210 | proto = htons(ETH_P_IPV6); | ||
211 | break; | ||
212 | default: | ||
213 | goto err; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | skb = netdev_alloc_skb_ip_align(dev->net, len + ETH_HLEN); | ||
218 | if (!skb) | ||
219 | goto err; | ||
220 | |||
221 | /* add an ethernet header */ | ||
222 | skb_put(skb, ETH_HLEN); | ||
223 | skb_reset_mac_header(skb); | ||
224 | eth_hdr(skb)->h_proto = proto; | ||
225 | memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); | ||
226 | memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); | ||
227 | |||
228 | /* add datagram */ | ||
229 | memcpy(skb_put(skb, len), buf, len); | ||
230 | |||
231 | /* map MBIM session to VLAN */ | ||
232 | if (tci) | ||
233 | vlan_put_tag(skb, tci); | ||
234 | err: | ||
235 | return skb; | ||
236 | } | ||
237 | |||
238 | static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | ||
239 | { | ||
240 | struct sk_buff *skb; | ||
241 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
242 | struct cdc_ncm_ctx *ctx = info->ctx; | ||
243 | int len; | ||
244 | int nframes; | ||
245 | int x; | ||
246 | int offset; | ||
247 | struct usb_cdc_ncm_ndp16 *ndp16; | ||
248 | struct usb_cdc_ncm_dpe16 *dpe16; | ||
249 | int ndpoffset; | ||
250 | int loopcount = 50; /* arbitrary max preventing infinite loop */ | ||
251 | u8 *c; | ||
252 | u16 tci; | ||
253 | |||
254 | ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); | ||
255 | if (ndpoffset < 0) | ||
256 | goto error; | ||
257 | |||
258 | next_ndp: | ||
259 | nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); | ||
260 | if (nframes < 0) | ||
261 | goto error; | ||
262 | |||
263 | ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); | ||
264 | |||
265 | switch (ndp16->dwSignature & cpu_to_le32(0x00ffffff)) { | ||
266 | case cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN): | ||
267 | c = (u8 *)&ndp16->dwSignature; | ||
268 | tci = c[3]; | ||
269 | break; | ||
270 | case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN): | ||
271 | c = (u8 *)&ndp16->dwSignature; | ||
272 | tci = c[3] + 256; | ||
273 | break; | ||
274 | default: | ||
275 | netif_dbg(dev, rx_err, dev->net, | ||
276 | "unsupported NDP signature <0x%08x>\n", | ||
277 | le32_to_cpu(ndp16->dwSignature)); | ||
278 | goto err_ndp; | ||
279 | |||
280 | } | ||
281 | |||
282 | dpe16 = ndp16->dpe16; | ||
283 | for (x = 0; x < nframes; x++, dpe16++) { | ||
284 | offset = le16_to_cpu(dpe16->wDatagramIndex); | ||
285 | len = le16_to_cpu(dpe16->wDatagramLength); | ||
286 | |||
287 | /* | ||
288 | * CDC NCM ch. 3.7 | ||
289 | * All entries after first NULL entry are to be ignored | ||
290 | */ | ||
291 | if ((offset == 0) || (len == 0)) { | ||
292 | if (!x) | ||
293 | goto err_ndp; /* empty NTB */ | ||
294 | break; | ||
295 | } | ||
296 | |||
297 | /* sanity checking */ | ||
298 | if (((offset + len) > skb_in->len) || (len > ctx->rx_max)) { | ||
299 | netif_dbg(dev, rx_err, dev->net, | ||
300 | "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", | ||
301 | x, offset, len, skb_in); | ||
302 | if (!x) | ||
303 | goto err_ndp; | ||
304 | break; | ||
305 | } else { | ||
306 | skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len, tci); | ||
307 | if (!skb) | ||
308 | goto error; | ||
309 | usbnet_skb_return(dev, skb); | ||
310 | } | ||
311 | } | ||
312 | err_ndp: | ||
313 | /* are there more NDPs to process? */ | ||
314 | ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); | ||
315 | if (ndpoffset && loopcount--) | ||
316 | goto next_ndp; | ||
317 | |||
318 | return 1; | ||
319 | error: | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int cdc_mbim_suspend(struct usb_interface *intf, pm_message_t message) | ||
324 | { | ||
325 | int ret = 0; | ||
326 | struct usbnet *dev = usb_get_intfdata(intf); | ||
327 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
328 | struct cdc_ncm_ctx *ctx = info->ctx; | ||
329 | |||
330 | if (ctx == NULL) { | ||
331 | ret = -1; | ||
332 | goto error; | ||
333 | } | ||
334 | |||
335 | ret = usbnet_suspend(intf, message); | ||
336 | if (ret < 0) | ||
337 | goto error; | ||
338 | |||
339 | if (intf == ctx->control && info->subdriver && info->subdriver->suspend) | ||
340 | ret = info->subdriver->suspend(intf, message); | ||
341 | if (ret < 0) | ||
342 | usbnet_resume(intf); | ||
343 | |||
344 | error: | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | static int cdc_mbim_resume(struct usb_interface *intf) | ||
349 | { | ||
350 | int ret = 0; | ||
351 | struct usbnet *dev = usb_get_intfdata(intf); | ||
352 | struct cdc_mbim_state *info = (void *)&dev->data; | ||
353 | struct cdc_ncm_ctx *ctx = info->ctx; | ||
354 | bool callsub = (intf == ctx->control && info->subdriver && info->subdriver->resume); | ||
355 | |||
356 | if (callsub) | ||
357 | ret = info->subdriver->resume(intf); | ||
358 | if (ret < 0) | ||
359 | goto err; | ||
360 | ret = usbnet_resume(intf); | ||
361 | if (ret < 0 && callsub && info->subdriver->suspend) | ||
362 | info->subdriver->suspend(intf, PMSG_SUSPEND); | ||
363 | err: | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | static const struct driver_info cdc_mbim_info = { | ||
368 | .description = "CDC MBIM", | ||
369 | .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN, | ||
370 | .bind = cdc_mbim_bind, | ||
371 | .unbind = cdc_mbim_unbind, | ||
372 | .manage_power = cdc_mbim_manage_power, | ||
373 | .rx_fixup = cdc_mbim_rx_fixup, | ||
374 | .tx_fixup = cdc_mbim_tx_fixup, | ||
375 | }; | ||
376 | |||
377 | static const struct usb_device_id mbim_devs[] = { | ||
378 | /* This duplicate NCM entry is intentional. MBIM devices can | ||
379 | * be disguised as NCM by default, and this is necessary to | ||
380 | * allow us to bind the correct driver_info to such devices. | ||
381 | * | ||
382 | * bind() will sort out this for us, selecting the correct | ||
383 | * entry and reject the other | ||
384 | */ | ||
385 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | ||
386 | .driver_info = (unsigned long)&cdc_mbim_info, | ||
387 | }, | ||
388 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), | ||
389 | .driver_info = (unsigned long)&cdc_mbim_info, | ||
390 | }, | ||
391 | { | ||
392 | }, | ||
393 | }; | ||
394 | MODULE_DEVICE_TABLE(usb, mbim_devs); | ||
395 | |||
396 | static struct usb_driver cdc_mbim_driver = { | ||
397 | .name = "cdc_mbim", | ||
398 | .id_table = mbim_devs, | ||
399 | .probe = usbnet_probe, | ||
400 | .disconnect = usbnet_disconnect, | ||
401 | .suspend = cdc_mbim_suspend, | ||
402 | .resume = cdc_mbim_resume, | ||
403 | .reset_resume = cdc_mbim_resume, | ||
404 | .supports_autosuspend = 1, | ||
405 | .disable_hub_initiated_lpm = 1, | ||
406 | }; | ||
407 | module_usb_driver(cdc_mbim_driver); | ||
408 | |||
409 | MODULE_AUTHOR("Greg Suarez <gsuarez@smithmicro.com>"); | ||
410 | MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>"); | ||
411 | MODULE_DESCRIPTION("USB CDC MBIM host driver"); | ||
412 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a4f625..ddc7b8880f60 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -51,90 +51,10 @@ | |||
51 | #include <linux/atomic.h> | 51 | #include <linux/atomic.h> |
52 | #include <linux/usb/usbnet.h> | 52 | #include <linux/usb/usbnet.h> |
53 | #include <linux/usb/cdc.h> | 53 | #include <linux/usb/cdc.h> |
54 | #include <linux/usb/cdc_ncm.h> | ||
54 | 55 | ||
55 | #define DRIVER_VERSION "14-Mar-2012" | 56 | #define DRIVER_VERSION "14-Mar-2012" |
56 | 57 | ||
57 | /* CDC NCM subclass 3.2.1 */ | ||
58 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 | ||
59 | |||
60 | /* Maximum NTB length */ | ||
61 | #define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */ | ||
62 | #define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */ | ||
63 | |||
64 | /* Minimum value for MaxDatagramSize, ch. 6.2.9 */ | ||
65 | #define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */ | ||
66 | |||
67 | #define CDC_NCM_MIN_TX_PKT 512 /* bytes */ | ||
68 | |||
69 | /* Default value for MaxDatagramSize */ | ||
70 | #define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */ | ||
71 | |||
72 | /* | ||
73 | * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting | ||
74 | * the last NULL entry. | ||
75 | */ | ||
76 | #define CDC_NCM_DPT_DATAGRAMS_MAX 40 | ||
77 | |||
78 | /* Restart the timer, if amount of datagrams is less than given value */ | ||
79 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 | ||
80 | #define CDC_NCM_TIMER_PENDING_CNT 2 | ||
81 | #define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC) | ||
82 | |||
83 | /* The following macro defines the minimum header space */ | ||
84 | #define CDC_NCM_MIN_HDR_SIZE \ | ||
85 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ | ||
86 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) | ||
87 | |||
88 | struct cdc_ncm_data { | ||
89 | struct usb_cdc_ncm_nth16 nth16; | ||
90 | struct usb_cdc_ncm_ndp16 ndp16; | ||
91 | struct usb_cdc_ncm_dpe16 dpe16[CDC_NCM_DPT_DATAGRAMS_MAX + 1]; | ||
92 | }; | ||
93 | |||
94 | struct cdc_ncm_ctx { | ||
95 | struct cdc_ncm_data tx_ncm; | ||
96 | struct usb_cdc_ncm_ntb_parameters ncm_parm; | ||
97 | struct hrtimer tx_timer; | ||
98 | struct tasklet_struct bh; | ||
99 | |||
100 | const struct usb_cdc_ncm_desc *func_desc; | ||
101 | const struct usb_cdc_header_desc *header_desc; | ||
102 | const struct usb_cdc_union_desc *union_desc; | ||
103 | const struct usb_cdc_ether_desc *ether_desc; | ||
104 | |||
105 | struct net_device *netdev; | ||
106 | struct usb_device *udev; | ||
107 | struct usb_host_endpoint *in_ep; | ||
108 | struct usb_host_endpoint *out_ep; | ||
109 | struct usb_host_endpoint *status_ep; | ||
110 | struct usb_interface *intf; | ||
111 | struct usb_interface *control; | ||
112 | struct usb_interface *data; | ||
113 | |||
114 | struct sk_buff *tx_curr_skb; | ||
115 | struct sk_buff *tx_rem_skb; | ||
116 | |||
117 | spinlock_t mtx; | ||
118 | atomic_t stop; | ||
119 | |||
120 | u32 tx_timer_pending; | ||
121 | u32 tx_curr_offset; | ||
122 | u32 tx_curr_last_offset; | ||
123 | u32 tx_curr_frame_num; | ||
124 | u32 rx_speed; | ||
125 | u32 tx_speed; | ||
126 | u32 rx_max; | ||
127 | u32 tx_max; | ||
128 | u32 max_datagram_size; | ||
129 | u16 tx_max_datagrams; | ||
130 | u16 tx_remainder; | ||
131 | u16 tx_modulus; | ||
132 | u16 tx_ndp_modulus; | ||
133 | u16 tx_seq; | ||
134 | u16 rx_seq; | ||
135 | u16 connected; | ||
136 | }; | ||
137 | |||
138 | static void cdc_ncm_txpath_bh(unsigned long param); | 58 | static void cdc_ncm_txpath_bh(unsigned long param); |
139 | static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); | 59 | static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); |
140 | static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); | 60 | static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); |
@@ -158,17 +78,19 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
158 | u8 flags; | 78 | u8 flags; |
159 | u8 iface_no; | 79 | u8 iface_no; |
160 | int err; | 80 | int err; |
81 | int eth_hlen; | ||
161 | u16 ntb_fmt_supported; | 82 | u16 ntb_fmt_supported; |
83 | u32 min_dgram_size; | ||
84 | u32 min_hdr_size; | ||
85 | struct usbnet *dev = netdev_priv(ctx->netdev); | ||
162 | 86 | ||
163 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; | 87 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; |
164 | 88 | ||
165 | err = usb_control_msg(ctx->udev, | 89 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, |
166 | usb_rcvctrlpipe(ctx->udev, 0), | 90 | USB_TYPE_CLASS | USB_DIR_IN |
167 | USB_CDC_GET_NTB_PARAMETERS, | 91 | |USB_RECIP_INTERFACE, |
168 | USB_TYPE_CLASS | USB_DIR_IN | 92 | 0, iface_no, &ctx->ncm_parm, |
169 | | USB_RECIP_INTERFACE, | 93 | sizeof(ctx->ncm_parm)); |
170 | 0, iface_no, &ctx->ncm_parm, | ||
171 | sizeof(ctx->ncm_parm), 10000); | ||
172 | if (err < 0) { | 94 | if (err < 0) { |
173 | pr_debug("failed GET_NTB_PARAMETERS\n"); | 95 | pr_debug("failed GET_NTB_PARAMETERS\n"); |
174 | return 1; | 96 | return 1; |
@@ -184,10 +106,19 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
184 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); | 106 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); |
185 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); | 107 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); |
186 | 108 | ||
187 | if (ctx->func_desc != NULL) | 109 | eth_hlen = ETH_HLEN; |
110 | min_dgram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | ||
111 | min_hdr_size = CDC_NCM_MIN_HDR_SIZE; | ||
112 | if (ctx->mbim_desc != NULL) { | ||
113 | flags = ctx->mbim_desc->bmNetworkCapabilities; | ||
114 | eth_hlen = 0; | ||
115 | min_dgram_size = CDC_MBIM_MIN_DATAGRAM_SIZE; | ||
116 | min_hdr_size = 0; | ||
117 | } else if (ctx->func_desc != NULL) { | ||
188 | flags = ctx->func_desc->bmNetworkCapabilities; | 118 | flags = ctx->func_desc->bmNetworkCapabilities; |
189 | else | 119 | } else { |
190 | flags = 0; | 120 | flags = 0; |
121 | } | ||
191 | 122 | ||
192 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " | 123 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " |
193 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " | 124 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " |
@@ -215,49 +146,19 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
215 | 146 | ||
216 | /* inform device about NTB input size changes */ | 147 | /* inform device about NTB input size changes */ |
217 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { | 148 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { |
149 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
218 | 150 | ||
219 | if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { | 151 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, |
220 | struct usb_cdc_ncm_ndp_input_size *ndp_in_sz; | 152 | USB_TYPE_CLASS | USB_DIR_OUT |
221 | 153 | | USB_RECIP_INTERFACE, | |
222 | ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL); | 154 | 0, iface_no, &dwNtbInMaxSize, 4); |
223 | if (!ndp_in_sz) { | ||
224 | err = -ENOMEM; | ||
225 | goto size_err; | ||
226 | } | ||
227 | |||
228 | err = usb_control_msg(ctx->udev, | ||
229 | usb_sndctrlpipe(ctx->udev, 0), | ||
230 | USB_CDC_SET_NTB_INPUT_SIZE, | ||
231 | USB_TYPE_CLASS | USB_DIR_OUT | ||
232 | | USB_RECIP_INTERFACE, | ||
233 | 0, iface_no, ndp_in_sz, 8, 1000); | ||
234 | kfree(ndp_in_sz); | ||
235 | } else { | ||
236 | __le32 *dwNtbInMaxSize; | ||
237 | dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize), | ||
238 | GFP_KERNEL); | ||
239 | if (!dwNtbInMaxSize) { | ||
240 | err = -ENOMEM; | ||
241 | goto size_err; | ||
242 | } | ||
243 | *dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
244 | |||
245 | err = usb_control_msg(ctx->udev, | ||
246 | usb_sndctrlpipe(ctx->udev, 0), | ||
247 | USB_CDC_SET_NTB_INPUT_SIZE, | ||
248 | USB_TYPE_CLASS | USB_DIR_OUT | ||
249 | | USB_RECIP_INTERFACE, | ||
250 | 0, iface_no, dwNtbInMaxSize, 4, 1000); | ||
251 | kfree(dwNtbInMaxSize); | ||
252 | } | ||
253 | size_err: | ||
254 | if (err < 0) | 155 | if (err < 0) |
255 | pr_debug("Setting NTB Input Size failed\n"); | 156 | pr_debug("Setting NTB Input Size failed\n"); |
256 | } | 157 | } |
257 | 158 | ||
258 | /* verify maximum size of transmitted NTB in bytes */ | 159 | /* verify maximum size of transmitted NTB in bytes */ |
259 | if ((ctx->tx_max < | 160 | if ((ctx->tx_max < |
260 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || | 161 | (min_hdr_size + min_dgram_size)) || |
261 | (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) { | 162 | (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) { |
262 | pr_debug("Using default maximum transmit length=%d\n", | 163 | pr_debug("Using default maximum transmit length=%d\n", |
263 | CDC_NCM_NTB_MAX_SIZE_TX); | 164 | CDC_NCM_NTB_MAX_SIZE_TX); |
@@ -299,93 +200,85 @@ size_err: | |||
299 | } | 200 | } |
300 | 201 | ||
301 | /* adjust TX-remainder according to NCM specification. */ | 202 | /* adjust TX-remainder according to NCM specification. */ |
302 | ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) & | 203 | ctx->tx_remainder = ((ctx->tx_remainder - eth_hlen) & |
303 | (ctx->tx_modulus - 1)); | 204 | (ctx->tx_modulus - 1)); |
304 | 205 | ||
305 | /* additional configuration */ | 206 | /* additional configuration */ |
306 | 207 | ||
307 | /* set CRC Mode */ | 208 | /* set CRC Mode */ |
308 | if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { | 209 | if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { |
309 | err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), | 210 | err = usbnet_write_cmd(dev, USB_CDC_SET_CRC_MODE, |
310 | USB_CDC_SET_CRC_MODE, | 211 | USB_TYPE_CLASS | USB_DIR_OUT |
311 | USB_TYPE_CLASS | USB_DIR_OUT | 212 | | USB_RECIP_INTERFACE, |
312 | | USB_RECIP_INTERFACE, | 213 | USB_CDC_NCM_CRC_NOT_APPENDED, |
313 | USB_CDC_NCM_CRC_NOT_APPENDED, | 214 | iface_no, NULL, 0); |
314 | iface_no, NULL, 0, 1000); | ||
315 | if (err < 0) | 215 | if (err < 0) |
316 | pr_debug("Setting CRC mode off failed\n"); | 216 | pr_debug("Setting CRC mode off failed\n"); |
317 | } | 217 | } |
318 | 218 | ||
319 | /* set NTB format, if both formats are supported */ | 219 | /* set NTB format, if both formats are supported */ |
320 | if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { | 220 | if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { |
321 | err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), | 221 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, |
322 | USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS | 222 | USB_TYPE_CLASS | USB_DIR_OUT |
323 | | USB_DIR_OUT | USB_RECIP_INTERFACE, | 223 | | USB_RECIP_INTERFACE, |
324 | USB_CDC_NCM_NTB16_FORMAT, | 224 | USB_CDC_NCM_NTB16_FORMAT, |
325 | iface_no, NULL, 0, 1000); | 225 | iface_no, NULL, 0); |
326 | if (err < 0) | 226 | if (err < 0) |
327 | pr_debug("Setting NTB format to 16-bit failed\n"); | 227 | pr_debug("Setting NTB format to 16-bit failed\n"); |
328 | } | 228 | } |
329 | 229 | ||
330 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | 230 | ctx->max_datagram_size = min_dgram_size; |
331 | 231 | ||
332 | /* set Max Datagram Size (MTU) */ | 232 | /* set Max Datagram Size (MTU) */ |
333 | if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { | 233 | if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { |
334 | __le16 *max_datagram_size; | 234 | __le16 max_datagram_size; |
335 | u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); | 235 | u16 eth_max_sz; |
336 | 236 | if (ctx->ether_desc != NULL) | |
337 | max_datagram_size = kzalloc(sizeof(*max_datagram_size), | 237 | eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); |
338 | GFP_KERNEL); | 238 | else if (ctx->mbim_desc != NULL) |
339 | if (!max_datagram_size) { | 239 | eth_max_sz = le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize); |
340 | err = -ENOMEM; | 240 | else |
341 | goto max_dgram_err; | 241 | goto max_dgram_err; |
342 | } | ||
343 | 242 | ||
344 | err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0), | 243 | err = usbnet_read_cmd(dev, USB_CDC_GET_MAX_DATAGRAM_SIZE, |
345 | USB_CDC_GET_MAX_DATAGRAM_SIZE, | 244 | USB_TYPE_CLASS | USB_DIR_IN |
346 | USB_TYPE_CLASS | USB_DIR_IN | 245 | | USB_RECIP_INTERFACE, |
347 | | USB_RECIP_INTERFACE, | 246 | 0, iface_no, &max_datagram_size, 2); |
348 | 0, iface_no, max_datagram_size, | ||
349 | 2, 1000); | ||
350 | if (err < 0) { | 247 | if (err < 0) { |
351 | pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", | 248 | pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", |
352 | CDC_NCM_MIN_DATAGRAM_SIZE); | 249 | min_dgram_size); |
353 | } else { | 250 | } else { |
354 | ctx->max_datagram_size = | 251 | ctx->max_datagram_size = |
355 | le16_to_cpu(*max_datagram_size); | 252 | le16_to_cpu(max_datagram_size); |
356 | /* Check Eth descriptor value */ | 253 | /* Check Eth descriptor value */ |
357 | if (ctx->max_datagram_size > eth_max_sz) | 254 | if (ctx->max_datagram_size > eth_max_sz) |
358 | ctx->max_datagram_size = eth_max_sz; | 255 | ctx->max_datagram_size = eth_max_sz; |
359 | 256 | ||
360 | if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) | 257 | if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) |
361 | ctx->max_datagram_size = | 258 | ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; |
362 | CDC_NCM_MAX_DATAGRAM_SIZE; | ||
363 | 259 | ||
364 | if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) | 260 | if (ctx->max_datagram_size < min_dgram_size) |
365 | ctx->max_datagram_size = | 261 | ctx->max_datagram_size = min_dgram_size; |
366 | CDC_NCM_MIN_DATAGRAM_SIZE; | ||
367 | 262 | ||
368 | /* if value changed, update device */ | 263 | /* if value changed, update device */ |
369 | if (ctx->max_datagram_size != | 264 | if (ctx->max_datagram_size != |
370 | le16_to_cpu(*max_datagram_size)) { | 265 | le16_to_cpu(max_datagram_size)) { |
371 | err = usb_control_msg(ctx->udev, | 266 | err = usbnet_write_cmd(dev, |
372 | usb_sndctrlpipe(ctx->udev, 0), | ||
373 | USB_CDC_SET_MAX_DATAGRAM_SIZE, | 267 | USB_CDC_SET_MAX_DATAGRAM_SIZE, |
374 | USB_TYPE_CLASS | USB_DIR_OUT | 268 | USB_TYPE_CLASS | USB_DIR_OUT |
375 | | USB_RECIP_INTERFACE, | 269 | | USB_RECIP_INTERFACE, |
376 | 0, | 270 | 0, |
377 | iface_no, max_datagram_size, | 271 | iface_no, &max_datagram_size, |
378 | 2, 1000); | 272 | 2); |
379 | if (err < 0) | 273 | if (err < 0) |
380 | pr_debug("SET_MAX_DGRAM_SIZE failed\n"); | 274 | pr_debug("SET_MAX_DGRAM_SIZE failed\n"); |
381 | } | 275 | } |
382 | } | 276 | } |
383 | kfree(max_datagram_size); | ||
384 | } | 277 | } |
385 | 278 | ||
386 | max_dgram_err: | 279 | max_dgram_err: |
387 | if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) | 280 | if (ctx->netdev->mtu != (ctx->max_datagram_size - eth_hlen)) |
388 | ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN; | 281 | ctx->netdev->mtu = ctx->max_datagram_size - eth_hlen; |
389 | 282 | ||
390 | return 0; | 283 | return 0; |
391 | } | 284 | } |
@@ -451,7 +344,7 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = { | |||
451 | .nway_reset = usbnet_nway_reset, | 344 | .nway_reset = usbnet_nway_reset, |
452 | }; | 345 | }; |
453 | 346 | ||
454 | static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) | 347 | int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting) |
455 | { | 348 | { |
456 | struct cdc_ncm_ctx *ctx; | 349 | struct cdc_ncm_ctx *ctx; |
457 | struct usb_driver *driver; | 350 | struct usb_driver *driver; |
@@ -525,6 +418,13 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) | |||
525 | ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf; | 418 | ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf; |
526 | break; | 419 | break; |
527 | 420 | ||
421 | case USB_CDC_MBIM_TYPE: | ||
422 | if (buf[0] < sizeof(*(ctx->mbim_desc))) | ||
423 | break; | ||
424 | |||
425 | ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf; | ||
426 | break; | ||
427 | |||
528 | default: | 428 | default: |
529 | break; | 429 | break; |
530 | } | 430 | } |
@@ -537,7 +437,7 @@ advance: | |||
537 | 437 | ||
538 | /* check if we got everything */ | 438 | /* check if we got everything */ |
539 | if ((ctx->control == NULL) || (ctx->data == NULL) || | 439 | if ((ctx->control == NULL) || (ctx->data == NULL) || |
540 | (ctx->ether_desc == NULL) || (ctx->control != intf)) | 440 | ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) |
541 | goto error; | 441 | goto error; |
542 | 442 | ||
543 | /* claim interfaces, if any */ | 443 | /* claim interfaces, if any */ |
@@ -557,7 +457,7 @@ advance: | |||
557 | goto error2; | 457 | goto error2; |
558 | 458 | ||
559 | /* configure data interface */ | 459 | /* configure data interface */ |
560 | temp = usb_set_interface(dev->udev, iface_no, 1); | 460 | temp = usb_set_interface(dev->udev, iface_no, data_altsetting); |
561 | if (temp) | 461 | if (temp) |
562 | goto error2; | 462 | goto error2; |
563 | 463 | ||
@@ -574,11 +474,13 @@ advance: | |||
574 | usb_set_intfdata(ctx->control, dev); | 474 | usb_set_intfdata(ctx->control, dev); |
575 | usb_set_intfdata(ctx->intf, dev); | 475 | usb_set_intfdata(ctx->intf, dev); |
576 | 476 | ||
577 | temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); | 477 | if (ctx->ether_desc) { |
578 | if (temp) | 478 | temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); |
579 | goto error2; | 479 | if (temp) |
480 | goto error2; | ||
481 | dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr); | ||
482 | } | ||
580 | 483 | ||
581 | dev_info(&dev->udev->dev, "MAC-Address: %pM\n", dev->net->dev_addr); | ||
582 | 484 | ||
583 | dev->in = usb_rcvbulkpipe(dev->udev, | 485 | dev->in = usb_rcvbulkpipe(dev->udev, |
584 | ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 486 | ctx->in_ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
@@ -587,13 +489,6 @@ advance: | |||
587 | dev->status = ctx->status_ep; | 489 | dev->status = ctx->status_ep; |
588 | dev->rx_urb_size = ctx->rx_max; | 490 | dev->rx_urb_size = ctx->rx_max; |
589 | 491 | ||
590 | /* | ||
591 | * We should get an event when network connection is "connected" or | ||
592 | * "disconnected". Set network connection in "disconnected" state | ||
593 | * (carrier is OFF) during attach, so the IP network stack does not | ||
594 | * start IPv6 negotiation and more. | ||
595 | */ | ||
596 | netif_carrier_off(dev->net); | ||
597 | ctx->tx_speed = ctx->rx_speed = 0; | 492 | ctx->tx_speed = ctx->rx_speed = 0; |
598 | return 0; | 493 | return 0; |
599 | 494 | ||
@@ -607,8 +502,9 @@ error: | |||
607 | dev_info(&dev->udev->dev, "bind() failure\n"); | 502 | dev_info(&dev->udev->dev, "bind() failure\n"); |
608 | return -ENODEV; | 503 | return -ENODEV; |
609 | } | 504 | } |
505 | EXPORT_SYMBOL_GPL(cdc_ncm_bind_common); | ||
610 | 506 | ||
611 | static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) | 507 | void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) |
612 | { | 508 | { |
613 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; | 509 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; |
614 | struct usb_driver *driver = driver_of(intf); | 510 | struct usb_driver *driver = driver_of(intf); |
@@ -638,52 +534,121 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
638 | usb_set_intfdata(ctx->intf, NULL); | 534 | usb_set_intfdata(ctx->intf, NULL); |
639 | cdc_ncm_free(ctx); | 535 | cdc_ncm_free(ctx); |
640 | } | 536 | } |
537 | EXPORT_SYMBOL_GPL(cdc_ncm_unbind); | ||
641 | 538 | ||
642 | static void cdc_ncm_zero_fill(u8 *ptr, u32 first, u32 end, u32 max) | 539 | static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) |
643 | { | 540 | { |
644 | if (first >= max) | 541 | int ret; |
645 | return; | 542 | |
646 | if (first >= end) | 543 | /* The MBIM spec defines a NCM compatible default altsetting, |
647 | return; | 544 | * which we may have matched: |
648 | if (end > max) | 545 | * |
649 | end = max; | 546 | * "Functions that implement both NCM 1.0 and MBIM (an |
650 | memset(ptr + first, 0, end - first); | 547 | * “NCM/MBIM function”) according to this recommendation |
548 | * shall provide two alternate settings for the | ||
549 | * Communication Interface. Alternate setting 0, and the | ||
550 | * associated class and endpoint descriptors, shall be | ||
551 | * constructed according to the rules given for the | ||
552 | * Communication Interface in section 5 of [USBNCM10]. | ||
553 | * Alternate setting 1, and the associated class and | ||
554 | * endpoint descriptors, shall be constructed according to | ||
555 | * the rules given in section 6 (USB Device Model) of this | ||
556 | * specification." | ||
557 | * | ||
558 | * Do not bind to such interfaces, allowing cdc_mbim to handle | ||
559 | * them | ||
560 | */ | ||
561 | #if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) | ||
562 | if ((intf->num_altsetting == 2) && | ||
563 | !usb_set_interface(dev->udev, | ||
564 | intf->cur_altsetting->desc.bInterfaceNumber, | ||
565 | CDC_NCM_COMM_ALTSETTING_MBIM) && | ||
566 | cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) | ||
567 | return -ENODEV; | ||
568 | #endif | ||
569 | |||
570 | /* NCM data altsetting is always 1 */ | ||
571 | ret = cdc_ncm_bind_common(dev, intf, 1); | ||
572 | |||
573 | /* | ||
574 | * We should get an event when network connection is "connected" or | ||
575 | * "disconnected". Set network connection in "disconnected" state | ||
576 | * (carrier is OFF) during attach, so the IP network stack does not | ||
577 | * start IPv6 negotiation and more. | ||
578 | */ | ||
579 | netif_carrier_off(dev->net); | ||
580 | return ret; | ||
651 | } | 581 | } |
652 | 582 | ||
653 | static struct sk_buff * | 583 | static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max) |
654 | cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | ||
655 | { | 584 | { |
585 | size_t align = ALIGN(skb->len, modulus) - skb->len + remainder; | ||
586 | |||
587 | if (skb->len + align > max) | ||
588 | align = max - skb->len; | ||
589 | if (align && skb_tailroom(skb) >= align) | ||
590 | memset(skb_put(skb, align), 0, align); | ||
591 | } | ||
592 | |||
593 | /* return a pointer to a valid struct usb_cdc_ncm_ndp16 of type sign, possibly | ||
594 | * allocating a new one within skb | ||
595 | */ | ||
596 | static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) | ||
597 | { | ||
598 | struct usb_cdc_ncm_ndp16 *ndp16 = NULL; | ||
599 | struct usb_cdc_ncm_nth16 *nth16 = (void *)skb->data; | ||
600 | size_t ndpoffset = le16_to_cpu(nth16->wNdpIndex); | ||
601 | |||
602 | /* follow the chain of NDPs, looking for a match */ | ||
603 | while (ndpoffset) { | ||
604 | ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset); | ||
605 | if (ndp16->dwSignature == sign) | ||
606 | return ndp16; | ||
607 | ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); | ||
608 | } | ||
609 | |||
610 | /* align new NDP */ | ||
611 | cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_max); | ||
612 | |||
613 | /* verify that there is room for the NDP and the datagram (reserve) */ | ||
614 | if ((ctx->tx_max - skb->len - reserve) < CDC_NCM_NDP_SIZE) | ||
615 | return NULL; | ||
616 | |||
617 | /* link to it */ | ||
618 | if (ndp16) | ||
619 | ndp16->wNextNdpIndex = cpu_to_le16(skb->len); | ||
620 | else | ||
621 | nth16->wNdpIndex = cpu_to_le16(skb->len); | ||
622 | |||
623 | /* push a new empty NDP */ | ||
624 | ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, CDC_NCM_NDP_SIZE), 0, CDC_NCM_NDP_SIZE); | ||
625 | ndp16->dwSignature = sign; | ||
626 | ndp16->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp16) + sizeof(struct usb_cdc_ncm_dpe16)); | ||
627 | return ndp16; | ||
628 | } | ||
629 | |||
630 | struct sk_buff * | ||
631 | cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign) | ||
632 | { | ||
633 | struct usb_cdc_ncm_nth16 *nth16; | ||
634 | struct usb_cdc_ncm_ndp16 *ndp16; | ||
656 | struct sk_buff *skb_out; | 635 | struct sk_buff *skb_out; |
657 | u32 rem; | 636 | u16 n = 0, index, ndplen; |
658 | u32 offset; | ||
659 | u32 last_offset; | ||
660 | u16 n = 0, index; | ||
661 | u8 ready2send = 0; | 637 | u8 ready2send = 0; |
662 | 638 | ||
663 | /* if there is a remaining skb, it gets priority */ | 639 | /* if there is a remaining skb, it gets priority */ |
664 | if (skb != NULL) | 640 | if (skb != NULL) { |
665 | swap(skb, ctx->tx_rem_skb); | 641 | swap(skb, ctx->tx_rem_skb); |
666 | else | 642 | swap(sign, ctx->tx_rem_sign); |
643 | } else { | ||
667 | ready2send = 1; | 644 | ready2send = 1; |
668 | 645 | } | |
669 | /* | ||
670 | * +----------------+ | ||
671 | * | skb_out | | ||
672 | * +----------------+ | ||
673 | * ^ offset | ||
674 | * ^ last_offset | ||
675 | */ | ||
676 | 646 | ||
677 | /* check if we are resuming an OUT skb */ | 647 | /* check if we are resuming an OUT skb */ |
678 | if (ctx->tx_curr_skb != NULL) { | 648 | skb_out = ctx->tx_curr_skb; |
679 | /* pop variables */ | ||
680 | skb_out = ctx->tx_curr_skb; | ||
681 | offset = ctx->tx_curr_offset; | ||
682 | last_offset = ctx->tx_curr_last_offset; | ||
683 | n = ctx->tx_curr_frame_num; | ||
684 | 649 | ||
685 | } else { | 650 | /* allocate a new OUT skb */ |
686 | /* reset variables */ | 651 | if (!skb_out) { |
687 | skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC); | 652 | skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC); |
688 | if (skb_out == NULL) { | 653 | if (skb_out == NULL) { |
689 | if (skb != NULL) { | 654 | if (skb != NULL) { |
@@ -692,35 +657,21 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
692 | } | 657 | } |
693 | goto exit_no_skb; | 658 | goto exit_no_skb; |
694 | } | 659 | } |
660 | /* fill out the initial 16-bit NTB header */ | ||
661 | nth16 = (struct usb_cdc_ncm_nth16 *)memset(skb_put(skb_out, sizeof(struct usb_cdc_ncm_nth16)), 0, sizeof(struct usb_cdc_ncm_nth16)); | ||
662 | nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); | ||
663 | nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); | ||
664 | nth16->wSequence = cpu_to_le16(ctx->tx_seq++); | ||
695 | 665 | ||
696 | /* make room for NTH and NDP */ | 666 | /* count total number of frames in this NTB */ |
697 | offset = ALIGN(sizeof(struct usb_cdc_ncm_nth16), | ||
698 | ctx->tx_ndp_modulus) + | ||
699 | sizeof(struct usb_cdc_ncm_ndp16) + | ||
700 | (ctx->tx_max_datagrams + 1) * | ||
701 | sizeof(struct usb_cdc_ncm_dpe16); | ||
702 | |||
703 | /* store last valid offset before alignment */ | ||
704 | last_offset = offset; | ||
705 | /* align first Datagram offset correctly */ | ||
706 | offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder; | ||
707 | /* zero buffer till the first IP datagram */ | ||
708 | cdc_ncm_zero_fill(skb_out->data, 0, offset, offset); | ||
709 | n = 0; | ||
710 | ctx->tx_curr_frame_num = 0; | 667 | ctx->tx_curr_frame_num = 0; |
711 | } | 668 | } |
712 | 669 | ||
713 | for (; n < ctx->tx_max_datagrams; n++) { | 670 | for (n = ctx->tx_curr_frame_num; n < ctx->tx_max_datagrams; n++) { |
714 | /* check if end of transmit buffer is reached */ | 671 | /* send any remaining skb first */ |
715 | if (offset >= ctx->tx_max) { | ||
716 | ready2send = 1; | ||
717 | break; | ||
718 | } | ||
719 | /* compute maximum buffer size */ | ||
720 | rem = ctx->tx_max - offset; | ||
721 | |||
722 | if (skb == NULL) { | 672 | if (skb == NULL) { |
723 | skb = ctx->tx_rem_skb; | 673 | skb = ctx->tx_rem_skb; |
674 | sign = ctx->tx_rem_sign; | ||
724 | ctx->tx_rem_skb = NULL; | 675 | ctx->tx_rem_skb = NULL; |
725 | 676 | ||
726 | /* check for end of skb */ | 677 | /* check for end of skb */ |
@@ -728,7 +679,14 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
728 | break; | 679 | break; |
729 | } | 680 | } |
730 | 681 | ||
731 | if (skb->len > rem) { | 682 | /* get the appropriate NDP for this skb */ |
683 | ndp16 = cdc_ncm_ndp(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); | ||
684 | |||
685 | /* align beginning of next frame */ | ||
686 | cdc_ncm_align_tail(skb_out, ctx->tx_modulus, ctx->tx_remainder, ctx->tx_max); | ||
687 | |||
688 | /* check if we had enough room left for both NDP and frame */ | ||
689 | if (!ndp16 || skb_out->len + skb->len > ctx->tx_max) { | ||
732 | if (n == 0) { | 690 | if (n == 0) { |
733 | /* won't fit, MTU problem? */ | 691 | /* won't fit, MTU problem? */ |
734 | dev_kfree_skb_any(skb); | 692 | dev_kfree_skb_any(skb); |
@@ -741,31 +699,30 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
741 | ctx->netdev->stats.tx_dropped++; | 699 | ctx->netdev->stats.tx_dropped++; |
742 | } | 700 | } |
743 | ctx->tx_rem_skb = skb; | 701 | ctx->tx_rem_skb = skb; |
702 | ctx->tx_rem_sign = sign; | ||
744 | skb = NULL; | 703 | skb = NULL; |
745 | ready2send = 1; | 704 | ready2send = 1; |
746 | } | 705 | } |
747 | break; | 706 | break; |
748 | } | 707 | } |
749 | 708 | ||
750 | memcpy(((u8 *)skb_out->data) + offset, skb->data, skb->len); | 709 | /* calculate frame number withing this NDP */ |
710 | ndplen = le16_to_cpu(ndp16->wLength); | ||
711 | index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; | ||
751 | 712 | ||
752 | ctx->tx_ncm.dpe16[n].wDatagramLength = cpu_to_le16(skb->len); | 713 | /* OK, add this skb */ |
753 | ctx->tx_ncm.dpe16[n].wDatagramIndex = cpu_to_le16(offset); | 714 | ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); |
754 | 715 | ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); | |
755 | /* update offset */ | 716 | ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); |
756 | offset += skb->len; | 717 | memcpy(skb_put(skb_out, skb->len), skb->data, skb->len); |
757 | |||
758 | /* store last valid offset before alignment */ | ||
759 | last_offset = offset; | ||
760 | |||
761 | /* align offset correctly */ | ||
762 | offset = ALIGN(offset, ctx->tx_modulus) + ctx->tx_remainder; | ||
763 | |||
764 | /* zero padding */ | ||
765 | cdc_ncm_zero_fill(skb_out->data, last_offset, offset, | ||
766 | ctx->tx_max); | ||
767 | dev_kfree_skb_any(skb); | 718 | dev_kfree_skb_any(skb); |
768 | skb = NULL; | 719 | skb = NULL; |
720 | |||
721 | /* send now if this NDP is full */ | ||
722 | if (index >= CDC_NCM_DPT_DATAGRAMS_MAX) { | ||
723 | ready2send = 1; | ||
724 | break; | ||
725 | } | ||
769 | } | 726 | } |
770 | 727 | ||
771 | /* free up any dangling skb */ | 728 | /* free up any dangling skb */ |
@@ -781,16 +738,12 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
781 | /* wait for more frames */ | 738 | /* wait for more frames */ |
782 | /* push variables */ | 739 | /* push variables */ |
783 | ctx->tx_curr_skb = skb_out; | 740 | ctx->tx_curr_skb = skb_out; |
784 | ctx->tx_curr_offset = offset; | ||
785 | ctx->tx_curr_last_offset = last_offset; | ||
786 | goto exit_no_skb; | 741 | goto exit_no_skb; |
787 | 742 | ||
788 | } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) { | 743 | } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) { |
789 | /* wait for more frames */ | 744 | /* wait for more frames */ |
790 | /* push variables */ | 745 | /* push variables */ |
791 | ctx->tx_curr_skb = skb_out; | 746 | ctx->tx_curr_skb = skb_out; |
792 | ctx->tx_curr_offset = offset; | ||
793 | ctx->tx_curr_last_offset = last_offset; | ||
794 | /* set the pending count */ | 747 | /* set the pending count */ |
795 | if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT) | 748 | if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT) |
796 | ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT; | 749 | ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT; |
@@ -801,75 +754,24 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
801 | /* variables will be reset at next call */ | 754 | /* variables will be reset at next call */ |
802 | } | 755 | } |
803 | 756 | ||
804 | /* check for overflow */ | ||
805 | if (last_offset > ctx->tx_max) | ||
806 | last_offset = ctx->tx_max; | ||
807 | |||
808 | /* revert offset */ | ||
809 | offset = last_offset; | ||
810 | |||
811 | /* | 757 | /* |
812 | * If collected data size is less or equal CDC_NCM_MIN_TX_PKT bytes, | 758 | * If collected data size is less or equal CDC_NCM_MIN_TX_PKT bytes, |
813 | * we send buffers as it is. If we get more data, it would be more | 759 | * we send buffers as it is. If we get more data, it would be more |
814 | * efficient for USB HS mobile device with DMA engine to receive a full | 760 | * efficient for USB HS mobile device with DMA engine to receive a full |
815 | * size NTB, than canceling DMA transfer and receiving a short packet. | 761 | * size NTB, than canceling DMA transfer and receiving a short packet. |
816 | */ | 762 | */ |
817 | if (offset > CDC_NCM_MIN_TX_PKT) | 763 | if (skb_out->len > CDC_NCM_MIN_TX_PKT) |
818 | offset = ctx->tx_max; | 764 | /* final zero padding */ |
819 | 765 | memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, ctx->tx_max - skb_out->len); | |
820 | /* final zero padding */ | ||
821 | cdc_ncm_zero_fill(skb_out->data, last_offset, offset, ctx->tx_max); | ||
822 | |||
823 | /* store last offset */ | ||
824 | last_offset = offset; | ||
825 | |||
826 | if (((last_offset < ctx->tx_max) && ((last_offset % | ||
827 | le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) || | ||
828 | (((last_offset == ctx->tx_max) && ((ctx->tx_max % | ||
829 | le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) && | ||
830 | (ctx->tx_max < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)))) { | ||
831 | /* force short packet */ | ||
832 | *(((u8 *)skb_out->data) + last_offset) = 0; | ||
833 | last_offset++; | ||
834 | } | ||
835 | 766 | ||
836 | /* zero the rest of the DPEs plus the last NULL entry */ | 767 | /* do we need to prevent a ZLP? */ |
837 | for (; n <= CDC_NCM_DPT_DATAGRAMS_MAX; n++) { | 768 | if (((skb_out->len % le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0) && |
838 | ctx->tx_ncm.dpe16[n].wDatagramLength = 0; | 769 | (skb_out->len < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)) && skb_tailroom(skb_out)) |
839 | ctx->tx_ncm.dpe16[n].wDatagramIndex = 0; | 770 | *skb_put(skb_out, 1) = 0; /* force short packet */ |
840 | } | ||
841 | |||
842 | /* fill out 16-bit NTB header */ | ||
843 | ctx->tx_ncm.nth16.dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); | ||
844 | ctx->tx_ncm.nth16.wHeaderLength = | ||
845 | cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); | ||
846 | ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); | ||
847 | ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); | ||
848 | index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus); | ||
849 | ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index); | ||
850 | |||
851 | memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); | ||
852 | ctx->tx_seq++; | ||
853 | |||
854 | /* fill out 16-bit NDP table */ | ||
855 | ctx->tx_ncm.ndp16.dwSignature = | ||
856 | cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN); | ||
857 | rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * | ||
858 | sizeof(struct usb_cdc_ncm_dpe16)); | ||
859 | ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); | ||
860 | ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ | ||
861 | 771 | ||
862 | memcpy(((u8 *)skb_out->data) + index, | 772 | /* set final frame length */ |
863 | &(ctx->tx_ncm.ndp16), | 773 | nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; |
864 | sizeof(ctx->tx_ncm.ndp16)); | 774 | nth16->wBlockLength = cpu_to_le16(skb_out->len); |
865 | |||
866 | memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16), | ||
867 | &(ctx->tx_ncm.dpe16), | ||
868 | (ctx->tx_curr_frame_num + 1) * | ||
869 | sizeof(struct usb_cdc_ncm_dpe16)); | ||
870 | |||
871 | /* set frame length */ | ||
872 | skb_put(skb_out, last_offset); | ||
873 | 775 | ||
874 | /* return skb */ | 776 | /* return skb */ |
875 | ctx->tx_curr_skb = NULL; | 777 | ctx->tx_curr_skb = NULL; |
@@ -882,6 +784,7 @@ exit_no_skb: | |||
882 | cdc_ncm_tx_timeout_start(ctx); | 784 | cdc_ncm_tx_timeout_start(ctx); |
883 | return NULL; | 785 | return NULL; |
884 | } | 786 | } |
787 | EXPORT_SYMBOL_GPL(cdc_ncm_fill_tx_frame); | ||
885 | 788 | ||
886 | static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) | 789 | static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) |
887 | { | 790 | { |
@@ -916,6 +819,8 @@ static void cdc_ncm_txpath_bh(unsigned long param) | |||
916 | netif_tx_lock_bh(ctx->netdev); | 819 | netif_tx_lock_bh(ctx->netdev); |
917 | usbnet_start_xmit(NULL, ctx->netdev); | 820 | usbnet_start_xmit(NULL, ctx->netdev); |
918 | netif_tx_unlock_bh(ctx->netdev); | 821 | netif_tx_unlock_bh(ctx->netdev); |
822 | } else { | ||
823 | spin_unlock_bh(&ctx->mtx); | ||
919 | } | 824 | } |
920 | } | 825 | } |
921 | 826 | ||
@@ -936,7 +841,7 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | |||
936 | goto error; | 841 | goto error; |
937 | 842 | ||
938 | spin_lock_bh(&ctx->mtx); | 843 | spin_lock_bh(&ctx->mtx); |
939 | skb_out = cdc_ncm_fill_tx_frame(ctx, skb); | 844 | skb_out = cdc_ncm_fill_tx_frame(ctx, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)); |
940 | spin_unlock_bh(&ctx->mtx); | 845 | spin_unlock_bh(&ctx->mtx); |
941 | return skb_out; | 846 | return skb_out; |
942 | 847 | ||
@@ -947,17 +852,12 @@ error: | |||
947 | return NULL; | 852 | return NULL; |
948 | } | 853 | } |
949 | 854 | ||
950 | static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | 855 | /* verify NTB header and return offset of first NDP, or negative error */ |
856 | int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in) | ||
951 | { | 857 | { |
952 | struct sk_buff *skb; | ||
953 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; | ||
954 | int len; | ||
955 | int nframes; | ||
956 | int x; | ||
957 | int offset; | ||
958 | struct usb_cdc_ncm_nth16 *nth16; | 858 | struct usb_cdc_ncm_nth16 *nth16; |
959 | struct usb_cdc_ncm_ndp16 *ndp16; | 859 | int len; |
960 | struct usb_cdc_ncm_dpe16 *dpe16; | 860 | int ret = -EINVAL; |
961 | 861 | ||
962 | if (ctx == NULL) | 862 | if (ctx == NULL) |
963 | goto error; | 863 | goto error; |
@@ -991,20 +891,23 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
991 | } | 891 | } |
992 | ctx->rx_seq = le16_to_cpu(nth16->wSequence); | 892 | ctx->rx_seq = le16_to_cpu(nth16->wSequence); |
993 | 893 | ||
994 | len = le16_to_cpu(nth16->wNdpIndex); | 894 | ret = le16_to_cpu(nth16->wNdpIndex); |
995 | if ((len + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) { | 895 | error: |
996 | pr_debug("invalid DPT16 index <%u>\n", | 896 | return ret; |
997 | le16_to_cpu(nth16->wNdpIndex)); | 897 | } |
998 | goto error; | 898 | EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_nth16); |
999 | } | ||
1000 | 899 | ||
1001 | ndp16 = (struct usb_cdc_ncm_ndp16 *)(((u8 *)skb_in->data) + len); | 900 | /* verify NDP header and return number of datagrams, or negative error */ |
901 | int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset) | ||
902 | { | ||
903 | struct usb_cdc_ncm_ndp16 *ndp16; | ||
904 | int ret = -EINVAL; | ||
1002 | 905 | ||
1003 | if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) { | 906 | if ((ndpoffset + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) { |
1004 | pr_debug("invalid DPT16 signature <%u>\n", | 907 | pr_debug("invalid NDP offset <%u>\n", ndpoffset); |
1005 | le32_to_cpu(ndp16->dwSignature)); | ||
1006 | goto error; | 908 | goto error; |
1007 | } | 909 | } |
910 | ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); | ||
1008 | 911 | ||
1009 | if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) { | 912 | if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) { |
1010 | pr_debug("invalid DPT16 length <%u>\n", | 913 | pr_debug("invalid DPT16 length <%u>\n", |
@@ -1012,20 +915,52 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
1012 | goto error; | 915 | goto error; |
1013 | } | 916 | } |
1014 | 917 | ||
1015 | nframes = ((le16_to_cpu(ndp16->wLength) - | 918 | ret = ((le16_to_cpu(ndp16->wLength) - |
1016 | sizeof(struct usb_cdc_ncm_ndp16)) / | 919 | sizeof(struct usb_cdc_ncm_ndp16)) / |
1017 | sizeof(struct usb_cdc_ncm_dpe16)); | 920 | sizeof(struct usb_cdc_ncm_dpe16)); |
1018 | nframes--; /* we process NDP entries except for the last one */ | 921 | ret--; /* we process NDP entries except for the last one */ |
1019 | |||
1020 | len += sizeof(struct usb_cdc_ncm_ndp16); | ||
1021 | 922 | ||
1022 | if ((len + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > | 923 | if ((sizeof(struct usb_cdc_ncm_ndp16) + ret * (sizeof(struct usb_cdc_ncm_dpe16))) > |
1023 | skb_in->len) { | 924 | skb_in->len) { |
1024 | pr_debug("Invalid nframes = %d\n", nframes); | 925 | pr_debug("Invalid nframes = %d\n", ret); |
1025 | goto error; | 926 | ret = -EINVAL; |
1026 | } | 927 | } |
1027 | 928 | ||
1028 | dpe16 = (struct usb_cdc_ncm_dpe16 *)(((u8 *)skb_in->data) + len); | 929 | error: |
930 | return ret; | ||
931 | } | ||
932 | EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp16); | ||
933 | |||
934 | static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | ||
935 | { | ||
936 | struct sk_buff *skb; | ||
937 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; | ||
938 | int len; | ||
939 | int nframes; | ||
940 | int x; | ||
941 | int offset; | ||
942 | struct usb_cdc_ncm_ndp16 *ndp16; | ||
943 | struct usb_cdc_ncm_dpe16 *dpe16; | ||
944 | int ndpoffset; | ||
945 | int loopcount = 50; /* arbitrary max preventing infinite loop */ | ||
946 | |||
947 | ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); | ||
948 | if (ndpoffset < 0) | ||
949 | goto error; | ||
950 | |||
951 | next_ndp: | ||
952 | nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); | ||
953 | if (nframes < 0) | ||
954 | goto error; | ||
955 | |||
956 | ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); | ||
957 | |||
958 | if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) { | ||
959 | pr_debug("invalid DPT16 signature <%u>\n", | ||
960 | le32_to_cpu(ndp16->dwSignature)); | ||
961 | goto err_ndp; | ||
962 | } | ||
963 | dpe16 = ndp16->dpe16; | ||
1029 | 964 | ||
1030 | for (x = 0; x < nframes; x++, dpe16++) { | 965 | for (x = 0; x < nframes; x++, dpe16++) { |
1031 | offset = le16_to_cpu(dpe16->wDatagramIndex); | 966 | offset = le16_to_cpu(dpe16->wDatagramIndex); |
@@ -1037,7 +972,7 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
1037 | */ | 972 | */ |
1038 | if ((offset == 0) || (len == 0)) { | 973 | if ((offset == 0) || (len == 0)) { |
1039 | if (!x) | 974 | if (!x) |
1040 | goto error; /* empty NTB */ | 975 | goto err_ndp; /* empty NTB */ |
1041 | break; | 976 | break; |
1042 | } | 977 | } |
1043 | 978 | ||
@@ -1048,7 +983,7 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
1048 | "offset[%u]=%u, length=%u, skb=%p\n", | 983 | "offset[%u]=%u, length=%u, skb=%p\n", |
1049 | x, offset, len, skb_in); | 984 | x, offset, len, skb_in); |
1050 | if (!x) | 985 | if (!x) |
1051 | goto error; | 986 | goto err_ndp; |
1052 | break; | 987 | break; |
1053 | 988 | ||
1054 | } else { | 989 | } else { |
@@ -1061,6 +996,12 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
1061 | usbnet_skb_return(dev, skb); | 996 | usbnet_skb_return(dev, skb); |
1062 | } | 997 | } |
1063 | } | 998 | } |
999 | err_ndp: | ||
1000 | /* are there more NDPs to process? */ | ||
1001 | ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); | ||
1002 | if (ndpoffset && loopcount--) | ||
1003 | goto next_ndp; | ||
1004 | |||
1064 | return 1; | 1005 | return 1; |
1065 | error: | 1006 | error: |
1066 | return 0; | 1007 | return 0; |
@@ -1125,7 +1066,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) | |||
1125 | * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be | 1066 | * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be |
1126 | * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. | 1067 | * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. |
1127 | */ | 1068 | */ |
1128 | ctx->connected = event->wValue; | 1069 | ctx->connected = le16_to_cpu(event->wValue); |
1129 | 1070 | ||
1130 | printk(KERN_INFO KBUILD_MODNAME ": %s: network connection:" | 1071 | printk(KERN_INFO KBUILD_MODNAME ": %s: network connection:" |
1131 | " %sconnected\n", | 1072 | " %sconnected\n", |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index e0433ce6ced7..3f554c1149f3 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -56,27 +56,12 @@ | |||
56 | 56 | ||
57 | static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) | 57 | static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) |
58 | { | 58 | { |
59 | void *buf; | 59 | int err; |
60 | int err = -ENOMEM; | 60 | err = usbnet_read_cmd(dev, DM_READ_REGS, |
61 | 61 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
62 | netdev_dbg(dev->net, "dm_read() reg=0x%02x length=%d\n", reg, length); | 62 | 0, reg, data, length); |
63 | 63 | if(err != length && err >= 0) | |
64 | buf = kmalloc(length, GFP_KERNEL); | ||
65 | if (!buf) | ||
66 | goto out; | ||
67 | |||
68 | err = usb_control_msg(dev->udev, | ||
69 | usb_rcvctrlpipe(dev->udev, 0), | ||
70 | DM_READ_REGS, | ||
71 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
72 | 0, reg, buf, length, USB_CTRL_SET_TIMEOUT); | ||
73 | if (err == length) | ||
74 | memcpy(data, buf, length); | ||
75 | else if (err >= 0) | ||
76 | err = -EINVAL; | 64 | err = -EINVAL; |
77 | kfree(buf); | ||
78 | |||
79 | out: | ||
80 | return err; | 65 | return err; |
81 | } | 66 | } |
82 | 67 | ||
@@ -87,91 +72,29 @@ static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value) | |||
87 | 72 | ||
88 | static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) | 73 | static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) |
89 | { | 74 | { |
90 | void *buf = NULL; | 75 | int err; |
91 | int err = -ENOMEM; | 76 | err = usbnet_write_cmd(dev, DM_WRITE_REGS, |
92 | 77 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
93 | netdev_dbg(dev->net, "dm_write() reg=0x%02x, length=%d\n", reg, length); | 78 | 0, reg, data, length); |
94 | 79 | ||
95 | if (data) { | ||
96 | buf = kmemdup(data, length, GFP_KERNEL); | ||
97 | if (!buf) | ||
98 | goto out; | ||
99 | } | ||
100 | |||
101 | err = usb_control_msg(dev->udev, | ||
102 | usb_sndctrlpipe(dev->udev, 0), | ||
103 | DM_WRITE_REGS, | ||
104 | USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE, | ||
105 | 0, reg, buf, length, USB_CTRL_SET_TIMEOUT); | ||
106 | kfree(buf); | ||
107 | if (err >= 0 && err < length) | 80 | if (err >= 0 && err < length) |
108 | err = -EINVAL; | 81 | err = -EINVAL; |
109 | out: | ||
110 | return err; | 82 | return err; |
111 | } | 83 | } |
112 | 84 | ||
113 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) | 85 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) |
114 | { | 86 | { |
115 | netdev_dbg(dev->net, "dm_write_reg() reg=0x%02x, value=0x%02x\n", | 87 | return usbnet_write_cmd(dev, DM_WRITE_REGS, |
116 | reg, value); | 88 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
117 | return usb_control_msg(dev->udev, | 89 | value, reg, NULL, 0); |
118 | usb_sndctrlpipe(dev->udev, 0), | ||
119 | DM_WRITE_REG, | ||
120 | USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE, | ||
121 | value, reg, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
122 | } | ||
123 | |||
124 | static void dm_write_async_callback(struct urb *urb) | ||
125 | { | ||
126 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
127 | int status = urb->status; | ||
128 | |||
129 | if (status < 0) | ||
130 | printk(KERN_DEBUG "dm_write_async_callback() failed with %d\n", | ||
131 | status); | ||
132 | |||
133 | kfree(req); | ||
134 | usb_free_urb(urb); | ||
135 | } | 90 | } |
136 | 91 | ||
137 | static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, | 92 | static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, |
138 | u16 length, void *data) | 93 | u16 length, void *data) |
139 | { | 94 | { |
140 | struct usb_ctrlrequest *req; | 95 | usbnet_write_cmd_async(dev, DM_WRITE_REGS, |
141 | struct urb *urb; | 96 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
142 | int status; | 97 | value, reg, data, length); |
143 | |||
144 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
145 | if (!urb) { | ||
146 | netdev_err(dev->net, "Error allocating URB in dm_write_async_helper!\n"); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); | ||
151 | if (!req) { | ||
152 | netdev_err(dev->net, "Failed to allocate memory for control request\n"); | ||
153 | usb_free_urb(urb); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | ||
158 | req->bRequest = length ? DM_WRITE_REGS : DM_WRITE_REG; | ||
159 | req->wValue = cpu_to_le16(value); | ||
160 | req->wIndex = cpu_to_le16(reg); | ||
161 | req->wLength = cpu_to_le16(length); | ||
162 | |||
163 | usb_fill_control_urb(urb, dev->udev, | ||
164 | usb_sndctrlpipe(dev->udev, 0), | ||
165 | (void *)req, data, length, | ||
166 | dm_write_async_callback, req); | ||
167 | |||
168 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
169 | if (status < 0) { | ||
170 | netdev_err(dev->net, "Error submitting the control message: status=%d\n", | ||
171 | status); | ||
172 | kfree(req); | ||
173 | usb_free_urb(urb); | ||
174 | } | ||
175 | } | 98 | } |
176 | 99 | ||
177 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) | 100 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) |
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index 8de641713d5f..ace9e74ffbdd 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c | |||
@@ -116,23 +116,8 @@ static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev, | |||
116 | return skb; | 116 | return skb; |
117 | } | 117 | } |
118 | 118 | ||
119 | static void int51x1_async_cmd_callback(struct urb *urb) | ||
120 | { | ||
121 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
122 | int status = urb->status; | ||
123 | |||
124 | if (status < 0) | ||
125 | dev_warn(&urb->dev->dev, "async callback failed with %d\n", status); | ||
126 | |||
127 | kfree(req); | ||
128 | usb_free_urb(urb); | ||
129 | } | ||
130 | |||
131 | static void int51x1_set_multicast(struct net_device *netdev) | 119 | static void int51x1_set_multicast(struct net_device *netdev) |
132 | { | 120 | { |
133 | struct usb_ctrlrequest *req; | ||
134 | int status; | ||
135 | struct urb *urb; | ||
136 | struct usbnet *dev = netdev_priv(netdev); | 121 | struct usbnet *dev = netdev_priv(netdev); |
137 | u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST; | 122 | u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST; |
138 | 123 | ||
@@ -149,40 +134,9 @@ static void int51x1_set_multicast(struct net_device *netdev) | |||
149 | netdev_dbg(dev->net, "receive own packets only\n"); | 134 | netdev_dbg(dev->net, "receive own packets only\n"); |
150 | } | 135 | } |
151 | 136 | ||
152 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 137 | usbnet_write_cmd_async(dev, SET_ETHERNET_PACKET_FILTER, |
153 | if (!urb) { | 138 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
154 | netdev_warn(dev->net, "Error allocating URB\n"); | 139 | filter, 0, NULL, 0); |
155 | return; | ||
156 | } | ||
157 | |||
158 | req = kmalloc(sizeof(*req), GFP_ATOMIC); | ||
159 | if (!req) { | ||
160 | netdev_warn(dev->net, "Error allocating control msg\n"); | ||
161 | goto out; | ||
162 | } | ||
163 | |||
164 | req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | ||
165 | req->bRequest = SET_ETHERNET_PACKET_FILTER; | ||
166 | req->wValue = cpu_to_le16(filter); | ||
167 | req->wIndex = 0; | ||
168 | req->wLength = 0; | ||
169 | |||
170 | usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
171 | (void *)req, NULL, 0, | ||
172 | int51x1_async_cmd_callback, | ||
173 | (void *)req); | ||
174 | |||
175 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
176 | if (status < 0) { | ||
177 | netdev_warn(dev->net, "Error submitting control msg, sts=%d\n", | ||
178 | status); | ||
179 | goto out1; | ||
180 | } | ||
181 | return; | ||
182 | out1: | ||
183 | kfree(req); | ||
184 | out: | ||
185 | usb_free_urb(urb); | ||
186 | } | 140 | } |
187 | 141 | ||
188 | static const struct net_device_ops int51x1_netdev_ops = { | 142 | static const struct net_device_ops int51x1_netdev_ops = { |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index cc7e72010ac3..3f3f566afa0b 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -124,93 +124,20 @@ static const char driver_name[] = "MOSCHIP usb-ethernet driver"; | |||
124 | 124 | ||
125 | static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) | 125 | static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) |
126 | { | 126 | { |
127 | struct usb_device *xdev = dev->udev; | 127 | return usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, |
128 | int ret; | 128 | 0x0000, index, data, size); |
129 | void *buffer; | ||
130 | |||
131 | buffer = kmalloc(size, GFP_NOIO); | ||
132 | if (buffer == NULL) | ||
133 | return -ENOMEM; | ||
134 | |||
135 | ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ, | ||
136 | MCS7830_RD_BMREQ, 0x0000, index, buffer, | ||
137 | size, MCS7830_CTRL_TIMEOUT); | ||
138 | memcpy(data, buffer, size); | ||
139 | kfree(buffer); | ||
140 | |||
141 | return ret; | ||
142 | } | 129 | } |
143 | 130 | ||
144 | static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) | 131 | static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) |
145 | { | 132 | { |
146 | struct usb_device *xdev = dev->udev; | 133 | return usbnet_write_cmd(dev, MCS7830_WR_BREQ, MCS7830_WR_BMREQ, |
147 | int ret; | 134 | 0x0000, index, data, size); |
148 | void *buffer; | ||
149 | |||
150 | buffer = kmemdup(data, size, GFP_NOIO); | ||
151 | if (buffer == NULL) | ||
152 | return -ENOMEM; | ||
153 | |||
154 | ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ, | ||
155 | MCS7830_WR_BMREQ, 0x0000, index, buffer, | ||
156 | size, MCS7830_CTRL_TIMEOUT); | ||
157 | kfree(buffer); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static void mcs7830_async_cmd_callback(struct urb *urb) | ||
162 | { | ||
163 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
164 | int status = urb->status; | ||
165 | |||
166 | if (status < 0) | ||
167 | printk(KERN_DEBUG "%s() failed with %d\n", | ||
168 | __func__, status); | ||
169 | |||
170 | kfree(req); | ||
171 | usb_free_urb(urb); | ||
172 | } | 135 | } |
173 | 136 | ||
174 | static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data) | 137 | static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data) |
175 | { | 138 | { |
176 | struct usb_ctrlrequest *req; | 139 | usbnet_write_cmd_async(dev, MCS7830_WR_BREQ, MCS7830_WR_BMREQ, |
177 | int ret; | 140 | 0x0000, index, data, size); |
178 | struct urb *urb; | ||
179 | |||
180 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
181 | if (!urb) { | ||
182 | dev_dbg(&dev->udev->dev, | ||
183 | "Error allocating URB in write_cmd_async!\n"); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | req = kmalloc(sizeof *req, GFP_ATOMIC); | ||
188 | if (!req) { | ||
189 | dev_err(&dev->udev->dev, | ||
190 | "Failed to allocate memory for control request\n"); | ||
191 | goto out; | ||
192 | } | ||
193 | req->bRequestType = MCS7830_WR_BMREQ; | ||
194 | req->bRequest = MCS7830_WR_BREQ; | ||
195 | req->wValue = 0; | ||
196 | req->wIndex = cpu_to_le16(index); | ||
197 | req->wLength = cpu_to_le16(size); | ||
198 | |||
199 | usb_fill_control_urb(urb, dev->udev, | ||
200 | usb_sndctrlpipe(dev->udev, 0), | ||
201 | (void *)req, data, size, | ||
202 | mcs7830_async_cmd_callback, req); | ||
203 | |||
204 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
205 | if (ret < 0) { | ||
206 | dev_err(&dev->udev->dev, | ||
207 | "Error submitting the control message: ret=%d\n", ret); | ||
208 | goto out; | ||
209 | } | ||
210 | return; | ||
211 | out: | ||
212 | kfree(req); | ||
213 | usb_free_urb(urb); | ||
214 | } | 141 | } |
215 | 142 | ||
216 | static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr) | 143 | static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr) |
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index c062a3e8295c..93e0716a118c 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -109,13 +109,11 @@ struct nc_trailer { | |||
109 | static int | 109 | static int |
110 | nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) | 110 | nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) |
111 | { | 111 | { |
112 | int status = usb_control_msg(dev->udev, | 112 | int status = usbnet_read_cmd(dev, req, |
113 | usb_rcvctrlpipe(dev->udev, 0), | 113 | USB_DIR_IN | USB_TYPE_VENDOR | |
114 | req, | 114 | USB_RECIP_DEVICE, |
115 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 115 | 0, regnum, retval_ptr, |
116 | 0, regnum, | 116 | sizeof *retval_ptr); |
117 | retval_ptr, sizeof *retval_ptr, | ||
118 | USB_CTRL_GET_TIMEOUT); | ||
119 | if (status > 0) | 117 | if (status > 0) |
120 | status = 0; | 118 | status = 0; |
121 | if (!status) | 119 | if (!status) |
@@ -133,13 +131,9 @@ nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr) | |||
133 | static void | 131 | static void |
134 | nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value) | 132 | nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value) |
135 | { | 133 | { |
136 | usb_control_msg(dev->udev, | 134 | usbnet_write_cmd(dev, req, |
137 | usb_sndctrlpipe(dev->udev, 0), | 135 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
138 | req, | 136 | value, regnum, NULL, 0); |
139 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
140 | value, regnum, | ||
141 | NULL, 0, // data is in setup packet | ||
142 | USB_CTRL_SET_TIMEOUT); | ||
143 | } | 137 | } |
144 | 138 | ||
145 | static inline void | 139 | static inline void |
@@ -288,37 +282,34 @@ static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) | |||
288 | static int net1080_reset(struct usbnet *dev) | 282 | static int net1080_reset(struct usbnet *dev) |
289 | { | 283 | { |
290 | u16 usbctl, status, ttl; | 284 | u16 usbctl, status, ttl; |
291 | u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL); | 285 | u16 vp; |
292 | int retval; | 286 | int retval; |
293 | 287 | ||
294 | if (!vp) | ||
295 | return -ENOMEM; | ||
296 | |||
297 | // nc_dump_registers(dev); | 288 | // nc_dump_registers(dev); |
298 | 289 | ||
299 | if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) { | 290 | if ((retval = nc_register_read(dev, REG_STATUS, &vp)) < 0) { |
300 | netdev_dbg(dev->net, "can't read %s-%s status: %d\n", | 291 | netdev_dbg(dev->net, "can't read %s-%s status: %d\n", |
301 | dev->udev->bus->bus_name, dev->udev->devpath, retval); | 292 | dev->udev->bus->bus_name, dev->udev->devpath, retval); |
302 | goto done; | 293 | goto done; |
303 | } | 294 | } |
304 | status = *vp; | 295 | status = vp; |
305 | nc_dump_status(dev, status); | 296 | nc_dump_status(dev, status); |
306 | 297 | ||
307 | if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) { | 298 | if ((retval = nc_register_read(dev, REG_USBCTL, &vp)) < 0) { |
308 | netdev_dbg(dev->net, "can't read USBCTL, %d\n", retval); | 299 | netdev_dbg(dev->net, "can't read USBCTL, %d\n", retval); |
309 | goto done; | 300 | goto done; |
310 | } | 301 | } |
311 | usbctl = *vp; | 302 | usbctl = vp; |
312 | nc_dump_usbctl(dev, usbctl); | 303 | nc_dump_usbctl(dev, usbctl); |
313 | 304 | ||
314 | nc_register_write(dev, REG_USBCTL, | 305 | nc_register_write(dev, REG_USBCTL, |
315 | USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER); | 306 | USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER); |
316 | 307 | ||
317 | if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) { | 308 | if ((retval = nc_register_read(dev, REG_TTL, &vp)) < 0) { |
318 | netdev_dbg(dev->net, "can't read TTL, %d\n", retval); | 309 | netdev_dbg(dev->net, "can't read TTL, %d\n", retval); |
319 | goto done; | 310 | goto done; |
320 | } | 311 | } |
321 | ttl = *vp; | 312 | ttl = vp; |
322 | // nc_dump_ttl(dev, ttl); | 313 | // nc_dump_ttl(dev, ttl); |
323 | 314 | ||
324 | nc_register_write(dev, REG_TTL, | 315 | nc_register_write(dev, REG_TTL, |
@@ -331,7 +322,6 @@ static int net1080_reset(struct usbnet *dev) | |||
331 | retval = 0; | 322 | retval = 0; |
332 | 323 | ||
333 | done: | 324 | done: |
334 | kfree(vp); | ||
335 | return retval; | 325 | return retval; |
336 | } | 326 | } |
337 | 327 | ||
@@ -339,13 +329,10 @@ static int net1080_check_connect(struct usbnet *dev) | |||
339 | { | 329 | { |
340 | int retval; | 330 | int retval; |
341 | u16 status; | 331 | u16 status; |
342 | u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL); | 332 | u16 vp; |
343 | 333 | ||
344 | if (!vp) | 334 | retval = nc_register_read(dev, REG_STATUS, &vp); |
345 | return -ENOMEM; | 335 | status = vp; |
346 | retval = nc_register_read(dev, REG_STATUS, vp); | ||
347 | status = *vp; | ||
348 | kfree(vp); | ||
349 | if (retval != 0) { | 336 | if (retval != 0) { |
350 | netdev_dbg(dev->net, "net1080_check_conn read - %d\n", retval); | 337 | netdev_dbg(dev->net, "net1080_check_conn read - %d\n", retval); |
351 | return retval; | 338 | return retval; |
@@ -355,59 +342,22 @@ static int net1080_check_connect(struct usbnet *dev) | |||
355 | return 0; | 342 | return 0; |
356 | } | 343 | } |
357 | 344 | ||
358 | static void nc_flush_complete(struct urb *urb) | ||
359 | { | ||
360 | kfree(urb->context); | ||
361 | usb_free_urb(urb); | ||
362 | } | ||
363 | |||
364 | static void nc_ensure_sync(struct usbnet *dev) | 345 | static void nc_ensure_sync(struct usbnet *dev) |
365 | { | 346 | { |
366 | dev->frame_errors++; | 347 | if (++dev->frame_errors <= 5) |
367 | if (dev->frame_errors > 5) { | 348 | return; |
368 | struct urb *urb; | ||
369 | struct usb_ctrlrequest *req; | ||
370 | int status; | ||
371 | |||
372 | /* Send a flush */ | ||
373 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
374 | if (!urb) | ||
375 | return; | ||
376 | |||
377 | req = kmalloc(sizeof *req, GFP_ATOMIC); | ||
378 | if (!req) { | ||
379 | usb_free_urb(urb); | ||
380 | return; | ||
381 | } | ||
382 | 349 | ||
383 | req->bRequestType = USB_DIR_OUT | 350 | if (usbnet_write_cmd_async(dev, REQUEST_REGISTER, |
384 | | USB_TYPE_VENDOR | 351 | USB_DIR_OUT | USB_TYPE_VENDOR | |
385 | | USB_RECIP_DEVICE; | 352 | USB_RECIP_DEVICE, |
386 | req->bRequest = REQUEST_REGISTER; | 353 | USBCTL_FLUSH_THIS | |
387 | req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS | 354 | USBCTL_FLUSH_OTHER, |
388 | | USBCTL_FLUSH_OTHER); | 355 | REG_USBCTL, NULL, 0)) |
389 | req->wIndex = cpu_to_le16(REG_USBCTL); | 356 | return; |
390 | req->wLength = cpu_to_le16(0); | ||
391 | |||
392 | /* queue an async control request, we don't need | ||
393 | * to do anything when it finishes except clean up. | ||
394 | */ | ||
395 | usb_fill_control_urb(urb, dev->udev, | ||
396 | usb_sndctrlpipe(dev->udev, 0), | ||
397 | (unsigned char *) req, | ||
398 | NULL, 0, | ||
399 | nc_flush_complete, req); | ||
400 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
401 | if (status) { | ||
402 | kfree(req); | ||
403 | usb_free_urb(urb); | ||
404 | return; | ||
405 | } | ||
406 | 357 | ||
407 | netif_dbg(dev, rx_err, dev->net, | 358 | netif_dbg(dev, rx_err, dev->net, |
408 | "flush net1080; too many framing errors\n"); | 359 | "flush net1080; too many framing errors\n"); |
409 | dev->frame_errors = 0; | 360 | dev->frame_errors = 0; |
410 | } | ||
411 | } | 361 | } |
412 | 362 | ||
413 | static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 363 | static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index 4584b9a805b3..0fcc8e65a068 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c | |||
@@ -71,13 +71,10 @@ | |||
71 | static inline int | 71 | static inline int |
72 | pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index) | 72 | pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index) |
73 | { | 73 | { |
74 | return usb_control_msg(dev->udev, | 74 | return usbnet_read_cmd(dev, req, |
75 | usb_rcvctrlpipe(dev->udev, 0), | 75 | USB_DIR_IN | USB_TYPE_VENDOR | |
76 | req, | 76 | USB_RECIP_DEVICE, |
77 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 77 | val, index, NULL, 0); |
78 | val, index, | ||
79 | NULL, 0, | ||
80 | USB_CTRL_GET_TIMEOUT); | ||
81 | } | 78 | } |
82 | 79 | ||
83 | static inline int | 80 | static inline int |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index c27d27701aee..18dd4257ab17 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
@@ -311,10 +311,9 @@ static int sierra_net_send_cmd(struct usbnet *dev, | |||
311 | struct sierra_net_data *priv = sierra_net_get_private(dev); | 311 | struct sierra_net_data *priv = sierra_net_get_private(dev); |
312 | int status; | 312 | int status; |
313 | 313 | ||
314 | status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 314 | status = usbnet_write_cmd(dev, USB_CDC_SEND_ENCAPSULATED_COMMAND, |
315 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | 315 | USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, |
316 | USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0, | 316 | 0, priv->ifnum, cmd, cmdlen); |
317 | priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT); | ||
318 | 317 | ||
319 | if (status != cmdlen && status != -ENODEV) | 318 | if (status != cmdlen && status != -ENODEV) |
320 | netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status); | 319 | netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status); |
@@ -340,7 +339,7 @@ static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) | |||
340 | dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix); | 339 | dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix); |
341 | priv->tx_hdr_template[0] = 0x3F; | 340 | priv->tx_hdr_template[0] = 0x3F; |
342 | priv->tx_hdr_template[1] = ctx_ix; | 341 | priv->tx_hdr_template[1] = ctx_ix; |
343 | *((u16 *)&priv->tx_hdr_template[2]) = | 342 | *((__be16 *)&priv->tx_hdr_template[2]) = |
344 | cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID); | 343 | cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID); |
345 | } | 344 | } |
346 | 345 | ||
@@ -632,32 +631,22 @@ static int sierra_net_change_mtu(struct net_device *net, int new_mtu) | |||
632 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | 631 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) |
633 | { | 632 | { |
634 | int result = 0; | 633 | int result = 0; |
635 | u16 *attrdata; | 634 | __le16 attrdata; |
636 | 635 | ||
637 | attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL); | 636 | result = usbnet_read_cmd(dev, |
638 | if (!attrdata) | 637 | /* _u8 vendor specific request */ |
639 | return -ENOMEM; | 638 | SWI_USB_REQUEST_GET_FW_ATTR, |
640 | 639 | USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */ | |
641 | result = usb_control_msg( | 640 | 0x0000, /* __u16 value not used */ |
642 | dev->udev, | 641 | 0x0000, /* __u16 index not used */ |
643 | usb_rcvctrlpipe(dev->udev, 0), | 642 | &attrdata, /* char *data */ |
644 | /* _u8 vendor specific request */ | 643 | sizeof(attrdata) /* __u16 size */ |
645 | SWI_USB_REQUEST_GET_FW_ATTR, | 644 | ); |
646 | USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */ | 645 | |
647 | 0x0000, /* __u16 value not used */ | 646 | if (result < 0) |
648 | 0x0000, /* __u16 index not used */ | ||
649 | attrdata, /* char *data */ | ||
650 | sizeof(*attrdata), /* __u16 size */ | ||
651 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
652 | |||
653 | if (result < 0) { | ||
654 | kfree(attrdata); | ||
655 | return -EIO; | 647 | return -EIO; |
656 | } | ||
657 | |||
658 | *datap = le16_to_cpu(*attrdata); | ||
659 | 648 | ||
660 | kfree(attrdata); | 649 | *datap = le16_to_cpu(attrdata); |
661 | return result; | 650 | return result; |
662 | } | 651 | } |
663 | 652 | ||
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index b77ae76f4aa8..c5353cfc9c8c 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/ethtool.h> | 26 | #include <linux/ethtool.h> |
27 | #include <linux/mii.h> | 27 | #include <linux/mii.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <linux/bitrev.h> | ||
30 | #include <linux/crc16.h> | ||
29 | #include <linux/crc32.h> | 31 | #include <linux/crc32.h> |
30 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
31 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -52,7 +54,8 @@ | |||
52 | #define USB_PRODUCT_ID_LAN7500 (0x7500) | 54 | #define USB_PRODUCT_ID_LAN7500 (0x7500) |
53 | #define USB_PRODUCT_ID_LAN7505 (0x7505) | 55 | #define USB_PRODUCT_ID_LAN7505 (0x7505) |
54 | #define RXW_PADDING 2 | 56 | #define RXW_PADDING 2 |
55 | #define SUPPORTED_WAKE (WAKE_MAGIC) | 57 | #define SUPPORTED_WAKE (WAKE_UCAST | WAKE_BCAST | \ |
58 | WAKE_MCAST | WAKE_ARP | WAKE_MAGIC) | ||
56 | 59 | ||
57 | #define check_warn(ret, fmt, args...) \ | 60 | #define check_warn(ret, fmt, args...) \ |
58 | ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) | 61 | ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) |
@@ -82,71 +85,92 @@ static bool turbo_mode = true; | |||
82 | module_param(turbo_mode, bool, 0644); | 85 | module_param(turbo_mode, bool, 0644); |
83 | MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); | 86 | MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); |
84 | 87 | ||
85 | static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, | 88 | static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, |
86 | u32 *data) | 89 | u32 *data, int in_pm) |
87 | { | 90 | { |
88 | u32 *buf = kmalloc(4, GFP_KERNEL); | 91 | u32 buf; |
89 | int ret; | 92 | int ret; |
93 | int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); | ||
90 | 94 | ||
91 | BUG_ON(!dev); | 95 | BUG_ON(!dev); |
92 | 96 | ||
93 | if (!buf) | 97 | if (!in_pm) |
94 | return -ENOMEM; | 98 | fn = usbnet_read_cmd; |
95 | 99 | else | |
96 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | 100 | fn = usbnet_read_cmd_nopm; |
97 | USB_VENDOR_REQUEST_READ_REGISTER, | ||
98 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
99 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); | ||
100 | 101 | ||
102 | ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN | ||
103 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
104 | 0, index, &buf, 4); | ||
101 | if (unlikely(ret < 0)) | 105 | if (unlikely(ret < 0)) |
102 | netdev_warn(dev->net, | 106 | netdev_warn(dev->net, |
103 | "Failed to read reg index 0x%08x: %d", index, ret); | 107 | "Failed to read reg index 0x%08x: %d", index, ret); |
104 | 108 | ||
105 | le32_to_cpus(buf); | 109 | le32_to_cpus(&buf); |
106 | *data = *buf; | 110 | *data = buf; |
107 | kfree(buf); | ||
108 | 111 | ||
109 | return ret; | 112 | return ret; |
110 | } | 113 | } |
111 | 114 | ||
112 | static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, | 115 | static int __must_check __smsc75xx_write_reg(struct usbnet *dev, u32 index, |
113 | u32 data) | 116 | u32 data, int in_pm) |
114 | { | 117 | { |
115 | u32 *buf = kmalloc(4, GFP_KERNEL); | 118 | u32 buf; |
116 | int ret; | 119 | int ret; |
120 | int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); | ||
117 | 121 | ||
118 | BUG_ON(!dev); | 122 | BUG_ON(!dev); |
119 | 123 | ||
120 | if (!buf) | 124 | if (!in_pm) |
121 | return -ENOMEM; | 125 | fn = usbnet_write_cmd; |
122 | 126 | else | |
123 | *buf = data; | 127 | fn = usbnet_write_cmd_nopm; |
124 | cpu_to_le32s(buf); | ||
125 | 128 | ||
126 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 129 | buf = data; |
127 | USB_VENDOR_REQUEST_WRITE_REGISTER, | 130 | cpu_to_le32s(&buf); |
128 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
129 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); | ||
130 | 131 | ||
132 | ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT | ||
133 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
134 | 0, index, &buf, 4); | ||
131 | if (unlikely(ret < 0)) | 135 | if (unlikely(ret < 0)) |
132 | netdev_warn(dev->net, | 136 | netdev_warn(dev->net, |
133 | "Failed to write reg index 0x%08x: %d", index, ret); | 137 | "Failed to write reg index 0x%08x: %d", index, ret); |
134 | 138 | ||
135 | kfree(buf); | ||
136 | |||
137 | return ret; | 139 | return ret; |
138 | } | 140 | } |
139 | 141 | ||
142 | static int __must_check smsc75xx_read_reg_nopm(struct usbnet *dev, u32 index, | ||
143 | u32 *data) | ||
144 | { | ||
145 | return __smsc75xx_read_reg(dev, index, data, 1); | ||
146 | } | ||
147 | |||
148 | static int __must_check smsc75xx_write_reg_nopm(struct usbnet *dev, u32 index, | ||
149 | u32 data) | ||
150 | { | ||
151 | return __smsc75xx_write_reg(dev, index, data, 1); | ||
152 | } | ||
153 | |||
154 | static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, | ||
155 | u32 *data) | ||
156 | { | ||
157 | return __smsc75xx_read_reg(dev, index, data, 0); | ||
158 | } | ||
159 | |||
160 | static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, | ||
161 | u32 data) | ||
162 | { | ||
163 | return __smsc75xx_write_reg(dev, index, data, 0); | ||
164 | } | ||
165 | |||
140 | static int smsc75xx_set_feature(struct usbnet *dev, u32 feature) | 166 | static int smsc75xx_set_feature(struct usbnet *dev, u32 feature) |
141 | { | 167 | { |
142 | if (WARN_ON_ONCE(!dev)) | 168 | if (WARN_ON_ONCE(!dev)) |
143 | return -EINVAL; | 169 | return -EINVAL; |
144 | 170 | ||
145 | cpu_to_le32s(&feature); | 171 | return usbnet_write_cmd_nopm(dev, USB_REQ_SET_FEATURE, |
146 | 172 | USB_DIR_OUT | USB_RECIP_DEVICE, | |
147 | return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 173 | feature, 0, NULL, 0); |
148 | USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0, | ||
149 | USB_CTRL_SET_TIMEOUT); | ||
150 | } | 174 | } |
151 | 175 | ||
152 | static int smsc75xx_clear_feature(struct usbnet *dev, u32 feature) | 176 | static int smsc75xx_clear_feature(struct usbnet *dev, u32 feature) |
@@ -154,11 +178,9 @@ static int smsc75xx_clear_feature(struct usbnet *dev, u32 feature) | |||
154 | if (WARN_ON_ONCE(!dev)) | 178 | if (WARN_ON_ONCE(!dev)) |
155 | return -EINVAL; | 179 | return -EINVAL; |
156 | 180 | ||
157 | cpu_to_le32s(&feature); | 181 | return usbnet_write_cmd_nopm(dev, USB_REQ_CLEAR_FEATURE, |
158 | 182 | USB_DIR_OUT | USB_RECIP_DEVICE, | |
159 | return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 183 | feature, 0, NULL, 0); |
160 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0, | ||
161 | USB_CTRL_SET_TIMEOUT); | ||
162 | } | 184 | } |
163 | 185 | ||
164 | /* Loop until the read is completed with timeout | 186 | /* Loop until the read is completed with timeout |
@@ -804,13 +826,16 @@ static int smsc75xx_set_features(struct net_device *netdev, | |||
804 | return 0; | 826 | return 0; |
805 | } | 827 | } |
806 | 828 | ||
807 | static int smsc75xx_wait_ready(struct usbnet *dev) | 829 | static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm) |
808 | { | 830 | { |
809 | int timeout = 0; | 831 | int timeout = 0; |
810 | 832 | ||
811 | do { | 833 | do { |
812 | u32 buf; | 834 | u32 buf; |
813 | int ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); | 835 | int ret; |
836 | |||
837 | ret = __smsc75xx_read_reg(dev, PMT_CTL, &buf, in_pm); | ||
838 | |||
814 | check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); | 839 | check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); |
815 | 840 | ||
816 | if (buf & PMT_CTL_DEV_RDY) | 841 | if (buf & PMT_CTL_DEV_RDY) |
@@ -832,7 +857,7 @@ static int smsc75xx_reset(struct usbnet *dev) | |||
832 | 857 | ||
833 | netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); | 858 | netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); |
834 | 859 | ||
835 | ret = smsc75xx_wait_ready(dev); | 860 | ret = smsc75xx_wait_ready(dev, 0); |
836 | check_warn_return(ret, "device not ready in smsc75xx_reset"); | 861 | check_warn_return(ret, "device not ready in smsc75xx_reset"); |
837 | 862 | ||
838 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | 863 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); |
@@ -1154,6 +1179,36 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
1154 | } | 1179 | } |
1155 | } | 1180 | } |
1156 | 1181 | ||
1182 | static u16 smsc_crc(const u8 *buffer, size_t len) | ||
1183 | { | ||
1184 | return bitrev16(crc16(0xFFFF, buffer, len)); | ||
1185 | } | ||
1186 | |||
1187 | static int smsc75xx_write_wuff(struct usbnet *dev, int filter, u32 wuf_cfg, | ||
1188 | u32 wuf_mask1) | ||
1189 | { | ||
1190 | int cfg_base = WUF_CFGX + filter * 4; | ||
1191 | int mask_base = WUF_MASKX + filter * 16; | ||
1192 | int ret; | ||
1193 | |||
1194 | ret = smsc75xx_write_reg(dev, cfg_base, wuf_cfg); | ||
1195 | check_warn_return(ret, "Error writing WUF_CFGX"); | ||
1196 | |||
1197 | ret = smsc75xx_write_reg(dev, mask_base, wuf_mask1); | ||
1198 | check_warn_return(ret, "Error writing WUF_MASKX"); | ||
1199 | |||
1200 | ret = smsc75xx_write_reg(dev, mask_base + 4, 0); | ||
1201 | check_warn_return(ret, "Error writing WUF_MASKX"); | ||
1202 | |||
1203 | ret = smsc75xx_write_reg(dev, mask_base + 8, 0); | ||
1204 | check_warn_return(ret, "Error writing WUF_MASKX"); | ||
1205 | |||
1206 | ret = smsc75xx_write_reg(dev, mask_base + 12, 0); | ||
1207 | check_warn_return(ret, "Error writing WUF_MASKX"); | ||
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1157 | static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message) | 1212 | static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message) |
1158 | { | 1213 | { |
1159 | struct usbnet *dev = usb_get_intfdata(intf); | 1214 | struct usbnet *dev = usb_get_intfdata(intf); |
@@ -1169,101 +1224,156 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message) | |||
1169 | netdev_info(dev->net, "entering SUSPEND2 mode"); | 1224 | netdev_info(dev->net, "entering SUSPEND2 mode"); |
1170 | 1225 | ||
1171 | /* disable energy detect (link up) & wake up events */ | 1226 | /* disable energy detect (link up) & wake up events */ |
1172 | ret = smsc75xx_read_reg(dev, WUCSR, &val); | 1227 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); |
1173 | check_warn_return(ret, "Error reading WUCSR"); | 1228 | check_warn_return(ret, "Error reading WUCSR"); |
1174 | 1229 | ||
1175 | val &= ~(WUCSR_MPEN | WUCSR_WUEN); | 1230 | val &= ~(WUCSR_MPEN | WUCSR_WUEN); |
1176 | 1231 | ||
1177 | ret = smsc75xx_write_reg(dev, WUCSR, val); | 1232 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); |
1178 | check_warn_return(ret, "Error writing WUCSR"); | 1233 | check_warn_return(ret, "Error writing WUCSR"); |
1179 | 1234 | ||
1180 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | 1235 | ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); |
1181 | check_warn_return(ret, "Error reading PMT_CTL"); | 1236 | check_warn_return(ret, "Error reading PMT_CTL"); |
1182 | 1237 | ||
1183 | val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN); | 1238 | val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN); |
1184 | 1239 | ||
1185 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1240 | ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); |
1186 | check_warn_return(ret, "Error writing PMT_CTL"); | 1241 | check_warn_return(ret, "Error writing PMT_CTL"); |
1187 | 1242 | ||
1188 | /* enter suspend2 mode */ | 1243 | /* enter suspend2 mode */ |
1189 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | 1244 | ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); |
1190 | check_warn_return(ret, "Error reading PMT_CTL"); | 1245 | check_warn_return(ret, "Error reading PMT_CTL"); |
1191 | 1246 | ||
1192 | val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST); | 1247 | val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST); |
1193 | val |= PMT_CTL_SUS_MODE_2; | 1248 | val |= PMT_CTL_SUS_MODE_2; |
1194 | 1249 | ||
1195 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1250 | ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); |
1196 | check_warn_return(ret, "Error writing PMT_CTL"); | 1251 | check_warn_return(ret, "Error writing PMT_CTL"); |
1197 | 1252 | ||
1198 | return 0; | 1253 | return 0; |
1199 | } | 1254 | } |
1200 | 1255 | ||
1201 | if (pdata->wolopts & WAKE_MAGIC) { | 1256 | if (pdata->wolopts & (WAKE_MCAST | WAKE_ARP)) { |
1202 | /* clear any pending magic packet status */ | 1257 | int i, filter = 0; |
1203 | ret = smsc75xx_read_reg(dev, WUCSR, &val); | 1258 | |
1259 | /* disable all filters */ | ||
1260 | for (i = 0; i < WUF_NUM; i++) { | ||
1261 | ret = smsc75xx_write_reg_nopm(dev, WUF_CFGX + i * 4, 0); | ||
1262 | check_warn_return(ret, "Error writing WUF_CFGX"); | ||
1263 | } | ||
1264 | |||
1265 | if (pdata->wolopts & WAKE_MCAST) { | ||
1266 | const u8 mcast[] = {0x01, 0x00, 0x5E}; | ||
1267 | netdev_info(dev->net, "enabling multicast detection"); | ||
1268 | |||
1269 | val = WUF_CFGX_EN | WUF_CFGX_ATYPE_MULTICAST | ||
1270 | | smsc_crc(mcast, 3); | ||
1271 | ret = smsc75xx_write_wuff(dev, filter++, val, 0x0007); | ||
1272 | check_warn_return(ret, "Error writing wakeup filter"); | ||
1273 | } | ||
1274 | |||
1275 | if (pdata->wolopts & WAKE_ARP) { | ||
1276 | const u8 arp[] = {0x08, 0x06}; | ||
1277 | netdev_info(dev->net, "enabling ARP detection"); | ||
1278 | |||
1279 | val = WUF_CFGX_EN | WUF_CFGX_ATYPE_ALL | (0x0C << 16) | ||
1280 | | smsc_crc(arp, 2); | ||
1281 | ret = smsc75xx_write_wuff(dev, filter++, val, 0x0003); | ||
1282 | check_warn_return(ret, "Error writing wakeup filter"); | ||
1283 | } | ||
1284 | |||
1285 | /* clear any pending pattern match packet status */ | ||
1286 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); | ||
1204 | check_warn_return(ret, "Error reading WUCSR"); | 1287 | check_warn_return(ret, "Error reading WUCSR"); |
1205 | 1288 | ||
1206 | val |= WUCSR_MPR; | 1289 | val |= WUCSR_WUFR; |
1207 | 1290 | ||
1208 | ret = smsc75xx_write_reg(dev, WUCSR, val); | 1291 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); |
1292 | check_warn_return(ret, "Error writing WUCSR"); | ||
1293 | |||
1294 | netdev_info(dev->net, "enabling packet match detection"); | ||
1295 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); | ||
1296 | check_warn_return(ret, "Error reading WUCSR"); | ||
1297 | |||
1298 | val |= WUCSR_WUEN; | ||
1299 | |||
1300 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); | ||
1301 | check_warn_return(ret, "Error writing WUCSR"); | ||
1302 | } else { | ||
1303 | netdev_info(dev->net, "disabling packet match detection"); | ||
1304 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); | ||
1305 | check_warn_return(ret, "Error reading WUCSR"); | ||
1306 | |||
1307 | val &= ~WUCSR_WUEN; | ||
1308 | |||
1309 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); | ||
1209 | check_warn_return(ret, "Error writing WUCSR"); | 1310 | check_warn_return(ret, "Error writing WUCSR"); |
1210 | } | 1311 | } |
1211 | 1312 | ||
1212 | /* enable/disable magic packup wake */ | 1313 | /* disable magic, bcast & unicast wakeup sources */ |
1213 | ret = smsc75xx_read_reg(dev, WUCSR, &val); | 1314 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); |
1214 | check_warn_return(ret, "Error reading WUCSR"); | 1315 | check_warn_return(ret, "Error reading WUCSR"); |
1215 | 1316 | ||
1317 | val &= ~(WUCSR_MPEN | WUCSR_BCST_EN | WUCSR_PFDA_EN); | ||
1318 | |||
1319 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); | ||
1320 | check_warn_return(ret, "Error writing WUCSR"); | ||
1321 | |||
1216 | if (pdata->wolopts & WAKE_MAGIC) { | 1322 | if (pdata->wolopts & WAKE_MAGIC) { |
1217 | netdev_info(dev->net, "enabling magic packet wakeup"); | 1323 | netdev_info(dev->net, "enabling magic packet wakeup"); |
1218 | val |= WUCSR_MPEN; | 1324 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); |
1219 | } else { | 1325 | check_warn_return(ret, "Error reading WUCSR"); |
1220 | netdev_info(dev->net, "disabling magic packet wakeup"); | 1326 | |
1221 | val &= ~WUCSR_MPEN; | 1327 | /* clear any pending magic packet status */ |
1328 | val |= WUCSR_MPR | WUCSR_MPEN; | ||
1329 | |||
1330 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); | ||
1331 | check_warn_return(ret, "Error writing WUCSR"); | ||
1222 | } | 1332 | } |
1223 | 1333 | ||
1224 | ret = smsc75xx_write_reg(dev, WUCSR, val); | 1334 | if (pdata->wolopts & WAKE_BCAST) { |
1225 | check_warn_return(ret, "Error writing WUCSR"); | 1335 | netdev_info(dev->net, "enabling broadcast detection"); |
1336 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); | ||
1337 | check_warn_return(ret, "Error reading WUCSR"); | ||
1226 | 1338 | ||
1227 | /* enable wol wakeup source */ | 1339 | val |= WUCSR_BCAST_FR | WUCSR_BCST_EN; |
1228 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | ||
1229 | check_warn_return(ret, "Error reading PMT_CTL"); | ||
1230 | 1340 | ||
1231 | val |= PMT_CTL_WOL_EN; | 1341 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); |
1342 | check_warn_return(ret, "Error writing WUCSR"); | ||
1343 | } | ||
1232 | 1344 | ||
1233 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1345 | if (pdata->wolopts & WAKE_UCAST) { |
1234 | check_warn_return(ret, "Error writing PMT_CTL"); | 1346 | netdev_info(dev->net, "enabling unicast detection"); |
1347 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); | ||
1348 | check_warn_return(ret, "Error reading WUCSR"); | ||
1349 | |||
1350 | val |= WUCSR_WUFR | WUCSR_PFDA_EN; | ||
1351 | |||
1352 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); | ||
1353 | check_warn_return(ret, "Error writing WUCSR"); | ||
1354 | } | ||
1235 | 1355 | ||
1236 | /* enable receiver */ | 1356 | /* enable receiver to enable frame reception */ |
1237 | ret = smsc75xx_read_reg(dev, MAC_RX, &val); | 1357 | ret = smsc75xx_read_reg_nopm(dev, MAC_RX, &val); |
1238 | check_warn_return(ret, "Failed to read MAC_RX: %d", ret); | 1358 | check_warn_return(ret, "Failed to read MAC_RX: %d", ret); |
1239 | 1359 | ||
1240 | val |= MAC_RX_RXEN; | 1360 | val |= MAC_RX_RXEN; |
1241 | 1361 | ||
1242 | ret = smsc75xx_write_reg(dev, MAC_RX, val); | 1362 | ret = smsc75xx_write_reg_nopm(dev, MAC_RX, val); |
1243 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); | 1363 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); |
1244 | 1364 | ||
1245 | /* some wol options are enabled, so enter SUSPEND0 */ | 1365 | /* some wol options are enabled, so enter SUSPEND0 */ |
1246 | netdev_info(dev->net, "entering SUSPEND0 mode"); | 1366 | netdev_info(dev->net, "entering SUSPEND0 mode"); |
1247 | 1367 | ||
1248 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | 1368 | ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); |
1249 | check_warn_return(ret, "Error reading PMT_CTL"); | 1369 | check_warn_return(ret, "Error reading PMT_CTL"); |
1250 | 1370 | ||
1251 | val &= (~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST)); | 1371 | val &= (~(PMT_CTL_SUS_MODE | PMT_CTL_PHY_RST)); |
1252 | val |= PMT_CTL_SUS_MODE_0; | 1372 | val |= PMT_CTL_SUS_MODE_0 | PMT_CTL_WOL_EN | PMT_CTL_WUPS; |
1253 | 1373 | ||
1254 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1374 | ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); |
1255 | check_warn_return(ret, "Error writing PMT_CTL"); | 1375 | check_warn_return(ret, "Error writing PMT_CTL"); |
1256 | 1376 | ||
1257 | /* clear wol status */ | ||
1258 | val &= ~PMT_CTL_WUPS; | ||
1259 | val |= PMT_CTL_WUPS_WOL; | ||
1260 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | ||
1261 | check_warn_return(ret, "Error writing PMT_CTL"); | ||
1262 | |||
1263 | /* read back PMT_CTL */ | ||
1264 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | ||
1265 | check_warn_return(ret, "Error reading PMT_CTL"); | ||
1266 | |||
1267 | smsc75xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP); | 1377 | smsc75xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP); |
1268 | 1378 | ||
1269 | return 0; | 1379 | return 0; |
@@ -1276,42 +1386,43 @@ static int smsc75xx_resume(struct usb_interface *intf) | |||
1276 | int ret; | 1386 | int ret; |
1277 | u32 val; | 1387 | u32 val; |
1278 | 1388 | ||
1279 | if (pdata->wolopts & WAKE_MAGIC) { | 1389 | if (pdata->wolopts) { |
1280 | netdev_info(dev->net, "resuming from SUSPEND0"); | 1390 | netdev_info(dev->net, "resuming from SUSPEND0"); |
1281 | 1391 | ||
1282 | smsc75xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP); | 1392 | smsc75xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP); |
1283 | 1393 | ||
1284 | /* Disable magic packup wake */ | 1394 | /* Disable wakeup sources */ |
1285 | ret = smsc75xx_read_reg(dev, WUCSR, &val); | 1395 | ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); |
1286 | check_warn_return(ret, "Error reading WUCSR"); | 1396 | check_warn_return(ret, "Error reading WUCSR"); |
1287 | 1397 | ||
1288 | val &= ~WUCSR_MPEN; | 1398 | val &= ~(WUCSR_WUEN | WUCSR_MPEN | WUCSR_PFDA_EN |
1399 | | WUCSR_BCST_EN); | ||
1289 | 1400 | ||
1290 | ret = smsc75xx_write_reg(dev, WUCSR, val); | 1401 | ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); |
1291 | check_warn_return(ret, "Error writing WUCSR"); | 1402 | check_warn_return(ret, "Error writing WUCSR"); |
1292 | 1403 | ||
1293 | /* clear wake-up status */ | 1404 | /* clear wake-up status */ |
1294 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | 1405 | ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); |
1295 | check_warn_return(ret, "Error reading PMT_CTL"); | 1406 | check_warn_return(ret, "Error reading PMT_CTL"); |
1296 | 1407 | ||
1297 | val &= ~PMT_CTL_WOL_EN; | 1408 | val &= ~PMT_CTL_WOL_EN; |
1298 | val |= PMT_CTL_WUPS; | 1409 | val |= PMT_CTL_WUPS; |
1299 | 1410 | ||
1300 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1411 | ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); |
1301 | check_warn_return(ret, "Error writing PMT_CTL"); | 1412 | check_warn_return(ret, "Error writing PMT_CTL"); |
1302 | } else { | 1413 | } else { |
1303 | netdev_info(dev->net, "resuming from SUSPEND2"); | 1414 | netdev_info(dev->net, "resuming from SUSPEND2"); |
1304 | 1415 | ||
1305 | ret = smsc75xx_read_reg(dev, PMT_CTL, &val); | 1416 | ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); |
1306 | check_warn_return(ret, "Error reading PMT_CTL"); | 1417 | check_warn_return(ret, "Error reading PMT_CTL"); |
1307 | 1418 | ||
1308 | val |= PMT_CTL_PHY_PWRUP; | 1419 | val |= PMT_CTL_PHY_PWRUP; |
1309 | 1420 | ||
1310 | ret = smsc75xx_write_reg(dev, PMT_CTL, val); | 1421 | ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); |
1311 | check_warn_return(ret, "Error writing PMT_CTL"); | 1422 | check_warn_return(ret, "Error writing PMT_CTL"); |
1312 | } | 1423 | } |
1313 | 1424 | ||
1314 | ret = smsc75xx_wait_ready(dev); | 1425 | ret = smsc75xx_wait_ready(dev, 1); |
1315 | check_warn_return(ret, "device not ready in smsc75xx_resume"); | 1426 | check_warn_return(ret, "device not ready in smsc75xx_resume"); |
1316 | 1427 | ||
1317 | return usbnet_resume(intf); | 1428 | return usbnet_resume(intf); |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 3286166415b4..e07f70b5f39c 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/ethtool.h> | 26 | #include <linux/ethtool.h> |
27 | #include <linux/mii.h> | 27 | #include <linux/mii.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <linux/bitrev.h> | ||
30 | #include <linux/crc16.h> | ||
29 | #include <linux/crc32.h> | 31 | #include <linux/crc32.h> |
30 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
31 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -46,7 +48,8 @@ | |||
46 | #define SMSC95XX_INTERNAL_PHY_ID (1) | 48 | #define SMSC95XX_INTERNAL_PHY_ID (1) |
47 | #define SMSC95XX_TX_OVERHEAD (8) | 49 | #define SMSC95XX_TX_OVERHEAD (8) |
48 | #define SMSC95XX_TX_OVERHEAD_CSUM (12) | 50 | #define SMSC95XX_TX_OVERHEAD_CSUM (12) |
49 | #define SUPPORTED_WAKE (WAKE_MAGIC) | 51 | #define SUPPORTED_WAKE (WAKE_UCAST | WAKE_BCAST | \ |
52 | WAKE_MCAST | WAKE_ARP | WAKE_MAGIC) | ||
50 | 53 | ||
51 | #define check_warn(ret, fmt, args...) \ | 54 | #define check_warn(ret, fmt, args...) \ |
52 | ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) | 55 | ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) |
@@ -63,80 +66,98 @@ struct smsc95xx_priv { | |||
63 | u32 hash_lo; | 66 | u32 hash_lo; |
64 | u32 wolopts; | 67 | u32 wolopts; |
65 | spinlock_t mac_cr_lock; | 68 | spinlock_t mac_cr_lock; |
66 | }; | 69 | int wuff_filter_count; |
67 | |||
68 | struct usb_context { | ||
69 | struct usb_ctrlrequest req; | ||
70 | struct usbnet *dev; | ||
71 | }; | 70 | }; |
72 | 71 | ||
73 | static bool turbo_mode = true; | 72 | static bool turbo_mode = true; |
74 | module_param(turbo_mode, bool, 0644); | 73 | module_param(turbo_mode, bool, 0644); |
75 | MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); | 74 | MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); |
76 | 75 | ||
77 | static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, | 76 | static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, |
78 | u32 *data) | 77 | u32 *data, int in_pm) |
79 | { | 78 | { |
80 | u32 *buf = kmalloc(4, GFP_KERNEL); | 79 | u32 buf; |
81 | int ret; | 80 | int ret; |
81 | int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); | ||
82 | 82 | ||
83 | BUG_ON(!dev); | 83 | BUG_ON(!dev); |
84 | 84 | ||
85 | if (!buf) | 85 | if (!in_pm) |
86 | return -ENOMEM; | 86 | fn = usbnet_read_cmd; |
87 | 87 | else | |
88 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | 88 | fn = usbnet_read_cmd_nopm; |
89 | USB_VENDOR_REQUEST_READ_REGISTER, | ||
90 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
91 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); | ||
92 | 89 | ||
90 | ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN | ||
91 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
92 | 0, index, &buf, 4); | ||
93 | if (unlikely(ret < 0)) | 93 | if (unlikely(ret < 0)) |
94 | netdev_warn(dev->net, "Failed to read register index 0x%08x\n", index); | 94 | netdev_warn(dev->net, |
95 | "Failed to read reg index 0x%08x: %d", index, ret); | ||
95 | 96 | ||
96 | le32_to_cpus(buf); | 97 | le32_to_cpus(&buf); |
97 | *data = *buf; | 98 | *data = buf; |
98 | kfree(buf); | ||
99 | 99 | ||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index, | 103 | static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index, |
104 | u32 data) | 104 | u32 data, int in_pm) |
105 | { | 105 | { |
106 | u32 *buf = kmalloc(4, GFP_KERNEL); | 106 | u32 buf; |
107 | int ret; | 107 | int ret; |
108 | int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); | ||
108 | 109 | ||
109 | BUG_ON(!dev); | 110 | BUG_ON(!dev); |
110 | 111 | ||
111 | if (!buf) | 112 | if (!in_pm) |
112 | return -ENOMEM; | 113 | fn = usbnet_write_cmd; |
113 | 114 | else | |
114 | *buf = data; | 115 | fn = usbnet_write_cmd_nopm; |
115 | cpu_to_le32s(buf); | ||
116 | 116 | ||
117 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 117 | buf = data; |
118 | USB_VENDOR_REQUEST_WRITE_REGISTER, | 118 | cpu_to_le32s(&buf); |
119 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
120 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); | ||
121 | 119 | ||
120 | ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT | ||
121 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
122 | 0, index, &buf, 4); | ||
122 | if (unlikely(ret < 0)) | 123 | if (unlikely(ret < 0)) |
123 | netdev_warn(dev->net, "Failed to write register index 0x%08x\n", index); | 124 | netdev_warn(dev->net, |
124 | 125 | "Failed to write reg index 0x%08x: %d", index, ret); | |
125 | kfree(buf); | ||
126 | 126 | ||
127 | return ret; | 127 | return ret; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int __must_check smsc95xx_read_reg_nopm(struct usbnet *dev, u32 index, | ||
131 | u32 *data) | ||
132 | { | ||
133 | return __smsc95xx_read_reg(dev, index, data, 1); | ||
134 | } | ||
135 | |||
136 | static int __must_check smsc95xx_write_reg_nopm(struct usbnet *dev, u32 index, | ||
137 | u32 data) | ||
138 | { | ||
139 | return __smsc95xx_write_reg(dev, index, data, 1); | ||
140 | } | ||
141 | |||
142 | static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, | ||
143 | u32 *data) | ||
144 | { | ||
145 | return __smsc95xx_read_reg(dev, index, data, 0); | ||
146 | } | ||
147 | |||
148 | static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index, | ||
149 | u32 data) | ||
150 | { | ||
151 | return __smsc95xx_write_reg(dev, index, data, 0); | ||
152 | } | ||
130 | static int smsc95xx_set_feature(struct usbnet *dev, u32 feature) | 153 | static int smsc95xx_set_feature(struct usbnet *dev, u32 feature) |
131 | { | 154 | { |
132 | if (WARN_ON_ONCE(!dev)) | 155 | if (WARN_ON_ONCE(!dev)) |
133 | return -EINVAL; | 156 | return -EINVAL; |
134 | 157 | ||
135 | cpu_to_le32s(&feature); | 158 | return usbnet_write_cmd_nopm(dev, USB_REQ_SET_FEATURE, |
136 | 159 | USB_RECIP_DEVICE, feature, 0, | |
137 | return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 160 | NULL, 0); |
138 | USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0, | ||
139 | USB_CTRL_SET_TIMEOUT); | ||
140 | } | 161 | } |
141 | 162 | ||
142 | static int smsc95xx_clear_feature(struct usbnet *dev, u32 feature) | 163 | static int smsc95xx_clear_feature(struct usbnet *dev, u32 feature) |
@@ -144,11 +165,9 @@ static int smsc95xx_clear_feature(struct usbnet *dev, u32 feature) | |||
144 | if (WARN_ON_ONCE(!dev)) | 165 | if (WARN_ON_ONCE(!dev)) |
145 | return -EINVAL; | 166 | return -EINVAL; |
146 | 167 | ||
147 | cpu_to_le32s(&feature); | 168 | return usbnet_write_cmd_nopm(dev, USB_REQ_CLEAR_FEATURE, |
148 | 169 | USB_RECIP_DEVICE, feature, | |
149 | return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | 170 | 0, NULL, 0); |
150 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0, | ||
151 | USB_CTRL_SET_TIMEOUT); | ||
152 | } | 171 | } |
153 | 172 | ||
154 | /* Loop until the read is completed with timeout | 173 | /* Loop until the read is completed with timeout |
@@ -350,60 +369,20 @@ static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, | |||
350 | return 0; | 369 | return 0; |
351 | } | 370 | } |
352 | 371 | ||
353 | static void smsc95xx_async_cmd_callback(struct urb *urb) | ||
354 | { | ||
355 | struct usb_context *usb_context = urb->context; | ||
356 | struct usbnet *dev = usb_context->dev; | ||
357 | int status = urb->status; | ||
358 | |||
359 | check_warn(status, "async callback failed with %d\n", status); | ||
360 | |||
361 | kfree(usb_context); | ||
362 | usb_free_urb(urb); | ||
363 | } | ||
364 | |||
365 | static int __must_check smsc95xx_write_reg_async(struct usbnet *dev, u16 index, | 372 | static int __must_check smsc95xx_write_reg_async(struct usbnet *dev, u16 index, |
366 | u32 *data) | 373 | u32 *data) |
367 | { | 374 | { |
368 | struct usb_context *usb_context; | ||
369 | int status; | ||
370 | struct urb *urb; | ||
371 | const u16 size = 4; | 375 | const u16 size = 4; |
376 | int ret; | ||
372 | 377 | ||
373 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 378 | ret = usbnet_write_cmd_async(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, |
374 | if (!urb) { | 379 | USB_DIR_OUT | USB_TYPE_VENDOR | |
375 | netdev_warn(dev->net, "Error allocating URB\n"); | 380 | USB_RECIP_DEVICE, |
376 | return -ENOMEM; | 381 | 0, index, data, size); |
377 | } | 382 | if (ret < 0) |
378 | 383 | netdev_warn(dev->net, "Error write async cmd, sts=%d\n", | |
379 | usb_context = kmalloc(sizeof(struct usb_context), GFP_ATOMIC); | 384 | ret); |
380 | if (usb_context == NULL) { | 385 | return ret; |
381 | netdev_warn(dev->net, "Error allocating control msg\n"); | ||
382 | usb_free_urb(urb); | ||
383 | return -ENOMEM; | ||
384 | } | ||
385 | |||
386 | usb_context->req.bRequestType = | ||
387 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | ||
388 | usb_context->req.bRequest = USB_VENDOR_REQUEST_WRITE_REGISTER; | ||
389 | usb_context->req.wValue = 00; | ||
390 | usb_context->req.wIndex = cpu_to_le16(index); | ||
391 | usb_context->req.wLength = cpu_to_le16(size); | ||
392 | |||
393 | usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
394 | (void *)&usb_context->req, data, size, | ||
395 | smsc95xx_async_cmd_callback, | ||
396 | (void *)usb_context); | ||
397 | |||
398 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
399 | if (status < 0) { | ||
400 | netdev_warn(dev->net, "Error submitting control msg, sts=%d\n", | ||
401 | status); | ||
402 | kfree(usb_context); | ||
403 | usb_free_urb(urb); | ||
404 | } | ||
405 | |||
406 | return status; | ||
407 | } | 386 | } |
408 | 387 | ||
409 | /* returns hash bit number for given MAC address | 388 | /* returns hash bit number for given MAC address |
@@ -765,7 +744,7 @@ static int smsc95xx_start_tx_path(struct usbnet *dev) | |||
765 | } | 744 | } |
766 | 745 | ||
767 | /* Starts the Receive path */ | 746 | /* Starts the Receive path */ |
768 | static int smsc95xx_start_rx_path(struct usbnet *dev) | 747 | static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm) |
769 | { | 748 | { |
770 | struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); | 749 | struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); |
771 | unsigned long flags; | 750 | unsigned long flags; |
@@ -775,7 +754,7 @@ static int smsc95xx_start_rx_path(struct usbnet *dev) | |||
775 | pdata->mac_cr |= MAC_CR_RXEN_; | 754 | pdata->mac_cr |= MAC_CR_RXEN_; |
776 | spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); | 755 | spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); |
777 | 756 | ||
778 | ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr); | 757 | ret = __smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr, in_pm); |
779 | check_warn_return(ret, "Failed to write MAC_CR: %d\n", ret); | 758 | check_warn_return(ret, "Failed to write MAC_CR: %d\n", ret); |
780 | 759 | ||
781 | return 0; | 760 | return 0; |
@@ -994,7 +973,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
994 | ret = smsc95xx_start_tx_path(dev); | 973 | ret = smsc95xx_start_tx_path(dev); |
995 | check_warn_return(ret, "Failed to start TX path"); | 974 | check_warn_return(ret, "Failed to start TX path"); |
996 | 975 | ||
997 | ret = smsc95xx_start_rx_path(dev); | 976 | ret = smsc95xx_start_rx_path(dev, 0); |
998 | check_warn_return(ret, "Failed to start RX path"); | 977 | check_warn_return(ret, "Failed to start RX path"); |
999 | 978 | ||
1000 | netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n"); | 979 | netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n"); |
@@ -1017,6 +996,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = { | |||
1017 | static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) | 996 | static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) |
1018 | { | 997 | { |
1019 | struct smsc95xx_priv *pdata = NULL; | 998 | struct smsc95xx_priv *pdata = NULL; |
999 | u32 val; | ||
1020 | int ret; | 1000 | int ret; |
1021 | 1001 | ||
1022 | printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); | 1002 | printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); |
@@ -1047,6 +1027,15 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1047 | /* Init all registers */ | 1027 | /* Init all registers */ |
1048 | ret = smsc95xx_reset(dev); | 1028 | ret = smsc95xx_reset(dev); |
1049 | 1029 | ||
1030 | /* detect device revision as different features may be available */ | ||
1031 | ret = smsc95xx_read_reg(dev, ID_REV, &val); | ||
1032 | check_warn_return(ret, "Failed to read ID_REV: %d\n", ret); | ||
1033 | val >>= 16; | ||
1034 | if ((val == ID_REV_CHIP_ID_9500A_) || (val == ID_REV_CHIP_ID_9512_)) | ||
1035 | pdata->wuff_filter_count = LAN9500A_WUFF_NUM; | ||
1036 | else | ||
1037 | pdata->wuff_filter_count = LAN9500_WUFF_NUM; | ||
1038 | |||
1050 | dev->net->netdev_ops = &smsc95xx_netdev_ops; | 1039 | dev->net->netdev_ops = &smsc95xx_netdev_ops; |
1051 | dev->net->ethtool_ops = &smsc95xx_ethtool_ops; | 1040 | dev->net->ethtool_ops = &smsc95xx_ethtool_ops; |
1052 | dev->net->flags |= IFF_MULTICAST; | 1041 | dev->net->flags |= IFF_MULTICAST; |
@@ -1066,6 +1055,11 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
1066 | } | 1055 | } |
1067 | } | 1056 | } |
1068 | 1057 | ||
1058 | static u16 smsc_crc(const u8 *buffer, size_t len, int filter) | ||
1059 | { | ||
1060 | return bitrev16(crc16(0xFFFF, buffer, len)) << ((filter % 2) * 16); | ||
1061 | } | ||
1062 | |||
1069 | static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) | 1063 | static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) |
1070 | { | 1064 | { |
1071 | struct usbnet *dev = usb_get_intfdata(intf); | 1065 | struct usbnet *dev = usb_get_intfdata(intf); |
@@ -1081,50 +1075,153 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) | |||
1081 | netdev_info(dev->net, "entering SUSPEND2 mode"); | 1075 | netdev_info(dev->net, "entering SUSPEND2 mode"); |
1082 | 1076 | ||
1083 | /* disable energy detect (link up) & wake up events */ | 1077 | /* disable energy detect (link up) & wake up events */ |
1084 | ret = smsc95xx_read_reg(dev, WUCSR, &val); | 1078 | ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); |
1085 | check_warn_return(ret, "Error reading WUCSR"); | 1079 | check_warn_return(ret, "Error reading WUCSR"); |
1086 | 1080 | ||
1087 | val &= ~(WUCSR_MPEN_ | WUCSR_WAKE_EN_); | 1081 | val &= ~(WUCSR_MPEN_ | WUCSR_WAKE_EN_); |
1088 | 1082 | ||
1089 | ret = smsc95xx_write_reg(dev, WUCSR, val); | 1083 | ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); |
1090 | check_warn_return(ret, "Error writing WUCSR"); | 1084 | check_warn_return(ret, "Error writing WUCSR"); |
1091 | 1085 | ||
1092 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1086 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1093 | check_warn_return(ret, "Error reading PM_CTRL"); | 1087 | check_warn_return(ret, "Error reading PM_CTRL"); |
1094 | 1088 | ||
1095 | val &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_); | 1089 | val &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_); |
1096 | 1090 | ||
1097 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1091 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1098 | check_warn_return(ret, "Error writing PM_CTRL"); | 1092 | check_warn_return(ret, "Error writing PM_CTRL"); |
1099 | 1093 | ||
1100 | /* enter suspend2 mode */ | 1094 | /* enter suspend2 mode */ |
1101 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1095 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1102 | check_warn_return(ret, "Error reading PM_CTRL"); | 1096 | check_warn_return(ret, "Error reading PM_CTRL"); |
1103 | 1097 | ||
1104 | val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_); | 1098 | val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_); |
1105 | val |= PM_CTL_SUS_MODE_2; | 1099 | val |= PM_CTL_SUS_MODE_2; |
1106 | 1100 | ||
1107 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1101 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1108 | check_warn_return(ret, "Error writing PM_CTRL"); | 1102 | check_warn_return(ret, "Error writing PM_CTRL"); |
1109 | 1103 | ||
1110 | return 0; | 1104 | return 0; |
1111 | } | 1105 | } |
1112 | 1106 | ||
1107 | if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { | ||
1108 | u32 *filter_mask = kzalloc(32, GFP_KERNEL); | ||
1109 | u32 command[2]; | ||
1110 | u32 offset[2]; | ||
1111 | u32 crc[4]; | ||
1112 | int i, filter = 0; | ||
1113 | |||
1114 | memset(command, 0, sizeof(command)); | ||
1115 | memset(offset, 0, sizeof(offset)); | ||
1116 | memset(crc, 0, sizeof(crc)); | ||
1117 | |||
1118 | if (pdata->wolopts & WAKE_BCAST) { | ||
1119 | const u8 bcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | ||
1120 | netdev_info(dev->net, "enabling broadcast detection"); | ||
1121 | filter_mask[filter * 4] = 0x003F; | ||
1122 | filter_mask[filter * 4 + 1] = 0x00; | ||
1123 | filter_mask[filter * 4 + 2] = 0x00; | ||
1124 | filter_mask[filter * 4 + 3] = 0x00; | ||
1125 | command[filter/4] |= 0x05UL << ((filter % 4) * 8); | ||
1126 | offset[filter/4] |= 0x00 << ((filter % 4) * 8); | ||
1127 | crc[filter/2] |= smsc_crc(bcast, 6, filter); | ||
1128 | filter++; | ||
1129 | } | ||
1130 | |||
1131 | if (pdata->wolopts & WAKE_MCAST) { | ||
1132 | const u8 mcast[] = {0x01, 0x00, 0x5E}; | ||
1133 | netdev_info(dev->net, "enabling multicast detection"); | ||
1134 | filter_mask[filter * 4] = 0x0007; | ||
1135 | filter_mask[filter * 4 + 1] = 0x00; | ||
1136 | filter_mask[filter * 4 + 2] = 0x00; | ||
1137 | filter_mask[filter * 4 + 3] = 0x00; | ||
1138 | command[filter/4] |= 0x09UL << ((filter % 4) * 8); | ||
1139 | offset[filter/4] |= 0x00 << ((filter % 4) * 8); | ||
1140 | crc[filter/2] |= smsc_crc(mcast, 3, filter); | ||
1141 | filter++; | ||
1142 | } | ||
1143 | |||
1144 | if (pdata->wolopts & WAKE_ARP) { | ||
1145 | const u8 arp[] = {0x08, 0x06}; | ||
1146 | netdev_info(dev->net, "enabling ARP detection"); | ||
1147 | filter_mask[filter * 4] = 0x0003; | ||
1148 | filter_mask[filter * 4 + 1] = 0x00; | ||
1149 | filter_mask[filter * 4 + 2] = 0x00; | ||
1150 | filter_mask[filter * 4 + 3] = 0x00; | ||
1151 | command[filter/4] |= 0x05UL << ((filter % 4) * 8); | ||
1152 | offset[filter/4] |= 0x0C << ((filter % 4) * 8); | ||
1153 | crc[filter/2] |= smsc_crc(arp, 2, filter); | ||
1154 | filter++; | ||
1155 | } | ||
1156 | |||
1157 | if (pdata->wolopts & WAKE_UCAST) { | ||
1158 | netdev_info(dev->net, "enabling unicast detection"); | ||
1159 | filter_mask[filter * 4] = 0x003F; | ||
1160 | filter_mask[filter * 4 + 1] = 0x00; | ||
1161 | filter_mask[filter * 4 + 2] = 0x00; | ||
1162 | filter_mask[filter * 4 + 3] = 0x00; | ||
1163 | command[filter/4] |= 0x01UL << ((filter % 4) * 8); | ||
1164 | offset[filter/4] |= 0x00 << ((filter % 4) * 8); | ||
1165 | crc[filter/2] |= smsc_crc(dev->net->dev_addr, ETH_ALEN, filter); | ||
1166 | filter++; | ||
1167 | } | ||
1168 | |||
1169 | for (i = 0; i < (pdata->wuff_filter_count * 4); i++) { | ||
1170 | ret = smsc95xx_write_reg_nopm(dev, WUFF, filter_mask[i]); | ||
1171 | if (ret < 0) | ||
1172 | kfree(filter_mask); | ||
1173 | check_warn_return(ret, "Error writing WUFF"); | ||
1174 | } | ||
1175 | kfree(filter_mask); | ||
1176 | |||
1177 | for (i = 0; i < (pdata->wuff_filter_count / 4); i++) { | ||
1178 | ret = smsc95xx_write_reg_nopm(dev, WUFF, command[i]); | ||
1179 | check_warn_return(ret, "Error writing WUFF"); | ||
1180 | } | ||
1181 | |||
1182 | for (i = 0; i < (pdata->wuff_filter_count / 4); i++) { | ||
1183 | ret = smsc95xx_write_reg_nopm(dev, WUFF, offset[i]); | ||
1184 | check_warn_return(ret, "Error writing WUFF"); | ||
1185 | } | ||
1186 | |||
1187 | for (i = 0; i < (pdata->wuff_filter_count / 2); i++) { | ||
1188 | ret = smsc95xx_write_reg_nopm(dev, WUFF, crc[i]); | ||
1189 | check_warn_return(ret, "Error writing WUFF"); | ||
1190 | } | ||
1191 | |||
1192 | /* clear any pending pattern match packet status */ | ||
1193 | ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); | ||
1194 | check_warn_return(ret, "Error reading WUCSR"); | ||
1195 | |||
1196 | val |= WUCSR_WUFR_; | ||
1197 | |||
1198 | ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); | ||
1199 | check_warn_return(ret, "Error writing WUCSR"); | ||
1200 | } | ||
1201 | |||
1113 | if (pdata->wolopts & WAKE_MAGIC) { | 1202 | if (pdata->wolopts & WAKE_MAGIC) { |
1114 | /* clear any pending magic packet status */ | 1203 | /* clear any pending magic packet status */ |
1115 | ret = smsc95xx_read_reg(dev, WUCSR, &val); | 1204 | ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); |
1116 | check_warn_return(ret, "Error reading WUCSR"); | 1205 | check_warn_return(ret, "Error reading WUCSR"); |
1117 | 1206 | ||
1118 | val |= WUCSR_MPR_; | 1207 | val |= WUCSR_MPR_; |
1119 | 1208 | ||
1120 | ret = smsc95xx_write_reg(dev, WUCSR, val); | 1209 | ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); |
1121 | check_warn_return(ret, "Error writing WUCSR"); | 1210 | check_warn_return(ret, "Error writing WUCSR"); |
1122 | } | 1211 | } |
1123 | 1212 | ||
1124 | /* enable/disable magic packup wake */ | 1213 | /* enable/disable wakeup sources */ |
1125 | ret = smsc95xx_read_reg(dev, WUCSR, &val); | 1214 | ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); |
1126 | check_warn_return(ret, "Error reading WUCSR"); | 1215 | check_warn_return(ret, "Error reading WUCSR"); |
1127 | 1216 | ||
1217 | if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { | ||
1218 | netdev_info(dev->net, "enabling pattern match wakeup"); | ||
1219 | val |= WUCSR_WAKE_EN_; | ||
1220 | } else { | ||
1221 | netdev_info(dev->net, "disabling pattern match wakeup"); | ||
1222 | val &= ~WUCSR_WAKE_EN_; | ||
1223 | } | ||
1224 | |||
1128 | if (pdata->wolopts & WAKE_MAGIC) { | 1225 | if (pdata->wolopts & WAKE_MAGIC) { |
1129 | netdev_info(dev->net, "enabling magic packet wakeup"); | 1226 | netdev_info(dev->net, "enabling magic packet wakeup"); |
1130 | val |= WUCSR_MPEN_; | 1227 | val |= WUCSR_MPEN_; |
@@ -1133,41 +1230,41 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) | |||
1133 | val &= ~WUCSR_MPEN_; | 1230 | val &= ~WUCSR_MPEN_; |
1134 | } | 1231 | } |
1135 | 1232 | ||
1136 | ret = smsc95xx_write_reg(dev, WUCSR, val); | 1233 | ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); |
1137 | check_warn_return(ret, "Error writing WUCSR"); | 1234 | check_warn_return(ret, "Error writing WUCSR"); |
1138 | 1235 | ||
1139 | /* enable wol wakeup source */ | 1236 | /* enable wol wakeup source */ |
1140 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1237 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1141 | check_warn_return(ret, "Error reading PM_CTRL"); | 1238 | check_warn_return(ret, "Error reading PM_CTRL"); |
1142 | 1239 | ||
1143 | val |= PM_CTL_WOL_EN_; | 1240 | val |= PM_CTL_WOL_EN_; |
1144 | 1241 | ||
1145 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1242 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1146 | check_warn_return(ret, "Error writing PM_CTRL"); | 1243 | check_warn_return(ret, "Error writing PM_CTRL"); |
1147 | 1244 | ||
1148 | /* enable receiver */ | 1245 | /* enable receiver to enable frame reception */ |
1149 | smsc95xx_start_rx_path(dev); | 1246 | smsc95xx_start_rx_path(dev, 1); |
1150 | 1247 | ||
1151 | /* some wol options are enabled, so enter SUSPEND0 */ | 1248 | /* some wol options are enabled, so enter SUSPEND0 */ |
1152 | netdev_info(dev->net, "entering SUSPEND0 mode"); | 1249 | netdev_info(dev->net, "entering SUSPEND0 mode"); |
1153 | 1250 | ||
1154 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1251 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1155 | check_warn_return(ret, "Error reading PM_CTRL"); | 1252 | check_warn_return(ret, "Error reading PM_CTRL"); |
1156 | 1253 | ||
1157 | val &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); | 1254 | val &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); |
1158 | val |= PM_CTL_SUS_MODE_0; | 1255 | val |= PM_CTL_SUS_MODE_0; |
1159 | 1256 | ||
1160 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1257 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1161 | check_warn_return(ret, "Error writing PM_CTRL"); | 1258 | check_warn_return(ret, "Error writing PM_CTRL"); |
1162 | 1259 | ||
1163 | /* clear wol status */ | 1260 | /* clear wol status */ |
1164 | val &= ~PM_CTL_WUPS_; | 1261 | val &= ~PM_CTL_WUPS_; |
1165 | val |= PM_CTL_WUPS_WOL_; | 1262 | val |= PM_CTL_WUPS_WOL_; |
1166 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1263 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1167 | check_warn_return(ret, "Error writing PM_CTRL"); | 1264 | check_warn_return(ret, "Error writing PM_CTRL"); |
1168 | 1265 | ||
1169 | /* read back PM_CTRL */ | 1266 | /* read back PM_CTRL */ |
1170 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1267 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1171 | check_warn_return(ret, "Error reading PM_CTRL"); | 1268 | check_warn_return(ret, "Error reading PM_CTRL"); |
1172 | 1269 | ||
1173 | smsc95xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP); | 1270 | smsc95xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP); |
@@ -1184,26 +1281,26 @@ static int smsc95xx_resume(struct usb_interface *intf) | |||
1184 | 1281 | ||
1185 | BUG_ON(!dev); | 1282 | BUG_ON(!dev); |
1186 | 1283 | ||
1187 | if (pdata->wolopts & WAKE_MAGIC) { | 1284 | if (pdata->wolopts) { |
1188 | smsc95xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP); | 1285 | smsc95xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP); |
1189 | 1286 | ||
1190 | /* Disable magic packup wake */ | 1287 | /* clear wake-up sources */ |
1191 | ret = smsc95xx_read_reg(dev, WUCSR, &val); | 1288 | ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); |
1192 | check_warn_return(ret, "Error reading WUCSR"); | 1289 | check_warn_return(ret, "Error reading WUCSR"); |
1193 | 1290 | ||
1194 | val &= ~WUCSR_MPEN_; | 1291 | val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_); |
1195 | 1292 | ||
1196 | ret = smsc95xx_write_reg(dev, WUCSR, val); | 1293 | ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); |
1197 | check_warn_return(ret, "Error writing WUCSR"); | 1294 | check_warn_return(ret, "Error writing WUCSR"); |
1198 | 1295 | ||
1199 | /* clear wake-up status */ | 1296 | /* clear wake-up status */ |
1200 | ret = smsc95xx_read_reg(dev, PM_CTRL, &val); | 1297 | ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); |
1201 | check_warn_return(ret, "Error reading PM_CTRL"); | 1298 | check_warn_return(ret, "Error reading PM_CTRL"); |
1202 | 1299 | ||
1203 | val &= ~PM_CTL_WOL_EN_; | 1300 | val &= ~PM_CTL_WOL_EN_; |
1204 | val |= PM_CTL_WUPS_; | 1301 | val |= PM_CTL_WUPS_; |
1205 | 1302 | ||
1206 | ret = smsc95xx_write_reg(dev, PM_CTRL, val); | 1303 | ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); |
1207 | check_warn_return(ret, "Error writing PM_CTRL"); | 1304 | check_warn_return(ret, "Error writing PM_CTRL"); |
1208 | } | 1305 | } |
1209 | 1306 | ||
diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h index 2ff9815aa27c..1f862693dd7e 100644 --- a/drivers/net/usb/smsc95xx.h +++ b/drivers/net/usb/smsc95xx.h | |||
@@ -53,6 +53,8 @@ | |||
53 | #define ID_REV_CHIP_ID_MASK_ (0xFFFF0000) | 53 | #define ID_REV_CHIP_ID_MASK_ (0xFFFF0000) |
54 | #define ID_REV_CHIP_REV_MASK_ (0x0000FFFF) | 54 | #define ID_REV_CHIP_REV_MASK_ (0x0000FFFF) |
55 | #define ID_REV_CHIP_ID_9500_ (0x9500) | 55 | #define ID_REV_CHIP_ID_9500_ (0x9500) |
56 | #define ID_REV_CHIP_ID_9500A_ (0x9E00) | ||
57 | #define ID_REV_CHIP_ID_9512_ (0xEC00) | ||
56 | 58 | ||
57 | #define INT_STS (0x08) | 59 | #define INT_STS (0x08) |
58 | #define INT_STS_TX_STOP_ (0x00020000) | 60 | #define INT_STS_TX_STOP_ (0x00020000) |
@@ -203,8 +205,11 @@ | |||
203 | #define VLAN2 (0x124) | 205 | #define VLAN2 (0x124) |
204 | 206 | ||
205 | #define WUFF (0x128) | 207 | #define WUFF (0x128) |
208 | #define LAN9500_WUFF_NUM (4) | ||
209 | #define LAN9500A_WUFF_NUM (8) | ||
206 | 210 | ||
207 | #define WUCSR (0x12C) | 211 | #define WUCSR (0x12C) |
212 | #define WUCSR_WFF_PTR_RST_ (0x80000000) | ||
208 | #define WUCSR_GUE_ (0x00000200) | 213 | #define WUCSR_GUE_ (0x00000200) |
209 | #define WUCSR_WUFR_ (0x00000040) | 214 | #define WUCSR_WUFR_ (0x00000040) |
210 | #define WUCSR_MPR_ (0x00000020) | 215 | #define WUCSR_MPR_ (0x00000020) |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index edb81ed06950..c04110ba677f 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1616,6 +1616,202 @@ void usbnet_device_suggests_idle(struct usbnet *dev) | |||
1616 | EXPORT_SYMBOL(usbnet_device_suggests_idle); | 1616 | EXPORT_SYMBOL(usbnet_device_suggests_idle); |
1617 | 1617 | ||
1618 | /*-------------------------------------------------------------------------*/ | 1618 | /*-------------------------------------------------------------------------*/ |
1619 | static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1620 | u16 value, u16 index, void *data, u16 size) | ||
1621 | { | ||
1622 | void *buf = NULL; | ||
1623 | int err = -ENOMEM; | ||
1624 | |||
1625 | netdev_dbg(dev->net, "usbnet_read_cmd cmd=0x%02x reqtype=%02x" | ||
1626 | " value=0x%04x index=0x%04x size=%d\n", | ||
1627 | cmd, reqtype, value, index, size); | ||
1628 | |||
1629 | if (data) { | ||
1630 | buf = kmalloc(size, GFP_KERNEL); | ||
1631 | if (!buf) | ||
1632 | goto out; | ||
1633 | } | ||
1634 | |||
1635 | err = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | ||
1636 | cmd, reqtype, value, index, buf, size, | ||
1637 | USB_CTRL_GET_TIMEOUT); | ||
1638 | if (err > 0 && err <= size) | ||
1639 | memcpy(data, buf, err); | ||
1640 | kfree(buf); | ||
1641 | out: | ||
1642 | return err; | ||
1643 | } | ||
1644 | |||
1645 | static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1646 | u16 value, u16 index, const void *data, | ||
1647 | u16 size) | ||
1648 | { | ||
1649 | void *buf = NULL; | ||
1650 | int err = -ENOMEM; | ||
1651 | |||
1652 | netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x" | ||
1653 | " value=0x%04x index=0x%04x size=%d\n", | ||
1654 | cmd, reqtype, value, index, size); | ||
1655 | |||
1656 | if (data) { | ||
1657 | buf = kmemdup(data, size, GFP_KERNEL); | ||
1658 | if (!buf) | ||
1659 | goto out; | ||
1660 | } | ||
1661 | |||
1662 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
1663 | cmd, reqtype, value, index, buf, size, | ||
1664 | USB_CTRL_SET_TIMEOUT); | ||
1665 | kfree(buf); | ||
1666 | |||
1667 | out: | ||
1668 | return err; | ||
1669 | } | ||
1670 | |||
1671 | /* | ||
1672 | * The function can't be called inside suspend/resume callback, | ||
1673 | * otherwise deadlock will be caused. | ||
1674 | */ | ||
1675 | int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1676 | u16 value, u16 index, void *data, u16 size) | ||
1677 | { | ||
1678 | int ret; | ||
1679 | |||
1680 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
1681 | return -ENODEV; | ||
1682 | ret = __usbnet_read_cmd(dev, cmd, reqtype, value, index, | ||
1683 | data, size); | ||
1684 | usb_autopm_put_interface(dev->intf); | ||
1685 | return ret; | ||
1686 | } | ||
1687 | EXPORT_SYMBOL_GPL(usbnet_read_cmd); | ||
1688 | |||
1689 | /* | ||
1690 | * The function can't be called inside suspend/resume callback, | ||
1691 | * otherwise deadlock will be caused. | ||
1692 | */ | ||
1693 | int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1694 | u16 value, u16 index, const void *data, u16 size) | ||
1695 | { | ||
1696 | int ret; | ||
1697 | |||
1698 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
1699 | return -ENODEV; | ||
1700 | ret = __usbnet_write_cmd(dev, cmd, reqtype, value, index, | ||
1701 | data, size); | ||
1702 | usb_autopm_put_interface(dev->intf); | ||
1703 | return ret; | ||
1704 | } | ||
1705 | EXPORT_SYMBOL_GPL(usbnet_write_cmd); | ||
1706 | |||
1707 | /* | ||
1708 | * The function can be called inside suspend/resume callback safely | ||
1709 | * and should only be called by suspend/resume callback generally. | ||
1710 | */ | ||
1711 | int usbnet_read_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1712 | u16 value, u16 index, void *data, u16 size) | ||
1713 | { | ||
1714 | return __usbnet_read_cmd(dev, cmd, reqtype, value, index, | ||
1715 | data, size); | ||
1716 | } | ||
1717 | EXPORT_SYMBOL_GPL(usbnet_read_cmd_nopm); | ||
1718 | |||
1719 | /* | ||
1720 | * The function can be called inside suspend/resume callback safely | ||
1721 | * and should only be called by suspend/resume callback generally. | ||
1722 | */ | ||
1723 | int usbnet_write_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1724 | u16 value, u16 index, const void *data, | ||
1725 | u16 size) | ||
1726 | { | ||
1727 | return __usbnet_write_cmd(dev, cmd, reqtype, value, index, | ||
1728 | data, size); | ||
1729 | } | ||
1730 | EXPORT_SYMBOL_GPL(usbnet_write_cmd_nopm); | ||
1731 | |||
1732 | static void usbnet_async_cmd_cb(struct urb *urb) | ||
1733 | { | ||
1734 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
1735 | int status = urb->status; | ||
1736 | |||
1737 | if (status < 0) | ||
1738 | dev_dbg(&urb->dev->dev, "%s failed with %d", | ||
1739 | __func__, status); | ||
1740 | |||
1741 | kfree(req); | ||
1742 | usb_free_urb(urb); | ||
1743 | } | ||
1744 | |||
1745 | /* | ||
1746 | * The caller must make sure that device can't be put into suspend | ||
1747 | * state until the control URB completes. | ||
1748 | */ | ||
1749 | int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
1750 | u16 value, u16 index, const void *data, u16 size) | ||
1751 | { | ||
1752 | struct usb_ctrlrequest *req = NULL; | ||
1753 | struct urb *urb; | ||
1754 | int err = -ENOMEM; | ||
1755 | void *buf = NULL; | ||
1756 | |||
1757 | netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x" | ||
1758 | " value=0x%04x index=0x%04x size=%d\n", | ||
1759 | cmd, reqtype, value, index, size); | ||
1760 | |||
1761 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
1762 | if (!urb) { | ||
1763 | netdev_err(dev->net, "Error allocating URB in" | ||
1764 | " %s!\n", __func__); | ||
1765 | goto fail; | ||
1766 | } | ||
1767 | |||
1768 | if (data) { | ||
1769 | buf = kmemdup(data, size, GFP_ATOMIC); | ||
1770 | if (!buf) { | ||
1771 | netdev_err(dev->net, "Error allocating buffer" | ||
1772 | " in %s!\n", __func__); | ||
1773 | goto fail_free; | ||
1774 | } | ||
1775 | } | ||
1776 | |||
1777 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); | ||
1778 | if (!req) { | ||
1779 | netdev_err(dev->net, "Failed to allocate memory for %s\n", | ||
1780 | __func__); | ||
1781 | goto fail_free_buf; | ||
1782 | } | ||
1783 | |||
1784 | req->bRequestType = reqtype; | ||
1785 | req->bRequest = cmd; | ||
1786 | req->wValue = cpu_to_le16(value); | ||
1787 | req->wIndex = cpu_to_le16(index); | ||
1788 | req->wLength = cpu_to_le16(size); | ||
1789 | |||
1790 | usb_fill_control_urb(urb, dev->udev, | ||
1791 | usb_sndctrlpipe(dev->udev, 0), | ||
1792 | (void *)req, buf, size, | ||
1793 | usbnet_async_cmd_cb, req); | ||
1794 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
1795 | |||
1796 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
1797 | if (err < 0) { | ||
1798 | netdev_err(dev->net, "Error submitting the control" | ||
1799 | " message: status=%d\n", err); | ||
1800 | goto fail_free; | ||
1801 | } | ||
1802 | return 0; | ||
1803 | |||
1804 | fail_free_buf: | ||
1805 | kfree(buf); | ||
1806 | fail_free: | ||
1807 | kfree(req); | ||
1808 | usb_free_urb(urb); | ||
1809 | fail: | ||
1810 | return err; | ||
1811 | |||
1812 | } | ||
1813 | EXPORT_SYMBOL_GPL(usbnet_write_cmd_async); | ||
1814 | /*-------------------------------------------------------------------------*/ | ||
1619 | 1815 | ||
1620 | static int __init usbnet_init(void) | 1816 | static int __init usbnet_init(void) |
1621 | { | 1817 | { |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index e522ff70444c..24f6b27e169f 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -264,6 +264,7 @@ static void veth_setup(struct net_device *dev) | |||
264 | ether_setup(dev); | 264 | ether_setup(dev); |
265 | 265 | ||
266 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 266 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
267 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | ||
267 | 268 | ||
268 | dev->netdev_ops = &veth_netdev_ops; | 269 | dev->netdev_ops = &veth_netdev_ops; |
269 | dev->ethtool_ops = &veth_ethtool_ops; | 270 | dev->ethtool_ops = &veth_ethtool_ops; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index cbf8b0625352..26c502e4b871 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -212,8 +212,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, | |||
212 | * the case of a broken device. | 212 | * the case of a broken device. |
213 | */ | 213 | */ |
214 | if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) { | 214 | if (unlikely(len > MAX_SKB_FRAGS * PAGE_SIZE)) { |
215 | if (net_ratelimit()) | 215 | net_dbg_ratelimited("%s: too much data\n", skb->dev->name); |
216 | pr_debug("%s: too much data\n", skb->dev->name); | ||
217 | dev_kfree_skb(skb); | 216 | dev_kfree_skb(skb); |
218 | return NULL; | 217 | return NULL; |
219 | } | 218 | } |
@@ -333,9 +332,8 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) | |||
333 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 332 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; |
334 | break; | 333 | break; |
335 | default: | 334 | default: |
336 | if (net_ratelimit()) | 335 | net_warn_ratelimited("%s: bad gso type %u.\n", |
337 | printk(KERN_WARNING "%s: bad gso type %u.\n", | 336 | dev->name, hdr->hdr.gso_type); |
338 | dev->name, hdr->hdr.gso_type); | ||
339 | goto frame_err; | 337 | goto frame_err; |
340 | } | 338 | } |
341 | 339 | ||
@@ -344,9 +342,7 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) | |||
344 | 342 | ||
345 | skb_shinfo(skb)->gso_size = hdr->hdr.gso_size; | 343 | skb_shinfo(skb)->gso_size = hdr->hdr.gso_size; |
346 | if (skb_shinfo(skb)->gso_size == 0) { | 344 | if (skb_shinfo(skb)->gso_size == 0) { |
347 | if (net_ratelimit()) | 345 | net_warn_ratelimited("%s: zero gso size.\n", dev->name); |
348 | printk(KERN_WARNING "%s: zero gso size.\n", | ||
349 | dev->name); | ||
350 | goto frame_err; | 346 | goto frame_err; |
351 | } | 347 | } |
352 | 348 | ||
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 0ae1bcc6da73..7e9622fea0a9 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -1922,7 +1922,7 @@ vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) | |||
1922 | free_irq(adapter->pdev->irq, adapter->netdev); | 1922 | free_irq(adapter->pdev->irq, adapter->netdev); |
1923 | break; | 1923 | break; |
1924 | default: | 1924 | default: |
1925 | BUG_ON(true); | 1925 | BUG(); |
1926 | } | 1926 | } |
1927 | } | 1927 | } |
1928 | 1928 | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 7b4adde93c01..8aca888734da 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1107,6 +1107,9 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, | |||
1107 | if (data[IFLA_VXLAN_TOS]) | 1107 | if (data[IFLA_VXLAN_TOS]) |
1108 | vxlan->tos = nla_get_u8(data[IFLA_VXLAN_TOS]); | 1108 | vxlan->tos = nla_get_u8(data[IFLA_VXLAN_TOS]); |
1109 | 1109 | ||
1110 | if (data[IFLA_VXLAN_TTL]) | ||
1111 | vxlan->ttl = nla_get_u8(data[IFLA_VXLAN_TTL]); | ||
1112 | |||
1110 | if (!data[IFLA_VXLAN_LEARNING] || nla_get_u8(data[IFLA_VXLAN_LEARNING])) | 1113 | if (!data[IFLA_VXLAN_LEARNING] || nla_get_u8(data[IFLA_VXLAN_LEARNING])) |
1111 | vxlan->learn = true; | 1114 | vxlan->learn = true; |
1112 | 1115 | ||
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index eac709bed7ae..df70248e2fda 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile | |||
@@ -52,9 +52,9 @@ endif | |||
52 | 52 | ||
53 | quiet_cmd_build_wanxlfw = BLD FW $@ | 53 | quiet_cmd_build_wanxlfw = BLD FW $@ |
54 | cmd_build_wanxlfw = \ | 54 | cmd_build_wanxlfw = \ |
55 | $(CPP) -Wp,-MD,$(depfile) -I$(srctree)/include $< | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ | 55 | $(CPP) -D__ASSEMBLY__ -Wp,-MD,$(depfile) -I$(srctree)/include/uapi $< | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ |
56 | $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ | 56 | $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ |
57 | hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \ | 57 | hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static const u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \ |
58 | rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o | 58 | rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o |
59 | 59 | ||
60 | $(obj)/wanxlfw.inc: $(src)/wanxlfw.S | 60 | $(obj)/wanxlfw.inc: $(src)/wanxlfw.S |
diff --git a/drivers/net/wan/wanxlfw.S b/drivers/net/wan/wanxlfw.S index 73aae2bf2f1c..21565d59ec7b 100644 --- a/drivers/net/wan/wanxlfw.S +++ b/drivers/net/wan/wanxlfw.S | |||
@@ -35,6 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/hdlc.h> | 37 | #include <linux/hdlc.h> |
38 | #include <linux/hdlc/ioctl.h> | ||
38 | #include "wanxl.h" | 39 | #include "wanxl.h" |
39 | 40 | ||
40 | /* memory addresses and offsets */ | 41 | /* memory addresses and offsets */ |
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index 258ca596e1bc..982d16b5a846 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig | |||
@@ -6,7 +6,6 @@ menu "PPS support" | |||
6 | 6 | ||
7 | config PPS | 7 | config PPS |
8 | tristate "PPS support" | 8 | tristate "PPS support" |
9 | depends on EXPERIMENTAL | ||
10 | ---help--- | 9 | ---help--- |
11 | PPS (Pulse Per Second) is a special pulse provided by some GPS | 10 | PPS (Pulse Per Second) is a special pulse provided by some GPS |
12 | antennae. Userland can use it to get a high-precision time | 11 | antennae. Userland can use it to get a high-precision time |
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index ffdf712f9a67..70c5836ebfc9 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig | |||
@@ -4,13 +4,9 @@ | |||
4 | 4 | ||
5 | menu "PTP clock support" | 5 | menu "PTP clock support" |
6 | 6 | ||
7 | comment "Enable Device Drivers -> PPS to see the PTP clock options." | ||
8 | depends on PPS=n | ||
9 | |||
10 | config PTP_1588_CLOCK | 7 | config PTP_1588_CLOCK |
11 | tristate "PTP clock support" | 8 | tristate "PTP clock support" |
12 | depends on EXPERIMENTAL | 9 | select PPS |
13 | depends on PPS | ||
14 | help | 10 | help |
15 | The IEEE 1588 standard defines a method to precisely | 11 | The IEEE 1588 standard defines a method to precisely |
16 | synchronize distributed clocks over Ethernet networks. The | 12 | synchronize distributed clocks over Ethernet networks. The |
@@ -29,8 +25,9 @@ config PTP_1588_CLOCK | |||
29 | 25 | ||
30 | config PTP_1588_CLOCK_GIANFAR | 26 | config PTP_1588_CLOCK_GIANFAR |
31 | tristate "Freescale eTSEC as PTP clock" | 27 | tristate "Freescale eTSEC as PTP clock" |
32 | depends on PTP_1588_CLOCK | ||
33 | depends on GIANFAR | 28 | depends on GIANFAR |
29 | select PTP_1588_CLOCK | ||
30 | default y | ||
34 | help | 31 | help |
35 | This driver adds support for using the eTSEC as a PTP | 32 | This driver adds support for using the eTSEC as a PTP |
36 | clock. This clock is only useful if your PTP programs are | 33 | clock. This clock is only useful if your PTP programs are |
@@ -42,8 +39,9 @@ config PTP_1588_CLOCK_GIANFAR | |||
42 | 39 | ||
43 | config PTP_1588_CLOCK_IXP46X | 40 | config PTP_1588_CLOCK_IXP46X |
44 | tristate "Intel IXP46x as PTP clock" | 41 | tristate "Intel IXP46x as PTP clock" |
45 | depends on PTP_1588_CLOCK | ||
46 | depends on IXP4XX_ETH | 42 | depends on IXP4XX_ETH |
43 | select PTP_1588_CLOCK | ||
44 | default y | ||
47 | help | 45 | help |
48 | This driver adds support for using the IXP46X as a PTP | 46 | This driver adds support for using the IXP46X as a PTP |
49 | clock. This clock is only useful if your PTP programs are | 47 | clock. This clock is only useful if your PTP programs are |
@@ -54,13 +52,13 @@ config PTP_1588_CLOCK_IXP46X | |||
54 | will be called ptp_ixp46x. | 52 | will be called ptp_ixp46x. |
55 | 53 | ||
56 | comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks." | 54 | comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks." |
57 | depends on PTP_1588_CLOCK && (PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n) | 55 | depends on PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n |
58 | 56 | ||
59 | config DP83640_PHY | 57 | config DP83640_PHY |
60 | tristate "Driver for the National Semiconductor DP83640 PHYTER" | 58 | tristate "Driver for the National Semiconductor DP83640 PHYTER" |
61 | depends on PTP_1588_CLOCK | ||
62 | depends on NETWORK_PHY_TIMESTAMPING | 59 | depends on NETWORK_PHY_TIMESTAMPING |
63 | depends on PHYLIB | 60 | depends on PHYLIB |
61 | select PTP_1588_CLOCK | ||
64 | ---help--- | 62 | ---help--- |
65 | Supports the DP83640 PHYTER with IEEE 1588 features. | 63 | Supports the DP83640 PHYTER with IEEE 1588 features. |
66 | 64 | ||
@@ -74,8 +72,9 @@ config DP83640_PHY | |||
74 | 72 | ||
75 | config PTP_1588_CLOCK_PCH | 73 | config PTP_1588_CLOCK_PCH |
76 | tristate "Intel PCH EG20T as PTP clock" | 74 | tristate "Intel PCH EG20T as PTP clock" |
77 | depends on PTP_1588_CLOCK | ||
78 | depends on PCH_GBE | 75 | depends on PCH_GBE |
76 | select PTP_1588_CLOCK | ||
77 | default y | ||
79 | help | 78 | help |
80 | This driver adds support for using the PCH EG20T as a PTP | 79 | This driver adds support for using the PCH EG20T as a PTP |
81 | clock. The hardware supports time stamping of PTP packets | 80 | clock. The hardware supports time stamping of PTP packets |
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index e7f301da2902..4f8ae8057a7e 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c | |||
@@ -33,9 +33,13 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
33 | { | 33 | { |
34 | struct ptp_clock_caps caps; | 34 | struct ptp_clock_caps caps; |
35 | struct ptp_clock_request req; | 35 | struct ptp_clock_request req; |
36 | struct ptp_sys_offset sysoff; | ||
36 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); | 37 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); |
37 | struct ptp_clock_info *ops = ptp->info; | 38 | struct ptp_clock_info *ops = ptp->info; |
39 | struct ptp_clock_time *pct; | ||
40 | struct timespec ts; | ||
38 | int enable, err = 0; | 41 | int enable, err = 0; |
42 | unsigned int i; | ||
39 | 43 | ||
40 | switch (cmd) { | 44 | switch (cmd) { |
41 | 45 | ||
@@ -88,6 +92,34 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) | |||
88 | err = ops->enable(ops, &req, enable); | 92 | err = ops->enable(ops, &req, enable); |
89 | break; | 93 | break; |
90 | 94 | ||
95 | case PTP_SYS_OFFSET: | ||
96 | if (copy_from_user(&sysoff, (void __user *)arg, | ||
97 | sizeof(sysoff))) { | ||
98 | err = -EFAULT; | ||
99 | break; | ||
100 | } | ||
101 | if (sysoff.n_samples > PTP_MAX_SAMPLES) { | ||
102 | err = -EINVAL; | ||
103 | break; | ||
104 | } | ||
105 | pct = &sysoff.ts[0]; | ||
106 | for (i = 0; i < sysoff.n_samples; i++) { | ||
107 | getnstimeofday(&ts); | ||
108 | pct->sec = ts.tv_sec; | ||
109 | pct->nsec = ts.tv_nsec; | ||
110 | pct++; | ||
111 | ptp->info->gettime(ptp->info, &ts); | ||
112 | pct->sec = ts.tv_sec; | ||
113 | pct->nsec = ts.tv_nsec; | ||
114 | pct++; | ||
115 | } | ||
116 | getnstimeofday(&ts); | ||
117 | pct->sec = ts.tv_sec; | ||
118 | pct->nsec = ts.tv_nsec; | ||
119 | if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff))) | ||
120 | err = -EFAULT; | ||
121 | break; | ||
122 | |||
91 | default: | 123 | default: |
92 | err = -ENOTTY; | 124 | err = -ENOTTY; |
93 | break; | 125 | break; |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 7f93f34b7f91..67898fa9c447 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -42,6 +42,21 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Experimental Zero Copy TX"); | |||
42 | #define VHOST_MAX_PEND 128 | 42 | #define VHOST_MAX_PEND 128 |
43 | #define VHOST_GOODCOPY_LEN 256 | 43 | #define VHOST_GOODCOPY_LEN 256 |
44 | 44 | ||
45 | /* | ||
46 | * For transmit, used buffer len is unused; we override it to track buffer | ||
47 | * status internally; used for zerocopy tx only. | ||
48 | */ | ||
49 | /* Lower device DMA failed */ | ||
50 | #define VHOST_DMA_FAILED_LEN 3 | ||
51 | /* Lower device DMA done */ | ||
52 | #define VHOST_DMA_DONE_LEN 2 | ||
53 | /* Lower device DMA in progress */ | ||
54 | #define VHOST_DMA_IN_PROGRESS 1 | ||
55 | /* Buffer unused */ | ||
56 | #define VHOST_DMA_CLEAR_LEN 0 | ||
57 | |||
58 | #define VHOST_DMA_IS_DONE(len) ((len) >= VHOST_DMA_DONE_LEN) | ||
59 | |||
45 | enum { | 60 | enum { |
46 | VHOST_NET_VQ_RX = 0, | 61 | VHOST_NET_VQ_RX = 0, |
47 | VHOST_NET_VQ_TX = 1, | 62 | VHOST_NET_VQ_TX = 1, |
@@ -62,8 +77,33 @@ struct vhost_net { | |||
62 | * We only do this when socket buffer fills up. | 77 | * We only do this when socket buffer fills up. |
63 | * Protected by tx vq lock. */ | 78 | * Protected by tx vq lock. */ |
64 | enum vhost_net_poll_state tx_poll_state; | 79 | enum vhost_net_poll_state tx_poll_state; |
80 | /* Number of TX recently submitted. | ||
81 | * Protected by tx vq lock. */ | ||
82 | unsigned tx_packets; | ||
83 | /* Number of times zerocopy TX recently failed. | ||
84 | * Protected by tx vq lock. */ | ||
85 | unsigned tx_zcopy_err; | ||
65 | }; | 86 | }; |
66 | 87 | ||
88 | static void vhost_net_tx_packet(struct vhost_net *net) | ||
89 | { | ||
90 | ++net->tx_packets; | ||
91 | if (net->tx_packets < 1024) | ||
92 | return; | ||
93 | net->tx_packets = 0; | ||
94 | net->tx_zcopy_err = 0; | ||
95 | } | ||
96 | |||
97 | static void vhost_net_tx_err(struct vhost_net *net) | ||
98 | { | ||
99 | ++net->tx_zcopy_err; | ||
100 | } | ||
101 | |||
102 | static bool vhost_net_tx_select_zcopy(struct vhost_net *net) | ||
103 | { | ||
104 | return net->tx_packets / 64 >= net->tx_zcopy_err; | ||
105 | } | ||
106 | |||
67 | static bool vhost_sock_zcopy(struct socket *sock) | 107 | static bool vhost_sock_zcopy(struct socket *sock) |
68 | { | 108 | { |
69 | return unlikely(experimental_zcopytx) && | 109 | return unlikely(experimental_zcopytx) && |
@@ -126,6 +166,55 @@ static void tx_poll_start(struct vhost_net *net, struct socket *sock) | |||
126 | net->tx_poll_state = VHOST_NET_POLL_STARTED; | 166 | net->tx_poll_state = VHOST_NET_POLL_STARTED; |
127 | } | 167 | } |
128 | 168 | ||
169 | /* In case of DMA done not in order in lower device driver for some reason. | ||
170 | * upend_idx is used to track end of used idx, done_idx is used to track head | ||
171 | * of used idx. Once lower device DMA done contiguously, we will signal KVM | ||
172 | * guest used idx. | ||
173 | */ | ||
174 | static int vhost_zerocopy_signal_used(struct vhost_net *net, | ||
175 | struct vhost_virtqueue *vq) | ||
176 | { | ||
177 | int i; | ||
178 | int j = 0; | ||
179 | |||
180 | for (i = vq->done_idx; i != vq->upend_idx; i = (i + 1) % UIO_MAXIOV) { | ||
181 | if (vq->heads[i].len == VHOST_DMA_FAILED_LEN) | ||
182 | vhost_net_tx_err(net); | ||
183 | if (VHOST_DMA_IS_DONE(vq->heads[i].len)) { | ||
184 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; | ||
185 | vhost_add_used_and_signal(vq->dev, vq, | ||
186 | vq->heads[i].id, 0); | ||
187 | ++j; | ||
188 | } else | ||
189 | break; | ||
190 | } | ||
191 | if (j) | ||
192 | vq->done_idx = i; | ||
193 | return j; | ||
194 | } | ||
195 | |||
196 | static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | ||
197 | { | ||
198 | struct vhost_ubuf_ref *ubufs = ubuf->ctx; | ||
199 | struct vhost_virtqueue *vq = ubufs->vq; | ||
200 | int cnt = atomic_read(&ubufs->kref.refcount); | ||
201 | |||
202 | /* | ||
203 | * Trigger polling thread if guest stopped submitting new buffers: | ||
204 | * in this case, the refcount after decrement will eventually reach 1 | ||
205 | * so here it is 2. | ||
206 | * We also trigger polling periodically after each 16 packets | ||
207 | * (the value 16 here is more or less arbitrary, it's tuned to trigger | ||
208 | * less than 10% of times). | ||
209 | */ | ||
210 | if (cnt <= 2 || !(cnt % 16)) | ||
211 | vhost_poll_queue(&vq->poll); | ||
212 | /* set len to mark this desc buffers done DMA */ | ||
213 | vq->heads[ubuf->desc].len = success ? | ||
214 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; | ||
215 | vhost_ubuf_put(ubufs); | ||
216 | } | ||
217 | |||
129 | /* Expects to be always run from workqueue - which acts as | 218 | /* Expects to be always run from workqueue - which acts as |
130 | * read-size critical section for our kind of RCU. */ | 219 | * read-size critical section for our kind of RCU. */ |
131 | static void handle_tx(struct vhost_net *net) | 220 | static void handle_tx(struct vhost_net *net) |
@@ -172,7 +261,7 @@ static void handle_tx(struct vhost_net *net) | |||
172 | for (;;) { | 261 | for (;;) { |
173 | /* Release DMAs done buffers first */ | 262 | /* Release DMAs done buffers first */ |
174 | if (zcopy) | 263 | if (zcopy) |
175 | vhost_zerocopy_signal_used(vq); | 264 | vhost_zerocopy_signal_used(net, vq); |
176 | 265 | ||
177 | head = vhost_get_vq_desc(&net->dev, vq, vq->iov, | 266 | head = vhost_get_vq_desc(&net->dev, vq, vq->iov, |
178 | ARRAY_SIZE(vq->iov), | 267 | ARRAY_SIZE(vq->iov), |
@@ -227,7 +316,8 @@ static void handle_tx(struct vhost_net *net) | |||
227 | /* use msg_control to pass vhost zerocopy ubuf info to skb */ | 316 | /* use msg_control to pass vhost zerocopy ubuf info to skb */ |
228 | if (zcopy) { | 317 | if (zcopy) { |
229 | vq->heads[vq->upend_idx].id = head; | 318 | vq->heads[vq->upend_idx].id = head; |
230 | if (len < VHOST_GOODCOPY_LEN) { | 319 | if (!vhost_net_tx_select_zcopy(net) || |
320 | len < VHOST_GOODCOPY_LEN) { | ||
231 | /* copy don't need to wait for DMA done */ | 321 | /* copy don't need to wait for DMA done */ |
232 | vq->heads[vq->upend_idx].len = | 322 | vq->heads[vq->upend_idx].len = |
233 | VHOST_DMA_DONE_LEN; | 323 | VHOST_DMA_DONE_LEN; |
@@ -237,7 +327,8 @@ static void handle_tx(struct vhost_net *net) | |||
237 | } else { | 327 | } else { |
238 | struct ubuf_info *ubuf = &vq->ubuf_info[head]; | 328 | struct ubuf_info *ubuf = &vq->ubuf_info[head]; |
239 | 329 | ||
240 | vq->heads[vq->upend_idx].len = len; | 330 | vq->heads[vq->upend_idx].len = |
331 | VHOST_DMA_IN_PROGRESS; | ||
241 | ubuf->callback = vhost_zerocopy_callback; | 332 | ubuf->callback = vhost_zerocopy_callback; |
242 | ubuf->ctx = vq->ubufs; | 333 | ubuf->ctx = vq->ubufs; |
243 | ubuf->desc = vq->upend_idx; | 334 | ubuf->desc = vq->upend_idx; |
@@ -268,8 +359,9 @@ static void handle_tx(struct vhost_net *net) | |||
268 | if (!zcopy) | 359 | if (!zcopy) |
269 | vhost_add_used_and_signal(&net->dev, vq, head, 0); | 360 | vhost_add_used_and_signal(&net->dev, vq, head, 0); |
270 | else | 361 | else |
271 | vhost_zerocopy_signal_used(vq); | 362 | vhost_zerocopy_signal_used(net, vq); |
272 | total_len += len; | 363 | total_len += len; |
364 | vhost_net_tx_packet(net); | ||
273 | if (unlikely(total_len >= VHOST_NET_WEIGHT)) { | 365 | if (unlikely(total_len >= VHOST_NET_WEIGHT)) { |
274 | vhost_poll_queue(&vq->poll); | 366 | vhost_poll_queue(&vq->poll); |
275 | break; | 367 | break; |
@@ -594,9 +686,18 @@ static int vhost_net_release(struct inode *inode, struct file *f) | |||
594 | struct vhost_net *n = f->private_data; | 686 | struct vhost_net *n = f->private_data; |
595 | struct socket *tx_sock; | 687 | struct socket *tx_sock; |
596 | struct socket *rx_sock; | 688 | struct socket *rx_sock; |
689 | int i; | ||
597 | 690 | ||
598 | vhost_net_stop(n, &tx_sock, &rx_sock); | 691 | vhost_net_stop(n, &tx_sock, &rx_sock); |
599 | vhost_net_flush(n); | 692 | vhost_net_flush(n); |
693 | vhost_dev_stop(&n->dev); | ||
694 | for (i = 0; i < n->dev.nvqs; ++i) { | ||
695 | /* Wait for all lower device DMAs done. */ | ||
696 | if (n->dev.vqs[i].ubufs) | ||
697 | vhost_ubuf_put_and_wait(n->dev.vqs[i].ubufs); | ||
698 | |||
699 | vhost_zerocopy_signal_used(n, &n->dev.vqs[i]); | ||
700 | } | ||
600 | vhost_dev_cleanup(&n->dev, false); | 701 | vhost_dev_cleanup(&n->dev, false); |
601 | if (tx_sock) | 702 | if (tx_sock) |
602 | fput(tx_sock->file); | 703 | fput(tx_sock->file); |
@@ -729,7 +830,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
729 | if (oldubufs) { | 830 | if (oldubufs) { |
730 | vhost_ubuf_put_and_wait(oldubufs); | 831 | vhost_ubuf_put_and_wait(oldubufs); |
731 | mutex_lock(&vq->mutex); | 832 | mutex_lock(&vq->mutex); |
732 | vhost_zerocopy_signal_used(vq); | 833 | vhost_zerocopy_signal_used(n, vq); |
733 | mutex_unlock(&vq->mutex); | 834 | mutex_unlock(&vq->mutex); |
734 | } | 835 | } |
735 | 836 | ||
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index aa31692064dd..23c138fdc195 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -895,6 +895,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) | |||
895 | vhost_scsi_clear_endpoint(s, &backend); | 895 | vhost_scsi_clear_endpoint(s, &backend); |
896 | } | 896 | } |
897 | 897 | ||
898 | vhost_dev_stop(&s->dev); | ||
898 | vhost_dev_cleanup(&s->dev, false); | 899 | vhost_dev_cleanup(&s->dev, false); |
899 | kfree(s); | 900 | kfree(s); |
900 | return 0; | 901 | return 0; |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 99ac2cb08b43..ef8f5988f855 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -26,10 +26,6 @@ | |||
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/cgroup.h> | 27 | #include <linux/cgroup.h> |
28 | 28 | ||
29 | #include <linux/net.h> | ||
30 | #include <linux/if_packet.h> | ||
31 | #include <linux/if_arp.h> | ||
32 | |||
33 | #include "vhost.h" | 29 | #include "vhost.h" |
34 | 30 | ||
35 | enum { | 31 | enum { |
@@ -414,28 +410,16 @@ long vhost_dev_reset_owner(struct vhost_dev *dev) | |||
414 | return 0; | 410 | return 0; |
415 | } | 411 | } |
416 | 412 | ||
417 | /* In case of DMA done not in order in lower device driver for some reason. | 413 | void vhost_dev_stop(struct vhost_dev *dev) |
418 | * upend_idx is used to track end of used idx, done_idx is used to track head | ||
419 | * of used idx. Once lower device DMA done contiguously, we will signal KVM | ||
420 | * guest used idx. | ||
421 | */ | ||
422 | int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq) | ||
423 | { | 414 | { |
424 | int i; | 415 | int i; |
425 | int j = 0; | 416 | |
426 | 417 | for (i = 0; i < dev->nvqs; ++i) { | |
427 | for (i = vq->done_idx; i != vq->upend_idx; i = (i + 1) % UIO_MAXIOV) { | 418 | if (dev->vqs[i].kick && dev->vqs[i].handle_kick) { |
428 | if ((vq->heads[i].len == VHOST_DMA_DONE_LEN)) { | 419 | vhost_poll_stop(&dev->vqs[i].poll); |
429 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; | 420 | vhost_poll_flush(&dev->vqs[i].poll); |
430 | vhost_add_used_and_signal(vq->dev, vq, | 421 | } |
431 | vq->heads[i].id, 0); | ||
432 | ++j; | ||
433 | } else | ||
434 | break; | ||
435 | } | 422 | } |
436 | if (j) | ||
437 | vq->done_idx = i; | ||
438 | return j; | ||
439 | } | 423 | } |
440 | 424 | ||
441 | /* Caller should have device mutex if and only if locked is set */ | 425 | /* Caller should have device mutex if and only if locked is set */ |
@@ -444,17 +428,6 @@ void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) | |||
444 | int i; | 428 | int i; |
445 | 429 | ||
446 | for (i = 0; i < dev->nvqs; ++i) { | 430 | for (i = 0; i < dev->nvqs; ++i) { |
447 | if (dev->vqs[i].kick && dev->vqs[i].handle_kick) { | ||
448 | vhost_poll_stop(&dev->vqs[i].poll); | ||
449 | vhost_poll_flush(&dev->vqs[i].poll); | ||
450 | } | ||
451 | /* Wait for all lower device DMAs done. */ | ||
452 | if (dev->vqs[i].ubufs) | ||
453 | vhost_ubuf_put_and_wait(dev->vqs[i].ubufs); | ||
454 | |||
455 | /* Signal guest as appropriate. */ | ||
456 | vhost_zerocopy_signal_used(&dev->vqs[i]); | ||
457 | |||
458 | if (dev->vqs[i].error_ctx) | 431 | if (dev->vqs[i].error_ctx) |
459 | eventfd_ctx_put(dev->vqs[i].error_ctx); | 432 | eventfd_ctx_put(dev->vqs[i].error_ctx); |
460 | if (dev->vqs[i].error) | 433 | if (dev->vqs[i].error) |
@@ -1599,14 +1572,3 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs) | |||
1599 | wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount)); | 1572 | wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount)); |
1600 | kfree(ubufs); | 1573 | kfree(ubufs); |
1601 | } | 1574 | } |
1602 | |||
1603 | void vhost_zerocopy_callback(struct ubuf_info *ubuf) | ||
1604 | { | ||
1605 | struct vhost_ubuf_ref *ubufs = ubuf->ctx; | ||
1606 | struct vhost_virtqueue *vq = ubufs->vq; | ||
1607 | |||
1608 | vhost_poll_queue(&vq->poll); | ||
1609 | /* set len = 1 to mark this desc buffers done DMA */ | ||
1610 | vq->heads[ubuf->desc].len = VHOST_DMA_DONE_LEN; | ||
1611 | kref_put(&ubufs->kref, vhost_zerocopy_done_signal); | ||
1612 | } | ||
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 1125af3d27d1..5e19e3d5db8c 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -7,17 +7,11 @@ | |||
7 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
8 | #include <linux/poll.h> | 8 | #include <linux/poll.h> |
9 | #include <linux/file.h> | 9 | #include <linux/file.h> |
10 | #include <linux/skbuff.h> | ||
11 | #include <linux/uio.h> | 10 | #include <linux/uio.h> |
12 | #include <linux/virtio_config.h> | 11 | #include <linux/virtio_config.h> |
13 | #include <linux/virtio_ring.h> | 12 | #include <linux/virtio_ring.h> |
14 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
15 | 14 | ||
16 | /* This is for zerocopy, used buffer len is set to 1 when lower device DMA | ||
17 | * done */ | ||
18 | #define VHOST_DMA_DONE_LEN 1 | ||
19 | #define VHOST_DMA_CLEAR_LEN 0 | ||
20 | |||
21 | struct vhost_device; | 15 | struct vhost_device; |
22 | 16 | ||
23 | struct vhost_work; | 17 | struct vhost_work; |
@@ -70,6 +64,8 @@ struct vhost_ubuf_ref *vhost_ubuf_alloc(struct vhost_virtqueue *, bool zcopy); | |||
70 | void vhost_ubuf_put(struct vhost_ubuf_ref *); | 64 | void vhost_ubuf_put(struct vhost_ubuf_ref *); |
71 | void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *); | 65 | void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *); |
72 | 66 | ||
67 | struct ubuf_info; | ||
68 | |||
73 | /* The virtqueue structure describes a queue attached to a device. */ | 69 | /* The virtqueue structure describes a queue attached to a device. */ |
74 | struct vhost_virtqueue { | 70 | struct vhost_virtqueue { |
75 | struct vhost_dev *dev; | 71 | struct vhost_dev *dev; |
@@ -167,6 +163,7 @@ long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs); | |||
167 | long vhost_dev_check_owner(struct vhost_dev *); | 163 | long vhost_dev_check_owner(struct vhost_dev *); |
168 | long vhost_dev_reset_owner(struct vhost_dev *); | 164 | long vhost_dev_reset_owner(struct vhost_dev *); |
169 | void vhost_dev_cleanup(struct vhost_dev *, bool locked); | 165 | void vhost_dev_cleanup(struct vhost_dev *, bool locked); |
166 | void vhost_dev_stop(struct vhost_dev *); | ||
170 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg); | 167 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg); |
171 | int vhost_vq_access_ok(struct vhost_virtqueue *vq); | 168 | int vhost_vq_access_ok(struct vhost_virtqueue *vq); |
172 | int vhost_log_access_ok(struct vhost_dev *); | 169 | int vhost_log_access_ok(struct vhost_dev *); |
@@ -191,8 +188,6 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); | |||
191 | 188 | ||
192 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | 189 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, |
193 | unsigned int log_num, u64 len); | 190 | unsigned int log_num, u64 len); |
194 | void vhost_zerocopy_callback(struct ubuf_info *); | ||
195 | int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq); | ||
196 | 191 | ||
197 | #define vq_err(vq, fmt, ...) do { \ | 192 | #define vq_err(vq, fmt, ...) do { \ |
198 | pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ | 193 | pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ |
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index b006ba0a9f42..243eea1e33d8 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -51,6 +51,26 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, | |||
51 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) | 51 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) |
52 | #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) | 52 | #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) |
53 | 53 | ||
54 | /* Reserved Ethernet Addresses per IEEE 802.1Q */ | ||
55 | static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = | ||
56 | { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; | ||
57 | |||
58 | /** | ||
59 | * is_link_local_ether_addr - Determine if given Ethernet address is link-local | ||
60 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
61 | * | ||
62 | * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per | ||
63 | * IEEE 802.1Q 8.6.3 Frame filtering. | ||
64 | */ | ||
65 | static inline bool is_link_local_ether_addr(const u8 *addr) | ||
66 | { | ||
67 | __be16 *a = (__be16 *)addr; | ||
68 | static const __be16 *b = (const __be16 *)eth_reserved_addr_base; | ||
69 | static const __be16 m = cpu_to_be16(0xfff0); | ||
70 | |||
71 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; | ||
72 | } | ||
73 | |||
54 | /** | 74 | /** |
55 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. | 75 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. |
56 | * @addr: Pointer to a six-byte array containing the Ethernet address | 76 | * @addr: Pointer to a six-byte array containing the Ethernet address |
diff --git a/include/linux/filter.h b/include/linux/filter.h index 24d251f3bab0..c45eabc135e1 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
@@ -45,6 +45,7 @@ extern void sk_unattached_filter_destroy(struct sk_filter *fp); | |||
45 | extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); | 45 | extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); |
46 | extern int sk_detach_filter(struct sock *sk); | 46 | extern int sk_detach_filter(struct sock *sk); |
47 | extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); | 47 | extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); |
48 | extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len); | ||
48 | 49 | ||
49 | #ifdef CONFIG_BPF_JIT | 50 | #ifdef CONFIG_BPF_JIT |
50 | extern void bpf_jit_compile(struct sk_filter *fp); | 51 | extern void bpf_jit_compile(struct sk_filter *fp); |
@@ -123,6 +124,8 @@ enum { | |||
123 | BPF_S_ANC_CPU, | 124 | BPF_S_ANC_CPU, |
124 | BPF_S_ANC_ALU_XOR_X, | 125 | BPF_S_ANC_ALU_XOR_X, |
125 | BPF_S_ANC_SECCOMP_LD_W, | 126 | BPF_S_ANC_SECCOMP_LD_W, |
127 | BPF_S_ANC_VLAN_TAG, | ||
128 | BPF_S_ANC_VLAN_TAG_PRESENT, | ||
126 | }; | 129 | }; |
127 | 130 | ||
128 | #endif /* __LINUX_FILTER_H__ */ | 131 | #endif /* __LINUX_FILTER_H__ */ |
diff --git a/include/linux/hdlc/Kbuild b/include/linux/hdlc/Kbuild index 1fb26448faa9..e69de29bb2d1 100644 --- a/include/linux/hdlc/Kbuild +++ b/include/linux/hdlc/Kbuild | |||
@@ -1 +0,0 @@ | |||
1 | header-y += ioctl.h | ||
diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 06177ba10a16..e83512f63df5 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h | |||
@@ -282,6 +282,25 @@ static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2) | |||
282 | return cmp1.tv64 == cmp2.tv64; | 282 | return cmp1.tv64 == cmp2.tv64; |
283 | } | 283 | } |
284 | 284 | ||
285 | /** | ||
286 | * ktime_compare - Compares two ktime_t variables for less, greater or equal | ||
287 | * @cmp1: comparable1 | ||
288 | * @cmp2: comparable2 | ||
289 | * | ||
290 | * Returns ... | ||
291 | * cmp1 < cmp2: return <0 | ||
292 | * cmp1 == cmp2: return 0 | ||
293 | * cmp1 > cmp2: return >0 | ||
294 | */ | ||
295 | static inline int ktime_compare(const ktime_t cmp1, const ktime_t cmp2) | ||
296 | { | ||
297 | if (cmp1.tv64 < cmp2.tv64) | ||
298 | return -1; | ||
299 | if (cmp1.tv64 > cmp2.tv64) | ||
300 | return 1; | ||
301 | return 0; | ||
302 | } | ||
303 | |||
285 | static inline s64 ktime_to_us(const ktime_t kt) | 304 | static inline s64 ktime_to_us(const ktime_t kt) |
286 | { | 305 | { |
287 | struct timeval tv = ktime_to_timeval(kt); | 306 | struct timeval tv = ktime_to_timeval(kt); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f8eda0276f03..7bf867c97043 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -887,6 +887,10 @@ struct netdev_fcoe_hbainfo { | |||
887 | * struct net_device *dev, int idx) | 887 | * struct net_device *dev, int idx) |
888 | * Used to add FDB entries to dump requests. Implementers should add | 888 | * Used to add FDB entries to dump requests. Implementers should add |
889 | * entries to skb and update idx with the number of entries. | 889 | * entries to skb and update idx with the number of entries. |
890 | * | ||
891 | * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) | ||
892 | * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, | ||
893 | * struct net_device *dev) | ||
890 | */ | 894 | */ |
891 | struct net_device_ops { | 895 | struct net_device_ops { |
892 | int (*ndo_init)(struct net_device *dev); | 896 | int (*ndo_init)(struct net_device *dev); |
@@ -998,6 +1002,12 @@ struct net_device_ops { | |||
998 | struct netlink_callback *cb, | 1002 | struct netlink_callback *cb, |
999 | struct net_device *dev, | 1003 | struct net_device *dev, |
1000 | int idx); | 1004 | int idx); |
1005 | |||
1006 | int (*ndo_bridge_setlink)(struct net_device *dev, | ||
1007 | struct nlmsghdr *nlh); | ||
1008 | int (*ndo_bridge_getlink)(struct sk_buff *skb, | ||
1009 | u32 pid, u32 seq, | ||
1010 | struct net_device *dev); | ||
1001 | }; | 1011 | }; |
1002 | 1012 | ||
1003 | /* | 1013 | /* |
diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h index c4e23d029498..b5c16c3df458 100644 --- a/include/linux/platform_data/cpsw.h +++ b/include/linux/platform_data/cpsw.h | |||
@@ -33,6 +33,9 @@ struct cpsw_platform_data { | |||
33 | 33 | ||
34 | u32 slaves; /* number of slave cpgmac ports */ | 34 | u32 slaves; /* number of slave cpgmac ports */ |
35 | struct cpsw_slave_data *slave_data; | 35 | struct cpsw_slave_data *slave_data; |
36 | u32 cpts_active_slave; /* time stamping slave */ | ||
37 | u32 cpts_clock_mult; /* convert input clock ticks to nanoseconds */ | ||
38 | u32 cpts_clock_shift; /* convert input clock ticks to nanoseconds */ | ||
36 | 39 | ||
37 | u32 ale_reg_ofs; /* address lookup engine reg offset */ | 40 | u32 ale_reg_ofs; /* address lookup engine reg offset */ |
38 | u32 ale_entries; /* ale table size */ | 41 | u32 ale_entries; /* ale table size */ |
@@ -41,6 +44,7 @@ struct cpsw_platform_data { | |||
41 | u32 host_port_num; /* The port number for the host port */ | 44 | u32 host_port_num; /* The port number for the host port */ |
42 | 45 | ||
43 | u32 hw_stats_reg_ofs; /* cpsw hardware statistics counters */ | 46 | u32 hw_stats_reg_ofs; /* cpsw hardware statistics counters */ |
47 | u32 cpts_reg_ofs; /* cpts registers */ | ||
44 | 48 | ||
45 | u32 bd_ram_ofs; /* embedded buffer descriptor RAM offset*/ | 49 | u32 bd_ram_ofs; /* embedded buffer descriptor RAM offset*/ |
46 | u32 bd_ram_size; /*buffer descriptor ram size */ | 50 | u32 bd_ram_size; /*buffer descriptor ram size */ |
diff --git a/include/linux/platform_data/macb.h b/include/linux/platform_data/macb.h index b081c7245ec8..044a124bfbbc 100644 --- a/include/linux/platform_data/macb.h +++ b/include/linux/platform_data/macb.h | |||
@@ -12,6 +12,7 @@ struct macb_platform_data { | |||
12 | u32 phy_mask; | 12 | u32 phy_mask; |
13 | int phy_irq_pin; /* PHY IRQ */ | 13 | int phy_irq_pin; /* PHY IRQ */ |
14 | u8 is_rmii; /* using RMII interface? */ | 14 | u8 is_rmii; /* using RMII interface? */ |
15 | u8 rev_eth_addr; /* reverse Ethernet address byte order */ | ||
15 | }; | 16 | }; |
16 | 17 | ||
17 | #endif /* __MACB_PDATA_H__ */ | 18 | #endif /* __MACB_PDATA_H__ */ |
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 7002bbfd5d4a..489dd7bb28ec 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -69,4 +69,7 @@ extern int ndo_dflt_fdb_dump(struct sk_buff *skb, | |||
69 | struct netlink_callback *cb, | 69 | struct netlink_callback *cb, |
70 | struct net_device *dev, | 70 | struct net_device *dev, |
71 | int idx); | 71 | int idx); |
72 | |||
73 | extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | ||
74 | struct net_device *dev, u16 mode); | ||
72 | #endif /* __LINUX_RTNETLINK_H */ | 75 | #endif /* __LINUX_RTNETLINK_H */ |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6a2c34e6d962..f2af494330ab 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -235,11 +235,13 @@ enum { | |||
235 | /* | 235 | /* |
236 | * The callback notifies userspace to release buffers when skb DMA is done in | 236 | * The callback notifies userspace to release buffers when skb DMA is done in |
237 | * lower device, the skb last reference should be 0 when calling this. | 237 | * lower device, the skb last reference should be 0 when calling this. |
238 | * The zerocopy_success argument is true if zero copy transmit occurred, | ||
239 | * false on data copy or out of memory error caused by data copy attempt. | ||
238 | * The ctx field is used to track device context. | 240 | * The ctx field is used to track device context. |
239 | * The desc field is used to track userspace buffer index. | 241 | * The desc field is used to track userspace buffer index. |
240 | */ | 242 | */ |
241 | struct ubuf_info { | 243 | struct ubuf_info { |
242 | void (*callback)(struct ubuf_info *); | 244 | void (*callback)(struct ubuf_info *, bool zerocopy_success); |
243 | void *ctx; | 245 | void *ctx; |
244 | unsigned long desc; | 246 | unsigned long desc; |
245 | }; | 247 | }; |
@@ -566,6 +568,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb) | |||
566 | } | 568 | } |
567 | 569 | ||
568 | extern void kfree_skb(struct sk_buff *skb); | 570 | extern void kfree_skb(struct sk_buff *skb); |
571 | extern void skb_tx_error(struct sk_buff *skb); | ||
569 | extern void consume_skb(struct sk_buff *skb); | 572 | extern void consume_skb(struct sk_buff *skb); |
570 | extern void __kfree_skb(struct sk_buff *skb); | 573 | extern void __kfree_skb(struct sk_buff *skb); |
571 | extern struct kmem_cache *skbuff_head_cache; | 574 | extern struct kmem_cache *skbuff_head_cache; |
@@ -643,7 +646,7 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, | |||
643 | extern void __skb_get_rxhash(struct sk_buff *skb); | 646 | extern void __skb_get_rxhash(struct sk_buff *skb); |
644 | static inline __u32 skb_get_rxhash(struct sk_buff *skb) | 647 | static inline __u32 skb_get_rxhash(struct sk_buff *skb) |
645 | { | 648 | { |
646 | if (!skb->rxhash) | 649 | if (!skb->l4_rxhash) |
647 | __skb_get_rxhash(skb); | 650 | __skb_get_rxhash(skb); |
648 | 651 | ||
649 | return skb->rxhash; | 652 | return skb->rxhash; |
diff --git a/include/linux/timecompare.h b/include/linux/timecompare.h deleted file mode 100644 index 546e2234e4b3..000000000000 --- a/include/linux/timecompare.h +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | /* | ||
2 | * Utility code which helps transforming between two different time | ||
3 | * bases, called "source" and "target" time in this code. | ||
4 | * | ||
5 | * Source time has to be provided via the timecounter API while target | ||
6 | * time is accessed via a function callback whose prototype | ||
7 | * intentionally matches ktime_get() and ktime_get_real(). These | ||
8 | * interfaces where chosen like this so that the code serves its | ||
9 | * initial purpose without additional glue code. | ||
10 | * | ||
11 | * This purpose is synchronizing a hardware clock in a NIC with system | ||
12 | * time, in order to implement the Precision Time Protocol (PTP, | ||
13 | * IEEE1588) with more accurate hardware assisted time stamping. In | ||
14 | * that context only synchronization against system time (= | ||
15 | * ktime_get_real()) is currently needed. But this utility code might | ||
16 | * become useful in other situations, which is why it was written as | ||
17 | * general purpose utility code. | ||
18 | * | ||
19 | * The source timecounter is assumed to return monotonically | ||
20 | * increasing time (but this code does its best to compensate if that | ||
21 | * is not the case) whereas target time may jump. | ||
22 | * | ||
23 | * The target time corresponding to a source time is determined by | ||
24 | * reading target time, reading source time, reading target time | ||
25 | * again, then assuming that average target time corresponds to source | ||
26 | * time. In other words, the assumption is that reading the source | ||
27 | * time is slow and involves equal time for sending the request and | ||
28 | * receiving the reply, whereas reading target time is assumed to be | ||
29 | * fast. | ||
30 | * | ||
31 | * Copyright (C) 2009 Intel Corporation. | ||
32 | * Author: Patrick Ohly <patrick.ohly@intel.com> | ||
33 | * | ||
34 | * This program is free software; you can redistribute it and/or modify it | ||
35 | * under the terms and conditions of the GNU General Public License, | ||
36 | * version 2, as published by the Free Software Foundation. | ||
37 | * | ||
38 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
39 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
40 | * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for | ||
41 | * more details. | ||
42 | * | ||
43 | * You should have received a copy of the GNU General Public License along with | ||
44 | * this program; if not, write to the Free Software Foundation, Inc., | ||
45 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
46 | */ | ||
47 | #ifndef _LINUX_TIMECOMPARE_H | ||
48 | #define _LINUX_TIMECOMPARE_H | ||
49 | |||
50 | #include <linux/clocksource.h> | ||
51 | #include <linux/ktime.h> | ||
52 | |||
53 | /** | ||
54 | * struct timecompare - stores state and configuration for the two clocks | ||
55 | * | ||
56 | * Initialize to zero, then set source/target/num_samples. | ||
57 | * | ||
58 | * Transformation between source time and target time is done with: | ||
59 | * target_time = source_time + offset + | ||
60 | * (source_time - last_update) * skew / | ||
61 | * TIMECOMPARE_SKEW_RESOLUTION | ||
62 | * | ||
63 | * @source: used to get source time stamps via timecounter_read() | ||
64 | * @target: function returning target time (for example, ktime_get | ||
65 | * for monotonic time, or ktime_get_real for wall clock) | ||
66 | * @num_samples: number of times that source time and target time are to | ||
67 | * be compared when determining their offset | ||
68 | * @offset: (target time - source time) at the time of the last update | ||
69 | * @skew: average (target time - source time) / delta source time * | ||
70 | * TIMECOMPARE_SKEW_RESOLUTION | ||
71 | * @last_update: last source time stamp when time offset was measured | ||
72 | */ | ||
73 | struct timecompare { | ||
74 | struct timecounter *source; | ||
75 | ktime_t (*target)(void); | ||
76 | int num_samples; | ||
77 | |||
78 | s64 offset; | ||
79 | s64 skew; | ||
80 | u64 last_update; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * timecompare_transform - transform source time stamp into target time base | ||
85 | * @sync: context for time sync | ||
86 | * @source_tstamp: the result of timecounter_read() or | ||
87 | * timecounter_cyc2time() | ||
88 | */ | ||
89 | extern ktime_t timecompare_transform(struct timecompare *sync, | ||
90 | u64 source_tstamp); | ||
91 | |||
92 | /** | ||
93 | * timecompare_offset - measure current (target time - source time) offset | ||
94 | * @sync: context for time sync | ||
95 | * @offset: average offset during sample period returned here | ||
96 | * @source_tstamp: average source time during sample period returned here | ||
97 | * | ||
98 | * Returns number of samples used. Might be zero (= no result) in the | ||
99 | * unlikely case that target time was monotonically decreasing for all | ||
100 | * samples (= broken). | ||
101 | */ | ||
102 | extern int timecompare_offset(struct timecompare *sync, | ||
103 | s64 *offset, | ||
104 | u64 *source_tstamp); | ||
105 | |||
106 | extern void __timecompare_update(struct timecompare *sync, | ||
107 | u64 source_tstamp); | ||
108 | |||
109 | /** | ||
110 | * timecompare_update - update offset and skew by measuring current offset | ||
111 | * @sync: context for time sync | ||
112 | * @source_tstamp: the result of timecounter_read() or | ||
113 | * timecounter_cyc2time(), pass zero to force update | ||
114 | * | ||
115 | * Updates are only done at most once per second. | ||
116 | */ | ||
117 | static inline void timecompare_update(struct timecompare *sync, | ||
118 | u64 source_tstamp) | ||
119 | { | ||
120 | if (!source_tstamp || | ||
121 | (s64)(source_tstamp - sync->last_update) >= NSEC_PER_SEC) | ||
122 | __timecompare_update(sync, source_tstamp); | ||
123 | } | ||
124 | |||
125 | #endif /* _LINUX_TIMECOMPARE_H */ | ||
diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h new file mode 100644 index 000000000000..3b8f9d4fc3fe --- /dev/null +++ b/include/linux/usb/cdc_ncm.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson 2010-2012 | ||
3 | * Contact: Alexey Orishko <alexey.orishko@stericsson.com> | ||
4 | * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> | ||
5 | * | ||
6 | * USB Host Driver for Network Control Model (NCM) | ||
7 | * http://www.usb.org/developers/devclass_docs/NCM10.zip | ||
8 | * | ||
9 | * The NCM encoding, decoding and initialization logic | ||
10 | * derives from FreeBSD 8.x. if_cdce.c and if_cdcereg.h | ||
11 | * | ||
12 | * This software is available to you under a choice of one of two | ||
13 | * licenses. You may choose this file to be licensed under the terms | ||
14 | * of the GNU General Public License (GPL) Version 2 or the 2-clause | ||
15 | * BSD license listed below: | ||
16 | * | ||
17 | * Redistribution and use in source and binary forms, with or without | ||
18 | * modification, are permitted provided that the following conditions | ||
19 | * are met: | ||
20 | * 1. Redistributions of source code must retain the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer. | ||
22 | * 2. Redistributions in binary form must reproduce the above copyright | ||
23 | * notice, this list of conditions and the following disclaimer in the | ||
24 | * documentation and/or other materials provided with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
36 | * SUCH DAMAGE. | ||
37 | */ | ||
38 | |||
39 | #define CDC_NCM_COMM_ALTSETTING_NCM 0 | ||
40 | #define CDC_NCM_COMM_ALTSETTING_MBIM 1 | ||
41 | |||
42 | #define CDC_NCM_DATA_ALTSETTING_NCM 1 | ||
43 | #define CDC_NCM_DATA_ALTSETTING_MBIM 2 | ||
44 | |||
45 | /* CDC NCM subclass 3.2.1 */ | ||
46 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 | ||
47 | |||
48 | /* Maximum NTB length */ | ||
49 | #define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */ | ||
50 | #define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */ | ||
51 | |||
52 | /* Minimum value for MaxDatagramSize, ch. 6.2.9 */ | ||
53 | #define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */ | ||
54 | |||
55 | /* Minimum value for MaxDatagramSize, ch. 8.1.3 */ | ||
56 | #define CDC_MBIM_MIN_DATAGRAM_SIZE 2048 /* bytes */ | ||
57 | |||
58 | #define CDC_NCM_MIN_TX_PKT 512 /* bytes */ | ||
59 | |||
60 | /* Default value for MaxDatagramSize */ | ||
61 | #define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */ | ||
62 | |||
63 | /* | ||
64 | * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting | ||
65 | * the last NULL entry. | ||
66 | */ | ||
67 | #define CDC_NCM_DPT_DATAGRAMS_MAX 40 | ||
68 | |||
69 | /* Restart the timer, if amount of datagrams is less than given value */ | ||
70 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 | ||
71 | #define CDC_NCM_TIMER_PENDING_CNT 2 | ||
72 | #define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC) | ||
73 | |||
74 | /* The following macro defines the minimum header space */ | ||
75 | #define CDC_NCM_MIN_HDR_SIZE \ | ||
76 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ | ||
77 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) | ||
78 | |||
79 | #define CDC_NCM_NDP_SIZE \ | ||
80 | (sizeof(struct usb_cdc_ncm_ndp16) + \ | ||
81 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) | ||
82 | |||
83 | #define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \ | ||
84 | (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) | ||
85 | #define cdc_ncm_data_intf_is_mbim(x) ((x)->desc.bInterfaceProtocol == USB_CDC_MBIM_PROTO_NTB) | ||
86 | |||
87 | struct cdc_ncm_ctx { | ||
88 | struct usb_cdc_ncm_ntb_parameters ncm_parm; | ||
89 | struct hrtimer tx_timer; | ||
90 | struct tasklet_struct bh; | ||
91 | |||
92 | const struct usb_cdc_ncm_desc *func_desc; | ||
93 | const struct usb_cdc_mbim_desc *mbim_desc; | ||
94 | const struct usb_cdc_header_desc *header_desc; | ||
95 | const struct usb_cdc_union_desc *union_desc; | ||
96 | const struct usb_cdc_ether_desc *ether_desc; | ||
97 | |||
98 | struct net_device *netdev; | ||
99 | struct usb_device *udev; | ||
100 | struct usb_host_endpoint *in_ep; | ||
101 | struct usb_host_endpoint *out_ep; | ||
102 | struct usb_host_endpoint *status_ep; | ||
103 | struct usb_interface *intf; | ||
104 | struct usb_interface *control; | ||
105 | struct usb_interface *data; | ||
106 | |||
107 | struct sk_buff *tx_curr_skb; | ||
108 | struct sk_buff *tx_rem_skb; | ||
109 | __le32 tx_rem_sign; | ||
110 | |||
111 | spinlock_t mtx; | ||
112 | atomic_t stop; | ||
113 | |||
114 | u32 tx_timer_pending; | ||
115 | u32 tx_curr_frame_num; | ||
116 | u32 rx_speed; | ||
117 | u32 tx_speed; | ||
118 | u32 rx_max; | ||
119 | u32 tx_max; | ||
120 | u32 max_datagram_size; | ||
121 | u16 tx_max_datagrams; | ||
122 | u16 tx_remainder; | ||
123 | u16 tx_modulus; | ||
124 | u16 tx_ndp_modulus; | ||
125 | u16 tx_seq; | ||
126 | u16 rx_seq; | ||
127 | u16 connected; | ||
128 | }; | ||
129 | |||
130 | extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); | ||
131 | extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); | ||
132 | extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign); | ||
133 | extern int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in); | ||
134 | extern int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset); | ||
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index ddbbb7de894b..9bbeabf66c54 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h | |||
@@ -163,6 +163,16 @@ extern int usbnet_resume(struct usb_interface *); | |||
163 | extern void usbnet_disconnect(struct usb_interface *); | 163 | extern void usbnet_disconnect(struct usb_interface *); |
164 | extern void usbnet_device_suggests_idle(struct usbnet *dev); | 164 | extern void usbnet_device_suggests_idle(struct usbnet *dev); |
165 | 165 | ||
166 | extern int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
167 | u16 value, u16 index, void *data, u16 size); | ||
168 | extern int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
169 | u16 value, u16 index, const void *data, u16 size); | ||
170 | extern int usbnet_read_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
171 | u16 value, u16 index, void *data, u16 size); | ||
172 | extern int usbnet_write_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
173 | u16 value, u16 index, const void *data, u16 size); | ||
174 | extern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, | ||
175 | u16 value, u16 index, const void *data, u16 size); | ||
166 | 176 | ||
167 | /* Drivers that reuse some of the standard USB CDC infrastructure | 177 | /* Drivers that reuse some of the standard USB CDC infrastructure |
168 | * (notably, using multiple interfaces according to the CDC | 178 | * (notably, using multiple interfaces according to the CDC |
diff --git a/include/net/af_unix.h b/include/net/af_unix.h index b5f8988e4283..0a996a3517ed 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h | |||
@@ -53,7 +53,6 @@ struct unix_sock { | |||
53 | struct path path; | 53 | struct path path; |
54 | struct mutex readlock; | 54 | struct mutex readlock; |
55 | struct sock *peer; | 55 | struct sock *peer; |
56 | struct sock *other; | ||
57 | struct list_head link; | 56 | struct list_head link; |
58 | atomic_long_t inflight; | 57 | atomic_long_t inflight; |
59 | spinlock_t lock; | 58 | spinlock_t lock; |
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index b6a6eeb3905f..2581638f4a3d 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h | |||
@@ -24,12 +24,12 @@ struct cgroup_cls_state | |||
24 | u32 classid; | 24 | u32 classid; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | extern void sock_update_classid(struct sock *sk); | 27 | extern void sock_update_classid(struct sock *sk, struct task_struct *task); |
28 | 28 | ||
29 | #if IS_BUILTIN(CONFIG_NET_CLS_CGROUP) | 29 | #if IS_BUILTIN(CONFIG_NET_CLS_CGROUP) |
30 | static inline u32 task_cls_classid(struct task_struct *p) | 30 | static inline u32 task_cls_classid(struct task_struct *p) |
31 | { | 31 | { |
32 | int classid; | 32 | u32 classid; |
33 | 33 | ||
34 | if (in_interrupt()) | 34 | if (in_interrupt()) |
35 | return 0; | 35 | return 0; |
@@ -61,7 +61,7 @@ static inline u32 task_cls_classid(struct task_struct *p) | |||
61 | } | 61 | } |
62 | #endif | 62 | #endif |
63 | #else /* !CGROUP_NET_CLS_CGROUP */ | 63 | #else /* !CGROUP_NET_CLS_CGROUP */ |
64 | static inline void sock_update_classid(struct sock *sk) | 64 | static inline void sock_update_classid(struct sock *sk, struct task_struct *task) |
65 | { | 65 | { |
66 | } | 66 | } |
67 | 67 | ||
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 8a2a203eb15d..fdc48a94a063 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h | |||
@@ -47,6 +47,8 @@ struct fib6_config { | |||
47 | unsigned long fc_expires; | 47 | unsigned long fc_expires; |
48 | struct nlattr *fc_mx; | 48 | struct nlattr *fc_mx; |
49 | int fc_mx_len; | 49 | int fc_mx_len; |
50 | int fc_mp_len; | ||
51 | struct nlattr *fc_mp; | ||
50 | 52 | ||
51 | struct nl_info fc_nlinfo; | 53 | struct nl_info fc_nlinfo; |
52 | }; | 54 | }; |
@@ -99,6 +101,14 @@ struct rt6_info { | |||
99 | 101 | ||
100 | struct in6_addr rt6i_gateway; | 102 | struct in6_addr rt6i_gateway; |
101 | 103 | ||
104 | /* Multipath routes: | ||
105 | * siblings is a list of rt6_info that have the the same metric/weight, | ||
106 | * destination, but not the same gateway. nsiblings is just a cache | ||
107 | * to speed up lookup. | ||
108 | */ | ||
109 | struct list_head rt6i_siblings; | ||
110 | unsigned int rt6i_nsiblings; | ||
111 | |||
102 | atomic_t rt6i_ref; | 112 | atomic_t rt6i_ref; |
103 | 113 | ||
104 | /* These are in a separate cache line. */ | 114 | /* These are in a separate cache line. */ |
@@ -107,7 +117,6 @@ struct rt6_info { | |||
107 | struct rt6key rt6i_src; | 117 | struct rt6key rt6i_src; |
108 | struct rt6key rt6i_prefsrc; | 118 | struct rt6key rt6i_prefsrc; |
109 | u32 rt6i_metric; | 119 | u32 rt6i_metric; |
110 | u32 rt6i_peer_genid; | ||
111 | 120 | ||
112 | struct inet6_dev *rt6i_idev; | 121 | struct inet6_dev *rt6i_idev; |
113 | unsigned long _rt6i_peer; | 122 | unsigned long _rt6i_peer; |
@@ -203,6 +212,15 @@ static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) | |||
203 | dst_hold(new); | 212 | dst_hold(new); |
204 | } | 213 | } |
205 | 214 | ||
215 | static inline void ip6_rt_put(struct rt6_info *rt) | ||
216 | { | ||
217 | /* dst_release() accepts a NULL parameter. | ||
218 | * We rely on dst being first structure in struct rt6_info | ||
219 | */ | ||
220 | BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0); | ||
221 | dst_release(&rt->dst); | ||
222 | } | ||
223 | |||
206 | struct fib6_walker_t { | 224 | struct fib6_walker_t { |
207 | struct list_head lh; | 225 | struct list_head lh; |
208 | struct fib6_node *root, *node; | 226 | struct fib6_node *root, *node; |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index ee75ccdf5188..68c69d54d392 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -22,7 +22,10 @@ | |||
22 | #include <linux/ip.h> | 22 | #include <linux/ip.h> |
23 | #include <linux/ipv6.h> /* for struct ipv6hdr */ | 23 | #include <linux/ipv6.h> /* for struct ipv6hdr */ |
24 | #include <net/ipv6.h> | 24 | #include <net/ipv6.h> |
25 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 25 | #if IS_ENABLED(CONFIG_IP_VS_IPV6) |
26 | #include <linux/netfilter_ipv6/ip6_tables.h> | ||
27 | #endif | ||
28 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) | ||
26 | #include <net/netfilter/nf_conntrack.h> | 29 | #include <net/netfilter/nf_conntrack.h> |
27 | #endif | 30 | #endif |
28 | #include <net/net_namespace.h> /* Netw namespace */ | 31 | #include <net/net_namespace.h> /* Netw namespace */ |
@@ -103,30 +106,117 @@ static inline struct net *seq_file_single_net(struct seq_file *seq) | |||
103 | /* Connections' size value needed by ip_vs_ctl.c */ | 106 | /* Connections' size value needed by ip_vs_ctl.c */ |
104 | extern int ip_vs_conn_tab_size; | 107 | extern int ip_vs_conn_tab_size; |
105 | 108 | ||
106 | |||
107 | struct ip_vs_iphdr { | 109 | struct ip_vs_iphdr { |
108 | int len; | 110 | __u32 len; /* IPv4 simply where L4 starts |
109 | __u8 protocol; | 111 | IPv6 where L4 Transport Header starts */ |
112 | __u32 thoff_reasm; /* Transport Header Offset in nfct_reasm skb */ | ||
113 | __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/ | ||
114 | __s16 protocol; | ||
115 | __s32 flags; | ||
110 | union nf_inet_addr saddr; | 116 | union nf_inet_addr saddr; |
111 | union nf_inet_addr daddr; | 117 | union nf_inet_addr daddr; |
112 | }; | 118 | }; |
113 | 119 | ||
120 | /* Dependency to module: nf_defrag_ipv6 */ | ||
121 | #if defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE) | ||
122 | static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb) | ||
123 | { | ||
124 | return skb->nfct_reasm; | ||
125 | } | ||
126 | static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, | ||
127 | int len, void *buffer, | ||
128 | const struct ip_vs_iphdr *ipvsh) | ||
129 | { | ||
130 | if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb))) | ||
131 | return skb_header_pointer(skb_nfct_reasm(skb), | ||
132 | ipvsh->thoff_reasm, len, buffer); | ||
133 | |||
134 | return skb_header_pointer(skb, offset, len, buffer); | ||
135 | } | ||
136 | #else | ||
137 | static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb) | ||
138 | { | ||
139 | return NULL; | ||
140 | } | ||
141 | static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, | ||
142 | int len, void *buffer, | ||
143 | const struct ip_vs_iphdr *ipvsh) | ||
144 | { | ||
145 | return skb_header_pointer(skb, offset, len, buffer); | ||
146 | } | ||
147 | #endif | ||
148 | |||
114 | static inline void | 149 | static inline void |
115 | ip_vs_fill_iphdr(int af, const void *nh, struct ip_vs_iphdr *iphdr) | 150 | ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr) |
151 | { | ||
152 | const struct iphdr *iph = nh; | ||
153 | |||
154 | iphdr->len = iph->ihl * 4; | ||
155 | iphdr->fragoffs = 0; | ||
156 | iphdr->protocol = iph->protocol; | ||
157 | iphdr->saddr.ip = iph->saddr; | ||
158 | iphdr->daddr.ip = iph->daddr; | ||
159 | } | ||
160 | |||
161 | /* This function handles filling *ip_vs_iphdr, both for IPv4 and IPv6. | ||
162 | * IPv6 requires some extra work, as finding proper header position, | ||
163 | * depend on the IPv6 extension headers. | ||
164 | */ | ||
165 | static inline void | ||
166 | ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr) | ||
116 | { | 167 | { |
117 | #ifdef CONFIG_IP_VS_IPV6 | 168 | #ifdef CONFIG_IP_VS_IPV6 |
118 | if (af == AF_INET6) { | 169 | if (af == AF_INET6) { |
119 | const struct ipv6hdr *iph = nh; | 170 | const struct ipv6hdr *iph = |
120 | iphdr->len = sizeof(struct ipv6hdr); | 171 | (struct ipv6hdr *)skb_network_header(skb); |
121 | iphdr->protocol = iph->nexthdr; | ||
122 | iphdr->saddr.in6 = iph->saddr; | 172 | iphdr->saddr.in6 = iph->saddr; |
123 | iphdr->daddr.in6 = iph->daddr; | 173 | iphdr->daddr.in6 = iph->daddr; |
174 | /* ipv6_find_hdr() updates len, flags, thoff_reasm */ | ||
175 | iphdr->thoff_reasm = 0; | ||
176 | iphdr->len = 0; | ||
177 | iphdr->flags = 0; | ||
178 | iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1, | ||
179 | &iphdr->fragoffs, | ||
180 | &iphdr->flags); | ||
181 | /* get proto from re-assembled packet and it's offset */ | ||
182 | if (skb_nfct_reasm(skb)) | ||
183 | iphdr->protocol = ipv6_find_hdr(skb_nfct_reasm(skb), | ||
184 | &iphdr->thoff_reasm, | ||
185 | -1, NULL, NULL); | ||
186 | |||
124 | } else | 187 | } else |
125 | #endif | 188 | #endif |
126 | { | 189 | { |
127 | const struct iphdr *iph = nh; | 190 | const struct iphdr *iph = |
128 | iphdr->len = iph->ihl * 4; | 191 | (struct iphdr *)skb_network_header(skb); |
129 | iphdr->protocol = iph->protocol; | 192 | iphdr->len = iph->ihl * 4; |
193 | iphdr->fragoffs = 0; | ||
194 | iphdr->protocol = iph->protocol; | ||
195 | iphdr->saddr.ip = iph->saddr; | ||
196 | iphdr->daddr.ip = iph->daddr; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | /* This function is a faster version of ip_vs_fill_iph_skb(). | ||
201 | * Where we only populate {s,d}addr (and avoid calling ipv6_find_hdr()). | ||
202 | * This is used by the some of the ip_vs_*_schedule() functions. | ||
203 | * (Mostly done to avoid ABI breakage of external schedulers) | ||
204 | */ | ||
205 | static inline void | ||
206 | ip_vs_fill_iph_addr_only(int af, const struct sk_buff *skb, | ||
207 | struct ip_vs_iphdr *iphdr) | ||
208 | { | ||
209 | #ifdef CONFIG_IP_VS_IPV6 | ||
210 | if (af == AF_INET6) { | ||
211 | const struct ipv6hdr *iph = | ||
212 | (struct ipv6hdr *)skb_network_header(skb); | ||
213 | iphdr->saddr.in6 = iph->saddr; | ||
214 | iphdr->daddr.in6 = iph->daddr; | ||
215 | } else | ||
216 | #endif | ||
217 | { | ||
218 | const struct iphdr *iph = | ||
219 | (struct iphdr *)skb_network_header(skb); | ||
130 | iphdr->saddr.ip = iph->saddr; | 220 | iphdr->saddr.ip = iph->saddr; |
131 | iphdr->daddr.ip = iph->daddr; | 221 | iphdr->daddr.ip = iph->daddr; |
132 | } | 222 | } |
@@ -165,7 +255,7 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len, | |||
165 | int len; | 255 | int len; |
166 | #ifdef CONFIG_IP_VS_IPV6 | 256 | #ifdef CONFIG_IP_VS_IPV6 |
167 | if (af == AF_INET6) | 257 | if (af == AF_INET6) |
168 | len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6]", | 258 | len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6c]", |
169 | &addr->in6) + 1; | 259 | &addr->in6) + 1; |
170 | else | 260 | else |
171 | #endif | 261 | #endif |
@@ -398,27 +488,26 @@ struct ip_vs_protocol { | |||
398 | 488 | ||
399 | int (*conn_schedule)(int af, struct sk_buff *skb, | 489 | int (*conn_schedule)(int af, struct sk_buff *skb, |
400 | struct ip_vs_proto_data *pd, | 490 | struct ip_vs_proto_data *pd, |
401 | int *verdict, struct ip_vs_conn **cpp); | 491 | int *verdict, struct ip_vs_conn **cpp, |
492 | struct ip_vs_iphdr *iph); | ||
402 | 493 | ||
403 | struct ip_vs_conn * | 494 | struct ip_vs_conn * |
404 | (*conn_in_get)(int af, | 495 | (*conn_in_get)(int af, |
405 | const struct sk_buff *skb, | 496 | const struct sk_buff *skb, |
406 | const struct ip_vs_iphdr *iph, | 497 | const struct ip_vs_iphdr *iph, |
407 | unsigned int proto_off, | ||
408 | int inverse); | 498 | int inverse); |
409 | 499 | ||
410 | struct ip_vs_conn * | 500 | struct ip_vs_conn * |
411 | (*conn_out_get)(int af, | 501 | (*conn_out_get)(int af, |
412 | const struct sk_buff *skb, | 502 | const struct sk_buff *skb, |
413 | const struct ip_vs_iphdr *iph, | 503 | const struct ip_vs_iphdr *iph, |
414 | unsigned int proto_off, | ||
415 | int inverse); | 504 | int inverse); |
416 | 505 | ||
417 | int (*snat_handler)(struct sk_buff *skb, | 506 | int (*snat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp, |
418 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp); | 507 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph); |
419 | 508 | ||
420 | int (*dnat_handler)(struct sk_buff *skb, | 509 | int (*dnat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp, |
421 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp); | 510 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph); |
422 | 511 | ||
423 | int (*csum_check)(int af, struct sk_buff *skb, | 512 | int (*csum_check)(int af, struct sk_buff *skb, |
424 | struct ip_vs_protocol *pp); | 513 | struct ip_vs_protocol *pp); |
@@ -518,7 +607,7 @@ struct ip_vs_conn { | |||
518 | NF_ACCEPT can be returned when destination is local. | 607 | NF_ACCEPT can be returned when destination is local. |
519 | */ | 608 | */ |
520 | int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, | 609 | int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, |
521 | struct ip_vs_protocol *pp); | 610 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); |
522 | 611 | ||
523 | /* Note: we can group the following members into a structure, | 612 | /* Note: we can group the following members into a structure, |
524 | in order to save more space, and the following members are | 613 | in order to save more space, and the following members are |
@@ -769,13 +858,11 @@ struct ip_vs_app { | |||
769 | 858 | ||
770 | struct ip_vs_conn * | 859 | struct ip_vs_conn * |
771 | (*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app, | 860 | (*conn_in_get)(const struct sk_buff *skb, struct ip_vs_app *app, |
772 | const struct iphdr *iph, unsigned int proto_off, | 861 | const struct iphdr *iph, int inverse); |
773 | int inverse); | ||
774 | 862 | ||
775 | struct ip_vs_conn * | 863 | struct ip_vs_conn * |
776 | (*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app, | 864 | (*conn_out_get)(const struct sk_buff *skb, struct ip_vs_app *app, |
777 | const struct iphdr *iph, unsigned int proto_off, | 865 | const struct iphdr *iph, int inverse); |
778 | int inverse); | ||
779 | 866 | ||
780 | int (*state_transition)(struct ip_vs_conn *cp, int direction, | 867 | int (*state_transition)(struct ip_vs_conn *cp, int direction, |
781 | const struct sk_buff *skb, | 868 | const struct sk_buff *skb, |
@@ -1074,14 +1161,12 @@ struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); | |||
1074 | 1161 | ||
1075 | struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, | 1162 | struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, |
1076 | const struct ip_vs_iphdr *iph, | 1163 | const struct ip_vs_iphdr *iph, |
1077 | unsigned int proto_off, | ||
1078 | int inverse); | 1164 | int inverse); |
1079 | 1165 | ||
1080 | struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); | 1166 | struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); |
1081 | 1167 | ||
1082 | struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, | 1168 | struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, |
1083 | const struct ip_vs_iphdr *iph, | 1169 | const struct ip_vs_iphdr *iph, |
1084 | unsigned int proto_off, | ||
1085 | int inverse); | 1170 | int inverse); |
1086 | 1171 | ||
1087 | /* put back the conn without restarting its timer */ | 1172 | /* put back the conn without restarting its timer */ |
@@ -1254,9 +1339,10 @@ extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); | |||
1254 | extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); | 1339 | extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); |
1255 | extern struct ip_vs_conn * | 1340 | extern struct ip_vs_conn * |
1256 | ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | 1341 | ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, |
1257 | struct ip_vs_proto_data *pd, int *ignored); | 1342 | struct ip_vs_proto_data *pd, int *ignored, |
1343 | struct ip_vs_iphdr *iph); | ||
1258 | extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | 1344 | extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, |
1259 | struct ip_vs_proto_data *pd); | 1345 | struct ip_vs_proto_data *pd, struct ip_vs_iphdr *iph); |
1260 | 1346 | ||
1261 | extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); | 1347 | extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); |
1262 | 1348 | ||
@@ -1315,33 +1401,38 @@ extern void ip_vs_read_estimator(struct ip_vs_stats_user *dst, | |||
1315 | /* | 1401 | /* |
1316 | * Various IPVS packet transmitters (from ip_vs_xmit.c) | 1402 | * Various IPVS packet transmitters (from ip_vs_xmit.c) |
1317 | */ | 1403 | */ |
1318 | extern int ip_vs_null_xmit | 1404 | extern int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1319 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1405 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); |
1320 | extern int ip_vs_bypass_xmit | 1406 | extern int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1321 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1407 | struct ip_vs_protocol *pp, |
1322 | extern int ip_vs_nat_xmit | 1408 | struct ip_vs_iphdr *iph); |
1323 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1409 | extern int ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1324 | extern int ip_vs_tunnel_xmit | 1410 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); |
1325 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1411 | extern int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1326 | extern int ip_vs_dr_xmit | 1412 | struct ip_vs_protocol *pp, |
1327 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1413 | struct ip_vs_iphdr *iph); |
1328 | extern int ip_vs_icmp_xmit | 1414 | extern int ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1329 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, | 1415 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); |
1330 | int offset, unsigned int hooknum); | 1416 | extern int ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1417 | struct ip_vs_protocol *pp, int offset, | ||
1418 | unsigned int hooknum, struct ip_vs_iphdr *iph); | ||
1331 | extern void ip_vs_dst_reset(struct ip_vs_dest *dest); | 1419 | extern void ip_vs_dst_reset(struct ip_vs_dest *dest); |
1332 | 1420 | ||
1333 | #ifdef CONFIG_IP_VS_IPV6 | 1421 | #ifdef CONFIG_IP_VS_IPV6 |
1334 | extern int ip_vs_bypass_xmit_v6 | 1422 | extern int ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1335 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1423 | struct ip_vs_protocol *pp, |
1336 | extern int ip_vs_nat_xmit_v6 | 1424 | struct ip_vs_iphdr *iph); |
1337 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1425 | extern int ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1338 | extern int ip_vs_tunnel_xmit_v6 | 1426 | struct ip_vs_protocol *pp, |
1339 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1427 | struct ip_vs_iphdr *iph); |
1340 | extern int ip_vs_dr_xmit_v6 | 1428 | extern int ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1341 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1429 | struct ip_vs_protocol *pp, |
1342 | extern int ip_vs_icmp_xmit_v6 | 1430 | struct ip_vs_iphdr *iph); |
1343 | (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, | 1431 | extern int ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1344 | int offset, unsigned int hooknum); | 1432 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); |
1433 | extern int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | ||
1434 | struct ip_vs_protocol *pp, int offset, | ||
1435 | unsigned int hooknum, struct ip_vs_iphdr *iph); | ||
1345 | #endif | 1436 | #endif |
1346 | 1437 | ||
1347 | #ifdef CONFIG_SYSCTL | 1438 | #ifdef CONFIG_SYSCTL |
diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h index 5e5eb1f9f14b..3573a81815ad 100644 --- a/include/net/netns/sctp.h +++ b/include/net/netns/sctp.h | |||
@@ -62,6 +62,9 @@ struct netns_sctp { | |||
62 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | 62 | /* Whether Cookie Preservative is enabled(1) or not(0) */ |
63 | int cookie_preserve_enable; | 63 | int cookie_preserve_enable; |
64 | 64 | ||
65 | /* The namespace default hmac alg */ | ||
66 | char *sctp_hmac_alg; | ||
67 | |||
65 | /* Valid.Cookie.Life - 60 seconds */ | 68 | /* Valid.Cookie.Life - 60 seconds */ |
66 | unsigned int valid_cookie_life; | 69 | unsigned int valid_cookie_life; |
67 | 70 | ||
diff --git a/include/net/request_sock.h b/include/net/request_sock.h index b01d8dd9ee7c..a51dbd17c2de 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h | |||
@@ -49,13 +49,16 @@ struct request_sock_ops { | |||
49 | struct request_sock *req); | 49 | struct request_sock *req); |
50 | }; | 50 | }; |
51 | 51 | ||
52 | extern int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req); | ||
53 | |||
52 | /* struct request_sock - mini sock to represent a connection request | 54 | /* struct request_sock - mini sock to represent a connection request |
53 | */ | 55 | */ |
54 | struct request_sock { | 56 | struct request_sock { |
55 | struct request_sock *dl_next; /* Must be first member! */ | 57 | struct request_sock *dl_next; /* Must be first member! */ |
56 | u16 mss; | 58 | u16 mss; |
57 | u8 retrans; | 59 | u8 num_retrans; /* number of retransmits */ |
58 | u8 cookie_ts; /* syncookie: encode tcpopts in timestamp */ | 60 | u8 cookie_ts:1; /* syncookie: encode tcpopts in timestamp */ |
61 | u8 num_timeout:7; /* number of timeouts */ | ||
59 | /* The following two fields can be easily recomputed I think -AK */ | 62 | /* The following two fields can be easily recomputed I think -AK */ |
60 | u32 window_clamp; /* window clamp at creation time */ | 63 | u32 window_clamp; /* window clamp at creation time */ |
61 | u32 rcv_wnd; /* rcv_wnd offered first time */ | 64 | u32 rcv_wnd; /* rcv_wnd offered first time */ |
@@ -231,7 +234,7 @@ static inline int reqsk_queue_removed(struct request_sock_queue *queue, | |||
231 | { | 234 | { |
232 | struct listen_sock *lopt = queue->listen_opt; | 235 | struct listen_sock *lopt = queue->listen_opt; |
233 | 236 | ||
234 | if (req->retrans == 0) | 237 | if (req->num_timeout == 0) |
235 | --lopt->qlen_young; | 238 | --lopt->qlen_young; |
236 | 239 | ||
237 | return --lopt->qlen; | 240 | return --lopt->qlen; |
@@ -269,7 +272,8 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, | |||
269 | struct listen_sock *lopt = queue->listen_opt; | 272 | struct listen_sock *lopt = queue->listen_opt; |
270 | 273 | ||
271 | req->expires = jiffies + timeout; | 274 | req->expires = jiffies + timeout; |
272 | req->retrans = 0; | 275 | req->num_retrans = 0; |
276 | req->num_timeout = 0; | ||
273 | req->sk = NULL; | 277 | req->sk = NULL; |
274 | req->dl_next = lopt->syn_table[hash]; | 278 | req->dl_next = lopt->syn_table[hash]; |
275 | 279 | ||
diff --git a/include/net/route.h b/include/net/route.h index bc40b633a5c4..2ea40c1b5e00 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -198,10 +198,13 @@ struct in_ifaddr; | |||
198 | extern void fib_add_ifaddr(struct in_ifaddr *); | 198 | extern void fib_add_ifaddr(struct in_ifaddr *); |
199 | extern void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); | 199 | extern void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); |
200 | 200 | ||
201 | static inline void ip_rt_put(struct rtable * rt) | 201 | static inline void ip_rt_put(struct rtable *rt) |
202 | { | 202 | { |
203 | if (rt) | 203 | /* dst_release() accepts a NULL parameter. |
204 | dst_release(&rt->dst); | 204 | * We rely on dst being first structure in struct rtable |
205 | */ | ||
206 | BUILD_BUG_ON(offsetof(struct rtable, dst) != 0); | ||
207 | dst_release(&rt->dst); | ||
205 | } | 208 | } |
206 | 209 | ||
207 | #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) | 210 | #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) |
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 712b3bebeda7..35247271e557 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -130,8 +130,6 @@ typedef union { | |||
130 | __be16 err; | 130 | __be16 err; |
131 | sctp_state_t state; | 131 | sctp_state_t state; |
132 | sctp_event_timeout_t to; | 132 | sctp_event_timeout_t to; |
133 | unsigned long zero; | ||
134 | void *ptr; | ||
135 | struct sctp_chunk *chunk; | 133 | struct sctp_chunk *chunk; |
136 | struct sctp_association *asoc; | 134 | struct sctp_association *asoc; |
137 | struct sctp_transport *transport; | 135 | struct sctp_transport *transport; |
@@ -154,23 +152,15 @@ typedef union { | |||
154 | * which takes an __s32 and returns a sctp_arg_t containing the | 152 | * which takes an __s32 and returns a sctp_arg_t containing the |
155 | * __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg. | 153 | * __s32. So, after foo = SCTP_I32(arg), foo.i32 == arg. |
156 | */ | 154 | */ |
157 | static inline sctp_arg_t SCTP_NULL(void) | ||
158 | { | ||
159 | sctp_arg_t retval; retval.ptr = NULL; return retval; | ||
160 | } | ||
161 | static inline sctp_arg_t SCTP_NOFORCE(void) | ||
162 | { | ||
163 | sctp_arg_t retval = {.zero = 0UL}; retval.i32 = 0; return retval; | ||
164 | } | ||
165 | static inline sctp_arg_t SCTP_FORCE(void) | ||
166 | { | ||
167 | sctp_arg_t retval = {.zero = 0UL}; retval.i32 = 1; return retval; | ||
168 | } | ||
169 | 155 | ||
170 | #define SCTP_ARG_CONSTRUCTOR(name, type, elt) \ | 156 | #define SCTP_ARG_CONSTRUCTOR(name, type, elt) \ |
171 | static inline sctp_arg_t \ | 157 | static inline sctp_arg_t \ |
172 | SCTP_## name (type arg) \ | 158 | SCTP_## name (type arg) \ |
173 | { sctp_arg_t retval = {.zero = 0UL}; retval.elt = arg; return retval; } | 159 | { sctp_arg_t retval;\ |
160 | memset(&retval, 0, sizeof(sctp_arg_t));\ | ||
161 | retval.elt = arg;\ | ||
162 | return retval;\ | ||
163 | } | ||
174 | 164 | ||
175 | SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) | 165 | SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) |
176 | SCTP_ARG_CONSTRUCTOR(U32, __u32, u32) | 166 | SCTP_ARG_CONSTRUCTOR(U32, __u32, u32) |
@@ -181,7 +171,6 @@ SCTP_ARG_CONSTRUCTOR(ERROR, int, error) | |||
181 | SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */ | 171 | SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */ |
182 | SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) | 172 | SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) |
183 | SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) | 173 | SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) |
184 | SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr) | ||
185 | SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk) | 174 | SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk) |
186 | SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc) | 175 | SCTP_ARG_CONSTRUCTOR(ASOC, struct sctp_association *, asoc) |
187 | SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport) | 176 | SCTP_ARG_CONSTRUCTOR(TRANSPORT, struct sctp_transport *, transport) |
@@ -192,6 +181,23 @@ SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet) | |||
192 | SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) | 181 | SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) |
193 | SCTP_ARG_CONSTRUCTOR(DATAMSG, struct sctp_datamsg *, msg) | 182 | SCTP_ARG_CONSTRUCTOR(DATAMSG, struct sctp_datamsg *, msg) |
194 | 183 | ||
184 | static inline sctp_arg_t SCTP_FORCE(void) | ||
185 | { | ||
186 | return SCTP_I32(1); | ||
187 | } | ||
188 | |||
189 | static inline sctp_arg_t SCTP_NOFORCE(void) | ||
190 | { | ||
191 | return SCTP_I32(0); | ||
192 | } | ||
193 | |||
194 | static inline sctp_arg_t SCTP_NULL(void) | ||
195 | { | ||
196 | sctp_arg_t retval; | ||
197 | memset(&retval, 0, sizeof(sctp_arg_t)); | ||
198 | return retval; | ||
199 | } | ||
200 | |||
195 | typedef struct { | 201 | typedef struct { |
196 | sctp_arg_t obj; | 202 | sctp_arg_t obj; |
197 | sctp_verb_t verb; | 203 | sctp_verb_t verb; |
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index d053d2e99876..c29707d654c0 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h | |||
@@ -312,14 +312,6 @@ enum { SCTP_MAX_GABS = 16 }; | |||
312 | * functions simpler to write. | 312 | * functions simpler to write. |
313 | */ | 313 | */ |
314 | 314 | ||
315 | #if defined (CONFIG_SCTP_HMAC_MD5) | ||
316 | #define SCTP_COOKIE_HMAC_ALG "hmac(md5)" | ||
317 | #elif defined (CONFIG_SCTP_HMAC_SHA1) | ||
318 | #define SCTP_COOKIE_HMAC_ALG "hmac(sha1)" | ||
319 | #else | ||
320 | #define SCTP_COOKIE_HMAC_ALG NULL | ||
321 | #endif | ||
322 | |||
323 | /* These return values describe the success or failure of a number of | 315 | /* These return values describe the success or failure of a number of |
324 | * routines which form the lower interface to SCTP_outqueue. | 316 | * routines which form the lower interface to SCTP_outqueue. |
325 | */ | 317 | */ |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 64158aa1bb5f..2b2f61dd4036 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -177,6 +177,7 @@ struct sctp_sock { | |||
177 | 177 | ||
178 | /* Access to HMAC transform. */ | 178 | /* Access to HMAC transform. */ |
179 | struct crypto_hash *hmac; | 179 | struct crypto_hash *hmac; |
180 | char *sctp_hmac_alg; | ||
180 | 181 | ||
181 | /* What is our base endpointer? */ | 182 | /* What is our base endpointer? */ |
182 | struct sctp_endpoint *ep; | 183 | struct sctp_endpoint *ep; |
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h index 2e5ee0d8458d..ff1b8ba73ab1 100644 --- a/include/net/sctp/ulpqueue.h +++ b/include/net/sctp/ulpqueue.h | |||
@@ -72,7 +72,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev); | |||
72 | void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, gfp_t); | 72 | void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, gfp_t); |
73 | 73 | ||
74 | /* Perform partial delivery. */ | 74 | /* Perform partial delivery. */ |
75 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, gfp_t); | 75 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *, gfp_t); |
76 | 76 | ||
77 | /* Abort the partial delivery. */ | 77 | /* Abort the partial delivery. */ |
78 | void sctp_ulpq_abort_pd(struct sctp_ulpq *, gfp_t); | 78 | void sctp_ulpq_abort_pd(struct sctp_ulpq *, gfp_t); |
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index b1bea03274d5..2d32d073a6f9 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h | |||
@@ -43,6 +43,7 @@ | |||
43 | /* Socket filtering */ | 43 | /* Socket filtering */ |
44 | #define SO_ATTACH_FILTER 26 | 44 | #define SO_ATTACH_FILTER 26 |
45 | #define SO_DETACH_FILTER 27 | 45 | #define SO_DETACH_FILTER 27 |
46 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
46 | 47 | ||
47 | #define SO_PEERNAME 28 | 48 | #define SO_PEERNAME 28 |
48 | #define SO_TIMESTAMP 29 | 49 | #define SO_TIMESTAMP 29 |
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h index 3d7922433aba..9cfde6941099 100644 --- a/include/uapi/linux/filter.h +++ b/include/uapi/linux/filter.h | |||
@@ -127,7 +127,9 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ | |||
127 | #define SKF_AD_RXHASH 32 | 127 | #define SKF_AD_RXHASH 32 |
128 | #define SKF_AD_CPU 36 | 128 | #define SKF_AD_CPU 36 |
129 | #define SKF_AD_ALU_XOR_X 40 | 129 | #define SKF_AD_ALU_XOR_X 40 |
130 | #define SKF_AD_MAX 44 | 130 | #define SKF_AD_VLAN_TAG 44 |
131 | #define SKF_AD_VLAN_TAG_PRESENT 48 | ||
132 | #define SKF_AD_MAX 52 | ||
131 | #define SKF_NET_OFF (-0x100000) | 133 | #define SKF_NET_OFF (-0x100000) |
132 | #define SKF_LL_OFF (-0x200000) | 134 | #define SKF_LL_OFF (-0x200000) |
133 | 135 | ||
diff --git a/include/uapi/linux/hdlc/Kbuild b/include/uapi/linux/hdlc/Kbuild index aafaa5aa54d4..8c1d2cb75e33 100644 --- a/include/uapi/linux/hdlc/Kbuild +++ b/include/uapi/linux/hdlc/Kbuild | |||
@@ -1 +1,2 @@ | |||
1 | # UAPI Header export list | 1 | # UAPI Header export list |
2 | header-y += ioctl.h | ||
diff --git a/include/linux/hdlc/ioctl.h b/include/uapi/linux/hdlc/ioctl.h index 583972364357..04bc0274a189 100644 --- a/include/linux/hdlc/ioctl.h +++ b/include/uapi/linux/hdlc/ioctl.h | |||
@@ -34,13 +34,15 @@ | |||
34 | #define LMI_CCITT 3 /* ITU-T Annex A */ | 34 | #define LMI_CCITT 3 /* ITU-T Annex A */ |
35 | #define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */ | 35 | #define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */ |
36 | 36 | ||
37 | typedef struct { | 37 | #ifndef __ASSEMBLY__ |
38 | |||
39 | typedef struct { | ||
38 | unsigned int clock_rate; /* bits per second */ | 40 | unsigned int clock_rate; /* bits per second */ |
39 | unsigned int clock_type; /* internal, external, TX-internal etc. */ | 41 | unsigned int clock_type; /* internal, external, TX-internal etc. */ |
40 | unsigned short loopback; | 42 | unsigned short loopback; |
41 | } sync_serial_settings; /* V.35, V.24, X.21 */ | 43 | } sync_serial_settings; /* V.35, V.24, X.21 */ |
42 | 44 | ||
43 | typedef struct { | 45 | typedef struct { |
44 | unsigned int clock_rate; /* bits per second */ | 46 | unsigned int clock_rate; /* bits per second */ |
45 | unsigned int clock_type; /* internal, external, TX-internal etc. */ | 47 | unsigned int clock_type; /* internal, external, TX-internal etc. */ |
46 | unsigned short loopback; | 48 | unsigned short loopback; |
@@ -78,4 +80,5 @@ typedef struct { | |||
78 | 80 | ||
79 | /* PPP doesn't need any info now - supply length = 0 to ioctl */ | 81 | /* PPP doesn't need any info now - supply length = 0 to ioctl */ |
80 | 82 | ||
83 | #endif /* __ASSEMBLY__ */ | ||
81 | #endif /* __HDLC_IOCTL_H__ */ | 84 | #endif /* __HDLC_IOCTL_H__ */ |
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h index a8fe9549ddbc..b3885791e11e 100644 --- a/include/uapi/linux/if_bridge.h +++ b/include/uapi/linux/if_bridge.h | |||
@@ -97,5 +97,23 @@ struct __fdb_entry { | |||
97 | __u16 unused; | 97 | __u16 unused; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Bridge Flags */ | ||
101 | #define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */ | ||
102 | #define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */ | ||
100 | 103 | ||
104 | #define BRIDGE_MODE_VEB 0 /* Default loopback mode */ | ||
105 | #define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */ | ||
106 | |||
107 | /* Bridge management nested attributes | ||
108 | * [IFLA_AF_SPEC] = { | ||
109 | * [IFLA_BRIDGE_FLAGS] | ||
110 | * [IFLA_BRIDGE_MODE] | ||
111 | * } | ||
112 | */ | ||
113 | enum { | ||
114 | IFLA_BRIDGE_FLAGS, | ||
115 | IFLA_BRIDGE_MODE, | ||
116 | __IFLA_BRIDGE_MAX, | ||
117 | }; | ||
118 | #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) | ||
101 | #endif /* _UAPI_LINUX_IF_BRIDGE_H */ | 119 | #endif /* _UAPI_LINUX_IF_BRIDGE_H */ |
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 0343e1f0582c..67fb87ca1094 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
@@ -48,6 +48,7 @@ | |||
48 | #define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ | 48 | #define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ |
49 | #define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ | 49 | #define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ |
50 | #define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ | 50 | #define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ |
51 | #define ETH_P_BATMAN 0x4305 /* B.A.T.M.A.N.-Advanced packet [ NOT AN OFFICIALLY REGISTERED ID ] */ | ||
51 | #define ETH_P_DEC 0x6000 /* DEC Assigned proto */ | 52 | #define ETH_P_DEC 0x6000 /* DEC Assigned proto */ |
52 | #define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ | 53 | #define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ |
53 | #define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ | 54 | #define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ |
diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h index f3799295d231..f9a60375f0d0 100644 --- a/include/uapi/linux/if_packet.h +++ b/include/uapi/linux/if_packet.h | |||
@@ -50,6 +50,7 @@ struct sockaddr_ll { | |||
50 | #define PACKET_TX_TIMESTAMP 16 | 50 | #define PACKET_TX_TIMESTAMP 16 |
51 | #define PACKET_TIMESTAMP 17 | 51 | #define PACKET_TIMESTAMP 17 |
52 | #define PACKET_FANOUT 18 | 52 | #define PACKET_FANOUT 18 |
53 | #define PACKET_TX_HAS_OFF 19 | ||
53 | 54 | ||
54 | #define PACKET_FANOUT_HASH 0 | 55 | #define PACKET_FANOUT_HASH 0 |
55 | #define PACKET_FANOUT_LB 1 | 56 | #define PACKET_FANOUT_LB 1 |
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 25a585ce23e6..958497ad5bb5 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #define TUN_ONE_QUEUE 0x0080 | 34 | #define TUN_ONE_QUEUE 0x0080 |
35 | #define TUN_PERSIST 0x0100 | 35 | #define TUN_PERSIST 0x0100 |
36 | #define TUN_VNET_HDR 0x0200 | 36 | #define TUN_VNET_HDR 0x0200 |
37 | #define TUN_TAP_MQ 0x0400 | ||
37 | 38 | ||
38 | /* Ioctl defines */ | 39 | /* Ioctl defines */ |
39 | #define TUNSETNOCSUM _IOW('T', 200, int) | 40 | #define TUNSETNOCSUM _IOW('T', 200, int) |
@@ -53,6 +54,7 @@ | |||
53 | #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog) | 54 | #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog) |
54 | #define TUNGETVNETHDRSZ _IOR('T', 215, int) | 55 | #define TUNGETVNETHDRSZ _IOR('T', 215, int) |
55 | #define TUNSETVNETHDRSZ _IOW('T', 216, int) | 56 | #define TUNSETVNETHDRSZ _IOW('T', 216, int) |
57 | #define TUNSETQUEUE _IOW('T', 217, int) | ||
56 | 58 | ||
57 | /* TUNSETIFF ifr flags */ | 59 | /* TUNSETIFF ifr flags */ |
58 | #define IFF_TUN 0x0001 | 60 | #define IFF_TUN 0x0001 |
@@ -61,6 +63,9 @@ | |||
61 | #define IFF_ONE_QUEUE 0x2000 | 63 | #define IFF_ONE_QUEUE 0x2000 |
62 | #define IFF_VNET_HDR 0x4000 | 64 | #define IFF_VNET_HDR 0x4000 |
63 | #define IFF_TUN_EXCL 0x8000 | 65 | #define IFF_TUN_EXCL 0x8000 |
66 | #define IFF_MULTI_QUEUE 0x0100 | ||
67 | #define IFF_ATTACH_QUEUE 0x0200 | ||
68 | #define IFF_DETACH_QUEUE 0x0400 | ||
64 | 69 | ||
65 | /* Features for GSO (TUNSETOFFLOAD). */ | 70 | /* Features for GSO (TUNSETOFFLOAD). */ |
66 | #define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ | 71 | #define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ |
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 5db5942575fe..c1bf0b5a8da1 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h | |||
@@ -37,6 +37,20 @@ struct ip_tunnel_parm { | |||
37 | struct iphdr iph; | 37 | struct iphdr iph; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | enum { | ||
41 | IFLA_IPTUN_UNSPEC, | ||
42 | IFLA_IPTUN_LINK, | ||
43 | IFLA_IPTUN_LOCAL, | ||
44 | IFLA_IPTUN_REMOTE, | ||
45 | IFLA_IPTUN_TTL, | ||
46 | IFLA_IPTUN_TOS, | ||
47 | IFLA_IPTUN_ENCAP_LIMIT, | ||
48 | IFLA_IPTUN_FLOWINFO, | ||
49 | IFLA_IPTUN_FLAGS, | ||
50 | __IFLA_IPTUN_MAX, | ||
51 | }; | ||
52 | #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) | ||
53 | |||
40 | /* SIT-mode i_flags */ | 54 | /* SIT-mode i_flags */ |
41 | #define SIT_ISATAP 0x0001 | 55 | #define SIT_ISATAP 0x0001 |
42 | 56 | ||
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index 8c469af939aa..bbde90fa5838 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h | |||
@@ -109,9 +109,10 @@ enum { | |||
109 | INET_DIAG_TOS, | 109 | INET_DIAG_TOS, |
110 | INET_DIAG_TCLASS, | 110 | INET_DIAG_TCLASS, |
111 | INET_DIAG_SKMEMINFO, | 111 | INET_DIAG_SKMEMINFO, |
112 | INET_DIAG_SHUTDOWN, | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | #define INET_DIAG_MAX INET_DIAG_SKMEMINFO | 115 | #define INET_DIAG_MAX INET_DIAG_SHUTDOWN |
115 | 116 | ||
116 | 117 | ||
117 | /* INET_DIAG_MEM */ | 118 | /* INET_DIAG_MEM */ |
diff --git a/include/uapi/linux/netconf.h b/include/uapi/linux/netconf.h new file mode 100644 index 000000000000..75dcbc587fb5 --- /dev/null +++ b/include/uapi/linux/netconf.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef _UAPI_LINUX_NETCONF_H_ | ||
2 | #define _UAPI_LINUX_NETCONF_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/netlink.h> | ||
6 | |||
7 | struct netconfmsg { | ||
8 | __u8 ncm_family; | ||
9 | }; | ||
10 | |||
11 | enum { | ||
12 | NETCONFA_UNSPEC, | ||
13 | NETCONFA_IFINDEX, | ||
14 | NETCONFA_FORWARDING, | ||
15 | NETCONFA_RP_FILTER, | ||
16 | __NETCONFA_MAX | ||
17 | }; | ||
18 | #define NETCONFA_MAX (__NETCONFA_MAX - 1) | ||
19 | |||
20 | #define NETCONFA_IFINDEX_ALL -1 | ||
21 | #define NETCONFA_IFINDEX_DEFAULT -2 | ||
22 | |||
23 | #endif /* _UAPI_LINUX_NETCONF_H_ */ | ||
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h index 94e981f810a2..b65c834f83e9 100644 --- a/include/uapi/linux/ptp_clock.h +++ b/include/uapi/linux/ptp_clock.h | |||
@@ -67,12 +67,26 @@ struct ptp_perout_request { | |||
67 | unsigned int rsv[4]; /* Reserved for future use. */ | 67 | unsigned int rsv[4]; /* Reserved for future use. */ |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #define PTP_MAX_SAMPLES 25 /* Maximum allowed offset measurement samples. */ | ||
71 | |||
72 | struct ptp_sys_offset { | ||
73 | unsigned int n_samples; /* Desired number of measurements. */ | ||
74 | unsigned int rsv[3]; /* Reserved for future use. */ | ||
75 | /* | ||
76 | * Array of interleaved system/phc time stamps. The kernel | ||
77 | * will provide 2*n_samples + 1 time stamps, with the last | ||
78 | * one as a system time stamp. | ||
79 | */ | ||
80 | struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1]; | ||
81 | }; | ||
82 | |||
70 | #define PTP_CLK_MAGIC '=' | 83 | #define PTP_CLK_MAGIC '=' |
71 | 84 | ||
72 | #define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps) | 85 | #define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps) |
73 | #define PTP_EXTTS_REQUEST _IOW(PTP_CLK_MAGIC, 2, struct ptp_extts_request) | 86 | #define PTP_EXTTS_REQUEST _IOW(PTP_CLK_MAGIC, 2, struct ptp_extts_request) |
74 | #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request) | 87 | #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request) |
75 | #define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int) | 88 | #define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int) |
89 | #define PTP_SYS_OFFSET _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset) | ||
76 | 90 | ||
77 | struct ptp_extts_event { | 91 | struct ptp_extts_event { |
78 | struct ptp_clock_time t; /* Time event occured. */ | 92 | struct ptp_clock_time t; /* Time event occured. */ |
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index fcd768b09f6e..3dee071770d5 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h | |||
@@ -120,6 +120,11 @@ enum { | |||
120 | RTM_SETDCB, | 120 | RTM_SETDCB, |
121 | #define RTM_SETDCB RTM_SETDCB | 121 | #define RTM_SETDCB RTM_SETDCB |
122 | 122 | ||
123 | RTM_NEWNETCONF = 80, | ||
124 | #define RTM_NEWNETCONF RTM_NEWNETCONF | ||
125 | RTM_GETNETCONF = 82, | ||
126 | #define RTM_GETNETCONF RTM_GETNETCONF | ||
127 | |||
123 | __RTM_MAX, | 128 | __RTM_MAX, |
124 | #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) | 129 | #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) |
125 | }; | 130 | }; |
@@ -587,6 +592,10 @@ enum rtnetlink_groups { | |||
587 | #define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE | 592 | #define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE |
588 | RTNLGRP_DCB, | 593 | RTNLGRP_DCB, |
589 | #define RTNLGRP_DCB RTNLGRP_DCB | 594 | #define RTNLGRP_DCB RTNLGRP_DCB |
595 | RTNLGRP_IPV4_NETCONF, | ||
596 | #define RTNLGRP_IPV4_NETCONF RTNLGRP_IPV4_NETCONF | ||
597 | RTNLGRP_IPV6_NETCONF, | ||
598 | #define RTNLGRP_IPV6_NETCONF RTNLGRP_IPV6_NETCONF | ||
590 | __RTNLGRP_MAX | 599 | __RTNLGRP_MAX |
591 | }; | 600 | }; |
592 | #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) | 601 | #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) |
diff --git a/include/uapi/linux/unix_diag.h b/include/uapi/linux/unix_diag.h index b1d2bf16b33c..b8a24941db21 100644 --- a/include/uapi/linux/unix_diag.h +++ b/include/uapi/linux/unix_diag.h | |||
@@ -37,6 +37,7 @@ enum { | |||
37 | UNIX_DIAG_ICONS, | 37 | UNIX_DIAG_ICONS, |
38 | UNIX_DIAG_RQLEN, | 38 | UNIX_DIAG_RQLEN, |
39 | UNIX_DIAG_MEMINFO, | 39 | UNIX_DIAG_MEMINFO, |
40 | UNIX_DIAG_SHUTDOWN, | ||
40 | 41 | ||
41 | UNIX_DIAG_MAX, | 42 | UNIX_DIAG_MAX, |
42 | }; | 43 | }; |
diff --git a/include/uapi/linux/usb/cdc.h b/include/uapi/linux/usb/cdc.h index 81a927930bfd..f35aa0a338c7 100644 --- a/include/uapi/linux/usb/cdc.h +++ b/include/uapi/linux/usb/cdc.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define USB_CDC_SUBCLASS_OBEX 0x0b | 19 | #define USB_CDC_SUBCLASS_OBEX 0x0b |
20 | #define USB_CDC_SUBCLASS_EEM 0x0c | 20 | #define USB_CDC_SUBCLASS_EEM 0x0c |
21 | #define USB_CDC_SUBCLASS_NCM 0x0d | 21 | #define USB_CDC_SUBCLASS_NCM 0x0d |
22 | #define USB_CDC_SUBCLASS_MBIM 0x0e | ||
22 | 23 | ||
23 | #define USB_CDC_PROTO_NONE 0 | 24 | #define USB_CDC_PROTO_NONE 0 |
24 | 25 | ||
@@ -33,6 +34,7 @@ | |||
33 | #define USB_CDC_PROTO_EEM 7 | 34 | #define USB_CDC_PROTO_EEM 7 |
34 | 35 | ||
35 | #define USB_CDC_NCM_PROTO_NTB 1 | 36 | #define USB_CDC_NCM_PROTO_NTB 1 |
37 | #define USB_CDC_MBIM_PROTO_NTB 2 | ||
36 | 38 | ||
37 | /*-------------------------------------------------------------------------*/ | 39 | /*-------------------------------------------------------------------------*/ |
38 | 40 | ||
@@ -53,6 +55,7 @@ | |||
53 | #define USB_CDC_DMM_TYPE 0x14 | 55 | #define USB_CDC_DMM_TYPE 0x14 |
54 | #define USB_CDC_OBEX_TYPE 0x15 | 56 | #define USB_CDC_OBEX_TYPE 0x15 |
55 | #define USB_CDC_NCM_TYPE 0x1a | 57 | #define USB_CDC_NCM_TYPE 0x1a |
58 | #define USB_CDC_MBIM_TYPE 0x1b | ||
56 | 59 | ||
57 | /* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ | 60 | /* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ |
58 | struct usb_cdc_header_desc { | 61 | struct usb_cdc_header_desc { |
@@ -187,6 +190,21 @@ struct usb_cdc_ncm_desc { | |||
187 | __le16 bcdNcmVersion; | 190 | __le16 bcdNcmVersion; |
188 | __u8 bmNetworkCapabilities; | 191 | __u8 bmNetworkCapabilities; |
189 | } __attribute__ ((packed)); | 192 | } __attribute__ ((packed)); |
193 | |||
194 | /* "MBIM Control Model Functional Descriptor" */ | ||
195 | struct usb_cdc_mbim_desc { | ||
196 | __u8 bLength; | ||
197 | __u8 bDescriptorType; | ||
198 | __u8 bDescriptorSubType; | ||
199 | |||
200 | __le16 bcdMBIMVersion; | ||
201 | __le16 wMaxControlMessage; | ||
202 | __u8 bNumberFilters; | ||
203 | __u8 bMaxFilterSize; | ||
204 | __le16 wMaxSegmentSize; | ||
205 | __u8 bmNetworkCapabilities; | ||
206 | } __attribute__ ((packed)); | ||
207 | |||
190 | /*-------------------------------------------------------------------------*/ | 208 | /*-------------------------------------------------------------------------*/ |
191 | 209 | ||
192 | /* | 210 | /* |
@@ -332,6 +350,11 @@ struct usb_cdc_ncm_nth32 { | |||
332 | #define USB_CDC_NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */ | 350 | #define USB_CDC_NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */ |
333 | #define USB_CDC_NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */ | 351 | #define USB_CDC_NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */ |
334 | 352 | ||
353 | #define USB_CDC_MBIM_NDP16_IPS_SIGN 0x00535049 /* IPS<sessionID> : IPS0 for now */ | ||
354 | #define USB_CDC_MBIM_NDP32_IPS_SIGN 0x00737069 /* ips<sessionID> : ips0 for now */ | ||
355 | #define USB_CDC_MBIM_NDP16_DSS_SIGN 0x00535344 /* DSS<sessionID> */ | ||
356 | #define USB_CDC_MBIM_NDP32_DSS_SIGN 0x00737364 /* dss<sessionID> */ | ||
357 | |||
335 | /* 16-bit NCM Datagram Pointer Entry */ | 358 | /* 16-bit NCM Datagram Pointer Entry */ |
336 | struct usb_cdc_ncm_dpe16 { | 359 | struct usb_cdc_ncm_dpe16 { |
337 | __le16 wDatagramIndex; | 360 | __le16 wDatagramIndex; |
diff --git a/kernel/time/Makefile b/kernel/time/Makefile index e2fd74b8e8c2..ff7d9d2ab504 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o | 1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o |
2 | obj-y += timeconv.o posix-clock.o alarmtimer.o | 2 | obj-y += timeconv.o posix-clock.o alarmtimer.o |
3 | 3 | ||
4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o | 4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o |
diff --git a/kernel/time/timecompare.c b/kernel/time/timecompare.c deleted file mode 100644 index a9ae369925ce..000000000000 --- a/kernel/time/timecompare.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Intel Corporation. | ||
3 | * Author: Patrick Ohly <patrick.ohly@intel.com> | ||
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; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/timecompare.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/math64.h> | ||
24 | #include <linux/kernel.h> | ||
25 | |||
26 | /* | ||
27 | * fixed point arithmetic scale factor for skew | ||
28 | * | ||
29 | * Usually one would measure skew in ppb (parts per billion, 1e9), but | ||
30 | * using a factor of 2 simplifies the math. | ||
31 | */ | ||
32 | #define TIMECOMPARE_SKEW_RESOLUTION (((s64)1)<<30) | ||
33 | |||
34 | ktime_t timecompare_transform(struct timecompare *sync, | ||
35 | u64 source_tstamp) | ||
36 | { | ||
37 | u64 nsec; | ||
38 | |||
39 | nsec = source_tstamp + sync->offset; | ||
40 | nsec += (s64)(source_tstamp - sync->last_update) * sync->skew / | ||
41 | TIMECOMPARE_SKEW_RESOLUTION; | ||
42 | |||
43 | return ns_to_ktime(nsec); | ||
44 | } | ||
45 | EXPORT_SYMBOL_GPL(timecompare_transform); | ||
46 | |||
47 | int timecompare_offset(struct timecompare *sync, | ||
48 | s64 *offset, | ||
49 | u64 *source_tstamp) | ||
50 | { | ||
51 | u64 start_source = 0, end_source = 0; | ||
52 | struct { | ||
53 | s64 offset; | ||
54 | s64 duration_target; | ||
55 | } buffer[10], sample, *samples; | ||
56 | int counter = 0, i; | ||
57 | int used; | ||
58 | int index; | ||
59 | int num_samples = sync->num_samples; | ||
60 | |||
61 | if (num_samples > ARRAY_SIZE(buffer)) { | ||
62 | samples = kmalloc(sizeof(*samples) * num_samples, GFP_ATOMIC); | ||
63 | if (!samples) { | ||
64 | samples = buffer; | ||
65 | num_samples = ARRAY_SIZE(buffer); | ||
66 | } | ||
67 | } else { | ||
68 | samples = buffer; | ||
69 | } | ||
70 | |||
71 | /* run until we have enough valid samples, but do not try forever */ | ||
72 | i = 0; | ||
73 | counter = 0; | ||
74 | while (1) { | ||
75 | u64 ts; | ||
76 | ktime_t start, end; | ||
77 | |||
78 | start = sync->target(); | ||
79 | ts = timecounter_read(sync->source); | ||
80 | end = sync->target(); | ||
81 | |||
82 | if (!i) | ||
83 | start_source = ts; | ||
84 | |||
85 | /* ignore negative durations */ | ||
86 | sample.duration_target = ktime_to_ns(ktime_sub(end, start)); | ||
87 | if (sample.duration_target >= 0) { | ||
88 | /* | ||
89 | * assume symetric delay to and from source: | ||
90 | * average target time corresponds to measured | ||
91 | * source time | ||
92 | */ | ||
93 | sample.offset = | ||
94 | (ktime_to_ns(end) + ktime_to_ns(start)) / 2 - | ||
95 | ts; | ||
96 | |||
97 | /* simple insertion sort based on duration */ | ||
98 | index = counter - 1; | ||
99 | while (index >= 0) { | ||
100 | if (samples[index].duration_target < | ||
101 | sample.duration_target) | ||
102 | break; | ||
103 | samples[index + 1] = samples[index]; | ||
104 | index--; | ||
105 | } | ||
106 | samples[index + 1] = sample; | ||
107 | counter++; | ||
108 | } | ||
109 | |||
110 | i++; | ||
111 | if (counter >= num_samples || i >= 100000) { | ||
112 | end_source = ts; | ||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | *source_tstamp = (end_source + start_source) / 2; | ||
118 | |||
119 | /* remove outliers by only using 75% of the samples */ | ||
120 | used = counter * 3 / 4; | ||
121 | if (!used) | ||
122 | used = counter; | ||
123 | if (used) { | ||
124 | /* calculate average */ | ||
125 | s64 off = 0; | ||
126 | for (index = 0; index < used; index++) | ||
127 | off += samples[index].offset; | ||
128 | *offset = div_s64(off, used); | ||
129 | } | ||
130 | |||
131 | if (samples && samples != buffer) | ||
132 | kfree(samples); | ||
133 | |||
134 | return used; | ||
135 | } | ||
136 | EXPORT_SYMBOL_GPL(timecompare_offset); | ||
137 | |||
138 | void __timecompare_update(struct timecompare *sync, | ||
139 | u64 source_tstamp) | ||
140 | { | ||
141 | s64 offset; | ||
142 | u64 average_time; | ||
143 | |||
144 | if (!timecompare_offset(sync, &offset, &average_time)) | ||
145 | return; | ||
146 | |||
147 | if (!sync->last_update) { | ||
148 | sync->last_update = average_time; | ||
149 | sync->offset = offset; | ||
150 | sync->skew = 0; | ||
151 | } else { | ||
152 | s64 delta_nsec = average_time - sync->last_update; | ||
153 | |||
154 | /* avoid division by negative or small deltas */ | ||
155 | if (delta_nsec >= 10000) { | ||
156 | s64 delta_offset_nsec = offset - sync->offset; | ||
157 | s64 skew; /* delta_offset_nsec * | ||
158 | TIMECOMPARE_SKEW_RESOLUTION / | ||
159 | delta_nsec */ | ||
160 | u64 divisor; | ||
161 | |||
162 | /* div_s64() is limited to 32 bit divisor */ | ||
163 | skew = delta_offset_nsec * TIMECOMPARE_SKEW_RESOLUTION; | ||
164 | divisor = delta_nsec; | ||
165 | while (unlikely(divisor >= ((s64)1) << 32)) { | ||
166 | /* divide both by 2; beware, right shift | ||
167 | of negative value has undefined | ||
168 | behavior and can only be used for | ||
169 | the positive divisor */ | ||
170 | skew = div_s64(skew, 2); | ||
171 | divisor >>= 1; | ||
172 | } | ||
173 | skew = div_s64(skew, divisor); | ||
174 | |||
175 | /* | ||
176 | * Calculate new overall skew as 4/16 the | ||
177 | * old value and 12/16 the new one. This is | ||
178 | * a rather arbitrary tradeoff between | ||
179 | * only using the latest measurement (0/16 and | ||
180 | * 16/16) and even more weight on past measurements. | ||
181 | */ | ||
182 | #define TIMECOMPARE_NEW_SKEW_PER_16 12 | ||
183 | sync->skew = | ||
184 | div_s64((16 - TIMECOMPARE_NEW_SKEW_PER_16) * | ||
185 | sync->skew + | ||
186 | TIMECOMPARE_NEW_SKEW_PER_16 * skew, | ||
187 | 16); | ||
188 | sync->last_update = average_time; | ||
189 | sync->offset = offset; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | EXPORT_SYMBOL_GPL(__timecompare_update); | ||
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index ee070722a3a3..30ee4bc0f7cc 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -294,7 +294,7 @@ static void vlan_transfer_features(struct net_device *dev, | |||
294 | else | 294 | else |
295 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; | 295 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; |
296 | 296 | ||
297 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 297 | #if IS_ENABLED(CONFIG_FCOE) |
298 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; | 298 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; |
299 | #endif | 299 | #endif |
300 | 300 | ||
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 402442402af7..4a6d31a082b9 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -409,7 +409,7 @@ static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) | |||
409 | return err; | 409 | return err; |
410 | } | 410 | } |
411 | 411 | ||
412 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 412 | #if IS_ENABLED(CONFIG_FCOE) |
413 | static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, | 413 | static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, |
414 | struct scatterlist *sgl, unsigned int sgc) | 414 | struct scatterlist *sgl, unsigned int sgc) |
415 | { | 415 | { |
@@ -531,6 +531,10 @@ static const struct header_ops vlan_header_ops = { | |||
531 | .parse = eth_header_parse, | 531 | .parse = eth_header_parse, |
532 | }; | 532 | }; |
533 | 533 | ||
534 | static struct device_type vlan_type = { | ||
535 | .name = "vlan", | ||
536 | }; | ||
537 | |||
534 | static const struct net_device_ops vlan_netdev_ops; | 538 | static const struct net_device_ops vlan_netdev_ops; |
535 | 539 | ||
536 | static int vlan_dev_init(struct net_device *dev) | 540 | static int vlan_dev_init(struct net_device *dev) |
@@ -564,7 +568,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
564 | if (is_zero_ether_addr(dev->broadcast)) | 568 | if (is_zero_ether_addr(dev->broadcast)) |
565 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); | 569 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); |
566 | 570 | ||
567 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 571 | #if IS_ENABLED(CONFIG_FCOE) |
568 | dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; | 572 | dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; |
569 | #endif | 573 | #endif |
570 | 574 | ||
@@ -579,6 +583,8 @@ static int vlan_dev_init(struct net_device *dev) | |||
579 | 583 | ||
580 | dev->netdev_ops = &vlan_netdev_ops; | 584 | dev->netdev_ops = &vlan_netdev_ops; |
581 | 585 | ||
586 | SET_NETDEV_DEVTYPE(dev, &vlan_type); | ||
587 | |||
582 | if (is_vlan_dev(real_dev)) | 588 | if (is_vlan_dev(real_dev)) |
583 | subclass = 1; | 589 | subclass = 1; |
584 | 590 | ||
@@ -741,7 +747,7 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
741 | .ndo_do_ioctl = vlan_dev_ioctl, | 747 | .ndo_do_ioctl = vlan_dev_ioctl, |
742 | .ndo_neigh_setup = vlan_dev_neigh_setup, | 748 | .ndo_neigh_setup = vlan_dev_neigh_setup, |
743 | .ndo_get_stats64 = vlan_dev_get_stats64, | 749 | .ndo_get_stats64 = vlan_dev_get_stats64, |
744 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 750 | #if IS_ENABLED(CONFIG_FCOE) |
745 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | 751 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, |
746 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | 752 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, |
747 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | 753 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, |
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig index 53f5244e28f8..250e0b58109c 100644 --- a/net/batman-adv/Kconfig +++ b/net/batman-adv/Kconfig | |||
@@ -25,6 +25,16 @@ config BATMAN_ADV_BLA | |||
25 | more than one mesh node in the same LAN, you can safely remove | 25 | more than one mesh node in the same LAN, you can safely remove |
26 | this feature and save some space. | 26 | this feature and save some space. |
27 | 27 | ||
28 | config BATMAN_ADV_DAT | ||
29 | bool "Distributed ARP Table" | ||
30 | depends on BATMAN_ADV && INET | ||
31 | default n | ||
32 | help | ||
33 | This option enables DAT (Distributed ARP Table), a DHT based | ||
34 | mechanism that increases ARP reliability on sparse wireless | ||
35 | mesh networks. If you think that your network does not need | ||
36 | this option you can safely remove it and save some space. | ||
37 | |||
28 | config BATMAN_ADV_DEBUG | 38 | config BATMAN_ADV_DEBUG |
29 | bool "B.A.T.M.A.N. debugging" | 39 | bool "B.A.T.M.A.N. debugging" |
30 | depends on BATMAN_ADV | 40 | depends on BATMAN_ADV |
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index 8676d2b1d574..e45e3b4e32e3 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile | |||
@@ -23,6 +23,7 @@ batman-adv-y += bat_iv_ogm.o | |||
23 | batman-adv-y += bitarray.o | 23 | batman-adv-y += bitarray.o |
24 | batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o | 24 | batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o |
25 | batman-adv-y += debugfs.o | 25 | batman-adv-y += debugfs.o |
26 | batman-adv-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o | ||
26 | batman-adv-y += gateway_client.o | 27 | batman-adv-y += gateway_client.o |
27 | batman-adv-y += gateway_common.o | 28 | batman-adv-y += gateway_common.o |
28 | batman-adv-y += hard-interface.o | 29 | batman-adv-y += hard-interface.o |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index b02b75dae3a8..9f3925a85aab 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -57,20 +57,22 @@ out: | |||
57 | static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) | 57 | static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) |
58 | { | 58 | { |
59 | struct batadv_ogm_packet *batadv_ogm_packet; | 59 | struct batadv_ogm_packet *batadv_ogm_packet; |
60 | unsigned char *ogm_buff; | ||
60 | uint32_t random_seqno; | 61 | uint32_t random_seqno; |
61 | int res = -ENOMEM; | 62 | int res = -ENOMEM; |
62 | 63 | ||
63 | /* randomize initial seqno to avoid collision */ | 64 | /* randomize initial seqno to avoid collision */ |
64 | get_random_bytes(&random_seqno, sizeof(random_seqno)); | 65 | get_random_bytes(&random_seqno, sizeof(random_seqno)); |
65 | atomic_set(&hard_iface->seqno, random_seqno); | 66 | atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); |
66 | 67 | ||
67 | hard_iface->packet_len = BATADV_OGM_HLEN; | 68 | hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; |
68 | hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); | 69 | ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); |
69 | 70 | if (!ogm_buff) | |
70 | if (!hard_iface->packet_buff) | ||
71 | goto out; | 71 | goto out; |
72 | 72 | ||
73 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 73 | hard_iface->bat_iv.ogm_buff = ogm_buff; |
74 | |||
75 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | ||
74 | batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; | 76 | batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; |
75 | batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; | 77 | batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; |
76 | batadv_ogm_packet->header.ttl = 2; | 78 | batadv_ogm_packet->header.ttl = 2; |
@@ -87,15 +89,16 @@ out: | |||
87 | 89 | ||
88 | static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) | 90 | static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) |
89 | { | 91 | { |
90 | kfree(hard_iface->packet_buff); | 92 | kfree(hard_iface->bat_iv.ogm_buff); |
91 | hard_iface->packet_buff = NULL; | 93 | hard_iface->bat_iv.ogm_buff = NULL; |
92 | } | 94 | } |
93 | 95 | ||
94 | static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) | 96 | static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) |
95 | { | 97 | { |
96 | struct batadv_ogm_packet *batadv_ogm_packet; | 98 | struct batadv_ogm_packet *batadv_ogm_packet; |
99 | unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
97 | 100 | ||
98 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 101 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
99 | memcpy(batadv_ogm_packet->orig, | 102 | memcpy(batadv_ogm_packet->orig, |
100 | hard_iface->net_dev->dev_addr, ETH_ALEN); | 103 | hard_iface->net_dev->dev_addr, ETH_ALEN); |
101 | memcpy(batadv_ogm_packet->prev_sender, | 104 | memcpy(batadv_ogm_packet->prev_sender, |
@@ -106,8 +109,9 @@ static void | |||
106 | batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) | 109 | batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) |
107 | { | 110 | { |
108 | struct batadv_ogm_packet *batadv_ogm_packet; | 111 | struct batadv_ogm_packet *batadv_ogm_packet; |
112 | unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
109 | 113 | ||
110 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 114 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
111 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; | 115 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; |
112 | batadv_ogm_packet->header.ttl = BATADV_TTL; | 116 | batadv_ogm_packet->header.ttl = BATADV_TTL; |
113 | } | 117 | } |
@@ -407,9 +411,11 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, | |||
407 | 411 | ||
408 | if ((atomic_read(&bat_priv->aggregated_ogms)) && | 412 | if ((atomic_read(&bat_priv->aggregated_ogms)) && |
409 | (packet_len < BATADV_MAX_AGGREGATION_BYTES)) | 413 | (packet_len < BATADV_MAX_AGGREGATION_BYTES)) |
410 | skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN; | 414 | skb_size = BATADV_MAX_AGGREGATION_BYTES; |
411 | else | 415 | else |
412 | skb_size = packet_len + ETH_HLEN; | 416 | skb_size = packet_len; |
417 | |||
418 | skb_size += ETH_HLEN + NET_IP_ALIGN; | ||
413 | 419 | ||
414 | forw_packet_aggr->skb = dev_alloc_skb(skb_size); | 420 | forw_packet_aggr->skb = dev_alloc_skb(skb_size); |
415 | if (!forw_packet_aggr->skb) { | 421 | if (!forw_packet_aggr->skb) { |
@@ -418,7 +424,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, | |||
418 | kfree(forw_packet_aggr); | 424 | kfree(forw_packet_aggr); |
419 | goto out; | 425 | goto out; |
420 | } | 426 | } |
421 | skb_reserve(forw_packet_aggr->skb, ETH_HLEN); | 427 | skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN); |
422 | 428 | ||
423 | INIT_HLIST_NODE(&forw_packet_aggr->list); | 429 | INIT_HLIST_NODE(&forw_packet_aggr->list); |
424 | 430 | ||
@@ -590,8 +596,10 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, | |||
590 | static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | 596 | static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) |
591 | { | 597 | { |
592 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 598 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
599 | unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; | ||
593 | struct batadv_ogm_packet *batadv_ogm_packet; | 600 | struct batadv_ogm_packet *batadv_ogm_packet; |
594 | struct batadv_hard_iface *primary_if; | 601 | struct batadv_hard_iface *primary_if; |
602 | int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; | ||
595 | int vis_server, tt_num_changes = 0; | 603 | int vis_server, tt_num_changes = 0; |
596 | uint32_t seqno; | 604 | uint32_t seqno; |
597 | uint8_t bandwidth; | 605 | uint8_t bandwidth; |
@@ -600,17 +608,16 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | |||
600 | primary_if = batadv_primary_if_get_selected(bat_priv); | 608 | primary_if = batadv_primary_if_get_selected(bat_priv); |
601 | 609 | ||
602 | if (hard_iface == primary_if) | 610 | if (hard_iface == primary_if) |
603 | tt_num_changes = batadv_tt_append_diff(bat_priv, | 611 | tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff, |
604 | &hard_iface->packet_buff, | 612 | ogm_buff_len, |
605 | &hard_iface->packet_len, | ||
606 | BATADV_OGM_HLEN); | 613 | BATADV_OGM_HLEN); |
607 | 614 | ||
608 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 615 | batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff); |
609 | 616 | ||
610 | /* change sequence number to network order */ | 617 | /* change sequence number to network order */ |
611 | seqno = (uint32_t)atomic_read(&hard_iface->seqno); | 618 | seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno); |
612 | batadv_ogm_packet->seqno = htonl(seqno); | 619 | batadv_ogm_packet->seqno = htonl(seqno); |
613 | atomic_inc(&hard_iface->seqno); | 620 | atomic_inc(&hard_iface->bat_iv.ogm_seqno); |
614 | 621 | ||
615 | batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); | 622 | batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); |
616 | batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); | 623 | batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); |
@@ -631,8 +638,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | |||
631 | } | 638 | } |
632 | 639 | ||
633 | batadv_slide_own_bcast_window(hard_iface); | 640 | batadv_slide_own_bcast_window(hard_iface); |
634 | batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, | 641 | batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, |
635 | hard_iface->packet_len, hard_iface, 1, | 642 | hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, |
636 | batadv_iv_ogm_emit_send_time(bat_priv)); | 643 | batadv_iv_ogm_emit_send_time(bat_priv)); |
637 | 644 | ||
638 | if (primary_if) | 645 | if (primary_if) |
@@ -1015,7 +1022,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1015 | return; | 1022 | return; |
1016 | 1023 | ||
1017 | /* could be changed by schedule_own_packet() */ | 1024 | /* could be changed by schedule_own_packet() */ |
1018 | if_incoming_seqno = atomic_read(&if_incoming->seqno); | 1025 | if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno); |
1019 | 1026 | ||
1020 | if (batadv_ogm_packet->flags & BATADV_DIRECTLINK) | 1027 | if (batadv_ogm_packet->flags & BATADV_DIRECTLINK) |
1021 | has_directlink_flag = 1; | 1028 | has_directlink_flag = 1; |
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index aea174cdbfbd..5453b17d8df2 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c | |||
@@ -79,20 +79,17 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, | |||
79 | * or the old packet got delayed somewhere in the network. The | 79 | * or the old packet got delayed somewhere in the network. The |
80 | * packet should be dropped without calling this function if the | 80 | * packet should be dropped without calling this function if the |
81 | * seqno window is protected. | 81 | * seqno window is protected. |
82 | * | ||
83 | * seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE | ||
84 | * or | ||
85 | * seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE | ||
82 | */ | 86 | */ |
83 | if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE || | 87 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
84 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { | 88 | "Other host probably restarted!\n"); |
85 | 89 | ||
86 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 90 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); |
87 | "Other host probably restarted!\n"); | 91 | if (set_mark) |
88 | 92 | batadv_set_bit(seq_bits, 0); | |
89 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); | ||
90 | if (set_mark) | ||
91 | batadv_set_bit(seq_bits, 0); | ||
92 | |||
93 | return 1; | ||
94 | } | ||
95 | 93 | ||
96 | /* never reached */ | 94 | return 1; |
97 | return 0; | ||
98 | } | 95 | } |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index fd8d5afec0dd..29a5542aac75 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1585,23 +1585,11 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1585 | struct hlist_head *head; | 1585 | struct hlist_head *head; |
1586 | uint32_t i; | 1586 | uint32_t i; |
1587 | bool is_own; | 1587 | bool is_own; |
1588 | int ret = 0; | ||
1589 | uint8_t *primary_addr; | 1588 | uint8_t *primary_addr; |
1590 | 1589 | ||
1591 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1590 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
1592 | if (!primary_if) { | 1591 | if (!primary_if) |
1593 | ret = seq_printf(seq, | ||
1594 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
1595 | net_dev->name); | ||
1596 | goto out; | ||
1597 | } | ||
1598 | |||
1599 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
1600 | ret = seq_printf(seq, | ||
1601 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
1602 | net_dev->name); | ||
1603 | goto out; | 1592 | goto out; |
1604 | } | ||
1605 | 1593 | ||
1606 | primary_addr = primary_if->net_dev->dev_addr; | 1594 | primary_addr = primary_if->net_dev->dev_addr; |
1607 | seq_printf(seq, | 1595 | seq_printf(seq, |
@@ -1628,7 +1616,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1628 | out: | 1616 | out: |
1629 | if (primary_if) | 1617 | if (primary_if) |
1630 | batadv_hardif_free_ref(primary_if); | 1618 | batadv_hardif_free_ref(primary_if); |
1631 | return ret; | 1619 | return 0; |
1632 | } | 1620 | } |
1633 | 1621 | ||
1634 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | 1622 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) |
@@ -1643,23 +1631,11 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1643 | int secs, msecs; | 1631 | int secs, msecs; |
1644 | uint32_t i; | 1632 | uint32_t i; |
1645 | bool is_own; | 1633 | bool is_own; |
1646 | int ret = 0; | ||
1647 | uint8_t *primary_addr; | 1634 | uint8_t *primary_addr; |
1648 | 1635 | ||
1649 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1636 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
1650 | if (!primary_if) { | 1637 | if (!primary_if) |
1651 | ret = seq_printf(seq, | ||
1652 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
1653 | net_dev->name); | ||
1654 | goto out; | ||
1655 | } | ||
1656 | |||
1657 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
1658 | ret = seq_printf(seq, | ||
1659 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
1660 | net_dev->name); | ||
1661 | goto out; | 1638 | goto out; |
1662 | } | ||
1663 | 1639 | ||
1664 | primary_addr = primary_if->net_dev->dev_addr; | 1640 | primary_addr = primary_if->net_dev->dev_addr; |
1665 | seq_printf(seq, | 1641 | seq_printf(seq, |
@@ -1693,5 +1669,5 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1693 | out: | 1669 | out: |
1694 | if (primary_if) | 1670 | if (primary_if) |
1695 | batadv_hardif_free_ref(primary_if); | 1671 | batadv_hardif_free_ref(primary_if); |
1696 | return ret; | 1672 | return 0; |
1697 | } | 1673 | } |
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index 391d4fb2026f..3f679cb2d0e2 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "vis.h" | 31 | #include "vis.h" |
32 | #include "icmp_socket.h" | 32 | #include "icmp_socket.h" |
33 | #include "bridge_loop_avoidance.h" | 33 | #include "bridge_loop_avoidance.h" |
34 | #include "distributed-arp-table.h" | ||
34 | 35 | ||
35 | static struct dentry *batadv_debugfs; | 36 | static struct dentry *batadv_debugfs; |
36 | 37 | ||
@@ -99,15 +100,17 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) | |||
99 | 100 | ||
100 | static int batadv_log_open(struct inode *inode, struct file *file) | 101 | static int batadv_log_open(struct inode *inode, struct file *file) |
101 | { | 102 | { |
103 | if (!try_module_get(THIS_MODULE)) | ||
104 | return -EBUSY; | ||
105 | |||
102 | nonseekable_open(inode, file); | 106 | nonseekable_open(inode, file); |
103 | file->private_data = inode->i_private; | 107 | file->private_data = inode->i_private; |
104 | batadv_inc_module_count(); | ||
105 | return 0; | 108 | return 0; |
106 | } | 109 | } |
107 | 110 | ||
108 | static int batadv_log_release(struct inode *inode, struct file *file) | 111 | static int batadv_log_release(struct inode *inode, struct file *file) |
109 | { | 112 | { |
110 | batadv_dec_module_count(); | 113 | module_put(THIS_MODULE); |
111 | return 0; | 114 | return 0; |
112 | } | 115 | } |
113 | 116 | ||
@@ -278,6 +281,19 @@ static int batadv_bla_backbone_table_open(struct inode *inode, | |||
278 | 281 | ||
279 | #endif | 282 | #endif |
280 | 283 | ||
284 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
285 | /** | ||
286 | * batadv_dat_cache_open - Prepare file handler for reads from dat_chache | ||
287 | * @inode: inode which was opened | ||
288 | * @file: file handle to be initialized | ||
289 | */ | ||
290 | static int batadv_dat_cache_open(struct inode *inode, struct file *file) | ||
291 | { | ||
292 | struct net_device *net_dev = (struct net_device *)inode->i_private; | ||
293 | return single_open(file, batadv_dat_cache_seq_print_text, net_dev); | ||
294 | } | ||
295 | #endif | ||
296 | |||
281 | static int batadv_transtable_local_open(struct inode *inode, struct file *file) | 297 | static int batadv_transtable_local_open(struct inode *inode, struct file *file) |
282 | { | 298 | { |
283 | struct net_device *net_dev = (struct net_device *)inode->i_private; | 299 | struct net_device *net_dev = (struct net_device *)inode->i_private; |
@@ -317,6 +333,9 @@ static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); | |||
317 | static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, | 333 | static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, |
318 | batadv_bla_backbone_table_open); | 334 | batadv_bla_backbone_table_open); |
319 | #endif | 335 | #endif |
336 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
337 | static BATADV_DEBUGINFO(dat_cache, S_IRUGO, batadv_dat_cache_open); | ||
338 | #endif | ||
320 | static BATADV_DEBUGINFO(transtable_local, S_IRUGO, | 339 | static BATADV_DEBUGINFO(transtable_local, S_IRUGO, |
321 | batadv_transtable_local_open); | 340 | batadv_transtable_local_open); |
322 | static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); | 341 | static BATADV_DEBUGINFO(vis_data, S_IRUGO, batadv_vis_data_open); |
@@ -329,6 +348,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { | |||
329 | &batadv_debuginfo_bla_claim_table, | 348 | &batadv_debuginfo_bla_claim_table, |
330 | &batadv_debuginfo_bla_backbone_table, | 349 | &batadv_debuginfo_bla_backbone_table, |
331 | #endif | 350 | #endif |
351 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
352 | &batadv_debuginfo_dat_cache, | ||
353 | #endif | ||
332 | &batadv_debuginfo_transtable_local, | 354 | &batadv_debuginfo_transtable_local, |
333 | &batadv_debuginfo_vis_data, | 355 | &batadv_debuginfo_vis_data, |
334 | NULL, | 356 | NULL, |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c new file mode 100644 index 000000000000..8e1d89d2b1c1 --- /dev/null +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -0,0 +1,1066 @@ | |||
1 | /* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: | ||
2 | * | ||
3 | * Antonio Quartulli | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of version 2 of the GNU General Public | ||
7 | * License as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | * 02110-1301, USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/if_ether.h> | ||
21 | #include <linux/if_arp.h> | ||
22 | #include <net/arp.h> | ||
23 | |||
24 | #include "main.h" | ||
25 | #include "hash.h" | ||
26 | #include "distributed-arp-table.h" | ||
27 | #include "hard-interface.h" | ||
28 | #include "originator.h" | ||
29 | #include "send.h" | ||
30 | #include "types.h" | ||
31 | #include "translation-table.h" | ||
32 | #include "unicast.h" | ||
33 | |||
34 | static void batadv_dat_purge(struct work_struct *work); | ||
35 | |||
36 | /** | ||
37 | * batadv_dat_start_timer - initialise the DAT periodic worker | ||
38 | * @bat_priv: the bat priv with all the soft interface information | ||
39 | */ | ||
40 | static void batadv_dat_start_timer(struct batadv_priv *bat_priv) | ||
41 | { | ||
42 | INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); | ||
43 | queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, | ||
44 | msecs_to_jiffies(10000)); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * batadv_dat_entry_free_ref - decrements the dat_entry refcounter and possibly | ||
49 | * free it | ||
50 | * @dat_entry: the oentry to free | ||
51 | */ | ||
52 | static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry) | ||
53 | { | ||
54 | if (atomic_dec_and_test(&dat_entry->refcount)) | ||
55 | kfree_rcu(dat_entry, rcu); | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * batadv_dat_to_purge - checks whether a dat_entry has to be purged or not | ||
60 | * @dat_entry: the entry to check | ||
61 | * | ||
62 | * Returns true if the entry has to be purged now, false otherwise | ||
63 | */ | ||
64 | static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry) | ||
65 | { | ||
66 | return batadv_has_timed_out(dat_entry->last_update, | ||
67 | BATADV_DAT_ENTRY_TIMEOUT); | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * __batadv_dat_purge - delete entries from the DAT local storage | ||
72 | * @bat_priv: the bat priv with all the soft interface information | ||
73 | * @to_purge: function in charge to decide whether an entry has to be purged or | ||
74 | * not. This function takes the dat_entry as argument and has to | ||
75 | * returns a boolean value: true is the entry has to be deleted, | ||
76 | * false otherwise | ||
77 | * | ||
78 | * Loops over each entry in the DAT local storage and delete it if and only if | ||
79 | * the to_purge function passed as argument returns true | ||
80 | */ | ||
81 | static void __batadv_dat_purge(struct batadv_priv *bat_priv, | ||
82 | bool (*to_purge)(struct batadv_dat_entry *)) | ||
83 | { | ||
84 | spinlock_t *list_lock; /* protects write access to the hash lists */ | ||
85 | struct batadv_dat_entry *dat_entry; | ||
86 | struct hlist_node *node, *node_tmp; | ||
87 | struct hlist_head *head; | ||
88 | uint32_t i; | ||
89 | |||
90 | if (!bat_priv->dat.hash) | ||
91 | return; | ||
92 | |||
93 | for (i = 0; i < bat_priv->dat.hash->size; i++) { | ||
94 | head = &bat_priv->dat.hash->table[i]; | ||
95 | list_lock = &bat_priv->dat.hash->list_locks[i]; | ||
96 | |||
97 | spin_lock_bh(list_lock); | ||
98 | hlist_for_each_entry_safe(dat_entry, node, node_tmp, head, | ||
99 | hash_entry) { | ||
100 | /* if an helper function has been passed as parameter, | ||
101 | * ask it if the entry has to be purged or not | ||
102 | */ | ||
103 | if (to_purge && !to_purge(dat_entry)) | ||
104 | continue; | ||
105 | |||
106 | hlist_del_rcu(node); | ||
107 | batadv_dat_entry_free_ref(dat_entry); | ||
108 | } | ||
109 | spin_unlock_bh(list_lock); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * batadv_dat_purge - periodic task that deletes old entries from the local DAT | ||
115 | * hash table | ||
116 | * @work: kernel work struct | ||
117 | */ | ||
118 | static void batadv_dat_purge(struct work_struct *work) | ||
119 | { | ||
120 | struct delayed_work *delayed_work; | ||
121 | struct batadv_priv_dat *priv_dat; | ||
122 | struct batadv_priv *bat_priv; | ||
123 | |||
124 | delayed_work = container_of(work, struct delayed_work, work); | ||
125 | priv_dat = container_of(delayed_work, struct batadv_priv_dat, work); | ||
126 | bat_priv = container_of(priv_dat, struct batadv_priv, dat); | ||
127 | |||
128 | __batadv_dat_purge(bat_priv, batadv_dat_to_purge); | ||
129 | batadv_dat_start_timer(bat_priv); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * batadv_compare_dat - comparing function used in the local DAT hash table | ||
134 | * @node: node in the local table | ||
135 | * @data2: second object to compare the node to | ||
136 | * | ||
137 | * Returns 1 if the two entry are the same, 0 otherwise | ||
138 | */ | ||
139 | static int batadv_compare_dat(const struct hlist_node *node, const void *data2) | ||
140 | { | ||
141 | const void *data1 = container_of(node, struct batadv_dat_entry, | ||
142 | hash_entry); | ||
143 | |||
144 | return (memcmp(data1, data2, sizeof(__be32)) == 0 ? 1 : 0); | ||
145 | } | ||
146 | |||
147 | /** | ||
148 | * batadv_arp_hw_src - extract the hw_src field from an ARP packet | ||
149 | * @skb: ARP packet | ||
150 | * @hdr_size: size of the possible header before the ARP packet | ||
151 | * | ||
152 | * Returns the value of the hw_src field in the ARP packet | ||
153 | */ | ||
154 | static uint8_t *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size) | ||
155 | { | ||
156 | uint8_t *addr; | ||
157 | |||
158 | addr = (uint8_t *)(skb->data + hdr_size); | ||
159 | addr += ETH_HLEN + sizeof(struct arphdr); | ||
160 | |||
161 | return addr; | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * batadv_arp_ip_src - extract the ip_src field from an ARP packet | ||
166 | * @skb: ARP packet | ||
167 | * @hdr_size: size of the possible header before the ARP packet | ||
168 | * | ||
169 | * Returns the value of the ip_src field in the ARP packet | ||
170 | */ | ||
171 | static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size) | ||
172 | { | ||
173 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN); | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * batadv_arp_hw_dst - extract the hw_dst field from an ARP packet | ||
178 | * @skb: ARP packet | ||
179 | * @hdr_size: size of the possible header before the ARP packet | ||
180 | * | ||
181 | * Returns the value of the hw_dst field in the ARP packet | ||
182 | */ | ||
183 | static uint8_t *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size) | ||
184 | { | ||
185 | return batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN + 4; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * batadv_arp_ip_dst - extract the ip_dst field from an ARP packet | ||
190 | * @skb: ARP packet | ||
191 | * @hdr_size: size of the possible header before the ARP packet | ||
192 | * | ||
193 | * Returns the value of the ip_dst field in the ARP packet | ||
194 | */ | ||
195 | static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size) | ||
196 | { | ||
197 | return *(__be32 *)(batadv_arp_hw_src(skb, hdr_size) + ETH_ALEN * 2 + 4); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * batadv_hash_dat - compute the hash value for an IP address | ||
202 | * @data: data to hash | ||
203 | * @size: size of the hash table | ||
204 | * | ||
205 | * Returns the selected index in the hash table for the given data | ||
206 | */ | ||
207 | static uint32_t batadv_hash_dat(const void *data, uint32_t size) | ||
208 | { | ||
209 | const unsigned char *key = data; | ||
210 | uint32_t hash = 0; | ||
211 | size_t i; | ||
212 | |||
213 | for (i = 0; i < 4; i++) { | ||
214 | hash += key[i]; | ||
215 | hash += (hash << 10); | ||
216 | hash ^= (hash >> 6); | ||
217 | } | ||
218 | |||
219 | hash += (hash << 3); | ||
220 | hash ^= (hash >> 11); | ||
221 | hash += (hash << 15); | ||
222 | |||
223 | return hash % size; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * batadv_dat_entry_hash_find - looks for a given dat_entry in the local hash | ||
228 | * table | ||
229 | * @bat_priv: the bat priv with all the soft interface information | ||
230 | * @ip: search key | ||
231 | * | ||
232 | * Returns the dat_entry if found, NULL otherwise | ||
233 | */ | ||
234 | static struct batadv_dat_entry * | ||
235 | batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip) | ||
236 | { | ||
237 | struct hlist_head *head; | ||
238 | struct hlist_node *node; | ||
239 | struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL; | ||
240 | struct batadv_hashtable *hash = bat_priv->dat.hash; | ||
241 | uint32_t index; | ||
242 | |||
243 | if (!hash) | ||
244 | return NULL; | ||
245 | |||
246 | index = batadv_hash_dat(&ip, hash->size); | ||
247 | head = &hash->table[index]; | ||
248 | |||
249 | rcu_read_lock(); | ||
250 | hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) { | ||
251 | if (dat_entry->ip != ip) | ||
252 | continue; | ||
253 | |||
254 | if (!atomic_inc_not_zero(&dat_entry->refcount)) | ||
255 | continue; | ||
256 | |||
257 | dat_entry_tmp = dat_entry; | ||
258 | break; | ||
259 | } | ||
260 | rcu_read_unlock(); | ||
261 | |||
262 | return dat_entry_tmp; | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * batadv_dat_entry_add - add a new dat entry or update it if already exists | ||
267 | * @bat_priv: the bat priv with all the soft interface information | ||
268 | * @ip: ipv4 to add/edit | ||
269 | * @mac_addr: mac address to assign to the given ipv4 | ||
270 | */ | ||
271 | static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, | ||
272 | uint8_t *mac_addr) | ||
273 | { | ||
274 | struct batadv_dat_entry *dat_entry; | ||
275 | int hash_added; | ||
276 | |||
277 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip); | ||
278 | /* if this entry is already known, just update it */ | ||
279 | if (dat_entry) { | ||
280 | if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) | ||
281 | memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); | ||
282 | dat_entry->last_update = jiffies; | ||
283 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
284 | "Entry updated: %pI4 %pM\n", &dat_entry->ip, | ||
285 | dat_entry->mac_addr); | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC); | ||
290 | if (!dat_entry) | ||
291 | goto out; | ||
292 | |||
293 | dat_entry->ip = ip; | ||
294 | memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN); | ||
295 | dat_entry->last_update = jiffies; | ||
296 | atomic_set(&dat_entry->refcount, 2); | ||
297 | |||
298 | hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, | ||
299 | batadv_hash_dat, &dat_entry->ip, | ||
300 | &dat_entry->hash_entry); | ||
301 | |||
302 | if (unlikely(hash_added != 0)) { | ||
303 | /* remove the reference for the hash */ | ||
304 | batadv_dat_entry_free_ref(dat_entry); | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n", | ||
309 | &dat_entry->ip, dat_entry->mac_addr); | ||
310 | |||
311 | out: | ||
312 | if (dat_entry) | ||
313 | batadv_dat_entry_free_ref(dat_entry); | ||
314 | } | ||
315 | |||
316 | #ifdef CONFIG_BATMAN_ADV_DEBUG | ||
317 | |||
318 | /** | ||
319 | * batadv_dbg_arp - print a debug message containing all the ARP packet details | ||
320 | * @bat_priv: the bat priv with all the soft interface information | ||
321 | * @skb: ARP packet | ||
322 | * @type: ARP type | ||
323 | * @hdr_size: size of the possible header before the ARP packet | ||
324 | * @msg: message to print together with the debugging information | ||
325 | */ | ||
326 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | ||
327 | uint16_t type, int hdr_size, char *msg) | ||
328 | { | ||
329 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; | ||
330 | struct batadv_bcast_packet *bcast_pkt; | ||
331 | uint8_t *orig_addr; | ||
332 | __be32 ip_src, ip_dst; | ||
333 | |||
334 | if (msg) | ||
335 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "%s\n", msg); | ||
336 | |||
337 | ip_src = batadv_arp_ip_src(skb, hdr_size); | ||
338 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | ||
339 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
340 | "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", | ||
341 | batadv_arp_hw_src(skb, hdr_size), &ip_src, | ||
342 | batadv_arp_hw_dst(skb, hdr_size), &ip_dst); | ||
343 | |||
344 | if (hdr_size == 0) | ||
345 | return; | ||
346 | |||
347 | /* if the ARP packet is encapsulated in a batman packet, let's print | ||
348 | * some debug messages | ||
349 | */ | ||
350 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | ||
351 | |||
352 | switch (unicast_4addr_packet->u.header.packet_type) { | ||
353 | case BATADV_UNICAST: | ||
354 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
355 | "* encapsulated within a UNICAST packet\n"); | ||
356 | break; | ||
357 | case BATADV_UNICAST_4ADDR: | ||
358 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
359 | "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n", | ||
360 | unicast_4addr_packet->src); | ||
361 | switch (unicast_4addr_packet->subtype) { | ||
362 | case BATADV_P_DAT_DHT_PUT: | ||
363 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_PUT\n"); | ||
364 | break; | ||
365 | case BATADV_P_DAT_DHT_GET: | ||
366 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DAT_DHT_GET\n"); | ||
367 | break; | ||
368 | case BATADV_P_DAT_CACHE_REPLY: | ||
369 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
370 | "* type: DAT_CACHE_REPLY\n"); | ||
371 | break; | ||
372 | case BATADV_P_DATA: | ||
373 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: DATA\n"); | ||
374 | break; | ||
375 | default: | ||
376 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n", | ||
377 | unicast_4addr_packet->u.header.packet_type); | ||
378 | } | ||
379 | break; | ||
380 | case BATADV_BCAST: | ||
381 | bcast_pkt = (struct batadv_bcast_packet *)unicast_4addr_packet; | ||
382 | orig_addr = bcast_pkt->orig; | ||
383 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
384 | "* encapsulated within a BCAST packet (src: %pM)\n", | ||
385 | orig_addr); | ||
386 | break; | ||
387 | default: | ||
388 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
389 | "* encapsulated within an unknown packet type (0x%x)\n", | ||
390 | unicast_4addr_packet->u.header.packet_type); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | #else | ||
395 | |||
396 | static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, | ||
397 | uint16_t type, int hdr_size, char *msg) | ||
398 | { | ||
399 | } | ||
400 | |||
401 | #endif /* CONFIG_BATMAN_ADV_DEBUG */ | ||
402 | |||
403 | /** | ||
404 | * batadv_is_orig_node_eligible - check whether a node can be a DHT candidate | ||
405 | * @res: the array with the already selected candidates | ||
406 | * @select: number of already selected candidates | ||
407 | * @tmp_max: address of the currently evaluated node | ||
408 | * @max: current round max address | ||
409 | * @last_max: address of the last selected candidate | ||
410 | * @candidate: orig_node under evaluation | ||
411 | * @max_orig_node: last selected candidate | ||
412 | * | ||
413 | * Returns true if the node has been elected as next candidate or false othrwise | ||
414 | */ | ||
415 | static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res, | ||
416 | int select, batadv_dat_addr_t tmp_max, | ||
417 | batadv_dat_addr_t max, | ||
418 | batadv_dat_addr_t last_max, | ||
419 | struct batadv_orig_node *candidate, | ||
420 | struct batadv_orig_node *max_orig_node) | ||
421 | { | ||
422 | bool ret = false; | ||
423 | int j; | ||
424 | |||
425 | /* Check if this node has already been selected... */ | ||
426 | for (j = 0; j < select; j++) | ||
427 | if (res[j].orig_node == candidate) | ||
428 | break; | ||
429 | /* ..and possibly skip it */ | ||
430 | if (j < select) | ||
431 | goto out; | ||
432 | /* sanity check: has it already been selected? This should not happen */ | ||
433 | if (tmp_max > last_max) | ||
434 | goto out; | ||
435 | /* check if during this iteration an originator with a closer dht | ||
436 | * address has already been found | ||
437 | */ | ||
438 | if (tmp_max < max) | ||
439 | goto out; | ||
440 | /* this is an hash collision with the temporary selected node. Choose | ||
441 | * the one with the lowest address | ||
442 | */ | ||
443 | if ((tmp_max == max) && | ||
444 | (batadv_compare_eth(candidate->orig, max_orig_node->orig) > 0)) | ||
445 | goto out; | ||
446 | |||
447 | ret = true; | ||
448 | out: | ||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * batadv_choose_next_candidate - select the next DHT candidate | ||
454 | * @bat_priv: the bat priv with all the soft interface information | ||
455 | * @cands: candidates array | ||
456 | * @select: number of candidates already present in the array | ||
457 | * @ip_key: key to look up in the DHT | ||
458 | * @last_max: pointer where the address of the selected candidate will be saved | ||
459 | */ | ||
460 | static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, | ||
461 | struct batadv_dat_candidate *cands, | ||
462 | int select, batadv_dat_addr_t ip_key, | ||
463 | batadv_dat_addr_t *last_max) | ||
464 | { | ||
465 | batadv_dat_addr_t max = 0, tmp_max = 0; | ||
466 | struct batadv_orig_node *orig_node, *max_orig_node = NULL; | ||
467 | struct batadv_hashtable *hash = bat_priv->orig_hash; | ||
468 | struct hlist_node *node; | ||
469 | struct hlist_head *head; | ||
470 | int i; | ||
471 | |||
472 | /* if no node is eligible as candidate, leave the candidate type as | ||
473 | * NOT_FOUND | ||
474 | */ | ||
475 | cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND; | ||
476 | |||
477 | /* iterate over the originator list and find the node with closest | ||
478 | * dat_address which has not been selected yet | ||
479 | */ | ||
480 | for (i = 0; i < hash->size; i++) { | ||
481 | head = &hash->table[i]; | ||
482 | |||
483 | rcu_read_lock(); | ||
484 | hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { | ||
485 | /* the dht space is a ring and addresses are unsigned */ | ||
486 | tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + | ||
487 | ip_key; | ||
488 | |||
489 | if (!batadv_is_orig_node_eligible(cands, select, | ||
490 | tmp_max, max, | ||
491 | *last_max, orig_node, | ||
492 | max_orig_node)) | ||
493 | continue; | ||
494 | |||
495 | if (!atomic_inc_not_zero(&orig_node->refcount)) | ||
496 | continue; | ||
497 | |||
498 | max = tmp_max; | ||
499 | if (max_orig_node) | ||
500 | batadv_orig_node_free_ref(max_orig_node); | ||
501 | max_orig_node = orig_node; | ||
502 | } | ||
503 | rcu_read_unlock(); | ||
504 | } | ||
505 | if (max_orig_node) { | ||
506 | cands[select].type = BATADV_DAT_CANDIDATE_ORIG; | ||
507 | cands[select].orig_node = max_orig_node; | ||
508 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
509 | "dat_select_candidates() %d: selected %pM addr=%u dist=%u\n", | ||
510 | select, max_orig_node->orig, max_orig_node->dat_addr, | ||
511 | max); | ||
512 | } | ||
513 | *last_max = max; | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * batadv_dat_select_candidates - selects the nodes which the DHT message has to | ||
518 | * be sent to | ||
519 | * @bat_priv: the bat priv with all the soft interface information | ||
520 | * @ip_dst: ipv4 to look up in the DHT | ||
521 | * | ||
522 | * An originator O is selected if and only if its DHT_ID value is one of three | ||
523 | * closest values (from the LEFT, with wrap around if needed) then the hash | ||
524 | * value of the key. ip_dst is the key. | ||
525 | * | ||
526 | * Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM | ||
527 | */ | ||
528 | static struct batadv_dat_candidate * | ||
529 | batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) | ||
530 | { | ||
531 | int select; | ||
532 | batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; | ||
533 | struct batadv_dat_candidate *res; | ||
534 | |||
535 | if (!bat_priv->orig_hash) | ||
536 | return NULL; | ||
537 | |||
538 | res = kmalloc(BATADV_DAT_CANDIDATES_NUM * sizeof(*res), GFP_ATOMIC); | ||
539 | if (!res) | ||
540 | return NULL; | ||
541 | |||
542 | ip_key = (batadv_dat_addr_t)batadv_hash_dat(&ip_dst, | ||
543 | BATADV_DAT_ADDR_MAX); | ||
544 | |||
545 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
546 | "dat_select_candidates(): IP=%pI4 hash(IP)=%u\n", &ip_dst, | ||
547 | ip_key); | ||
548 | |||
549 | for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++) | ||
550 | batadv_choose_next_candidate(bat_priv, res, select, ip_key, | ||
551 | &last_max); | ||
552 | |||
553 | return res; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * batadv_dat_send_data - send a payload to the selected candidates | ||
558 | * @bat_priv: the bat priv with all the soft interface information | ||
559 | * @skb: payload to send | ||
560 | * @ip: the DHT key | ||
561 | * @packet_subtype: unicast4addr packet subtype to use | ||
562 | * | ||
563 | * In this function the skb is copied by means of pskb_copy() and is sent as | ||
564 | * unicast packet to each of the selected candidates | ||
565 | * | ||
566 | * Returns true if the packet is sent to at least one candidate, false otherwise | ||
567 | */ | ||
568 | static bool batadv_dat_send_data(struct batadv_priv *bat_priv, | ||
569 | struct sk_buff *skb, __be32 ip, | ||
570 | int packet_subtype) | ||
571 | { | ||
572 | int i; | ||
573 | bool ret = false; | ||
574 | int send_status; | ||
575 | struct batadv_neigh_node *neigh_node = NULL; | ||
576 | struct sk_buff *tmp_skb; | ||
577 | struct batadv_dat_candidate *cand; | ||
578 | |||
579 | cand = batadv_dat_select_candidates(bat_priv, ip); | ||
580 | if (!cand) | ||
581 | goto out; | ||
582 | |||
583 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "DHT_SEND for %pI4\n", &ip); | ||
584 | |||
585 | for (i = 0; i < BATADV_DAT_CANDIDATES_NUM; i++) { | ||
586 | if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND) | ||
587 | continue; | ||
588 | |||
589 | neigh_node = batadv_orig_node_get_router(cand[i].orig_node); | ||
590 | if (!neigh_node) | ||
591 | goto free_orig; | ||
592 | |||
593 | tmp_skb = pskb_copy(skb, GFP_ATOMIC); | ||
594 | if (!batadv_unicast_4addr_prepare_skb(bat_priv, tmp_skb, | ||
595 | cand[i].orig_node, | ||
596 | packet_subtype)) { | ||
597 | kfree_skb(tmp_skb); | ||
598 | goto free_neigh; | ||
599 | } | ||
600 | |||
601 | send_status = batadv_send_skb_packet(tmp_skb, | ||
602 | neigh_node->if_incoming, | ||
603 | neigh_node->addr); | ||
604 | if (send_status == NET_XMIT_SUCCESS) { | ||
605 | /* count the sent packet */ | ||
606 | switch (packet_subtype) { | ||
607 | case BATADV_P_DAT_DHT_GET: | ||
608 | batadv_inc_counter(bat_priv, | ||
609 | BATADV_CNT_DAT_GET_TX); | ||
610 | break; | ||
611 | case BATADV_P_DAT_DHT_PUT: | ||
612 | batadv_inc_counter(bat_priv, | ||
613 | BATADV_CNT_DAT_PUT_TX); | ||
614 | break; | ||
615 | } | ||
616 | |||
617 | /* packet sent to a candidate: return true */ | ||
618 | ret = true; | ||
619 | } | ||
620 | free_neigh: | ||
621 | batadv_neigh_node_free_ref(neigh_node); | ||
622 | free_orig: | ||
623 | batadv_orig_node_free_ref(cand[i].orig_node); | ||
624 | } | ||
625 | |||
626 | out: | ||
627 | kfree(cand); | ||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * batadv_dat_hash_free - free the local DAT hash table | ||
633 | * @bat_priv: the bat priv with all the soft interface information | ||
634 | */ | ||
635 | static void batadv_dat_hash_free(struct batadv_priv *bat_priv) | ||
636 | { | ||
637 | if (!bat_priv->dat.hash) | ||
638 | return; | ||
639 | |||
640 | __batadv_dat_purge(bat_priv, NULL); | ||
641 | |||
642 | batadv_hash_destroy(bat_priv->dat.hash); | ||
643 | |||
644 | bat_priv->dat.hash = NULL; | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * batadv_dat_init - initialise the DAT internals | ||
649 | * @bat_priv: the bat priv with all the soft interface information | ||
650 | */ | ||
651 | int batadv_dat_init(struct batadv_priv *bat_priv) | ||
652 | { | ||
653 | if (bat_priv->dat.hash) | ||
654 | return 0; | ||
655 | |||
656 | bat_priv->dat.hash = batadv_hash_new(1024); | ||
657 | |||
658 | if (!bat_priv->dat.hash) | ||
659 | return -ENOMEM; | ||
660 | |||
661 | batadv_dat_start_timer(bat_priv); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | /** | ||
667 | * batadv_dat_free - free the DAT internals | ||
668 | * @bat_priv: the bat priv with all the soft interface information | ||
669 | */ | ||
670 | void batadv_dat_free(struct batadv_priv *bat_priv) | ||
671 | { | ||
672 | cancel_delayed_work_sync(&bat_priv->dat.work); | ||
673 | |||
674 | batadv_dat_hash_free(bat_priv); | ||
675 | } | ||
676 | |||
677 | /** | ||
678 | * batadv_dat_cache_seq_print_text - print the local DAT hash table | ||
679 | * @seq: seq file to print on | ||
680 | * @offset: not used | ||
681 | */ | ||
682 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset) | ||
683 | { | ||
684 | struct net_device *net_dev = (struct net_device *)seq->private; | ||
685 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | ||
686 | struct batadv_hashtable *hash = bat_priv->dat.hash; | ||
687 | struct batadv_dat_entry *dat_entry; | ||
688 | struct batadv_hard_iface *primary_if; | ||
689 | struct hlist_node *node; | ||
690 | struct hlist_head *head; | ||
691 | unsigned long last_seen_jiffies; | ||
692 | int last_seen_msecs, last_seen_secs, last_seen_mins; | ||
693 | uint32_t i; | ||
694 | |||
695 | primary_if = batadv_seq_print_text_primary_if_get(seq); | ||
696 | if (!primary_if) | ||
697 | goto out; | ||
698 | |||
699 | seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); | ||
700 | seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC", | ||
701 | "last-seen"); | ||
702 | |||
703 | for (i = 0; i < hash->size; i++) { | ||
704 | head = &hash->table[i]; | ||
705 | |||
706 | rcu_read_lock(); | ||
707 | hlist_for_each_entry_rcu(dat_entry, node, head, hash_entry) { | ||
708 | last_seen_jiffies = jiffies - dat_entry->last_update; | ||
709 | last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); | ||
710 | last_seen_mins = last_seen_msecs / 60000; | ||
711 | last_seen_msecs = last_seen_msecs % 60000; | ||
712 | last_seen_secs = last_seen_msecs / 1000; | ||
713 | |||
714 | seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n", | ||
715 | &dat_entry->ip, dat_entry->mac_addr, | ||
716 | last_seen_mins, last_seen_secs); | ||
717 | } | ||
718 | rcu_read_unlock(); | ||
719 | } | ||
720 | |||
721 | out: | ||
722 | if (primary_if) | ||
723 | batadv_hardif_free_ref(primary_if); | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | /** | ||
728 | * batadv_arp_get_type - parse an ARP packet and gets the type | ||
729 | * @bat_priv: the bat priv with all the soft interface information | ||
730 | * @skb: packet to analyse | ||
731 | * @hdr_size: size of the possible header before the ARP packet in the skb | ||
732 | * | ||
733 | * Returns the ARP type if the skb contains a valid ARP packet, 0 otherwise | ||
734 | */ | ||
735 | static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv, | ||
736 | struct sk_buff *skb, int hdr_size) | ||
737 | { | ||
738 | struct arphdr *arphdr; | ||
739 | struct ethhdr *ethhdr; | ||
740 | __be32 ip_src, ip_dst; | ||
741 | uint16_t type = 0; | ||
742 | |||
743 | /* pull the ethernet header */ | ||
744 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN))) | ||
745 | goto out; | ||
746 | |||
747 | ethhdr = (struct ethhdr *)(skb->data + hdr_size); | ||
748 | |||
749 | if (ethhdr->h_proto != htons(ETH_P_ARP)) | ||
750 | goto out; | ||
751 | |||
752 | /* pull the ARP payload */ | ||
753 | if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN + | ||
754 | arp_hdr_len(skb->dev)))) | ||
755 | goto out; | ||
756 | |||
757 | arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); | ||
758 | |||
759 | /* Check whether the ARP packet carries a valid | ||
760 | * IP information | ||
761 | */ | ||
762 | if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) | ||
763 | goto out; | ||
764 | |||
765 | if (arphdr->ar_pro != htons(ETH_P_IP)) | ||
766 | goto out; | ||
767 | |||
768 | if (arphdr->ar_hln != ETH_ALEN) | ||
769 | goto out; | ||
770 | |||
771 | if (arphdr->ar_pln != 4) | ||
772 | goto out; | ||
773 | |||
774 | /* Check for bad reply/request. If the ARP message is not sane, DAT | ||
775 | * will simply ignore it | ||
776 | */ | ||
777 | ip_src = batadv_arp_ip_src(skb, hdr_size); | ||
778 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | ||
779 | if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) || | ||
780 | ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst)) | ||
781 | goto out; | ||
782 | |||
783 | type = ntohs(arphdr->ar_op); | ||
784 | out: | ||
785 | return type; | ||
786 | } | ||
787 | |||
788 | /** | ||
789 | * batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to | ||
790 | * answer using DAT | ||
791 | * @bat_priv: the bat priv with all the soft interface information | ||
792 | * @skb: packet to check | ||
793 | * | ||
794 | * Returns true if the message has been sent to the dht candidates, false | ||
795 | * otherwise. In case of true the message has to be enqueued to permit the | ||
796 | * fallback | ||
797 | */ | ||
798 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | ||
799 | struct sk_buff *skb) | ||
800 | { | ||
801 | uint16_t type = 0; | ||
802 | __be32 ip_dst, ip_src; | ||
803 | uint8_t *hw_src; | ||
804 | bool ret = false; | ||
805 | struct batadv_dat_entry *dat_entry = NULL; | ||
806 | struct sk_buff *skb_new; | ||
807 | struct batadv_hard_iface *primary_if = NULL; | ||
808 | |||
809 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
810 | goto out; | ||
811 | |||
812 | type = batadv_arp_get_type(bat_priv, skb, 0); | ||
813 | /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast | ||
814 | * message to the selected DHT candidates | ||
815 | */ | ||
816 | if (type != ARPOP_REQUEST) | ||
817 | goto out; | ||
818 | |||
819 | batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REQUEST"); | ||
820 | |||
821 | ip_src = batadv_arp_ip_src(skb, 0); | ||
822 | hw_src = batadv_arp_hw_src(skb, 0); | ||
823 | ip_dst = batadv_arp_ip_dst(skb, 0); | ||
824 | |||
825 | batadv_dat_entry_add(bat_priv, ip_src, hw_src); | ||
826 | |||
827 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); | ||
828 | if (dat_entry) { | ||
829 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
830 | if (!primary_if) | ||
831 | goto out; | ||
832 | |||
833 | skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, | ||
834 | primary_if->soft_iface, ip_dst, hw_src, | ||
835 | dat_entry->mac_addr, hw_src); | ||
836 | if (!skb_new) | ||
837 | goto out; | ||
838 | |||
839 | skb_reset_mac_header(skb_new); | ||
840 | skb_new->protocol = eth_type_trans(skb_new, | ||
841 | primary_if->soft_iface); | ||
842 | bat_priv->stats.rx_packets++; | ||
843 | bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; | ||
844 | primary_if->soft_iface->last_rx = jiffies; | ||
845 | |||
846 | netif_rx(skb_new); | ||
847 | batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n"); | ||
848 | ret = true; | ||
849 | } else { | ||
850 | /* Send the request on the DHT */ | ||
851 | ret = batadv_dat_send_data(bat_priv, skb, ip_dst, | ||
852 | BATADV_P_DAT_DHT_GET); | ||
853 | } | ||
854 | out: | ||
855 | if (dat_entry) | ||
856 | batadv_dat_entry_free_ref(dat_entry); | ||
857 | if (primary_if) | ||
858 | batadv_hardif_free_ref(primary_if); | ||
859 | return ret; | ||
860 | } | ||
861 | |||
862 | /** | ||
863 | * batadv_dat_snoop_incoming_arp_request - snoop the ARP request and try to | ||
864 | * answer using the local DAT storage | ||
865 | * @bat_priv: the bat priv with all the soft interface information | ||
866 | * @skb: packet to check | ||
867 | * @hdr_size: size of the encapsulation header | ||
868 | * | ||
869 | * Returns true if the request has been answered, false otherwise | ||
870 | */ | ||
871 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | ||
872 | struct sk_buff *skb, int hdr_size) | ||
873 | { | ||
874 | uint16_t type; | ||
875 | __be32 ip_src, ip_dst; | ||
876 | uint8_t *hw_src; | ||
877 | struct sk_buff *skb_new; | ||
878 | struct batadv_hard_iface *primary_if = NULL; | ||
879 | struct batadv_dat_entry *dat_entry = NULL; | ||
880 | bool ret = false; | ||
881 | int err; | ||
882 | |||
883 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
884 | goto out; | ||
885 | |||
886 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | ||
887 | if (type != ARPOP_REQUEST) | ||
888 | goto out; | ||
889 | |||
890 | hw_src = batadv_arp_hw_src(skb, hdr_size); | ||
891 | ip_src = batadv_arp_ip_src(skb, hdr_size); | ||
892 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | ||
893 | |||
894 | batadv_dbg_arp(bat_priv, skb, type, hdr_size, | ||
895 | "Parsing incoming ARP REQUEST"); | ||
896 | |||
897 | batadv_dat_entry_add(bat_priv, ip_src, hw_src); | ||
898 | |||
899 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); | ||
900 | if (!dat_entry) | ||
901 | goto out; | ||
902 | |||
903 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
904 | if (!primary_if) | ||
905 | goto out; | ||
906 | |||
907 | skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, | ||
908 | primary_if->soft_iface, ip_dst, hw_src, | ||
909 | dat_entry->mac_addr, hw_src); | ||
910 | |||
911 | if (!skb_new) | ||
912 | goto out; | ||
913 | |||
914 | /* to preserve backwards compatibility, here the node has to answer | ||
915 | * using the same packet type it received for the request. This is due | ||
916 | * to that if a node is not using the 4addr packet format it may not | ||
917 | * support it. | ||
918 | */ | ||
919 | if (hdr_size == sizeof(struct batadv_unicast_4addr_packet)) | ||
920 | err = batadv_unicast_4addr_send_skb(bat_priv, skb_new, | ||
921 | BATADV_P_DAT_CACHE_REPLY); | ||
922 | else | ||
923 | err = batadv_unicast_send_skb(bat_priv, skb_new); | ||
924 | |||
925 | if (!err) { | ||
926 | batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX); | ||
927 | ret = true; | ||
928 | } | ||
929 | out: | ||
930 | if (dat_entry) | ||
931 | batadv_dat_entry_free_ref(dat_entry); | ||
932 | if (primary_if) | ||
933 | batadv_hardif_free_ref(primary_if); | ||
934 | if (ret) | ||
935 | kfree_skb(skb); | ||
936 | return ret; | ||
937 | } | ||
938 | |||
939 | /** | ||
940 | * batadv_dat_snoop_outgoing_arp_reply - snoop the ARP reply and fill the DHT | ||
941 | * @bat_priv: the bat priv with all the soft interface information | ||
942 | * @skb: packet to check | ||
943 | */ | ||
944 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | ||
945 | struct sk_buff *skb) | ||
946 | { | ||
947 | uint16_t type; | ||
948 | __be32 ip_src, ip_dst; | ||
949 | uint8_t *hw_src, *hw_dst; | ||
950 | |||
951 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
952 | return; | ||
953 | |||
954 | type = batadv_arp_get_type(bat_priv, skb, 0); | ||
955 | if (type != ARPOP_REPLY) | ||
956 | return; | ||
957 | |||
958 | batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REPLY"); | ||
959 | |||
960 | hw_src = batadv_arp_hw_src(skb, 0); | ||
961 | ip_src = batadv_arp_ip_src(skb, 0); | ||
962 | hw_dst = batadv_arp_hw_dst(skb, 0); | ||
963 | ip_dst = batadv_arp_ip_dst(skb, 0); | ||
964 | |||
965 | batadv_dat_entry_add(bat_priv, ip_src, hw_src); | ||
966 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); | ||
967 | |||
968 | /* Send the ARP reply to the candidates for both the IP addresses that | ||
969 | * the node got within the ARP reply | ||
970 | */ | ||
971 | batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); | ||
972 | batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); | ||
973 | } | ||
974 | /** | ||
975 | * batadv_dat_snoop_incoming_arp_reply - snoop the ARP reply and fill the local | ||
976 | * DAT storage only | ||
977 | * @bat_priv: the bat priv with all the soft interface information | ||
978 | * @skb: packet to check | ||
979 | * @hdr_size: siaze of the encapsulation header | ||
980 | */ | ||
981 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | ||
982 | struct sk_buff *skb, int hdr_size) | ||
983 | { | ||
984 | uint16_t type; | ||
985 | __be32 ip_src, ip_dst; | ||
986 | uint8_t *hw_src, *hw_dst; | ||
987 | bool ret = false; | ||
988 | |||
989 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
990 | goto out; | ||
991 | |||
992 | type = batadv_arp_get_type(bat_priv, skb, hdr_size); | ||
993 | if (type != ARPOP_REPLY) | ||
994 | goto out; | ||
995 | |||
996 | batadv_dbg_arp(bat_priv, skb, type, hdr_size, | ||
997 | "Parsing incoming ARP REPLY"); | ||
998 | |||
999 | hw_src = batadv_arp_hw_src(skb, hdr_size); | ||
1000 | ip_src = batadv_arp_ip_src(skb, hdr_size); | ||
1001 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); | ||
1002 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | ||
1003 | |||
1004 | /* Update our internal cache with both the IP addresses the node got | ||
1005 | * within the ARP reply | ||
1006 | */ | ||
1007 | batadv_dat_entry_add(bat_priv, ip_src, hw_src); | ||
1008 | batadv_dat_entry_add(bat_priv, ip_dst, hw_dst); | ||
1009 | |||
1010 | /* if this REPLY is directed to a client of mine, let's deliver the | ||
1011 | * packet to the interface | ||
1012 | */ | ||
1013 | ret = !batadv_is_my_client(bat_priv, hw_dst); | ||
1014 | out: | ||
1015 | /* if ret == false -> packet has to be delivered to the interface */ | ||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
1019 | /** | ||
1020 | * batadv_dat_drop_broadcast_packet - check if an ARP request has to be dropped | ||
1021 | * (because the node has already got the reply via DAT) or not | ||
1022 | * @bat_priv: the bat priv with all the soft interface information | ||
1023 | * @forw_packet: the broadcast packet | ||
1024 | * | ||
1025 | * Returns true if the node can drop the packet, false otherwise | ||
1026 | */ | ||
1027 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | ||
1028 | struct batadv_forw_packet *forw_packet) | ||
1029 | { | ||
1030 | uint16_t type; | ||
1031 | __be32 ip_dst; | ||
1032 | struct batadv_dat_entry *dat_entry = NULL; | ||
1033 | bool ret = false; | ||
1034 | const size_t bcast_len = sizeof(struct batadv_bcast_packet); | ||
1035 | |||
1036 | if (!atomic_read(&bat_priv->distributed_arp_table)) | ||
1037 | goto out; | ||
1038 | |||
1039 | /* If this packet is an ARP_REQUEST and the node already has the | ||
1040 | * information that it is going to ask, then the packet can be dropped | ||
1041 | */ | ||
1042 | if (forw_packet->num_packets) | ||
1043 | goto out; | ||
1044 | |||
1045 | type = batadv_arp_get_type(bat_priv, forw_packet->skb, bcast_len); | ||
1046 | if (type != ARPOP_REQUEST) | ||
1047 | goto out; | ||
1048 | |||
1049 | ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len); | ||
1050 | dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); | ||
1051 | /* check if the node already got this entry */ | ||
1052 | if (!dat_entry) { | ||
1053 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1054 | "ARP Request for %pI4: fallback\n", &ip_dst); | ||
1055 | goto out; | ||
1056 | } | ||
1057 | |||
1058 | batadv_dbg(BATADV_DBG_DAT, bat_priv, | ||
1059 | "ARP Request for %pI4: fallback prevented\n", &ip_dst); | ||
1060 | ret = true; | ||
1061 | |||
1062 | out: | ||
1063 | if (dat_entry) | ||
1064 | batadv_dat_entry_free_ref(dat_entry); | ||
1065 | return ret; | ||
1066 | } | ||
diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h new file mode 100644 index 000000000000..d060c033e7de --- /dev/null +++ b/net/batman-adv/distributed-arp-table.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* Copyright (C) 2011-2012 B.A.T.M.A.N. contributors: | ||
2 | * | ||
3 | * Antonio Quartulli | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of version 2 of the GNU General Public | ||
7 | * License as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | * 02110-1301, USA | ||
18 | */ | ||
19 | |||
20 | #ifndef _NET_BATMAN_ADV_ARP_H_ | ||
21 | #define _NET_BATMAN_ADV_ARP_H_ | ||
22 | |||
23 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
24 | |||
25 | #include "types.h" | ||
26 | #include "originator.h" | ||
27 | |||
28 | #include <linux/if_arp.h> | ||
29 | |||
30 | #define BATADV_DAT_ADDR_MAX ((batadv_dat_addr_t)~(batadv_dat_addr_t)0) | ||
31 | |||
32 | bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | ||
33 | struct sk_buff *skb); | ||
34 | bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | ||
35 | struct sk_buff *skb, int hdr_size); | ||
36 | void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | ||
37 | struct sk_buff *skb); | ||
38 | bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | ||
39 | struct sk_buff *skb, int hdr_size); | ||
40 | bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | ||
41 | struct batadv_forw_packet *forw_packet); | ||
42 | |||
43 | /** | ||
44 | * batadv_dat_init_orig_node_addr - assign a DAT address to the orig_node | ||
45 | * @orig_node: the node to assign the DAT address to | ||
46 | */ | ||
47 | static inline void | ||
48 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) | ||
49 | { | ||
50 | uint32_t addr; | ||
51 | |||
52 | addr = batadv_choose_orig(orig_node->orig, BATADV_DAT_ADDR_MAX); | ||
53 | orig_node->dat_addr = (batadv_dat_addr_t)addr; | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * batadv_dat_init_own_addr - assign a DAT address to the node itself | ||
58 | * @bat_priv: the bat priv with all the soft interface information | ||
59 | * @primary_if: a pointer to the primary interface | ||
60 | */ | ||
61 | static inline void | ||
62 | batadv_dat_init_own_addr(struct batadv_priv *bat_priv, | ||
63 | struct batadv_hard_iface *primary_if) | ||
64 | { | ||
65 | uint32_t addr; | ||
66 | |||
67 | addr = batadv_choose_orig(primary_if->net_dev->dev_addr, | ||
68 | BATADV_DAT_ADDR_MAX); | ||
69 | |||
70 | bat_priv->dat.addr = (batadv_dat_addr_t)addr; | ||
71 | } | ||
72 | |||
73 | int batadv_dat_init(struct batadv_priv *bat_priv); | ||
74 | void batadv_dat_free(struct batadv_priv *bat_priv); | ||
75 | int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset); | ||
76 | |||
77 | /** | ||
78 | * batadv_dat_inc_counter - increment the correct DAT packet counter | ||
79 | * @bat_priv: the bat priv with all the soft interface information | ||
80 | * @subtype: the 4addr subtype of the packet to be counted | ||
81 | * | ||
82 | * Updates the ethtool statistics for the received packet if it is a DAT subtype | ||
83 | */ | ||
84 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, | ||
85 | uint8_t subtype) | ||
86 | { | ||
87 | switch (subtype) { | ||
88 | case BATADV_P_DAT_DHT_GET: | ||
89 | batadv_inc_counter(bat_priv, | ||
90 | BATADV_CNT_DAT_GET_RX); | ||
91 | break; | ||
92 | case BATADV_P_DAT_DHT_PUT: | ||
93 | batadv_inc_counter(bat_priv, | ||
94 | BATADV_CNT_DAT_PUT_RX); | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | #else | ||
100 | |||
101 | static inline bool | ||
102 | batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, | ||
103 | struct sk_buff *skb) | ||
104 | { | ||
105 | return false; | ||
106 | } | ||
107 | |||
108 | static inline bool | ||
109 | batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv, | ||
110 | struct sk_buff *skb, int hdr_size) | ||
111 | { | ||
112 | return false; | ||
113 | } | ||
114 | |||
115 | static inline bool | ||
116 | batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, | ||
117 | struct sk_buff *skb) | ||
118 | { | ||
119 | return false; | ||
120 | } | ||
121 | |||
122 | static inline bool | ||
123 | batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | ||
124 | struct sk_buff *skb, int hdr_size) | ||
125 | { | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | static inline bool | ||
130 | batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv, | ||
131 | struct batadv_forw_packet *forw_packet) | ||
132 | { | ||
133 | return false; | ||
134 | } | ||
135 | |||
136 | static inline void | ||
137 | batadv_dat_init_orig_node_addr(struct batadv_orig_node *orig_node) | ||
138 | { | ||
139 | } | ||
140 | |||
141 | static inline void batadv_dat_init_own_addr(struct batadv_priv *bat_priv, | ||
142 | struct batadv_hard_iface *iface) | ||
143 | { | ||
144 | } | ||
145 | |||
146 | static inline void batadv_arp_change_timeout(struct net_device *soft_iface, | ||
147 | const char *name) | ||
148 | { | ||
149 | } | ||
150 | |||
151 | static inline int batadv_dat_init(struct batadv_priv *bat_priv) | ||
152 | { | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static inline void batadv_dat_free(struct batadv_priv *bat_priv) | ||
157 | { | ||
158 | } | ||
159 | |||
160 | static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, | ||
161 | uint8_t subtype) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | #endif /* CONFIG_BATMAN_ADV_DAT */ | ||
166 | |||
167 | #endif /* _NET_BATMAN_ADV_ARP_H_ */ | ||
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 15d67abc10a4..dd07c7e3654f 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -477,22 +477,11 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) | |||
477 | struct batadv_hard_iface *primary_if; | 477 | struct batadv_hard_iface *primary_if; |
478 | struct batadv_gw_node *gw_node; | 478 | struct batadv_gw_node *gw_node; |
479 | struct hlist_node *node; | 479 | struct hlist_node *node; |
480 | int gw_count = 0, ret = 0; | 480 | int gw_count = 0; |
481 | 481 | ||
482 | primary_if = batadv_primary_if_get_selected(bat_priv); | 482 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
483 | if (!primary_if) { | 483 | if (!primary_if) |
484 | ret = seq_printf(seq, | ||
485 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
486 | net_dev->name); | ||
487 | goto out; | 484 | goto out; |
488 | } | ||
489 | |||
490 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
491 | ret = seq_printf(seq, | ||
492 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
493 | net_dev->name); | ||
494 | goto out; | ||
495 | } | ||
496 | 485 | ||
497 | seq_printf(seq, | 486 | seq_printf(seq, |
498 | " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", | 487 | " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", |
@@ -519,7 +508,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) | |||
519 | out: | 508 | out: |
520 | if (primary_if) | 509 | if (primary_if) |
521 | batadv_hardif_free_ref(primary_if); | 510 | batadv_hardif_free_ref(primary_if); |
522 | return ret; | 511 | return 0; |
523 | } | 512 | } |
524 | 513 | ||
525 | static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) | 514 | static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index d112fd6750b0..6b7a5d3eeb77 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "main.h" | 20 | #include "main.h" |
21 | #include "distributed-arp-table.h" | ||
21 | #include "hard-interface.h" | 22 | #include "hard-interface.h" |
22 | #include "soft-interface.h" | 23 | #include "soft-interface.h" |
23 | #include "send.h" | 24 | #include "send.h" |
@@ -109,6 +110,8 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, | |||
109 | if (!primary_if) | 110 | if (!primary_if) |
110 | goto out; | 111 | goto out; |
111 | 112 | ||
113 | batadv_dat_init_own_addr(bat_priv, primary_if); | ||
114 | |||
112 | skb = bat_priv->vis.my_info->skb_packet; | 115 | skb = bat_priv->vis.my_info->skb_packet; |
113 | vis_packet = (struct batadv_vis_packet *)skb->data; | 116 | vis_packet = (struct batadv_vis_packet *)skb->data; |
114 | memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); | 117 | memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); |
@@ -450,8 +453,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) | |||
450 | /* This can't be called via a bat_priv callback because | 453 | /* This can't be called via a bat_priv callback because |
451 | * we have no bat_priv yet. | 454 | * we have no bat_priv yet. |
452 | */ | 455 | */ |
453 | atomic_set(&hard_iface->seqno, 1); | 456 | atomic_set(&hard_iface->bat_iv.ogm_seqno, 1); |
454 | hard_iface->packet_buff = NULL; | 457 | hard_iface->bat_iv.ogm_buff = NULL; |
455 | 458 | ||
456 | return hard_iface; | 459 | return hard_iface; |
457 | 460 | ||
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index bde3cf747507..87ca8095b011 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c | |||
@@ -42,12 +42,16 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
42 | unsigned int i; | 42 | unsigned int i; |
43 | struct batadv_socket_client *socket_client; | 43 | struct batadv_socket_client *socket_client; |
44 | 44 | ||
45 | if (!try_module_get(THIS_MODULE)) | ||
46 | return -EBUSY; | ||
47 | |||
45 | nonseekable_open(inode, file); | 48 | nonseekable_open(inode, file); |
46 | 49 | ||
47 | socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); | 50 | socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); |
48 | 51 | if (!socket_client) { | |
49 | if (!socket_client) | 52 | module_put(THIS_MODULE); |
50 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | } | ||
51 | 55 | ||
52 | for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { | 56 | for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { |
53 | if (!batadv_socket_client_hash[i]) { | 57 | if (!batadv_socket_client_hash[i]) { |
@@ -59,6 +63,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
59 | if (i == ARRAY_SIZE(batadv_socket_client_hash)) { | 63 | if (i == ARRAY_SIZE(batadv_socket_client_hash)) { |
60 | pr_err("Error - can't add another packet client: maximum number of clients reached\n"); | 64 | pr_err("Error - can't add another packet client: maximum number of clients reached\n"); |
61 | kfree(socket_client); | 65 | kfree(socket_client); |
66 | module_put(THIS_MODULE); | ||
62 | return -EXFULL; | 67 | return -EXFULL; |
63 | } | 68 | } |
64 | 69 | ||
@@ -71,7 +76,6 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
71 | 76 | ||
72 | file->private_data = socket_client; | 77 | file->private_data = socket_client; |
73 | 78 | ||
74 | batadv_inc_module_count(); | ||
75 | return 0; | 79 | return 0; |
76 | } | 80 | } |
77 | 81 | ||
@@ -96,7 +100,7 @@ static int batadv_socket_release(struct inode *inode, struct file *file) | |||
96 | spin_unlock_bh(&socket_client->lock); | 100 | spin_unlock_bh(&socket_client->lock); |
97 | 101 | ||
98 | kfree(socket_client); | 102 | kfree(socket_client); |
99 | batadv_dec_module_count(); | 103 | module_put(THIS_MODULE); |
100 | 104 | ||
101 | return 0; | 105 | return 0; |
102 | } | 106 | } |
@@ -173,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, | |||
173 | if (len >= sizeof(struct batadv_icmp_packet_rr)) | 177 | if (len >= sizeof(struct batadv_icmp_packet_rr)) |
174 | packet_len = sizeof(struct batadv_icmp_packet_rr); | 178 | packet_len = sizeof(struct batadv_icmp_packet_rr); |
175 | 179 | ||
176 | skb = dev_alloc_skb(packet_len + ETH_HLEN); | 180 | skb = dev_alloc_skb(packet_len + ETH_HLEN + NET_IP_ALIGN); |
177 | if (!skb) { | 181 | if (!skb) { |
178 | len = -ENOMEM; | 182 | len = -ENOMEM; |
179 | goto out; | 183 | goto out; |
180 | } | 184 | } |
181 | 185 | ||
182 | skb_reserve(skb, ETH_HLEN); | 186 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
183 | icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); | 187 | icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); |
184 | 188 | ||
185 | if (copy_from_user(icmp_packet, buff, packet_len)) { | 189 | if (copy_from_user(icmp_packet, buff, packet_len)) { |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index b4aa470bc4a6..dc33a0c484a4 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "hard-interface.h" | 29 | #include "hard-interface.h" |
30 | #include "gateway_client.h" | 30 | #include "gateway_client.h" |
31 | #include "bridge_loop_avoidance.h" | 31 | #include "bridge_loop_avoidance.h" |
32 | #include "distributed-arp-table.h" | ||
32 | #include "vis.h" | 33 | #include "vis.h" |
33 | #include "hash.h" | 34 | #include "hash.h" |
34 | #include "bat_algo.h" | 35 | #include "bat_algo.h" |
@@ -128,6 +129,10 @@ int batadv_mesh_init(struct net_device *soft_iface) | |||
128 | if (ret < 0) | 129 | if (ret < 0) |
129 | goto err; | 130 | goto err; |
130 | 131 | ||
132 | ret = batadv_dat_init(bat_priv); | ||
133 | if (ret < 0) | ||
134 | goto err; | ||
135 | |||
131 | atomic_set(&bat_priv->gw.reselect, 0); | 136 | atomic_set(&bat_priv->gw.reselect, 0); |
132 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); | 137 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); |
133 | 138 | ||
@@ -155,21 +160,13 @@ void batadv_mesh_free(struct net_device *soft_iface) | |||
155 | 160 | ||
156 | batadv_bla_free(bat_priv); | 161 | batadv_bla_free(bat_priv); |
157 | 162 | ||
163 | batadv_dat_free(bat_priv); | ||
164 | |||
158 | free_percpu(bat_priv->bat_counters); | 165 | free_percpu(bat_priv->bat_counters); |
159 | 166 | ||
160 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); | 167 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
161 | } | 168 | } |
162 | 169 | ||
163 | void batadv_inc_module_count(void) | ||
164 | { | ||
165 | try_module_get(THIS_MODULE); | ||
166 | } | ||
167 | |||
168 | void batadv_dec_module_count(void) | ||
169 | { | ||
170 | module_put(THIS_MODULE); | ||
171 | } | ||
172 | |||
173 | int batadv_is_my_mac(const uint8_t *addr) | 170 | int batadv_is_my_mac(const uint8_t *addr) |
174 | { | 171 | { |
175 | const struct batadv_hard_iface *hard_iface; | 172 | const struct batadv_hard_iface *hard_iface; |
@@ -188,6 +185,42 @@ int batadv_is_my_mac(const uint8_t *addr) | |||
188 | return 0; | 185 | return 0; |
189 | } | 186 | } |
190 | 187 | ||
188 | /** | ||
189 | * batadv_seq_print_text_primary_if_get - called from debugfs table printing | ||
190 | * function that requires the primary interface | ||
191 | * @seq: debugfs table seq_file struct | ||
192 | * | ||
193 | * Returns primary interface if found or NULL otherwise. | ||
194 | */ | ||
195 | struct batadv_hard_iface * | ||
196 | batadv_seq_print_text_primary_if_get(struct seq_file *seq) | ||
197 | { | ||
198 | struct net_device *net_dev = (struct net_device *)seq->private; | ||
199 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | ||
200 | struct batadv_hard_iface *primary_if; | ||
201 | |||
202 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
203 | |||
204 | if (!primary_if) { | ||
205 | seq_printf(seq, | ||
206 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
207 | net_dev->name); | ||
208 | goto out; | ||
209 | } | ||
210 | |||
211 | if (primary_if->if_status == BATADV_IF_ACTIVE) | ||
212 | goto out; | ||
213 | |||
214 | seq_printf(seq, | ||
215 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
216 | net_dev->name); | ||
217 | batadv_hardif_free_ref(primary_if); | ||
218 | primary_if = NULL; | ||
219 | |||
220 | out: | ||
221 | return primary_if; | ||
222 | } | ||
223 | |||
191 | static int batadv_recv_unhandled_packet(struct sk_buff *skb, | 224 | static int batadv_recv_unhandled_packet(struct sk_buff *skb, |
192 | struct batadv_hard_iface *recv_if) | 225 | struct batadv_hard_iface *recv_if) |
193 | { | 226 | { |
@@ -274,6 +307,8 @@ static void batadv_recv_handler_init(void) | |||
274 | 307 | ||
275 | /* batman icmp packet */ | 308 | /* batman icmp packet */ |
276 | batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; | 309 | batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; |
310 | /* unicast with 4 addresses packet */ | ||
311 | batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet; | ||
277 | /* unicast packet */ | 312 | /* unicast packet */ |
278 | batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; | 313 | batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet; |
279 | /* fragmented unicast packet */ | 314 | /* fragmented unicast packet */ |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d57b746219de..240c74ffeb93 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -44,6 +44,7 @@ | |||
44 | #define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ | 44 | #define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ |
45 | #define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ | 45 | #define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ |
46 | #define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ | 46 | #define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ |
47 | #define BATADV_DAT_ENTRY_TIMEOUT (5*60000) /* 5 mins in milliseconds */ | ||
47 | /* sliding packet range of received originator messages in sequence numbers | 48 | /* sliding packet range of received originator messages in sequence numbers |
48 | * (should be a multiple of our word size) | 49 | * (should be a multiple of our word size) |
49 | */ | 50 | */ |
@@ -73,6 +74,11 @@ | |||
73 | 74 | ||
74 | #define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */ | 75 | #define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */ |
75 | 76 | ||
77 | /* msecs after which an ARP_REQUEST is sent in broadcast as fallback */ | ||
78 | #define ARP_REQ_DELAY 250 | ||
79 | /* numbers of originator to contact for any PUT/GET DHT operation */ | ||
80 | #define BATADV_DAT_CANDIDATES_NUM 3 | ||
81 | |||
76 | #define BATADV_VIS_INTERVAL 5000 /* 5 seconds */ | 82 | #define BATADV_VIS_INTERVAL 5000 /* 5 seconds */ |
77 | 83 | ||
78 | /* how much worse secondary interfaces may be to be considered as bonding | 84 | /* how much worse secondary interfaces may be to be considered as bonding |
@@ -117,6 +123,9 @@ enum batadv_uev_type { | |||
117 | 123 | ||
118 | #define BATADV_GW_THRESHOLD 50 | 124 | #define BATADV_GW_THRESHOLD 50 |
119 | 125 | ||
126 | #define BATADV_DAT_CANDIDATE_NOT_FOUND 0 | ||
127 | #define BATADV_DAT_CANDIDATE_ORIG 1 | ||
128 | |||
120 | /* Debug Messages */ | 129 | /* Debug Messages */ |
121 | #ifdef pr_fmt | 130 | #ifdef pr_fmt |
122 | #undef pr_fmt | 131 | #undef pr_fmt |
@@ -150,9 +159,9 @@ extern struct workqueue_struct *batadv_event_workqueue; | |||
150 | 159 | ||
151 | int batadv_mesh_init(struct net_device *soft_iface); | 160 | int batadv_mesh_init(struct net_device *soft_iface); |
152 | void batadv_mesh_free(struct net_device *soft_iface); | 161 | void batadv_mesh_free(struct net_device *soft_iface); |
153 | void batadv_inc_module_count(void); | ||
154 | void batadv_dec_module_count(void); | ||
155 | int batadv_is_my_mac(const uint8_t *addr); | 162 | int batadv_is_my_mac(const uint8_t *addr); |
163 | struct batadv_hard_iface * | ||
164 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); | ||
156 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | 165 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, |
157 | struct packet_type *ptype, | 166 | struct packet_type *ptype, |
158 | struct net_device *orig_dev); | 167 | struct net_device *orig_dev); |
@@ -165,13 +174,22 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops); | |||
165 | int batadv_algo_select(struct batadv_priv *bat_priv, char *name); | 174 | int batadv_algo_select(struct batadv_priv *bat_priv, char *name); |
166 | int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); | 175 | int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); |
167 | 176 | ||
168 | /* all messages related to routing / flooding / broadcasting / etc */ | 177 | /** |
178 | * enum batadv_dbg_level - available log levels | ||
179 | * @BATADV_DBG_BATMAN: OGM and TQ computations related messages | ||
180 | * @BATADV_DBG_ROUTES: route added / changed / deleted | ||
181 | * @BATADV_DBG_TT: translation table messages | ||
182 | * @BATADV_DBG_BLA: bridge loop avoidance messages | ||
183 | * @BATADV_DBG_DAT: ARP snooping and DAT related messages | ||
184 | * @BATADV_DBG_ALL: the union of all the above log levels | ||
185 | */ | ||
169 | enum batadv_dbg_level { | 186 | enum batadv_dbg_level { |
170 | BATADV_DBG_BATMAN = BIT(0), | 187 | BATADV_DBG_BATMAN = BIT(0), |
171 | BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */ | 188 | BATADV_DBG_ROUTES = BIT(1), |
172 | BATADV_DBG_TT = BIT(2), /* translation table operations */ | 189 | BATADV_DBG_TT = BIT(2), |
173 | BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */ | 190 | BATADV_DBG_BLA = BIT(3), |
174 | BATADV_DBG_ALL = 15, | 191 | BATADV_DBG_DAT = BIT(4), |
192 | BATADV_DBG_ALL = 31, | ||
175 | }; | 193 | }; |
176 | 194 | ||
177 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 195 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ac9bdf8f80a6..84930a4f5369 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "main.h" | 20 | #include "main.h" |
21 | #include "distributed-arp-table.h" | ||
21 | #include "originator.h" | 22 | #include "originator.h" |
22 | #include "hash.h" | 23 | #include "hash.h" |
23 | #include "translation-table.h" | 24 | #include "translation-table.h" |
@@ -223,6 +224,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, | |||
223 | orig_node->tt_poss_change = false; | 224 | orig_node->tt_poss_change = false; |
224 | orig_node->bat_priv = bat_priv; | 225 | orig_node->bat_priv = bat_priv; |
225 | memcpy(orig_node->orig, addr, ETH_ALEN); | 226 | memcpy(orig_node->orig, addr, ETH_ALEN); |
227 | batadv_dat_init_orig_node_addr(orig_node); | ||
226 | orig_node->router = NULL; | 228 | orig_node->router = NULL; |
227 | orig_node->tt_crc = 0; | 229 | orig_node->tt_crc = 0; |
228 | atomic_set(&orig_node->last_ttvn, 0); | 230 | atomic_set(&orig_node->last_ttvn, 0); |
@@ -415,23 +417,10 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) | |||
415 | int last_seen_msecs; | 417 | int last_seen_msecs; |
416 | unsigned long last_seen_jiffies; | 418 | unsigned long last_seen_jiffies; |
417 | uint32_t i; | 419 | uint32_t i; |
418 | int ret = 0; | ||
419 | 420 | ||
420 | primary_if = batadv_primary_if_get_selected(bat_priv); | 421 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
421 | 422 | if (!primary_if) | |
422 | if (!primary_if) { | ||
423 | ret = seq_printf(seq, | ||
424 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
425 | net_dev->name); | ||
426 | goto out; | ||
427 | } | ||
428 | |||
429 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
430 | ret = seq_printf(seq, | ||
431 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
432 | net_dev->name); | ||
433 | goto out; | 423 | goto out; |
434 | } | ||
435 | 424 | ||
436 | seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", | 425 | seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", |
437 | BATADV_SOURCE_VERSION, primary_if->net_dev->name, | 426 | BATADV_SOURCE_VERSION, primary_if->net_dev->name, |
@@ -485,7 +474,7 @@ next: | |||
485 | out: | 474 | out: |
486 | if (primary_if) | 475 | if (primary_if) |
487 | batadv_hardif_free_ref(primary_if); | 476 | batadv_hardif_free_ref(primary_if); |
488 | return ret; | 477 | return 0; |
489 | } | 478 | } |
490 | 479 | ||
491 | static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, | 480 | static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, |
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 2d23a14c220e..df548ed196d3 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -23,14 +23,29 @@ | |||
23 | #define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ | 23 | #define BATADV_ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ |
24 | 24 | ||
25 | enum batadv_packettype { | 25 | enum batadv_packettype { |
26 | BATADV_IV_OGM = 0x01, | 26 | BATADV_IV_OGM = 0x01, |
27 | BATADV_ICMP = 0x02, | 27 | BATADV_ICMP = 0x02, |
28 | BATADV_UNICAST = 0x03, | 28 | BATADV_UNICAST = 0x03, |
29 | BATADV_BCAST = 0x04, | 29 | BATADV_BCAST = 0x04, |
30 | BATADV_VIS = 0x05, | 30 | BATADV_VIS = 0x05, |
31 | BATADV_UNICAST_FRAG = 0x06, | 31 | BATADV_UNICAST_FRAG = 0x06, |
32 | BATADV_TT_QUERY = 0x07, | 32 | BATADV_TT_QUERY = 0x07, |
33 | BATADV_ROAM_ADV = 0x08, | 33 | BATADV_ROAM_ADV = 0x08, |
34 | BATADV_UNICAST_4ADDR = 0x09, | ||
35 | }; | ||
36 | |||
37 | /** | ||
38 | * enum batadv_subtype - packet subtype for unicast4addr | ||
39 | * @BATADV_P_DATA: user payload | ||
40 | * @BATADV_P_DAT_DHT_GET: DHT request message | ||
41 | * @BATADV_P_DAT_DHT_PUT: DHT store message | ||
42 | * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT | ||
43 | */ | ||
44 | enum batadv_subtype { | ||
45 | BATADV_P_DATA = 0x01, | ||
46 | BATADV_P_DAT_DHT_GET = 0x02, | ||
47 | BATADV_P_DAT_DHT_PUT = 0x03, | ||
48 | BATADV_P_DAT_CACHE_REPLY = 0x04, | ||
34 | }; | 49 | }; |
35 | 50 | ||
36 | /* this file is included by batctl which needs these defines */ | 51 | /* this file is included by batctl which needs these defines */ |
@@ -106,13 +121,16 @@ struct batadv_bla_claim_dst { | |||
106 | uint8_t magic[3]; /* FF:43:05 */ | 121 | uint8_t magic[3]; /* FF:43:05 */ |
107 | uint8_t type; /* bla_claimframe */ | 122 | uint8_t type; /* bla_claimframe */ |
108 | __be16 group; /* group id */ | 123 | __be16 group; /* group id */ |
109 | } __packed; | 124 | }; |
110 | 125 | ||
111 | struct batadv_header { | 126 | struct batadv_header { |
112 | uint8_t packet_type; | 127 | uint8_t packet_type; |
113 | uint8_t version; /* batman version field */ | 128 | uint8_t version; /* batman version field */ |
114 | uint8_t ttl; | 129 | uint8_t ttl; |
115 | } __packed; | 130 | /* the parent struct has to add a byte after the header to make |
131 | * everything 4 bytes aligned again | ||
132 | */ | ||
133 | }; | ||
116 | 134 | ||
117 | struct batadv_ogm_packet { | 135 | struct batadv_ogm_packet { |
118 | struct batadv_header header; | 136 | struct batadv_header header; |
@@ -137,7 +155,7 @@ struct batadv_icmp_packet { | |||
137 | __be16 seqno; | 155 | __be16 seqno; |
138 | uint8_t uid; | 156 | uint8_t uid; |
139 | uint8_t reserved; | 157 | uint8_t reserved; |
140 | } __packed; | 158 | }; |
141 | 159 | ||
142 | #define BATADV_RR_LEN 16 | 160 | #define BATADV_RR_LEN 16 |
143 | 161 | ||
@@ -153,13 +171,32 @@ struct batadv_icmp_packet_rr { | |||
153 | uint8_t uid; | 171 | uint8_t uid; |
154 | uint8_t rr_cur; | 172 | uint8_t rr_cur; |
155 | uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; | 173 | uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; |
156 | } __packed; | 174 | }; |
157 | 175 | ||
158 | struct batadv_unicast_packet { | 176 | struct batadv_unicast_packet { |
159 | struct batadv_header header; | 177 | struct batadv_header header; |
160 | uint8_t ttvn; /* destination translation table version number */ | 178 | uint8_t ttvn; /* destination translation table version number */ |
161 | uint8_t dest[ETH_ALEN]; | 179 | uint8_t dest[ETH_ALEN]; |
162 | } __packed; | 180 | /* "4 bytes boundary + 2 bytes" long to make the payload after the |
181 | * following ethernet header again 4 bytes boundary aligned | ||
182 | */ | ||
183 | }; | ||
184 | |||
185 | /** | ||
186 | * struct batadv_unicast_4addr_packet - extended unicast packet | ||
187 | * @u: common unicast packet header | ||
188 | * @src: address of the source | ||
189 | * @subtype: packet subtype | ||
190 | */ | ||
191 | struct batadv_unicast_4addr_packet { | ||
192 | struct batadv_unicast_packet u; | ||
193 | uint8_t src[ETH_ALEN]; | ||
194 | uint8_t subtype; | ||
195 | uint8_t reserved; | ||
196 | /* "4 bytes boundary + 2 bytes" long to make the payload after the | ||
197 | * following ethernet header again 4 bytes boundary aligned | ||
198 | */ | ||
199 | }; | ||
163 | 200 | ||
164 | struct batadv_unicast_frag_packet { | 201 | struct batadv_unicast_frag_packet { |
165 | struct batadv_header header; | 202 | struct batadv_header header; |
@@ -176,6 +213,9 @@ struct batadv_bcast_packet { | |||
176 | uint8_t reserved; | 213 | uint8_t reserved; |
177 | __be32 seqno; | 214 | __be32 seqno; |
178 | uint8_t orig[ETH_ALEN]; | 215 | uint8_t orig[ETH_ALEN]; |
216 | /* "4 bytes boundary + 2 bytes" long to make the payload after the | ||
217 | * following ethernet header again 4 bytes boundary aligned | ||
218 | */ | ||
179 | } __packed; | 219 | } __packed; |
180 | 220 | ||
181 | struct batadv_vis_packet { | 221 | struct batadv_vis_packet { |
@@ -187,7 +227,7 @@ struct batadv_vis_packet { | |||
187 | uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */ | 227 | uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */ |
188 | uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */ | 228 | uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */ |
189 | uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */ | 229 | uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */ |
190 | } __packed; | 230 | }; |
191 | 231 | ||
192 | struct batadv_tt_query_packet { | 232 | struct batadv_tt_query_packet { |
193 | struct batadv_header header; | 233 | struct batadv_header header; |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 376b4cc6ca82..32aa4d460e1f 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "vis.h" | 28 | #include "vis.h" |
29 | #include "unicast.h" | 29 | #include "unicast.h" |
30 | #include "bridge_loop_avoidance.h" | 30 | #include "bridge_loop_avoidance.h" |
31 | #include "distributed-arp-table.h" | ||
31 | 32 | ||
32 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 33 | static int batadv_route_unicast_packet(struct sk_buff *skb, |
33 | struct batadv_hard_iface *recv_if); | 34 | struct batadv_hard_iface *recv_if); |
@@ -549,25 +550,18 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, | |||
549 | if (tmp_neigh_node->if_incoming == recv_if) | 550 | if (tmp_neigh_node->if_incoming == recv_if) |
550 | continue; | 551 | continue; |
551 | 552 | ||
552 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) | 553 | if (router && tmp_neigh_node->tq_avg <= router->tq_avg) |
553 | continue; | 554 | continue; |
554 | 555 | ||
555 | /* if we don't have a router yet | 556 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) |
556 | * or this one is better, choose it. | 557 | continue; |
557 | */ | ||
558 | if ((!router) || | ||
559 | (tmp_neigh_node->tq_avg > router->tq_avg)) { | ||
560 | /* decrement refcount of | ||
561 | * previously selected router | ||
562 | */ | ||
563 | if (router) | ||
564 | batadv_neigh_node_free_ref(router); | ||
565 | 558 | ||
566 | router = tmp_neigh_node; | 559 | /* decrement refcount of previously selected router */ |
567 | atomic_inc_not_zero(&router->refcount); | 560 | if (router) |
568 | } | 561 | batadv_neigh_node_free_ref(router); |
569 | 562 | ||
570 | batadv_neigh_node_free_ref(tmp_neigh_node); | 563 | /* we found a better router (or at least one valid router) */ |
564 | router = tmp_neigh_node; | ||
571 | } | 565 | } |
572 | 566 | ||
573 | /* use the first candidate if nothing was found. */ | 567 | /* use the first candidate if nothing was found. */ |
@@ -687,21 +681,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) | |||
687 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 681 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
688 | struct batadv_roam_adv_packet *roam_adv_packet; | 682 | struct batadv_roam_adv_packet *roam_adv_packet; |
689 | struct batadv_orig_node *orig_node; | 683 | struct batadv_orig_node *orig_node; |
690 | struct ethhdr *ethhdr; | ||
691 | 684 | ||
692 | /* drop packet if it has not necessary minimum size */ | 685 | if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0) |
693 | if (unlikely(!pskb_may_pull(skb, | ||
694 | sizeof(struct batadv_roam_adv_packet)))) | ||
695 | goto out; | ||
696 | |||
697 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | ||
698 | |||
699 | /* packet with unicast indication but broadcast recipient */ | ||
700 | if (is_broadcast_ether_addr(ethhdr->h_dest)) | ||
701 | goto out; | ||
702 | |||
703 | /* packet with broadcast sender address */ | ||
704 | if (is_broadcast_ether_addr(ethhdr->h_source)) | ||
705 | goto out; | 686 | goto out; |
706 | 687 | ||
707 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); | 688 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); |
@@ -928,8 +909,12 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
928 | bool tt_poss_change; | 909 | bool tt_poss_change; |
929 | int is_old_ttvn; | 910 | int is_old_ttvn; |
930 | 911 | ||
931 | /* I could need to modify it */ | 912 | /* check if there is enough data before accessing it */ |
932 | if (skb_cow(skb, sizeof(struct batadv_unicast_packet)) < 0) | 913 | if (pskb_may_pull(skb, sizeof(*unicast_packet) + ETH_HLEN) < 0) |
914 | return 0; | ||
915 | |||
916 | /* create a copy of the skb (in case of for re-routing) to modify it. */ | ||
917 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) | ||
933 | return 0; | 918 | return 0; |
934 | 919 | ||
935 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 920 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
@@ -985,10 +970,10 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
985 | batadv_orig_node_free_ref(orig_node); | 970 | batadv_orig_node_free_ref(orig_node); |
986 | } | 971 | } |
987 | 972 | ||
988 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, | 973 | net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv, |
989 | "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", | 974 | "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", |
990 | unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest, | 975 | unicast_packet->ttvn, curr_ttvn, |
991 | unicast_packet->dest); | 976 | ethhdr->h_dest, unicast_packet->dest); |
992 | 977 | ||
993 | unicast_packet->ttvn = curr_ttvn; | 978 | unicast_packet->ttvn = curr_ttvn; |
994 | } | 979 | } |
@@ -1000,7 +985,19 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
1000 | { | 985 | { |
1001 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 986 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
1002 | struct batadv_unicast_packet *unicast_packet; | 987 | struct batadv_unicast_packet *unicast_packet; |
988 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; | ||
989 | uint8_t *orig_addr; | ||
990 | struct batadv_orig_node *orig_node = NULL; | ||
1003 | int hdr_size = sizeof(*unicast_packet); | 991 | int hdr_size = sizeof(*unicast_packet); |
992 | bool is4addr; | ||
993 | |||
994 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
995 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | ||
996 | |||
997 | is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR; | ||
998 | /* the caller function should have already pulled 2 bytes */ | ||
999 | if (is4addr) | ||
1000 | hdr_size = sizeof(*unicast_4addr_packet); | ||
1004 | 1001 | ||
1005 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) | 1002 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) |
1006 | return NET_RX_DROP; | 1003 | return NET_RX_DROP; |
@@ -1008,12 +1005,28 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
1008 | if (!batadv_check_unicast_ttvn(bat_priv, skb)) | 1005 | if (!batadv_check_unicast_ttvn(bat_priv, skb)) |
1009 | return NET_RX_DROP; | 1006 | return NET_RX_DROP; |
1010 | 1007 | ||
1011 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
1012 | |||
1013 | /* packet for me */ | 1008 | /* packet for me */ |
1014 | if (batadv_is_my_mac(unicast_packet->dest)) { | 1009 | if (batadv_is_my_mac(unicast_packet->dest)) { |
1010 | if (is4addr) { | ||
1011 | batadv_dat_inc_counter(bat_priv, | ||
1012 | unicast_4addr_packet->subtype); | ||
1013 | orig_addr = unicast_4addr_packet->src; | ||
1014 | orig_node = batadv_orig_hash_find(bat_priv, orig_addr); | ||
1015 | } | ||
1016 | |||
1017 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, | ||
1018 | hdr_size)) | ||
1019 | goto rx_success; | ||
1020 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, | ||
1021 | hdr_size)) | ||
1022 | goto rx_success; | ||
1023 | |||
1015 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 1024 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, |
1016 | NULL); | 1025 | orig_node); |
1026 | |||
1027 | rx_success: | ||
1028 | if (orig_node) | ||
1029 | batadv_orig_node_free_ref(orig_node); | ||
1017 | 1030 | ||
1018 | return NET_RX_SUCCESS; | 1031 | return NET_RX_SUCCESS; |
1019 | } | 1032 | } |
@@ -1050,8 +1063,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, | |||
1050 | if (!new_skb) | 1063 | if (!new_skb) |
1051 | return NET_RX_SUCCESS; | 1064 | return NET_RX_SUCCESS; |
1052 | 1065 | ||
1066 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb, | ||
1067 | hdr_size)) | ||
1068 | goto rx_success; | ||
1069 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb, | ||
1070 | hdr_size)) | ||
1071 | goto rx_success; | ||
1072 | |||
1053 | batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, | 1073 | batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, |
1054 | sizeof(struct batadv_unicast_packet), NULL); | 1074 | sizeof(struct batadv_unicast_packet), NULL); |
1075 | |||
1076 | rx_success: | ||
1055 | return NET_RX_SUCCESS; | 1077 | return NET_RX_SUCCESS; |
1056 | } | 1078 | } |
1057 | 1079 | ||
@@ -1143,9 +1165,16 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1143 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) | 1165 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) |
1144 | goto out; | 1166 | goto out; |
1145 | 1167 | ||
1168 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size)) | ||
1169 | goto rx_success; | ||
1170 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size)) | ||
1171 | goto rx_success; | ||
1172 | |||
1146 | /* broadcast for me */ | 1173 | /* broadcast for me */ |
1147 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 1174 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, |
1148 | orig_node); | 1175 | orig_node); |
1176 | |||
1177 | rx_success: | ||
1149 | ret = NET_RX_SUCCESS; | 1178 | ret = NET_RX_SUCCESS; |
1150 | goto out; | 1179 | goto out; |
1151 | 1180 | ||
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 570a8bce0364..660d9bf7d219 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "main.h" | 20 | #include "main.h" |
21 | #include "distributed-arp-table.h" | ||
21 | #include "send.h" | 22 | #include "send.h" |
22 | #include "routing.h" | 23 | #include "routing.h" |
23 | #include "translation-table.h" | 24 | #include "translation-table.h" |
@@ -209,6 +210,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) | |||
209 | if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) | 210 | if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) |
210 | goto out; | 211 | goto out; |
211 | 212 | ||
213 | if (batadv_dat_drop_broadcast_packet(bat_priv, forw_packet)) | ||
214 | goto out; | ||
215 | |||
212 | /* rebroadcast packet */ | 216 | /* rebroadcast packet */ |
213 | rcu_read_lock(); | 217 | rcu_read_lock(); |
214 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { | 218 | list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e8..c283d87c4cce 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "main.h" | 20 | #include "main.h" |
21 | #include "soft-interface.h" | 21 | #include "soft-interface.h" |
22 | #include "hard-interface.h" | 22 | #include "hard-interface.h" |
23 | #include "distributed-arp-table.h" | ||
23 | #include "routing.h" | 24 | #include "routing.h" |
24 | #include "send.h" | 25 | #include "send.h" |
25 | #include "debugfs.h" | 26 | #include "debugfs.h" |
@@ -146,13 +147,16 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
146 | struct batadv_bcast_packet *bcast_packet; | 147 | struct batadv_bcast_packet *bcast_packet; |
147 | struct vlan_ethhdr *vhdr; | 148 | struct vlan_ethhdr *vhdr; |
148 | __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); | 149 | __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); |
149 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, | 150 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, |
150 | 0x00}; | 151 | 0x00, 0x00}; |
152 | static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, | ||
153 | 0x00, 0x00}; | ||
151 | unsigned int header_len = 0; | 154 | unsigned int header_len = 0; |
152 | int data_len = skb->len, ret; | 155 | int data_len = skb->len, ret; |
153 | short vid __maybe_unused = -1; | 156 | short vid __maybe_unused = -1; |
154 | bool do_bcast = false; | 157 | bool do_bcast = false; |
155 | uint32_t seqno; | 158 | uint32_t seqno; |
159 | unsigned long brd_delay = 1; | ||
156 | 160 | ||
157 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) | 161 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
158 | goto dropped; | 162 | goto dropped; |
@@ -180,10 +184,16 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
180 | 184 | ||
181 | /* don't accept stp packets. STP does not help in meshes. | 185 | /* don't accept stp packets. STP does not help in meshes. |
182 | * better use the bridge loop avoidance ... | 186 | * better use the bridge loop avoidance ... |
187 | * | ||
188 | * The same goes for ECTP sent at least by some Cisco Switches, | ||
189 | * it might confuse the mesh when used with bridge loop avoidance. | ||
183 | */ | 190 | */ |
184 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) | 191 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) |
185 | goto dropped; | 192 | goto dropped; |
186 | 193 | ||
194 | if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) | ||
195 | goto dropped; | ||
196 | |||
187 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 197 | if (is_multicast_ether_addr(ethhdr->h_dest)) { |
188 | do_bcast = true; | 198 | do_bcast = true; |
189 | 199 | ||
@@ -216,6 +226,13 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
216 | if (!primary_if) | 226 | if (!primary_if) |
217 | goto dropped; | 227 | goto dropped; |
218 | 228 | ||
229 | /* in case of ARP request, we do not immediately broadcasti the | ||
230 | * packet, instead we first wait for DAT to try to retrieve the | ||
231 | * correct ARP entry | ||
232 | */ | ||
233 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) | ||
234 | brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); | ||
235 | |||
219 | if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) | 236 | if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) |
220 | goto dropped; | 237 | goto dropped; |
221 | 238 | ||
@@ -237,7 +254,7 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
237 | seqno = atomic_inc_return(&bat_priv->bcast_seqno); | 254 | seqno = atomic_inc_return(&bat_priv->bcast_seqno); |
238 | bcast_packet->seqno = htonl(seqno); | 255 | bcast_packet->seqno = htonl(seqno); |
239 | 256 | ||
240 | batadv_add_bcast_packet_to_list(bat_priv, skb, 1); | 257 | batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay); |
241 | 258 | ||
242 | /* a copy is stored in the bcast list, therefore removing | 259 | /* a copy is stored in the bcast list, therefore removing |
243 | * the original skb. | 260 | * the original skb. |
@@ -252,7 +269,12 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
252 | goto dropped; | 269 | goto dropped; |
253 | } | 270 | } |
254 | 271 | ||
255 | ret = batadv_unicast_send_skb(skb, bat_priv); | 272 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) |
273 | goto dropped; | ||
274 | |||
275 | batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); | ||
276 | |||
277 | ret = batadv_unicast_send_skb(bat_priv, skb); | ||
256 | if (ret != 0) | 278 | if (ret != 0) |
257 | goto dropped_freed; | 279 | goto dropped_freed; |
258 | } | 280 | } |
@@ -347,7 +369,51 @@ out: | |||
347 | return; | 369 | return; |
348 | } | 370 | } |
349 | 371 | ||
372 | /* batman-adv network devices have devices nesting below it and are a special | ||
373 | * "super class" of normal network devices; split their locks off into a | ||
374 | * separate class since they always nest. | ||
375 | */ | ||
376 | static struct lock_class_key batadv_netdev_xmit_lock_key; | ||
377 | static struct lock_class_key batadv_netdev_addr_lock_key; | ||
378 | |||
379 | /** | ||
380 | * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue | ||
381 | * @dev: device which owns the tx queue | ||
382 | * @txq: tx queue to modify | ||
383 | * @_unused: always NULL | ||
384 | */ | ||
385 | static void batadv_set_lockdep_class_one(struct net_device *dev, | ||
386 | struct netdev_queue *txq, | ||
387 | void *_unused) | ||
388 | { | ||
389 | lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * batadv_set_lockdep_class - Set txq and addr_list lockdep class | ||
394 | * @dev: network device to modify | ||
395 | */ | ||
396 | static void batadv_set_lockdep_class(struct net_device *dev) | ||
397 | { | ||
398 | lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); | ||
399 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * batadv_softif_init - Late stage initialization of soft interface | ||
404 | * @dev: registered network device to modify | ||
405 | * | ||
406 | * Returns error code on failures | ||
407 | */ | ||
408 | static int batadv_softif_init(struct net_device *dev) | ||
409 | { | ||
410 | batadv_set_lockdep_class(dev); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
350 | static const struct net_device_ops batadv_netdev_ops = { | 415 | static const struct net_device_ops batadv_netdev_ops = { |
416 | .ndo_init = batadv_softif_init, | ||
351 | .ndo_open = batadv_interface_open, | 417 | .ndo_open = batadv_interface_open, |
352 | .ndo_stop = batadv_interface_release, | 418 | .ndo_stop = batadv_interface_release, |
353 | .ndo_get_stats = batadv_interface_stats, | 419 | .ndo_get_stats = batadv_interface_stats, |
@@ -414,6 +480,9 @@ struct net_device *batadv_softif_create(const char *name) | |||
414 | atomic_set(&bat_priv->aggregated_ogms, 1); | 480 | atomic_set(&bat_priv->aggregated_ogms, 1); |
415 | atomic_set(&bat_priv->bonding, 0); | 481 | atomic_set(&bat_priv->bonding, 0); |
416 | atomic_set(&bat_priv->bridge_loop_avoidance, 0); | 482 | atomic_set(&bat_priv->bridge_loop_avoidance, 0); |
483 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
484 | atomic_set(&bat_priv->distributed_arp_table, 1); | ||
485 | #endif | ||
417 | atomic_set(&bat_priv->ap_isolation, 0); | 486 | atomic_set(&bat_priv->ap_isolation, 0); |
418 | atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); | 487 | atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); |
419 | atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); | 488 | atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); |
@@ -556,6 +625,13 @@ static const struct { | |||
556 | { "tt_response_rx" }, | 625 | { "tt_response_rx" }, |
557 | { "tt_roam_adv_tx" }, | 626 | { "tt_roam_adv_tx" }, |
558 | { "tt_roam_adv_rx" }, | 627 | { "tt_roam_adv_rx" }, |
628 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
629 | { "dat_get_tx" }, | ||
630 | { "dat_get_rx" }, | ||
631 | { "dat_put_tx" }, | ||
632 | { "dat_put_rx" }, | ||
633 | { "dat_cached_reply_tx" }, | ||
634 | #endif | ||
559 | }; | 635 | }; |
560 | 636 | ||
561 | static void batadv_get_strings(struct net_device *dev, uint32_t stringset, | 637 | static void batadv_get_strings(struct net_device *dev, uint32_t stringset, |
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 66518c75c217..fa3cc1af0918 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "main.h" | 20 | #include "main.h" |
21 | #include "sysfs.h" | 21 | #include "sysfs.h" |
22 | #include "translation-table.h" | 22 | #include "translation-table.h" |
23 | #include "distributed-arp-table.h" | ||
23 | #include "originator.h" | 24 | #include "originator.h" |
24 | #include "hard-interface.h" | 25 | #include "hard-interface.h" |
25 | #include "gateway_common.h" | 26 | #include "gateway_common.h" |
@@ -122,55 +123,6 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ | |||
122 | batadv_store_##_name) | 123 | batadv_store_##_name) |
123 | 124 | ||
124 | 125 | ||
125 | #define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ | ||
126 | ssize_t batadv_store_##_name(struct kobject *kobj, \ | ||
127 | struct attribute *attr, char *buff, \ | ||
128 | size_t count) \ | ||
129 | { \ | ||
130 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ | ||
131 | struct batadv_hard_iface *hard_iface; \ | ||
132 | ssize_t length; \ | ||
133 | \ | ||
134 | hard_iface = batadv_hardif_get_by_netdev(net_dev); \ | ||
135 | if (!hard_iface) \ | ||
136 | return 0; \ | ||
137 | \ | ||
138 | length = __batadv_store_uint_attr(buff, count, _min, _max, \ | ||
139 | _post_func, attr, \ | ||
140 | &hard_iface->_name, net_dev); \ | ||
141 | \ | ||
142 | batadv_hardif_free_ref(hard_iface); \ | ||
143 | return length; \ | ||
144 | } | ||
145 | |||
146 | #define BATADV_ATTR_HIF_SHOW_UINT(_name) \ | ||
147 | ssize_t batadv_show_##_name(struct kobject *kobj, \ | ||
148 | struct attribute *attr, char *buff) \ | ||
149 | { \ | ||
150 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ | ||
151 | struct batadv_hard_iface *hard_iface; \ | ||
152 | ssize_t length; \ | ||
153 | \ | ||
154 | hard_iface = batadv_hardif_get_by_netdev(net_dev); \ | ||
155 | if (!hard_iface) \ | ||
156 | return 0; \ | ||
157 | \ | ||
158 | length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ | ||
159 | \ | ||
160 | batadv_hardif_free_ref(hard_iface); \ | ||
161 | return length; \ | ||
162 | } | ||
163 | |||
164 | /* Use this, if you are going to set [name] in hard_iface to an | ||
165 | * unsigned integer value | ||
166 | */ | ||
167 | #define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ | ||
168 | static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\ | ||
169 | static BATADV_ATTR_HIF_SHOW_UINT(_name) \ | ||
170 | static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ | ||
171 | batadv_store_##_name) | ||
172 | |||
173 | |||
174 | static int batadv_store_bool_attr(char *buff, size_t count, | 126 | static int batadv_store_bool_attr(char *buff, size_t count, |
175 | struct net_device *net_dev, | 127 | struct net_device *net_dev, |
176 | const char *attr_name, atomic_t *attr) | 128 | const char *attr_name, atomic_t *attr) |
@@ -469,6 +421,9 @@ BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); | |||
469 | #ifdef CONFIG_BATMAN_ADV_BLA | 421 | #ifdef CONFIG_BATMAN_ADV_BLA |
470 | BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); | 422 | BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); |
471 | #endif | 423 | #endif |
424 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
425 | BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, NULL); | ||
426 | #endif | ||
472 | BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); | 427 | BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); |
473 | BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); | 428 | BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); |
474 | static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, | 429 | static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode, |
@@ -494,6 +449,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = { | |||
494 | #ifdef CONFIG_BATMAN_ADV_BLA | 449 | #ifdef CONFIG_BATMAN_ADV_BLA |
495 | &batadv_attr_bridge_loop_avoidance, | 450 | &batadv_attr_bridge_loop_avoidance, |
496 | #endif | 451 | #endif |
452 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
453 | &batadv_attr_distributed_arp_table, | ||
454 | #endif | ||
497 | &batadv_attr_fragmentation, | 455 | &batadv_attr_fragmentation, |
498 | &batadv_attr_ap_isolation, | 456 | &batadv_attr_ap_isolation, |
499 | &batadv_attr_vis_mode, | 457 | &batadv_attr_vis_mode, |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd371b2f..f8b9c32c29a5 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -434,22 +434,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
434 | struct hlist_node *node; | 434 | struct hlist_node *node; |
435 | struct hlist_head *head; | 435 | struct hlist_head *head; |
436 | uint32_t i; | 436 | uint32_t i; |
437 | int ret = 0; | ||
438 | |||
439 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
440 | if (!primary_if) { | ||
441 | ret = seq_printf(seq, | ||
442 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
443 | net_dev->name); | ||
444 | goto out; | ||
445 | } | ||
446 | 437 | ||
447 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | 438 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
448 | ret = seq_printf(seq, | 439 | if (!primary_if) |
449 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
450 | net_dev->name); | ||
451 | goto out; | 440 | goto out; |
452 | } | ||
453 | 441 | ||
454 | seq_printf(seq, | 442 | seq_printf(seq, |
455 | "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", | 443 | "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", |
@@ -479,7 +467,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
479 | out: | 467 | out: |
480 | if (primary_if) | 468 | if (primary_if) |
481 | batadv_hardif_free_ref(primary_if); | 469 | batadv_hardif_free_ref(primary_if); |
482 | return ret; | 470 | return 0; |
483 | } | 471 | } |
484 | 472 | ||
485 | static void | 473 | static void |
@@ -501,24 +489,39 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv, | |||
501 | tt_local_entry->common.addr, message); | 489 | tt_local_entry->common.addr, message); |
502 | } | 490 | } |
503 | 491 | ||
504 | void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr, | 492 | /** |
505 | const char *message, bool roaming) | 493 | * batadv_tt_local_remove - logically remove an entry from the local table |
494 | * @bat_priv: the bat priv with all the soft interface information | ||
495 | * @addr: the MAC address of the client to remove | ||
496 | * @message: message to append to the log on deletion | ||
497 | * @roaming: true if the deletion is due to a roaming event | ||
498 | * | ||
499 | * Returns the flags assigned to the local entry before being deleted | ||
500 | */ | ||
501 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | ||
502 | const uint8_t *addr, const char *message, | ||
503 | bool roaming) | ||
506 | { | 504 | { |
507 | struct batadv_tt_local_entry *tt_local_entry = NULL; | 505 | struct batadv_tt_local_entry *tt_local_entry = NULL; |
508 | uint16_t flags; | 506 | uint16_t flags, curr_flags = BATADV_NO_FLAGS; |
509 | 507 | ||
510 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); | 508 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); |
511 | if (!tt_local_entry) | 509 | if (!tt_local_entry) |
512 | goto out; | 510 | goto out; |
513 | 511 | ||
512 | curr_flags = tt_local_entry->common.flags; | ||
513 | |||
514 | flags = BATADV_TT_CLIENT_DEL; | 514 | flags = BATADV_TT_CLIENT_DEL; |
515 | if (roaming) | 515 | if (roaming) |
516 | flags |= BATADV_TT_CLIENT_ROAM; | 516 | flags |= BATADV_TT_CLIENT_ROAM; |
517 | 517 | ||
518 | batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); | 518 | batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); |
519 | |||
519 | out: | 520 | out: |
520 | if (tt_local_entry) | 521 | if (tt_local_entry) |
521 | batadv_tt_local_entry_free_ref(tt_local_entry); | 522 | batadv_tt_local_entry_free_ref(tt_local_entry); |
523 | |||
524 | return curr_flags; | ||
522 | } | 525 | } |
523 | 526 | ||
524 | static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, | 527 | static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, |
@@ -725,6 +728,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
725 | int ret = 0; | 728 | int ret = 0; |
726 | int hash_added; | 729 | int hash_added; |
727 | struct batadv_tt_common_entry *common; | 730 | struct batadv_tt_common_entry *common; |
731 | uint16_t local_flags; | ||
728 | 732 | ||
729 | tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); | 733 | tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); |
730 | 734 | ||
@@ -738,6 +742,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
738 | 742 | ||
739 | common->flags = flags; | 743 | common->flags = flags; |
740 | tt_global_entry->roam_at = 0; | 744 | tt_global_entry->roam_at = 0; |
745 | /* node must store current time in case of roaming. This is | ||
746 | * needed to purge this entry out on timeout (if nobody claims | ||
747 | * it) | ||
748 | */ | ||
749 | if (flags & BATADV_TT_CLIENT_ROAM) | ||
750 | tt_global_entry->roam_at = jiffies; | ||
741 | atomic_set(&common->refcount, 2); | 751 | atomic_set(&common->refcount, 2); |
742 | common->added_at = jiffies; | 752 | common->added_at = jiffies; |
743 | 753 | ||
@@ -788,13 +798,16 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
788 | batadv_dbg(BATADV_DBG_TT, bat_priv, | 798 | batadv_dbg(BATADV_DBG_TT, bat_priv, |
789 | "Creating new global tt entry: %pM (via %pM)\n", | 799 | "Creating new global tt entry: %pM (via %pM)\n", |
790 | tt_global_entry->common.addr, orig_node->orig); | 800 | tt_global_entry->common.addr, orig_node->orig); |
801 | ret = 1; | ||
791 | 802 | ||
792 | out_remove: | 803 | out_remove: |
804 | |||
793 | /* remove address from local hash if present */ | 805 | /* remove address from local hash if present */ |
794 | batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, | 806 | local_flags = batadv_tt_local_remove(bat_priv, tt_addr, |
795 | "global tt received", | 807 | "global tt received", |
796 | flags & BATADV_TT_CLIENT_ROAM); | 808 | flags & BATADV_TT_CLIENT_ROAM); |
797 | ret = 1; | 809 | tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; |
810 | |||
798 | out: | 811 | out: |
799 | if (tt_global_entry) | 812 | if (tt_global_entry) |
800 | batadv_tt_global_entry_free_ref(tt_global_entry); | 813 | batadv_tt_global_entry_free_ref(tt_global_entry); |
@@ -842,22 +855,10 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
842 | struct hlist_node *node; | 855 | struct hlist_node *node; |
843 | struct hlist_head *head; | 856 | struct hlist_head *head; |
844 | uint32_t i; | 857 | uint32_t i; |
845 | int ret = 0; | ||
846 | |||
847 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
848 | if (!primary_if) { | ||
849 | ret = seq_printf(seq, | ||
850 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
851 | net_dev->name); | ||
852 | goto out; | ||
853 | } | ||
854 | 858 | ||
855 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | 859 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
856 | ret = seq_printf(seq, | 860 | if (!primary_if) |
857 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
858 | net_dev->name); | ||
859 | goto out; | 861 | goto out; |
860 | } | ||
861 | 862 | ||
862 | seq_printf(seq, | 863 | seq_printf(seq, |
863 | "Globally announced TT entries received via the mesh %s\n", | 864 | "Globally announced TT entries received via the mesh %s\n", |
@@ -881,7 +882,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
881 | out: | 882 | out: |
882 | if (primary_if) | 883 | if (primary_if) |
883 | batadv_hardif_free_ref(primary_if); | 884 | batadv_hardif_free_ref(primary_if); |
884 | return ret; | 885 | return 0; |
885 | } | 886 | } |
886 | 887 | ||
887 | /* deletes the orig list of a tt_global_entry */ | 888 | /* deletes the orig list of a tt_global_entry */ |
@@ -1471,11 +1472,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, | |||
1471 | tt_tot = tt_len / sizeof(struct batadv_tt_change); | 1472 | tt_tot = tt_len / sizeof(struct batadv_tt_change); |
1472 | 1473 | ||
1473 | len = tt_query_size + tt_len; | 1474 | len = tt_query_size + tt_len; |
1474 | skb = dev_alloc_skb(len + ETH_HLEN); | 1475 | skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); |
1475 | if (!skb) | 1476 | if (!skb) |
1476 | goto out; | 1477 | goto out; |
1477 | 1478 | ||
1478 | skb_reserve(skb, ETH_HLEN); | 1479 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
1479 | tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); | 1480 | tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len); |
1480 | tt_response->ttvn = ttvn; | 1481 | tt_response->ttvn = ttvn; |
1481 | 1482 | ||
@@ -1537,11 +1538,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, | |||
1537 | if (!tt_req_node) | 1538 | if (!tt_req_node) |
1538 | goto out; | 1539 | goto out; |
1539 | 1540 | ||
1540 | skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN); | 1541 | skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN); |
1541 | if (!skb) | 1542 | if (!skb) |
1542 | goto out; | 1543 | goto out; |
1543 | 1544 | ||
1544 | skb_reserve(skb, ETH_HLEN); | 1545 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
1545 | 1546 | ||
1546 | tt_req_len = sizeof(*tt_request); | 1547 | tt_req_len = sizeof(*tt_request); |
1547 | tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); | 1548 | tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len); |
@@ -1652,11 +1653,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, | |||
1652 | tt_tot = tt_len / sizeof(struct batadv_tt_change); | 1653 | tt_tot = tt_len / sizeof(struct batadv_tt_change); |
1653 | 1654 | ||
1654 | len = sizeof(*tt_response) + tt_len; | 1655 | len = sizeof(*tt_response) + tt_len; |
1655 | skb = dev_alloc_skb(len + ETH_HLEN); | 1656 | skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); |
1656 | if (!skb) | 1657 | if (!skb) |
1657 | goto unlock; | 1658 | goto unlock; |
1658 | 1659 | ||
1659 | skb_reserve(skb, ETH_HLEN); | 1660 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
1660 | packet_pos = skb_put(skb, len); | 1661 | packet_pos = skb_put(skb, len); |
1661 | tt_response = (struct batadv_tt_query_packet *)packet_pos; | 1662 | tt_response = (struct batadv_tt_query_packet *)packet_pos; |
1662 | tt_response->ttvn = req_ttvn; | 1663 | tt_response->ttvn = req_ttvn; |
@@ -1779,11 +1780,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, | |||
1779 | tt_tot = tt_len / sizeof(struct batadv_tt_change); | 1780 | tt_tot = tt_len / sizeof(struct batadv_tt_change); |
1780 | 1781 | ||
1781 | len = sizeof(*tt_response) + tt_len; | 1782 | len = sizeof(*tt_response) + tt_len; |
1782 | skb = dev_alloc_skb(len + ETH_HLEN); | 1783 | skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); |
1783 | if (!skb) | 1784 | if (!skb) |
1784 | goto unlock; | 1785 | goto unlock; |
1785 | 1786 | ||
1786 | skb_reserve(skb, ETH_HLEN); | 1787 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
1787 | packet_pos = skb_put(skb, len); | 1788 | packet_pos = skb_put(skb, len); |
1788 | tt_response = (struct batadv_tt_query_packet *)packet_pos; | 1789 | tt_response = (struct batadv_tt_query_packet *)packet_pos; |
1789 | tt_response->ttvn = req_ttvn; | 1790 | tt_response->ttvn = req_ttvn; |
@@ -2117,11 +2118,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, | |||
2117 | if (!batadv_tt_check_roam_count(bat_priv, client)) | 2118 | if (!batadv_tt_check_roam_count(bat_priv, client)) |
2118 | goto out; | 2119 | goto out; |
2119 | 2120 | ||
2120 | skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN); | 2121 | skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN); |
2121 | if (!skb) | 2122 | if (!skb) |
2122 | goto out; | 2123 | goto out; |
2123 | 2124 | ||
2124 | skb_reserve(skb, ETH_HLEN); | 2125 | skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); |
2125 | 2126 | ||
2126 | roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); | 2127 | roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); |
2127 | 2128 | ||
@@ -2438,7 +2439,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, | |||
2438 | if (!tt_global_entry) | 2439 | if (!tt_global_entry) |
2439 | goto out; | 2440 | goto out; |
2440 | 2441 | ||
2441 | ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; | 2442 | ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM); |
2442 | batadv_tt_global_entry_free_ref(tt_global_entry); | 2443 | batadv_tt_global_entry_free_ref(tt_global_entry); |
2443 | out: | 2444 | out: |
2444 | return ret; | 2445 | return ret; |
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index 811fffd4760c..9fa4fe41c868 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h | |||
@@ -24,9 +24,9 @@ int batadv_tt_len(int changes_num); | |||
24 | int batadv_tt_init(struct batadv_priv *bat_priv); | 24 | int batadv_tt_init(struct batadv_priv *bat_priv); |
25 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | 25 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, |
26 | int ifindex); | 26 | int ifindex); |
27 | void batadv_tt_local_remove(struct batadv_priv *bat_priv, | 27 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, |
28 | const uint8_t *addr, const char *message, | 28 | const uint8_t *addr, const char *message, |
29 | bool roaming); | 29 | bool roaming); |
30 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); | 30 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); |
31 | void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, | 31 | void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, |
32 | struct batadv_orig_node *orig_node, | 32 | struct batadv_orig_node *orig_node, |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index ac1e07a80454..8ce16c1cbafb 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -28,20 +28,41 @@ | |||
28 | (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \ | 28 | (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \ |
29 | sizeof(struct batadv_bcast_packet))) | 29 | sizeof(struct batadv_bcast_packet))) |
30 | 30 | ||
31 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
32 | |||
33 | /* batadv_dat_addr_t is the type used for all DHT addresses. If it is changed, | ||
34 | * BATADV_DAT_ADDR_MAX is changed as well. | ||
35 | * | ||
36 | * *Please be careful: batadv_dat_addr_t must be UNSIGNED* | ||
37 | */ | ||
38 | #define batadv_dat_addr_t uint16_t | ||
39 | |||
40 | #endif /* CONFIG_BATMAN_ADV_DAT */ | ||
41 | |||
42 | /** | ||
43 | * struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data | ||
44 | * @ogm_buff: buffer holding the OGM packet | ||
45 | * @ogm_buff_len: length of the OGM packet buffer | ||
46 | * @ogm_seqno: OGM sequence number - used to identify each OGM | ||
47 | */ | ||
48 | struct batadv_hard_iface_bat_iv { | ||
49 | unsigned char *ogm_buff; | ||
50 | int ogm_buff_len; | ||
51 | atomic_t ogm_seqno; | ||
52 | }; | ||
53 | |||
31 | struct batadv_hard_iface { | 54 | struct batadv_hard_iface { |
32 | struct list_head list; | 55 | struct list_head list; |
33 | int16_t if_num; | 56 | int16_t if_num; |
34 | char if_status; | 57 | char if_status; |
35 | struct net_device *net_dev; | 58 | struct net_device *net_dev; |
36 | atomic_t seqno; | ||
37 | atomic_t frag_seqno; | 59 | atomic_t frag_seqno; |
38 | unsigned char *packet_buff; | ||
39 | int packet_len; | ||
40 | struct kobject *hardif_obj; | 60 | struct kobject *hardif_obj; |
41 | atomic_t refcount; | 61 | atomic_t refcount; |
42 | struct packet_type batman_adv_ptype; | 62 | struct packet_type batman_adv_ptype; |
43 | struct net_device *soft_iface; | 63 | struct net_device *soft_iface; |
44 | struct rcu_head rcu; | 64 | struct rcu_head rcu; |
65 | struct batadv_hard_iface_bat_iv bat_iv; | ||
45 | }; | 66 | }; |
46 | 67 | ||
47 | /** | 68 | /** |
@@ -63,6 +84,9 @@ struct batadv_orig_node { | |||
63 | uint8_t orig[ETH_ALEN]; | 84 | uint8_t orig[ETH_ALEN]; |
64 | uint8_t primary_addr[ETH_ALEN]; | 85 | uint8_t primary_addr[ETH_ALEN]; |
65 | struct batadv_neigh_node __rcu *router; /* rcu protected pointer */ | 86 | struct batadv_neigh_node __rcu *router; /* rcu protected pointer */ |
87 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
88 | batadv_dat_addr_t dat_addr; | ||
89 | #endif | ||
66 | unsigned long *bcast_own; | 90 | unsigned long *bcast_own; |
67 | uint8_t *bcast_own_sum; | 91 | uint8_t *bcast_own_sum; |
68 | unsigned long last_seen; | 92 | unsigned long last_seen; |
@@ -162,6 +186,13 @@ enum batadv_counters { | |||
162 | BATADV_CNT_TT_RESPONSE_RX, | 186 | BATADV_CNT_TT_RESPONSE_RX, |
163 | BATADV_CNT_TT_ROAM_ADV_TX, | 187 | BATADV_CNT_TT_ROAM_ADV_TX, |
164 | BATADV_CNT_TT_ROAM_ADV_RX, | 188 | BATADV_CNT_TT_ROAM_ADV_RX, |
189 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
190 | BATADV_CNT_DAT_GET_TX, | ||
191 | BATADV_CNT_DAT_GET_RX, | ||
192 | BATADV_CNT_DAT_PUT_TX, | ||
193 | BATADV_CNT_DAT_PUT_RX, | ||
194 | BATADV_CNT_DAT_CACHED_REPLY_TX, | ||
195 | #endif | ||
165 | BATADV_CNT_NUM, | 196 | BATADV_CNT_NUM, |
166 | }; | 197 | }; |
167 | 198 | ||
@@ -228,6 +259,20 @@ struct batadv_priv_vis { | |||
228 | struct batadv_vis_info *my_info; | 259 | struct batadv_vis_info *my_info; |
229 | }; | 260 | }; |
230 | 261 | ||
262 | /** | ||
263 | * struct batadv_priv_dat - per mesh interface DAT private data | ||
264 | * @addr: node DAT address | ||
265 | * @hash: hashtable representing the local ARP cache | ||
266 | * @work: work queue callback item for cache purging | ||
267 | */ | ||
268 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
269 | struct batadv_priv_dat { | ||
270 | batadv_dat_addr_t addr; | ||
271 | struct batadv_hashtable *hash; | ||
272 | struct delayed_work work; | ||
273 | }; | ||
274 | #endif | ||
275 | |||
231 | struct batadv_priv { | 276 | struct batadv_priv { |
232 | atomic_t mesh_state; | 277 | atomic_t mesh_state; |
233 | struct net_device_stats stats; | 278 | struct net_device_stats stats; |
@@ -237,6 +282,9 @@ struct batadv_priv { | |||
237 | atomic_t fragmentation; /* boolean */ | 282 | atomic_t fragmentation; /* boolean */ |
238 | atomic_t ap_isolation; /* boolean */ | 283 | atomic_t ap_isolation; /* boolean */ |
239 | atomic_t bridge_loop_avoidance; /* boolean */ | 284 | atomic_t bridge_loop_avoidance; /* boolean */ |
285 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
286 | atomic_t distributed_arp_table; /* boolean */ | ||
287 | #endif | ||
240 | atomic_t vis_mode; /* VIS_TYPE_* */ | 288 | atomic_t vis_mode; /* VIS_TYPE_* */ |
241 | atomic_t gw_mode; /* GW_MODE_* */ | 289 | atomic_t gw_mode; /* GW_MODE_* */ |
242 | atomic_t gw_sel_class; /* uint */ | 290 | atomic_t gw_sel_class; /* uint */ |
@@ -265,6 +313,9 @@ struct batadv_priv { | |||
265 | struct batadv_priv_gw gw; | 313 | struct batadv_priv_gw gw; |
266 | struct batadv_priv_tt tt; | 314 | struct batadv_priv_tt tt; |
267 | struct batadv_priv_vis vis; | 315 | struct batadv_priv_vis vis; |
316 | #ifdef CONFIG_BATMAN_ADV_DAT | ||
317 | struct batadv_priv_dat dat; | ||
318 | #endif | ||
268 | }; | 319 | }; |
269 | 320 | ||
270 | struct batadv_socket_client { | 321 | struct batadv_socket_client { |
@@ -437,4 +488,36 @@ struct batadv_algo_ops { | |||
437 | void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); | 488 | void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); |
438 | }; | 489 | }; |
439 | 490 | ||
491 | /** | ||
492 | * struct batadv_dat_entry - it is a single entry of batman-adv ARP backend. It | ||
493 | * is used to stored ARP entries needed for the global DAT cache | ||
494 | * @ip: the IPv4 corresponding to this DAT/ARP entry | ||
495 | * @mac_addr: the MAC address associated to the stored IPv4 | ||
496 | * @last_update: time in jiffies when this entry was refreshed last time | ||
497 | * @hash_entry: hlist node for batadv_priv_dat::hash | ||
498 | * @refcount: number of contexts the object is used | ||
499 | * @rcu: struct used for freeing in an RCU-safe manner | ||
500 | */ | ||
501 | struct batadv_dat_entry { | ||
502 | __be32 ip; | ||
503 | uint8_t mac_addr[ETH_ALEN]; | ||
504 | unsigned long last_update; | ||
505 | struct hlist_node hash_entry; | ||
506 | atomic_t refcount; | ||
507 | struct rcu_head rcu; | ||
508 | }; | ||
509 | |||
510 | /** | ||
511 | * struct batadv_dat_candidate - candidate destination for DAT operations | ||
512 | * @type: the type of the selected candidate. It can one of the following: | ||
513 | * - BATADV_DAT_CANDIDATE_NOT_FOUND | ||
514 | * - BATADV_DAT_CANDIDATE_ORIG | ||
515 | * @orig_node: if type is BATADV_DAT_CANDIDATE_ORIG this field points to the | ||
516 | * corresponding originator node structure | ||
517 | */ | ||
518 | struct batadv_dat_candidate { | ||
519 | int type; | ||
520 | struct batadv_orig_node *orig_node; | ||
521 | }; | ||
522 | |||
440 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ | 523 | #endif /* _NET_BATMAN_ADV_TYPES_H_ */ |
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index f39723281ca1..c9a1f6523c36 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
@@ -291,7 +291,111 @@ out: | |||
291 | return ret; | 291 | return ret; |
292 | } | 292 | } |
293 | 293 | ||
294 | int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) | 294 | /** |
295 | * batadv_unicast_push_and_fill_skb - extends the buffer and initializes the | ||
296 | * common fields for unicast packets | ||
297 | * @skb: packet | ||
298 | * @hdr_size: amount of bytes to push at the beginning of the skb | ||
299 | * @orig_node: the destination node | ||
300 | * | ||
301 | * Returns false if the buffer extension was not possible or true otherwise | ||
302 | */ | ||
303 | static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size, | ||
304 | struct batadv_orig_node *orig_node) | ||
305 | { | ||
306 | struct batadv_unicast_packet *unicast_packet; | ||
307 | uint8_t ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); | ||
308 | |||
309 | if (batadv_skb_head_push(skb, hdr_size) < 0) | ||
310 | return false; | ||
311 | |||
312 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | ||
313 | unicast_packet->header.version = BATADV_COMPAT_VERSION; | ||
314 | /* batman packet type: unicast */ | ||
315 | unicast_packet->header.packet_type = BATADV_UNICAST; | ||
316 | /* set unicast ttl */ | ||
317 | unicast_packet->header.ttl = BATADV_TTL; | ||
318 | /* copy the destination for faster routing */ | ||
319 | memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); | ||
320 | /* set the destination tt version number */ | ||
321 | unicast_packet->ttvn = ttvn; | ||
322 | |||
323 | return true; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * batadv_unicast_prepare_skb - encapsulate an skb with a unicast header | ||
328 | * @skb: the skb containing the payload to encapsulate | ||
329 | * @orig_node: the destination node | ||
330 | * | ||
331 | * Returns false if the payload could not be encapsulated or true otherwise | ||
332 | */ | ||
333 | static bool batadv_unicast_prepare_skb(struct sk_buff *skb, | ||
334 | struct batadv_orig_node *orig_node) | ||
335 | { | ||
336 | size_t uni_size = sizeof(struct batadv_unicast_packet); | ||
337 | return batadv_unicast_push_and_fill_skb(skb, uni_size, orig_node); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * batadv_unicast_4addr_prepare_skb - encapsulate an skb with a unicast4addr | ||
342 | * header | ||
343 | * @bat_priv: the bat priv with all the soft interface information | ||
344 | * @skb: the skb containing the payload to encapsulate | ||
345 | * @orig_node: the destination node | ||
346 | * @packet_subtype: the batman 4addr packet subtype to use | ||
347 | * | ||
348 | * Returns false if the payload could not be encapsulated or true otherwise | ||
349 | */ | ||
350 | bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv, | ||
351 | struct sk_buff *skb, | ||
352 | struct batadv_orig_node *orig, | ||
353 | int packet_subtype) | ||
354 | { | ||
355 | struct batadv_hard_iface *primary_if; | ||
356 | struct batadv_unicast_4addr_packet *unicast_4addr_packet; | ||
357 | bool ret = false; | ||
358 | |||
359 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
360 | if (!primary_if) | ||
361 | goto out; | ||
362 | |||
363 | /* pull the header space and fill the unicast_packet substructure. | ||
364 | * We can do that because the first member of the unicast_4addr_packet | ||
365 | * is of type struct unicast_packet | ||
366 | */ | ||
367 | if (!batadv_unicast_push_and_fill_skb(skb, | ||
368 | sizeof(*unicast_4addr_packet), | ||
369 | orig)) | ||
370 | goto out; | ||
371 | |||
372 | unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; | ||
373 | unicast_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR; | ||
374 | memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr, | ||
375 | ETH_ALEN); | ||
376 | unicast_4addr_packet->subtype = packet_subtype; | ||
377 | unicast_4addr_packet->reserved = 0; | ||
378 | |||
379 | ret = true; | ||
380 | out: | ||
381 | if (primary_if) | ||
382 | batadv_hardif_free_ref(primary_if); | ||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * batadv_unicast_generic_send_skb - send an skb as unicast | ||
388 | * @bat_priv: the bat priv with all the soft interface information | ||
389 | * @skb: payload to send | ||
390 | * @packet_type: the batman unicast packet type to use | ||
391 | * @packet_subtype: the batman packet subtype. It is ignored if packet_type is | ||
392 | * not BATADV_UNICAT_4ADDR | ||
393 | * | ||
394 | * Returns 1 in case of error or 0 otherwise | ||
395 | */ | ||
396 | int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, | ||
397 | struct sk_buff *skb, int packet_type, | ||
398 | int packet_subtype) | ||
295 | { | 399 | { |
296 | struct ethhdr *ethhdr = (struct ethhdr *)skb->data; | 400 | struct ethhdr *ethhdr = (struct ethhdr *)skb->data; |
297 | struct batadv_unicast_packet *unicast_packet; | 401 | struct batadv_unicast_packet *unicast_packet; |
@@ -324,21 +428,23 @@ find_router: | |||
324 | if (!neigh_node) | 428 | if (!neigh_node) |
325 | goto out; | 429 | goto out; |
326 | 430 | ||
327 | if (batadv_skb_head_push(skb, sizeof(*unicast_packet)) < 0) | 431 | switch (packet_type) { |
432 | case BATADV_UNICAST: | ||
433 | batadv_unicast_prepare_skb(skb, orig_node); | ||
434 | break; | ||
435 | case BATADV_UNICAST_4ADDR: | ||
436 | batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node, | ||
437 | packet_subtype); | ||
438 | break; | ||
439 | default: | ||
440 | /* this function supports UNICAST and UNICAST_4ADDR only. It | ||
441 | * should never be invoked with any other packet type | ||
442 | */ | ||
328 | goto out; | 443 | goto out; |
444 | } | ||
329 | 445 | ||
330 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 446 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
331 | 447 | ||
332 | unicast_packet->header.version = BATADV_COMPAT_VERSION; | ||
333 | /* batman packet type: unicast */ | ||
334 | unicast_packet->header.packet_type = BATADV_UNICAST; | ||
335 | /* set unicast ttl */ | ||
336 | unicast_packet->header.ttl = BATADV_TTL; | ||
337 | /* copy the destination for faster routing */ | ||
338 | memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); | ||
339 | /* set the destination tt version number */ | ||
340 | unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); | ||
341 | |||
342 | /* inform the destination node that we are still missing a correct route | 448 | /* inform the destination node that we are still missing a correct route |
343 | * for this client. The destination will receive this packet and will | 449 | * for this client. The destination will receive this packet and will |
344 | * try to reroute it because the ttvn contained in the header is less | 450 | * try to reroute it because the ttvn contained in the header is less |
@@ -348,7 +454,9 @@ find_router: | |||
348 | unicast_packet->ttvn = unicast_packet->ttvn - 1; | 454 | unicast_packet->ttvn = unicast_packet->ttvn - 1; |
349 | 455 | ||
350 | dev_mtu = neigh_node->if_incoming->net_dev->mtu; | 456 | dev_mtu = neigh_node->if_incoming->net_dev->mtu; |
351 | if (atomic_read(&bat_priv->fragmentation) && | 457 | /* fragmentation mechanism only works for UNICAST (now) */ |
458 | if (packet_type == BATADV_UNICAST && | ||
459 | atomic_read(&bat_priv->fragmentation) && | ||
352 | data_len + sizeof(*unicast_packet) > dev_mtu) { | 460 | data_len + sizeof(*unicast_packet) > dev_mtu) { |
353 | /* send frag skb decreases ttl */ | 461 | /* send frag skb decreases ttl */ |
354 | unicast_packet->header.ttl++; | 462 | unicast_packet->header.ttl++; |
@@ -360,7 +468,6 @@ find_router: | |||
360 | 468 | ||
361 | batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); | 469 | batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); |
362 | ret = 0; | 470 | ret = 0; |
363 | goto out; | ||
364 | 471 | ||
365 | out: | 472 | out: |
366 | if (neigh_node) | 473 | if (neigh_node) |
diff --git a/net/batman-adv/unicast.h b/net/batman-adv/unicast.h index 1c46e2eb1ef9..61abba58bd8f 100644 --- a/net/batman-adv/unicast.h +++ b/net/batman-adv/unicast.h | |||
@@ -29,10 +29,44 @@ int batadv_frag_reassemble_skb(struct sk_buff *skb, | |||
29 | struct batadv_priv *bat_priv, | 29 | struct batadv_priv *bat_priv, |
30 | struct sk_buff **new_skb); | 30 | struct sk_buff **new_skb); |
31 | void batadv_frag_list_free(struct list_head *head); | 31 | void batadv_frag_list_free(struct list_head *head); |
32 | int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv); | ||
33 | int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, | 32 | int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv, |
34 | struct batadv_hard_iface *hard_iface, | 33 | struct batadv_hard_iface *hard_iface, |
35 | const uint8_t dstaddr[]); | 34 | const uint8_t dstaddr[]); |
35 | bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv, | ||
36 | struct sk_buff *skb, | ||
37 | struct batadv_orig_node *orig_node, | ||
38 | int packet_subtype); | ||
39 | int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, | ||
40 | struct sk_buff *skb, int packet_type, | ||
41 | int packet_subtype); | ||
42 | |||
43 | |||
44 | /** | ||
45 | * batadv_unicast_send_skb - send the skb encapsulated in a unicast packet | ||
46 | * @bat_priv: the bat priv with all the soft interface information | ||
47 | * @skb: the payload to send | ||
48 | */ | ||
49 | static inline int batadv_unicast_send_skb(struct batadv_priv *bat_priv, | ||
50 | struct sk_buff *skb) | ||
51 | { | ||
52 | return batadv_unicast_generic_send_skb(bat_priv, skb, BATADV_UNICAST, | ||
53 | 0); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * batadv_unicast_send_skb - send the skb encapsulated in a unicast4addr packet | ||
58 | * @bat_priv: the bat priv with all the soft interface information | ||
59 | * @skb: the payload to send | ||
60 | * @packet_subtype: the batman 4addr packet subtype to use | ||
61 | */ | ||
62 | static inline int batadv_unicast_4addr_send_skb(struct batadv_priv *bat_priv, | ||
63 | struct sk_buff *skb, | ||
64 | int packet_subtype) | ||
65 | { | ||
66 | return batadv_unicast_generic_send_skb(bat_priv, skb, | ||
67 | BATADV_UNICAST_4ADDR, | ||
68 | packet_subtype); | ||
69 | } | ||
36 | 70 | ||
37 | static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu) | 71 | static inline int batadv_frag_can_reassemble(const struct sk_buff *skb, int mtu) |
38 | { | 72 | { |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 5abd1454fb07..ad14a6c91d6a 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -396,12 +396,12 @@ batadv_add_packet(struct batadv_priv *bat_priv, | |||
396 | return NULL; | 396 | return NULL; |
397 | 397 | ||
398 | len = sizeof(*packet) + vis_info_len; | 398 | len = sizeof(*packet) + vis_info_len; |
399 | info->skb_packet = dev_alloc_skb(len + ETH_HLEN); | 399 | info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN); |
400 | if (!info->skb_packet) { | 400 | if (!info->skb_packet) { |
401 | kfree(info); | 401 | kfree(info); |
402 | return NULL; | 402 | return NULL; |
403 | } | 403 | } |
404 | skb_reserve(info->skb_packet, ETH_HLEN); | 404 | skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN); |
405 | packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len); | 405 | packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len); |
406 | 406 | ||
407 | kref_init(&info->refcount); | 407 | kref_init(&info->refcount); |
@@ -873,12 +873,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv) | |||
873 | if (!bat_priv->vis.my_info) | 873 | if (!bat_priv->vis.my_info) |
874 | goto err; | 874 | goto err; |
875 | 875 | ||
876 | len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; | 876 | len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE; |
877 | len += ETH_HLEN + NET_IP_ALIGN; | ||
877 | bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); | 878 | bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); |
878 | if (!bat_priv->vis.my_info->skb_packet) | 879 | if (!bat_priv->vis.my_info->skb_packet) |
879 | goto free_info; | 880 | goto free_info; |
880 | 881 | ||
881 | skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN); | 882 | skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN); |
882 | tmp_skb = bat_priv->vis.my_info->skb_packet; | 883 | tmp_skb = bat_priv->vis.my_info->skb_packet; |
883 | packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); | 884 | packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); |
884 | 885 | ||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 070e8a68cfc6..7c78e2640190 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -313,6 +313,8 @@ static const struct net_device_ops br_netdev_ops = { | |||
313 | .ndo_fdb_add = br_fdb_add, | 313 | .ndo_fdb_add = br_fdb_add, |
314 | .ndo_fdb_del = br_fdb_delete, | 314 | .ndo_fdb_del = br_fdb_delete, |
315 | .ndo_fdb_dump = br_fdb_dump, | 315 | .ndo_fdb_dump = br_fdb_dump, |
316 | .ndo_bridge_getlink = br_getlink, | ||
317 | .ndo_bridge_setlink = br_setlink, | ||
316 | }; | 318 | }; |
317 | 319 | ||
318 | static void br_dev_free(struct net_device *dev) | 320 | static void br_dev_free(struct net_device *dev) |
@@ -356,7 +358,7 @@ void br_dev_setup(struct net_device *dev) | |||
356 | br->bridge_id.prio[0] = 0x80; | 358 | br->bridge_id.prio[0] = 0x80; |
357 | br->bridge_id.prio[1] = 0x00; | 359 | br->bridge_id.prio[1] = 0x00; |
358 | 360 | ||
359 | memcpy(br->group_addr, br_group_address, ETH_ALEN); | 361 | memcpy(br->group_addr, eth_reserved_addr_base, ETH_ALEN); |
360 | 362 | ||
361 | br->stp_enabled = BR_NO_STP; | 363 | br->stp_enabled = BR_NO_STP; |
362 | br->group_fwd_mask = BR_GROUPFWD_DEFAULT; | 364 | br->group_fwd_mask = BR_GROUPFWD_DEFAULT; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 76f15fda0212..4b34207419b1 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -19,9 +19,6 @@ | |||
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include "br_private.h" | 20 | #include "br_private.h" |
21 | 21 | ||
22 | /* Bridge group multicast address 802.1d (pg 51). */ | ||
23 | const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; | ||
24 | |||
25 | /* Hook for brouter */ | 22 | /* Hook for brouter */ |
26 | br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; | 23 | br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; |
27 | EXPORT_SYMBOL(br_should_route_hook); | 24 | EXPORT_SYMBOL(br_should_route_hook); |
@@ -127,18 +124,6 @@ static int br_handle_local_finish(struct sk_buff *skb) | |||
127 | return 0; /* process further */ | 124 | return 0; /* process further */ |
128 | } | 125 | } |
129 | 126 | ||
130 | /* Does address match the link local multicast address. | ||
131 | * 01:80:c2:00:00:0X | ||
132 | */ | ||
133 | static inline int is_link_local(const unsigned char *dest) | ||
134 | { | ||
135 | __be16 *a = (__be16 *)dest; | ||
136 | static const __be16 *b = (const __be16 *)br_group_address; | ||
137 | static const __be16 m = cpu_to_be16(0xfff0); | ||
138 | |||
139 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; | ||
140 | } | ||
141 | |||
142 | /* | 127 | /* |
143 | * Return NULL if skb is handled | 128 | * Return NULL if skb is handled |
144 | * note: already called with rcu_read_lock | 129 | * note: already called with rcu_read_lock |
@@ -162,7 +147,7 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) | |||
162 | 147 | ||
163 | p = br_port_get_rcu(skb->dev); | 148 | p = br_port_get_rcu(skb->dev); |
164 | 149 | ||
165 | if (unlikely(is_link_local(dest))) { | 150 | if (unlikely(is_link_local_ether_addr(dest))) { |
166 | /* | 151 | /* |
167 | * See IEEE 802.1D Table 7-10 Reserved addresses | 152 | * See IEEE 802.1D Table 7-10 Reserved addresses |
168 | * | 153 | * |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 093f527276a3..14b065cbd214 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -111,54 +111,33 @@ errout: | |||
111 | /* | 111 | /* |
112 | * Dump information about all ports, in response to GETLINK | 112 | * Dump information about all ports, in response to GETLINK |
113 | */ | 113 | */ |
114 | static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 114 | int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, |
115 | struct net_device *dev) | ||
115 | { | 116 | { |
116 | struct net *net = sock_net(skb->sk); | 117 | int err = 0; |
117 | struct net_device *dev; | 118 | struct net_bridge_port *port = br_port_get_rcu(dev); |
118 | int idx; | 119 | |
119 | 120 | /* not a bridge port */ | |
120 | idx = 0; | 121 | if (!port) |
121 | rcu_read_lock(); | 122 | goto out; |
122 | for_each_netdev_rcu(net, dev) { | ||
123 | struct net_bridge_port *port = br_port_get_rcu(dev); | ||
124 | |||
125 | /* not a bridge port */ | ||
126 | if (!port || idx < cb->args[0]) | ||
127 | goto skip; | ||
128 | |||
129 | if (br_fill_ifinfo(skb, port, | ||
130 | NETLINK_CB(cb->skb).portid, | ||
131 | cb->nlh->nlmsg_seq, RTM_NEWLINK, | ||
132 | NLM_F_MULTI) < 0) | ||
133 | break; | ||
134 | skip: | ||
135 | ++idx; | ||
136 | } | ||
137 | rcu_read_unlock(); | ||
138 | cb->args[0] = idx; | ||
139 | 123 | ||
140 | return skb->len; | 124 | err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI); |
125 | out: | ||
126 | return err; | ||
141 | } | 127 | } |
142 | 128 | ||
143 | /* | 129 | /* |
144 | * Change state of port (ie from forwarding to blocking etc) | 130 | * Change state of port (ie from forwarding to blocking etc) |
145 | * Used by spanning tree in user space. | 131 | * Used by spanning tree in user space. |
146 | */ | 132 | */ |
147 | static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 133 | int br_setlink(struct net_device *dev, struct nlmsghdr *nlh) |
148 | { | 134 | { |
149 | struct net *net = sock_net(skb->sk); | ||
150 | struct ifinfomsg *ifm; | 135 | struct ifinfomsg *ifm; |
151 | struct nlattr *protinfo; | 136 | struct nlattr *protinfo; |
152 | struct net_device *dev; | ||
153 | struct net_bridge_port *p; | 137 | struct net_bridge_port *p; |
154 | u8 new_state; | 138 | u8 new_state; |
155 | 139 | ||
156 | if (nlmsg_len(nlh) < sizeof(*ifm)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | ifm = nlmsg_data(nlh); | 140 | ifm = nlmsg_data(nlh); |
160 | if (ifm->ifi_family != AF_BRIDGE) | ||
161 | return -EPFNOSUPPORT; | ||
162 | 141 | ||
163 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); | 142 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); |
164 | if (!protinfo || nla_len(protinfo) < sizeof(u8)) | 143 | if (!protinfo || nla_len(protinfo) < sizeof(u8)) |
@@ -168,10 +147,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
168 | if (new_state > BR_STATE_BLOCKING) | 147 | if (new_state > BR_STATE_BLOCKING) |
169 | return -EINVAL; | 148 | return -EINVAL; |
170 | 149 | ||
171 | dev = __dev_get_by_index(net, ifm->ifi_index); | ||
172 | if (!dev) | ||
173 | return -ENODEV; | ||
174 | |||
175 | p = br_port_get_rtnl(dev); | 150 | p = br_port_get_rtnl(dev); |
176 | if (!p) | 151 | if (!p) |
177 | return -EINVAL; | 152 | return -EINVAL; |
@@ -191,8 +166,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
191 | br_port_state_selection(p->br); | 166 | br_port_state_selection(p->br); |
192 | spin_unlock_bh(&p->br->lock); | 167 | spin_unlock_bh(&p->br->lock); |
193 | 168 | ||
194 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
195 | |||
196 | return 0; | 169 | return 0; |
197 | } | 170 | } |
198 | 171 | ||
@@ -218,29 +191,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = { | |||
218 | 191 | ||
219 | int __init br_netlink_init(void) | 192 | int __init br_netlink_init(void) |
220 | { | 193 | { |
221 | int err; | 194 | return rtnl_link_register(&br_link_ops); |
222 | |||
223 | err = rtnl_link_register(&br_link_ops); | ||
224 | if (err < 0) | ||
225 | goto err1; | ||
226 | |||
227 | err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, | ||
228 | br_dump_ifinfo, NULL); | ||
229 | if (err) | ||
230 | goto err2; | ||
231 | err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, | ||
232 | br_rtm_setlink, NULL, NULL); | ||
233 | if (err) | ||
234 | goto err3; | ||
235 | |||
236 | return 0; | ||
237 | |||
238 | err3: | ||
239 | rtnl_unregister_all(PF_BRIDGE); | ||
240 | err2: | ||
241 | rtnl_link_unregister(&br_link_ops); | ||
242 | err1: | ||
243 | return err; | ||
244 | } | 195 | } |
245 | 196 | ||
246 | void __exit br_netlink_fini(void) | 197 | void __exit br_netlink_fini(void) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 9b278c4ebee1..22111ffd68df 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -158,7 +158,9 @@ struct net_bridge_port | |||
158 | 158 | ||
159 | static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) | 159 | static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) |
160 | { | 160 | { |
161 | struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data); | 161 | struct net_bridge_port *port = |
162 | rcu_dereference_rtnl(dev->rx_handler_data); | ||
163 | |||
162 | return br_port_exists(dev) ? port : NULL; | 164 | return br_port_exists(dev) ? port : NULL; |
163 | } | 165 | } |
164 | 166 | ||
@@ -288,7 +290,6 @@ struct br_input_skb_cb { | |||
288 | pr_debug("%s: " format, (br)->dev->name, ##args) | 290 | pr_debug("%s: " format, (br)->dev->name, ##args) |
289 | 291 | ||
290 | extern struct notifier_block br_device_notifier; | 292 | extern struct notifier_block br_device_notifier; |
291 | extern const u8 br_group_address[ETH_ALEN]; | ||
292 | 293 | ||
293 | /* called under bridge lock */ | 294 | /* called under bridge lock */ |
294 | static inline int br_is_root_bridge(const struct net_bridge *br) | 295 | static inline int br_is_root_bridge(const struct net_bridge *br) |
@@ -553,6 +554,9 @@ extern struct rtnl_link_ops br_link_ops; | |||
553 | extern int br_netlink_init(void); | 554 | extern int br_netlink_init(void); |
554 | extern void br_netlink_fini(void); | 555 | extern void br_netlink_fini(void); |
555 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); | 556 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); |
557 | extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg); | ||
558 | extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, | ||
559 | struct net_device *dev); | ||
556 | 560 | ||
557 | #ifdef CONFIG_SYSFS | 561 | #ifdef CONFIG_SYSFS |
558 | /* br_sysfs_if.c */ | 562 | /* br_sysfs_if.c */ |
@@ -566,10 +570,10 @@ extern void br_sysfs_delbr(struct net_device *dev); | |||
566 | 570 | ||
567 | #else | 571 | #else |
568 | 572 | ||
569 | #define br_sysfs_addif(p) (0) | 573 | static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; } |
570 | #define br_sysfs_renameif(p) (0) | 574 | static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; } |
571 | #define br_sysfs_addbr(dev) (0) | 575 | static inline int br_sysfs_addbr(struct net_device *dev) { return 0; } |
572 | #define br_sysfs_delbr(dev) do { } while(0) | 576 | static inline void br_sysfs_delbr(struct net_device *dev) { return; } |
573 | #endif /* CONFIG_SYSFS */ | 577 | #endif /* CONFIG_SYSFS */ |
574 | 578 | ||
575 | #endif | 579 | #endif |
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index c5c059333eab..cffb76e2161c 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/capability.h> | 14 | #include <linux/capability.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/etherdevice.h> | ||
17 | #include <linux/if_bridge.h> | 18 | #include <linux/if_bridge.h> |
18 | #include <linux/rtnetlink.h> | 19 | #include <linux/rtnetlink.h> |
19 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
@@ -297,23 +298,18 @@ static ssize_t store_group_addr(struct device *d, | |||
297 | const char *buf, size_t len) | 298 | const char *buf, size_t len) |
298 | { | 299 | { |
299 | struct net_bridge *br = to_bridge(d); | 300 | struct net_bridge *br = to_bridge(d); |
300 | unsigned int new_addr[6]; | 301 | u8 new_addr[6]; |
301 | int i; | 302 | int i; |
302 | 303 | ||
303 | if (!capable(CAP_NET_ADMIN)) | 304 | if (!capable(CAP_NET_ADMIN)) |
304 | return -EPERM; | 305 | return -EPERM; |
305 | 306 | ||
306 | if (sscanf(buf, "%x:%x:%x:%x:%x:%x", | 307 | if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", |
307 | &new_addr[0], &new_addr[1], &new_addr[2], | 308 | &new_addr[0], &new_addr[1], &new_addr[2], |
308 | &new_addr[3], &new_addr[4], &new_addr[5]) != 6) | 309 | &new_addr[3], &new_addr[4], &new_addr[5]) != 6) |
309 | return -EINVAL; | 310 | return -EINVAL; |
310 | 311 | ||
311 | /* Must be 01:80:c2:00:00:0X */ | 312 | if (!is_link_local_ether_addr(new_addr)) |
312 | for (i = 0; i < 5; i++) | ||
313 | if (new_addr[i] != br_group_address[i]) | ||
314 | return -EINVAL; | ||
315 | |||
316 | if (new_addr[5] & ~0xf) | ||
317 | return -EINVAL; | 313 | return -EINVAL; |
318 | 314 | ||
319 | if (new_addr[5] == 1 || /* 802.3x Pause address */ | 315 | if (new_addr[5] == 1 || /* 802.3x Pause address */ |
diff --git a/net/core/dev.c b/net/core/dev.c index bda6d004f9f0..83232a1be1e7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -6264,7 +6264,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
6264 | goto out; | 6264 | goto out; |
6265 | 6265 | ||
6266 | /* Ensure the device has been registrered */ | 6266 | /* Ensure the device has been registrered */ |
6267 | err = -EINVAL; | ||
6268 | if (dev->reg_state != NETREG_REGISTERED) | 6267 | if (dev->reg_state != NETREG_REGISTERED) |
6269 | goto out; | 6268 | goto out; |
6270 | 6269 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index 3d92ebb7fbcf..c23543cba132 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/reciprocal_div.h> | 39 | #include <linux/reciprocal_div.h> |
40 | #include <linux/ratelimit.h> | 40 | #include <linux/ratelimit.h> |
41 | #include <linux/seccomp.h> | 41 | #include <linux/seccomp.h> |
42 | #include <linux/if_vlan.h> | ||
42 | 43 | ||
43 | /* No hurry in this branch | 44 | /* No hurry in this branch |
44 | * | 45 | * |
@@ -341,6 +342,12 @@ load_b: | |||
341 | case BPF_S_ANC_CPU: | 342 | case BPF_S_ANC_CPU: |
342 | A = raw_smp_processor_id(); | 343 | A = raw_smp_processor_id(); |
343 | continue; | 344 | continue; |
345 | case BPF_S_ANC_VLAN_TAG: | ||
346 | A = vlan_tx_tag_get(skb); | ||
347 | continue; | ||
348 | case BPF_S_ANC_VLAN_TAG_PRESENT: | ||
349 | A = !!vlan_tx_tag_present(skb); | ||
350 | continue; | ||
344 | case BPF_S_ANC_NLATTR: { | 351 | case BPF_S_ANC_NLATTR: { |
345 | struct nlattr *nla; | 352 | struct nlattr *nla; |
346 | 353 | ||
@@ -600,6 +607,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen) | |||
600 | ANCILLARY(RXHASH); | 607 | ANCILLARY(RXHASH); |
601 | ANCILLARY(CPU); | 608 | ANCILLARY(CPU); |
602 | ANCILLARY(ALU_XOR_X); | 609 | ANCILLARY(ALU_XOR_X); |
610 | ANCILLARY(VLAN_TAG); | ||
611 | ANCILLARY(VLAN_TAG_PRESENT); | ||
603 | } | 612 | } |
604 | } | 613 | } |
605 | ftest->code = code; | 614 | ftest->code = code; |
@@ -751,3 +760,133 @@ int sk_detach_filter(struct sock *sk) | |||
751 | return ret; | 760 | return ret; |
752 | } | 761 | } |
753 | EXPORT_SYMBOL_GPL(sk_detach_filter); | 762 | EXPORT_SYMBOL_GPL(sk_detach_filter); |
763 | |||
764 | static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) | ||
765 | { | ||
766 | static const u16 decodes[] = { | ||
767 | [BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K, | ||
768 | [BPF_S_ALU_ADD_X] = BPF_ALU|BPF_ADD|BPF_X, | ||
769 | [BPF_S_ALU_SUB_K] = BPF_ALU|BPF_SUB|BPF_K, | ||
770 | [BPF_S_ALU_SUB_X] = BPF_ALU|BPF_SUB|BPF_X, | ||
771 | [BPF_S_ALU_MUL_K] = BPF_ALU|BPF_MUL|BPF_K, | ||
772 | [BPF_S_ALU_MUL_X] = BPF_ALU|BPF_MUL|BPF_X, | ||
773 | [BPF_S_ALU_DIV_X] = BPF_ALU|BPF_DIV|BPF_X, | ||
774 | [BPF_S_ALU_MOD_K] = BPF_ALU|BPF_MOD|BPF_K, | ||
775 | [BPF_S_ALU_MOD_X] = BPF_ALU|BPF_MOD|BPF_X, | ||
776 | [BPF_S_ALU_AND_K] = BPF_ALU|BPF_AND|BPF_K, | ||
777 | [BPF_S_ALU_AND_X] = BPF_ALU|BPF_AND|BPF_X, | ||
778 | [BPF_S_ALU_OR_K] = BPF_ALU|BPF_OR|BPF_K, | ||
779 | [BPF_S_ALU_OR_X] = BPF_ALU|BPF_OR|BPF_X, | ||
780 | [BPF_S_ALU_XOR_K] = BPF_ALU|BPF_XOR|BPF_K, | ||
781 | [BPF_S_ALU_XOR_X] = BPF_ALU|BPF_XOR|BPF_X, | ||
782 | [BPF_S_ALU_LSH_K] = BPF_ALU|BPF_LSH|BPF_K, | ||
783 | [BPF_S_ALU_LSH_X] = BPF_ALU|BPF_LSH|BPF_X, | ||
784 | [BPF_S_ALU_RSH_K] = BPF_ALU|BPF_RSH|BPF_K, | ||
785 | [BPF_S_ALU_RSH_X] = BPF_ALU|BPF_RSH|BPF_X, | ||
786 | [BPF_S_ALU_NEG] = BPF_ALU|BPF_NEG, | ||
787 | [BPF_S_LD_W_ABS] = BPF_LD|BPF_W|BPF_ABS, | ||
788 | [BPF_S_LD_H_ABS] = BPF_LD|BPF_H|BPF_ABS, | ||
789 | [BPF_S_LD_B_ABS] = BPF_LD|BPF_B|BPF_ABS, | ||
790 | [BPF_S_ANC_PROTOCOL] = BPF_LD|BPF_B|BPF_ABS, | ||
791 | [BPF_S_ANC_PKTTYPE] = BPF_LD|BPF_B|BPF_ABS, | ||
792 | [BPF_S_ANC_IFINDEX] = BPF_LD|BPF_B|BPF_ABS, | ||
793 | [BPF_S_ANC_NLATTR] = BPF_LD|BPF_B|BPF_ABS, | ||
794 | [BPF_S_ANC_NLATTR_NEST] = BPF_LD|BPF_B|BPF_ABS, | ||
795 | [BPF_S_ANC_MARK] = BPF_LD|BPF_B|BPF_ABS, | ||
796 | [BPF_S_ANC_QUEUE] = BPF_LD|BPF_B|BPF_ABS, | ||
797 | [BPF_S_ANC_HATYPE] = BPF_LD|BPF_B|BPF_ABS, | ||
798 | [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, | ||
799 | [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, | ||
800 | [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, | ||
801 | [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, | ||
802 | [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, | ||
803 | [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, | ||
804 | [BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN, | ||
805 | [BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND, | ||
806 | [BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND, | ||
807 | [BPF_S_LD_B_IND] = BPF_LD|BPF_B|BPF_IND, | ||
808 | [BPF_S_LD_IMM] = BPF_LD|BPF_IMM, | ||
809 | [BPF_S_LDX_W_LEN] = BPF_LDX|BPF_W|BPF_LEN, | ||
810 | [BPF_S_LDX_B_MSH] = BPF_LDX|BPF_B|BPF_MSH, | ||
811 | [BPF_S_LDX_IMM] = BPF_LDX|BPF_IMM, | ||
812 | [BPF_S_MISC_TAX] = BPF_MISC|BPF_TAX, | ||
813 | [BPF_S_MISC_TXA] = BPF_MISC|BPF_TXA, | ||
814 | [BPF_S_RET_K] = BPF_RET|BPF_K, | ||
815 | [BPF_S_RET_A] = BPF_RET|BPF_A, | ||
816 | [BPF_S_ALU_DIV_K] = BPF_ALU|BPF_DIV|BPF_K, | ||
817 | [BPF_S_LD_MEM] = BPF_LD|BPF_MEM, | ||
818 | [BPF_S_LDX_MEM] = BPF_LDX|BPF_MEM, | ||
819 | [BPF_S_ST] = BPF_ST, | ||
820 | [BPF_S_STX] = BPF_STX, | ||
821 | [BPF_S_JMP_JA] = BPF_JMP|BPF_JA, | ||
822 | [BPF_S_JMP_JEQ_K] = BPF_JMP|BPF_JEQ|BPF_K, | ||
823 | [BPF_S_JMP_JEQ_X] = BPF_JMP|BPF_JEQ|BPF_X, | ||
824 | [BPF_S_JMP_JGE_K] = BPF_JMP|BPF_JGE|BPF_K, | ||
825 | [BPF_S_JMP_JGE_X] = BPF_JMP|BPF_JGE|BPF_X, | ||
826 | [BPF_S_JMP_JGT_K] = BPF_JMP|BPF_JGT|BPF_K, | ||
827 | [BPF_S_JMP_JGT_X] = BPF_JMP|BPF_JGT|BPF_X, | ||
828 | [BPF_S_JMP_JSET_K] = BPF_JMP|BPF_JSET|BPF_K, | ||
829 | [BPF_S_JMP_JSET_X] = BPF_JMP|BPF_JSET|BPF_X, | ||
830 | }; | ||
831 | u16 code; | ||
832 | |||
833 | code = filt->code; | ||
834 | |||
835 | to->code = decodes[code]; | ||
836 | to->jt = filt->jt; | ||
837 | to->jf = filt->jf; | ||
838 | |||
839 | if (code == BPF_S_ALU_DIV_K) { | ||
840 | /* | ||
841 | * When loaded this rule user gave us X, which was | ||
842 | * translated into R = r(X). Now we calculate the | ||
843 | * RR = r(R) and report it back. If next time this | ||
844 | * value is loaded and RRR = r(RR) is calculated | ||
845 | * then the R == RRR will be true. | ||
846 | * | ||
847 | * One exception. X == 1 translates into R == 0 and | ||
848 | * we can't calculate RR out of it with r(). | ||
849 | */ | ||
850 | |||
851 | if (filt->k == 0) | ||
852 | to->k = 1; | ||
853 | else | ||
854 | to->k = reciprocal_value(filt->k); | ||
855 | |||
856 | BUG_ON(reciprocal_value(to->k) != filt->k); | ||
857 | } else | ||
858 | to->k = filt->k; | ||
859 | } | ||
860 | |||
861 | int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, unsigned int len) | ||
862 | { | ||
863 | struct sk_filter *filter; | ||
864 | int i, ret; | ||
865 | |||
866 | lock_sock(sk); | ||
867 | filter = rcu_dereference_protected(sk->sk_filter, | ||
868 | sock_owned_by_user(sk)); | ||
869 | ret = 0; | ||
870 | if (!filter) | ||
871 | goto out; | ||
872 | ret = filter->len; | ||
873 | if (!len) | ||
874 | goto out; | ||
875 | ret = -EINVAL; | ||
876 | if (len < filter->len) | ||
877 | goto out; | ||
878 | |||
879 | ret = -EFAULT; | ||
880 | for (i = 0; i < filter->len; i++) { | ||
881 | struct sock_filter fb; | ||
882 | |||
883 | sk_decode_filter(&filter->insns[i], &fb); | ||
884 | if (copy_to_user(&ubuf[i], &fb, sizeof(fb))) | ||
885 | goto out; | ||
886 | } | ||
887 | |||
888 | ret = filter->len; | ||
889 | out: | ||
890 | release_sock(sk); | ||
891 | return ret; | ||
892 | } | ||
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 79285a36035f..847c02b197b0 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -248,7 +248,7 @@ static int update_netprio(const void *v, struct file *file, unsigned n) | |||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
250 | 250 | ||
251 | void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 251 | static void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) |
252 | { | 252 | { |
253 | struct task_struct *p; | 253 | struct task_struct *p; |
254 | void *v; | 254 | void *v; |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index d1dc14c2aac4..b29dacf900f9 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -419,20 +419,6 @@ struct pktgen_thread { | |||
419 | #define REMOVE 1 | 419 | #define REMOVE 1 |
420 | #define FIND 0 | 420 | #define FIND 0 |
421 | 421 | ||
422 | static inline ktime_t ktime_now(void) | ||
423 | { | ||
424 | struct timespec ts; | ||
425 | ktime_get_ts(&ts); | ||
426 | |||
427 | return timespec_to_ktime(ts); | ||
428 | } | ||
429 | |||
430 | /* This works even if 32 bit because of careful byte order choice */ | ||
431 | static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2) | ||
432 | { | ||
433 | return cmp1.tv64 < cmp2.tv64; | ||
434 | } | ||
435 | |||
436 | static const char version[] = | 422 | static const char version[] = |
437 | "Packet Generator for packet performance testing. " | 423 | "Packet Generator for packet performance testing. " |
438 | "Version: " VERSION "\n"; | 424 | "Version: " VERSION "\n"; |
@@ -675,7 +661,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
675 | seq_puts(seq, "\n"); | 661 | seq_puts(seq, "\n"); |
676 | 662 | ||
677 | /* not really stopped, more like last-running-at */ | 663 | /* not really stopped, more like last-running-at */ |
678 | stopped = pkt_dev->running ? ktime_now() : pkt_dev->stopped_at; | 664 | stopped = pkt_dev->running ? ktime_get() : pkt_dev->stopped_at; |
679 | idle = pkt_dev->idle_acc; | 665 | idle = pkt_dev->idle_acc; |
680 | do_div(idle, NSEC_PER_USEC); | 666 | do_div(idle, NSEC_PER_USEC); |
681 | 667 | ||
@@ -2141,12 +2127,12 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) | |||
2141 | return; | 2127 | return; |
2142 | } | 2128 | } |
2143 | 2129 | ||
2144 | start_time = ktime_now(); | 2130 | start_time = ktime_get(); |
2145 | if (remaining < 100000) { | 2131 | if (remaining < 100000) { |
2146 | /* for small delays (<100us), just loop until limit is reached */ | 2132 | /* for small delays (<100us), just loop until limit is reached */ |
2147 | do { | 2133 | do { |
2148 | end_time = ktime_now(); | 2134 | end_time = ktime_get(); |
2149 | } while (ktime_lt(end_time, spin_until)); | 2135 | } while (ktime_compare(end_time, spin_until) < 0); |
2150 | } else { | 2136 | } else { |
2151 | /* see do_nanosleep */ | 2137 | /* see do_nanosleep */ |
2152 | hrtimer_init_sleeper(&t, current); | 2138 | hrtimer_init_sleeper(&t, current); |
@@ -2162,7 +2148,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) | |||
2162 | hrtimer_cancel(&t.timer); | 2148 | hrtimer_cancel(&t.timer); |
2163 | } while (t.task && pkt_dev->running && !signal_pending(current)); | 2149 | } while (t.task && pkt_dev->running && !signal_pending(current)); |
2164 | __set_current_state(TASK_RUNNING); | 2150 | __set_current_state(TASK_RUNNING); |
2165 | end_time = ktime_now(); | 2151 | end_time = ktime_get(); |
2166 | } | 2152 | } |
2167 | 2153 | ||
2168 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time)); | 2154 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time)); |
@@ -2427,11 +2413,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2427 | } | 2413 | } |
2428 | } else { /* IPV6 * */ | 2414 | } else { /* IPV6 * */ |
2429 | 2415 | ||
2430 | if (pkt_dev->min_in6_daddr.s6_addr32[0] == 0 && | 2416 | if (!ipv6_addr_any(&pkt_dev->min_in6_daddr)) { |
2431 | pkt_dev->min_in6_daddr.s6_addr32[1] == 0 && | ||
2432 | pkt_dev->min_in6_daddr.s6_addr32[2] == 0 && | ||
2433 | pkt_dev->min_in6_daddr.s6_addr32[3] == 0) ; | ||
2434 | else { | ||
2435 | int i; | 2417 | int i; |
2436 | 2418 | ||
2437 | /* Only random destinations yet */ | 2419 | /* Only random destinations yet */ |
@@ -2916,8 +2898,7 @@ static void pktgen_run(struct pktgen_thread *t) | |||
2916 | pktgen_clear_counters(pkt_dev); | 2898 | pktgen_clear_counters(pkt_dev); |
2917 | pkt_dev->running = 1; /* Cranke yeself! */ | 2899 | pkt_dev->running = 1; /* Cranke yeself! */ |
2918 | pkt_dev->skb = NULL; | 2900 | pkt_dev->skb = NULL; |
2919 | pkt_dev->started_at = | 2901 | pkt_dev->started_at = pkt_dev->next_tx = ktime_get(); |
2920 | pkt_dev->next_tx = ktime_now(); | ||
2921 | 2902 | ||
2922 | set_pkt_overhead(pkt_dev); | 2903 | set_pkt_overhead(pkt_dev); |
2923 | 2904 | ||
@@ -3076,7 +3057,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
3076 | 3057 | ||
3077 | kfree_skb(pkt_dev->skb); | 3058 | kfree_skb(pkt_dev->skb); |
3078 | pkt_dev->skb = NULL; | 3059 | pkt_dev->skb = NULL; |
3079 | pkt_dev->stopped_at = ktime_now(); | 3060 | pkt_dev->stopped_at = ktime_get(); |
3080 | pkt_dev->running = 0; | 3061 | pkt_dev->running = 0; |
3081 | 3062 | ||
3082 | show_results(pkt_dev, nr_frags); | 3063 | show_results(pkt_dev, nr_frags); |
@@ -3095,7 +3076,7 @@ static struct pktgen_dev *next_to_run(struct pktgen_thread *t) | |||
3095 | continue; | 3076 | continue; |
3096 | if (best == NULL) | 3077 | if (best == NULL) |
3097 | best = pkt_dev; | 3078 | best = pkt_dev; |
3098 | else if (ktime_lt(pkt_dev->next_tx, best->next_tx)) | 3079 | else if (ktime_compare(pkt_dev->next_tx, best->next_tx) < 0) |
3099 | best = pkt_dev; | 3080 | best = pkt_dev; |
3100 | } | 3081 | } |
3101 | if_unlock(t); | 3082 | if_unlock(t); |
@@ -3180,14 +3161,14 @@ static void pktgen_rem_thread(struct pktgen_thread *t) | |||
3180 | 3161 | ||
3181 | static void pktgen_resched(struct pktgen_dev *pkt_dev) | 3162 | static void pktgen_resched(struct pktgen_dev *pkt_dev) |
3182 | { | 3163 | { |
3183 | ktime_t idle_start = ktime_now(); | 3164 | ktime_t idle_start = ktime_get(); |
3184 | schedule(); | 3165 | schedule(); |
3185 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start)); | 3166 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_get(), idle_start)); |
3186 | } | 3167 | } |
3187 | 3168 | ||
3188 | static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev) | 3169 | static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev) |
3189 | { | 3170 | { |
3190 | ktime_t idle_start = ktime_now(); | 3171 | ktime_t idle_start = ktime_get(); |
3191 | 3172 | ||
3192 | while (atomic_read(&(pkt_dev->skb->users)) != 1) { | 3173 | while (atomic_read(&(pkt_dev->skb->users)) != 1) { |
3193 | if (signal_pending(current)) | 3174 | if (signal_pending(current)) |
@@ -3198,7 +3179,7 @@ static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev) | |||
3198 | else | 3179 | else |
3199 | cpu_relax(); | 3180 | cpu_relax(); |
3200 | } | 3181 | } |
3201 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start)); | 3182 | pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_get(), idle_start)); |
3202 | } | 3183 | } |
3203 | 3184 | ||
3204 | static void pktgen_xmit(struct pktgen_dev *pkt_dev) | 3185 | static void pktgen_xmit(struct pktgen_dev *pkt_dev) |
@@ -3220,7 +3201,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
3220 | * "never transmit" | 3201 | * "never transmit" |
3221 | */ | 3202 | */ |
3222 | if (unlikely(pkt_dev->delay == ULLONG_MAX)) { | 3203 | if (unlikely(pkt_dev->delay == ULLONG_MAX)) { |
3223 | pkt_dev->next_tx = ktime_add_ns(ktime_now(), ULONG_MAX); | 3204 | pkt_dev->next_tx = ktime_add_ns(ktime_get(), ULONG_MAX); |
3224 | return; | 3205 | return; |
3225 | } | 3206 | } |
3226 | 3207 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index fad649ae4dec..a810f6a61372 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -128,7 +128,7 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex) | |||
128 | if (tab == NULL || tab[msgindex].doit == NULL) | 128 | if (tab == NULL || tab[msgindex].doit == NULL) |
129 | tab = rtnl_msg_handlers[PF_UNSPEC]; | 129 | tab = rtnl_msg_handlers[PF_UNSPEC]; |
130 | 130 | ||
131 | return tab ? tab[msgindex].doit : NULL; | 131 | return tab[msgindex].doit; |
132 | } | 132 | } |
133 | 133 | ||
134 | static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | 134 | static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) |
@@ -143,7 +143,7 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | |||
143 | if (tab == NULL || tab[msgindex].dumpit == NULL) | 143 | if (tab == NULL || tab[msgindex].dumpit == NULL) |
144 | tab = rtnl_msg_handlers[PF_UNSPEC]; | 144 | tab = rtnl_msg_handlers[PF_UNSPEC]; |
145 | 145 | ||
146 | return tab ? tab[msgindex].dumpit : NULL; | 146 | return tab[msgindex].dumpit; |
147 | } | 147 | } |
148 | 148 | ||
149 | static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) | 149 | static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) |
@@ -158,7 +158,7 @@ static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) | |||
158 | if (tab == NULL || tab[msgindex].calcit == NULL) | 158 | if (tab == NULL || tab[msgindex].calcit == NULL) |
159 | tab = rtnl_msg_handlers[PF_UNSPEC]; | 159 | tab = rtnl_msg_handlers[PF_UNSPEC]; |
160 | 160 | ||
161 | return tab ? tab[msgindex].calcit : NULL; | 161 | return tab[msgindex].calcit; |
162 | } | 162 | } |
163 | 163 | ||
164 | /** | 164 | /** |
@@ -2253,6 +2253,211 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2253 | return skb->len; | 2253 | return skb->len; |
2254 | } | 2254 | } |
2255 | 2255 | ||
2256 | int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | ||
2257 | struct net_device *dev, u16 mode) | ||
2258 | { | ||
2259 | struct nlmsghdr *nlh; | ||
2260 | struct ifinfomsg *ifm; | ||
2261 | struct nlattr *br_afspec; | ||
2262 | u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; | ||
2263 | |||
2264 | nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI); | ||
2265 | if (nlh == NULL) | ||
2266 | return -EMSGSIZE; | ||
2267 | |||
2268 | ifm = nlmsg_data(nlh); | ||
2269 | ifm->ifi_family = AF_BRIDGE; | ||
2270 | ifm->__ifi_pad = 0; | ||
2271 | ifm->ifi_type = dev->type; | ||
2272 | ifm->ifi_index = dev->ifindex; | ||
2273 | ifm->ifi_flags = dev_get_flags(dev); | ||
2274 | ifm->ifi_change = 0; | ||
2275 | |||
2276 | |||
2277 | if (nla_put_string(skb, IFLA_IFNAME, dev->name) || | ||
2278 | nla_put_u32(skb, IFLA_MTU, dev->mtu) || | ||
2279 | nla_put_u8(skb, IFLA_OPERSTATE, operstate) || | ||
2280 | (dev->master && | ||
2281 | nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) || | ||
2282 | (dev->addr_len && | ||
2283 | nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || | ||
2284 | (dev->ifindex != dev->iflink && | ||
2285 | nla_put_u32(skb, IFLA_LINK, dev->iflink))) | ||
2286 | goto nla_put_failure; | ||
2287 | |||
2288 | br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); | ||
2289 | if (!br_afspec) | ||
2290 | goto nla_put_failure; | ||
2291 | |||
2292 | if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF) || | ||
2293 | nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) { | ||
2294 | nla_nest_cancel(skb, br_afspec); | ||
2295 | goto nla_put_failure; | ||
2296 | } | ||
2297 | nla_nest_end(skb, br_afspec); | ||
2298 | |||
2299 | return nlmsg_end(skb, nlh); | ||
2300 | nla_put_failure: | ||
2301 | nlmsg_cancel(skb, nlh); | ||
2302 | return -EMSGSIZE; | ||
2303 | } | ||
2304 | EXPORT_SYMBOL(ndo_dflt_bridge_getlink); | ||
2305 | |||
2306 | static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) | ||
2307 | { | ||
2308 | struct net *net = sock_net(skb->sk); | ||
2309 | struct net_device *dev; | ||
2310 | int idx = 0; | ||
2311 | u32 portid = NETLINK_CB(cb->skb).portid; | ||
2312 | u32 seq = cb->nlh->nlmsg_seq; | ||
2313 | |||
2314 | rcu_read_lock(); | ||
2315 | for_each_netdev_rcu(net, dev) { | ||
2316 | const struct net_device_ops *ops = dev->netdev_ops; | ||
2317 | struct net_device *master = dev->master; | ||
2318 | |||
2319 | if (master && master->netdev_ops->ndo_bridge_getlink) { | ||
2320 | if (idx >= cb->args[0] && | ||
2321 | master->netdev_ops->ndo_bridge_getlink( | ||
2322 | skb, portid, seq, dev) < 0) | ||
2323 | break; | ||
2324 | idx++; | ||
2325 | } | ||
2326 | |||
2327 | if (ops->ndo_bridge_getlink) { | ||
2328 | if (idx >= cb->args[0] && | ||
2329 | ops->ndo_bridge_getlink(skb, portid, seq, dev) < 0) | ||
2330 | break; | ||
2331 | idx++; | ||
2332 | } | ||
2333 | } | ||
2334 | rcu_read_unlock(); | ||
2335 | cb->args[0] = idx; | ||
2336 | |||
2337 | return skb->len; | ||
2338 | } | ||
2339 | |||
2340 | static inline size_t bridge_nlmsg_size(void) | ||
2341 | { | ||
2342 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | ||
2343 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | ||
2344 | + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ | ||
2345 | + nla_total_size(sizeof(u32)) /* IFLA_MASTER */ | ||
2346 | + nla_total_size(sizeof(u32)) /* IFLA_MTU */ | ||
2347 | + nla_total_size(sizeof(u32)) /* IFLA_LINK */ | ||
2348 | + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */ | ||
2349 | + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */ | ||
2350 | + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */ | ||
2351 | + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */ | ||
2352 | + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ | ||
2353 | } | ||
2354 | |||
2355 | static int rtnl_bridge_notify(struct net_device *dev, u16 flags) | ||
2356 | { | ||
2357 | struct net *net = dev_net(dev); | ||
2358 | struct net_device *master = dev->master; | ||
2359 | struct sk_buff *skb; | ||
2360 | int err = -EOPNOTSUPP; | ||
2361 | |||
2362 | skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC); | ||
2363 | if (!skb) { | ||
2364 | err = -ENOMEM; | ||
2365 | goto errout; | ||
2366 | } | ||
2367 | |||
2368 | if ((!flags || (flags & BRIDGE_FLAGS_MASTER)) && | ||
2369 | master && master->netdev_ops->ndo_bridge_getlink) { | ||
2370 | err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); | ||
2371 | if (err < 0) | ||
2372 | goto errout; | ||
2373 | } | ||
2374 | |||
2375 | if ((flags & BRIDGE_FLAGS_SELF) && | ||
2376 | dev->netdev_ops->ndo_bridge_getlink) { | ||
2377 | err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); | ||
2378 | if (err < 0) | ||
2379 | goto errout; | ||
2380 | } | ||
2381 | |||
2382 | rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); | ||
2383 | return 0; | ||
2384 | errout: | ||
2385 | WARN_ON(err == -EMSGSIZE); | ||
2386 | kfree_skb(skb); | ||
2387 | rtnl_set_sk_err(net, RTNLGRP_LINK, err); | ||
2388 | return err; | ||
2389 | } | ||
2390 | |||
2391 | static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
2392 | void *arg) | ||
2393 | { | ||
2394 | struct net *net = sock_net(skb->sk); | ||
2395 | struct ifinfomsg *ifm; | ||
2396 | struct net_device *dev; | ||
2397 | struct nlattr *br_spec, *attr = NULL; | ||
2398 | int rem, err = -EOPNOTSUPP; | ||
2399 | u16 oflags, flags = 0; | ||
2400 | bool have_flags = false; | ||
2401 | |||
2402 | if (nlmsg_len(nlh) < sizeof(*ifm)) | ||
2403 | return -EINVAL; | ||
2404 | |||
2405 | ifm = nlmsg_data(nlh); | ||
2406 | if (ifm->ifi_family != AF_BRIDGE) | ||
2407 | return -EPFNOSUPPORT; | ||
2408 | |||
2409 | dev = __dev_get_by_index(net, ifm->ifi_index); | ||
2410 | if (!dev) { | ||
2411 | pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); | ||
2412 | return -ENODEV; | ||
2413 | } | ||
2414 | |||
2415 | br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); | ||
2416 | if (br_spec) { | ||
2417 | nla_for_each_nested(attr, br_spec, rem) { | ||
2418 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { | ||
2419 | have_flags = true; | ||
2420 | flags = nla_get_u16(attr); | ||
2421 | break; | ||
2422 | } | ||
2423 | } | ||
2424 | } | ||
2425 | |||
2426 | oflags = flags; | ||
2427 | |||
2428 | if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { | ||
2429 | if (!dev->master || | ||
2430 | !dev->master->netdev_ops->ndo_bridge_setlink) { | ||
2431 | err = -EOPNOTSUPP; | ||
2432 | goto out; | ||
2433 | } | ||
2434 | |||
2435 | err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh); | ||
2436 | if (err) | ||
2437 | goto out; | ||
2438 | |||
2439 | flags &= ~BRIDGE_FLAGS_MASTER; | ||
2440 | } | ||
2441 | |||
2442 | if ((flags & BRIDGE_FLAGS_SELF)) { | ||
2443 | if (!dev->netdev_ops->ndo_bridge_setlink) | ||
2444 | err = -EOPNOTSUPP; | ||
2445 | else | ||
2446 | err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); | ||
2447 | |||
2448 | if (!err) | ||
2449 | flags &= ~BRIDGE_FLAGS_SELF; | ||
2450 | } | ||
2451 | |||
2452 | if (have_flags) | ||
2453 | memcpy(nla_data(attr), &flags, sizeof(flags)); | ||
2454 | /* Generate event to notify upper layer of bridge change */ | ||
2455 | if (!err) | ||
2456 | err = rtnl_bridge_notify(dev, oflags); | ||
2457 | out: | ||
2458 | return err; | ||
2459 | } | ||
2460 | |||
2256 | /* Protected by RTNL sempahore. */ | 2461 | /* Protected by RTNL sempahore. */ |
2257 | static struct rtattr **rta_buf; | 2462 | static struct rtattr **rta_buf; |
2258 | static int rtattr_max; | 2463 | static int rtattr_max; |
@@ -2434,5 +2639,8 @@ void __init rtnetlink_init(void) | |||
2434 | rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); | 2639 | rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); |
2435 | rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); | 2640 | rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); |
2436 | rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); | 2641 | rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); |
2642 | |||
2643 | rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL); | ||
2644 | rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL); | ||
2437 | } | 2645 | } |
2438 | 2646 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4007c1437fda..880722e22cc5 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -519,7 +519,7 @@ static void skb_release_data(struct sk_buff *skb) | |||
519 | 519 | ||
520 | uarg = skb_shinfo(skb)->destructor_arg; | 520 | uarg = skb_shinfo(skb)->destructor_arg; |
521 | if (uarg->callback) | 521 | if (uarg->callback) |
522 | uarg->callback(uarg); | 522 | uarg->callback(uarg, true); |
523 | } | 523 | } |
524 | 524 | ||
525 | if (skb_has_frag_list(skb)) | 525 | if (skb_has_frag_list(skb)) |
@@ -635,6 +635,26 @@ void kfree_skb(struct sk_buff *skb) | |||
635 | EXPORT_SYMBOL(kfree_skb); | 635 | EXPORT_SYMBOL(kfree_skb); |
636 | 636 | ||
637 | /** | 637 | /** |
638 | * skb_tx_error - report an sk_buff xmit error | ||
639 | * @skb: buffer that triggered an error | ||
640 | * | ||
641 | * Report xmit error if a device callback is tracking this skb. | ||
642 | * skb must be freed afterwards. | ||
643 | */ | ||
644 | void skb_tx_error(struct sk_buff *skb) | ||
645 | { | ||
646 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | ||
647 | struct ubuf_info *uarg; | ||
648 | |||
649 | uarg = skb_shinfo(skb)->destructor_arg; | ||
650 | if (uarg->callback) | ||
651 | uarg->callback(uarg, false); | ||
652 | skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; | ||
653 | } | ||
654 | } | ||
655 | EXPORT_SYMBOL(skb_tx_error); | ||
656 | |||
657 | /** | ||
638 | * consume_skb - free an skbuff | 658 | * consume_skb - free an skbuff |
639 | * @skb: buffer to free | 659 | * @skb: buffer to free |
640 | * | 660 | * |
@@ -797,7 +817,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
797 | for (i = 0; i < num_frags; i++) | 817 | for (i = 0; i < num_frags; i++) |
798 | skb_frag_unref(skb, i); | 818 | skb_frag_unref(skb, i); |
799 | 819 | ||
800 | uarg->callback(uarg); | 820 | uarg->callback(uarg, false); |
801 | 821 | ||
802 | /* skb frags point to kernel buffers */ | 822 | /* skb frags point to kernel buffers */ |
803 | for (i = num_frags - 1; i >= 0; i--) { | 823 | for (i = num_frags - 1; i >= 0; i--) { |
diff --git a/net/core/sock.c b/net/core/sock.c index 8a146cfcc366..06286006a2cc 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1074,6 +1074,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
1074 | case SO_NOFCS: | 1074 | case SO_NOFCS: |
1075 | v.val = sock_flag(sk, SOCK_NOFCS); | 1075 | v.val = sock_flag(sk, SOCK_NOFCS); |
1076 | break; | 1076 | break; |
1077 | case SO_BINDTODEVICE: | ||
1078 | v.val = sk->sk_bound_dev_if; | ||
1079 | break; | ||
1080 | case SO_GET_FILTER: | ||
1081 | len = sk_get_filter(sk, (struct sock_filter __user *)optval, len); | ||
1082 | if (len < 0) | ||
1083 | return len; | ||
1084 | |||
1085 | goto lenout; | ||
1077 | default: | 1086 | default: |
1078 | return -ENOPROTOOPT; | 1087 | return -ENOPROTOOPT; |
1079 | } | 1088 | } |
@@ -1214,13 +1223,11 @@ static void sk_prot_free(struct proto *prot, struct sock *sk) | |||
1214 | 1223 | ||
1215 | #ifdef CONFIG_CGROUPS | 1224 | #ifdef CONFIG_CGROUPS |
1216 | #if IS_ENABLED(CONFIG_NET_CLS_CGROUP) | 1225 | #if IS_ENABLED(CONFIG_NET_CLS_CGROUP) |
1217 | void sock_update_classid(struct sock *sk) | 1226 | void sock_update_classid(struct sock *sk, struct task_struct *task) |
1218 | { | 1227 | { |
1219 | u32 classid; | 1228 | u32 classid; |
1220 | 1229 | ||
1221 | rcu_read_lock(); /* doing current task, which cannot vanish. */ | 1230 | classid = task_cls_classid(task); |
1222 | classid = task_cls_classid(current); | ||
1223 | rcu_read_unlock(); | ||
1224 | if (classid != sk->sk_classid) | 1231 | if (classid != sk->sk_classid) |
1225 | sk->sk_classid = classid; | 1232 | sk->sk_classid = classid; |
1226 | } | 1233 | } |
@@ -1263,7 +1270,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1263 | sock_net_set(sk, get_net(net)); | 1270 | sock_net_set(sk, get_net(net)); |
1264 | atomic_set(&sk->sk_wmem_alloc, 1); | 1271 | atomic_set(&sk->sk_wmem_alloc, 1); |
1265 | 1272 | ||
1266 | sock_update_classid(sk); | 1273 | sock_update_classid(sk, current); |
1267 | sock_update_netprioidx(sk, current); | 1274 | sock_update_netprioidx(sk, current); |
1268 | } | 1275 | } |
1269 | 1276 | ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index ea850ce35d4a..662071b249cc 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -174,8 +174,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, | |||
174 | * To protect against Request floods, increment retrans | 174 | * To protect against Request floods, increment retrans |
175 | * counter (backoff, monitored by dccp_response_timer). | 175 | * counter (backoff, monitored by dccp_response_timer). |
176 | */ | 176 | */ |
177 | req->retrans++; | 177 | inet_rtx_syn_ack(sk, req); |
178 | req->rsk_ops->rtx_syn_ack(sk, req, NULL); | ||
179 | } | 178 | } |
180 | /* Network Duplicate, discard packet */ | 179 | /* Network Duplicate, discard packet */ |
181 | return NULL; | 180 | return NULL; |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 2a6abc163ed2..f6db227c1fd9 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/sysctl.h> | 55 | #include <linux/sysctl.h> |
56 | #endif | 56 | #endif |
57 | #include <linux/kmod.h> | 57 | #include <linux/kmod.h> |
58 | #include <linux/netconf.h> | ||
58 | 59 | ||
59 | #include <net/arp.h> | 60 | #include <net/arp.h> |
60 | #include <net/ip.h> | 61 | #include <net/ip.h> |
@@ -1442,6 +1443,149 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) | |||
1442 | return 0; | 1443 | return 0; |
1443 | } | 1444 | } |
1444 | 1445 | ||
1446 | static int inet_netconf_msgsize_devconf(int type) | ||
1447 | { | ||
1448 | int size = NLMSG_ALIGN(sizeof(struct netconfmsg)) | ||
1449 | + nla_total_size(4); /* NETCONFA_IFINDEX */ | ||
1450 | |||
1451 | /* type -1 is used for ALL */ | ||
1452 | if (type == -1 || type == NETCONFA_FORWARDING) | ||
1453 | size += nla_total_size(4); | ||
1454 | if (type == -1 || type == NETCONFA_RP_FILTER) | ||
1455 | size += nla_total_size(4); | ||
1456 | |||
1457 | return size; | ||
1458 | } | ||
1459 | |||
1460 | static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | ||
1461 | struct ipv4_devconf *devconf, u32 portid, | ||
1462 | u32 seq, int event, unsigned int flags, | ||
1463 | int type) | ||
1464 | { | ||
1465 | struct nlmsghdr *nlh; | ||
1466 | struct netconfmsg *ncm; | ||
1467 | |||
1468 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg), | ||
1469 | flags); | ||
1470 | if (nlh == NULL) | ||
1471 | return -EMSGSIZE; | ||
1472 | |||
1473 | ncm = nlmsg_data(nlh); | ||
1474 | ncm->ncm_family = AF_INET; | ||
1475 | |||
1476 | if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0) | ||
1477 | goto nla_put_failure; | ||
1478 | |||
1479 | /* type -1 is used for ALL */ | ||
1480 | if ((type == -1 || type == NETCONFA_FORWARDING) && | ||
1481 | nla_put_s32(skb, NETCONFA_FORWARDING, | ||
1482 | IPV4_DEVCONF(*devconf, FORWARDING)) < 0) | ||
1483 | goto nla_put_failure; | ||
1484 | if ((type == -1 || type == NETCONFA_RP_FILTER) && | ||
1485 | nla_put_s32(skb, NETCONFA_RP_FILTER, | ||
1486 | IPV4_DEVCONF(*devconf, RP_FILTER)) < 0) | ||
1487 | goto nla_put_failure; | ||
1488 | |||
1489 | return nlmsg_end(skb, nlh); | ||
1490 | |||
1491 | nla_put_failure: | ||
1492 | nlmsg_cancel(skb, nlh); | ||
1493 | return -EMSGSIZE; | ||
1494 | } | ||
1495 | |||
1496 | static void inet_netconf_notify_devconf(struct net *net, int type, int ifindex, | ||
1497 | struct ipv4_devconf *devconf) | ||
1498 | { | ||
1499 | struct sk_buff *skb; | ||
1500 | int err = -ENOBUFS; | ||
1501 | |||
1502 | skb = nlmsg_new(inet_netconf_msgsize_devconf(type), GFP_ATOMIC); | ||
1503 | if (skb == NULL) | ||
1504 | goto errout; | ||
1505 | |||
1506 | err = inet_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, | ||
1507 | RTM_NEWNETCONF, 0, type); | ||
1508 | if (err < 0) { | ||
1509 | /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */ | ||
1510 | WARN_ON(err == -EMSGSIZE); | ||
1511 | kfree_skb(skb); | ||
1512 | goto errout; | ||
1513 | } | ||
1514 | rtnl_notify(skb, net, 0, RTNLGRP_IPV4_NETCONF, NULL, GFP_ATOMIC); | ||
1515 | return; | ||
1516 | errout: | ||
1517 | if (err < 0) | ||
1518 | rtnl_set_sk_err(net, RTNLGRP_IPV4_NETCONF, err); | ||
1519 | } | ||
1520 | |||
1521 | static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = { | ||
1522 | [NETCONFA_IFINDEX] = { .len = sizeof(int) }, | ||
1523 | [NETCONFA_FORWARDING] = { .len = sizeof(int) }, | ||
1524 | [NETCONFA_RP_FILTER] = { .len = sizeof(int) }, | ||
1525 | }; | ||
1526 | |||
1527 | static int inet_netconf_get_devconf(struct sk_buff *in_skb, | ||
1528 | struct nlmsghdr *nlh, | ||
1529 | void *arg) | ||
1530 | { | ||
1531 | struct net *net = sock_net(in_skb->sk); | ||
1532 | struct nlattr *tb[NETCONFA_MAX+1]; | ||
1533 | struct netconfmsg *ncm; | ||
1534 | struct sk_buff *skb; | ||
1535 | struct ipv4_devconf *devconf; | ||
1536 | struct in_device *in_dev; | ||
1537 | struct net_device *dev; | ||
1538 | int ifindex; | ||
1539 | int err; | ||
1540 | |||
1541 | err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX, | ||
1542 | devconf_ipv4_policy); | ||
1543 | if (err < 0) | ||
1544 | goto errout; | ||
1545 | |||
1546 | err = EINVAL; | ||
1547 | if (!tb[NETCONFA_IFINDEX]) | ||
1548 | goto errout; | ||
1549 | |||
1550 | ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]); | ||
1551 | switch (ifindex) { | ||
1552 | case NETCONFA_IFINDEX_ALL: | ||
1553 | devconf = net->ipv4.devconf_all; | ||
1554 | break; | ||
1555 | case NETCONFA_IFINDEX_DEFAULT: | ||
1556 | devconf = net->ipv4.devconf_dflt; | ||
1557 | break; | ||
1558 | default: | ||
1559 | dev = __dev_get_by_index(net, ifindex); | ||
1560 | if (dev == NULL) | ||
1561 | goto errout; | ||
1562 | in_dev = __in_dev_get_rtnl(dev); | ||
1563 | if (in_dev == NULL) | ||
1564 | goto errout; | ||
1565 | devconf = &in_dev->cnf; | ||
1566 | break; | ||
1567 | } | ||
1568 | |||
1569 | err = -ENOBUFS; | ||
1570 | skb = nlmsg_new(inet_netconf_msgsize_devconf(-1), GFP_ATOMIC); | ||
1571 | if (skb == NULL) | ||
1572 | goto errout; | ||
1573 | |||
1574 | err = inet_netconf_fill_devconf(skb, ifindex, devconf, | ||
1575 | NETLINK_CB(in_skb).portid, | ||
1576 | nlh->nlmsg_seq, RTM_NEWNETCONF, 0, | ||
1577 | -1); | ||
1578 | if (err < 0) { | ||
1579 | /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */ | ||
1580 | WARN_ON(err == -EMSGSIZE); | ||
1581 | kfree_skb(skb); | ||
1582 | goto errout; | ||
1583 | } | ||
1584 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); | ||
1585 | errout: | ||
1586 | return err; | ||
1587 | } | ||
1588 | |||
1445 | #ifdef CONFIG_SYSCTL | 1589 | #ifdef CONFIG_SYSCTL |
1446 | 1590 | ||
1447 | static void devinet_copy_dflt_conf(struct net *net, int i) | 1591 | static void devinet_copy_dflt_conf(struct net *net, int i) |
@@ -1467,6 +1611,12 @@ static void inet_forward_change(struct net *net) | |||
1467 | 1611 | ||
1468 | IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on; | 1612 | IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on; |
1469 | IPV4_DEVCONF_DFLT(net, FORWARDING) = on; | 1613 | IPV4_DEVCONF_DFLT(net, FORWARDING) = on; |
1614 | inet_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
1615 | NETCONFA_IFINDEX_ALL, | ||
1616 | net->ipv4.devconf_all); | ||
1617 | inet_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
1618 | NETCONFA_IFINDEX_DEFAULT, | ||
1619 | net->ipv4.devconf_dflt); | ||
1470 | 1620 | ||
1471 | for_each_netdev(net, dev) { | 1621 | for_each_netdev(net, dev) { |
1472 | struct in_device *in_dev; | 1622 | struct in_device *in_dev; |
@@ -1474,8 +1624,11 @@ static void inet_forward_change(struct net *net) | |||
1474 | dev_disable_lro(dev); | 1624 | dev_disable_lro(dev); |
1475 | rcu_read_lock(); | 1625 | rcu_read_lock(); |
1476 | in_dev = __in_dev_get_rcu(dev); | 1626 | in_dev = __in_dev_get_rcu(dev); |
1477 | if (in_dev) | 1627 | if (in_dev) { |
1478 | IN_DEV_CONF_SET(in_dev, FORWARDING, on); | 1628 | IN_DEV_CONF_SET(in_dev, FORWARDING, on); |
1629 | inet_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
1630 | dev->ifindex, &in_dev->cnf); | ||
1631 | } | ||
1479 | rcu_read_unlock(); | 1632 | rcu_read_unlock(); |
1480 | } | 1633 | } |
1481 | } | 1634 | } |
@@ -1501,6 +1654,23 @@ static int devinet_conf_proc(ctl_table *ctl, int write, | |||
1501 | i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) | 1654 | i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) |
1502 | if ((new_value == 0) && (old_value != 0)) | 1655 | if ((new_value == 0) && (old_value != 0)) |
1503 | rt_cache_flush(net); | 1656 | rt_cache_flush(net); |
1657 | if (i == IPV4_DEVCONF_RP_FILTER - 1 && | ||
1658 | new_value != old_value) { | ||
1659 | int ifindex; | ||
1660 | |||
1661 | if (cnf == net->ipv4.devconf_dflt) | ||
1662 | ifindex = NETCONFA_IFINDEX_DEFAULT; | ||
1663 | else if (cnf == net->ipv4.devconf_all) | ||
1664 | ifindex = NETCONFA_IFINDEX_ALL; | ||
1665 | else { | ||
1666 | struct in_device *idev = | ||
1667 | container_of(cnf, struct in_device, | ||
1668 | cnf); | ||
1669 | ifindex = idev->dev->ifindex; | ||
1670 | } | ||
1671 | inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER, | ||
1672 | ifindex, cnf); | ||
1673 | } | ||
1504 | } | 1674 | } |
1505 | 1675 | ||
1506 | return ret; | 1676 | return ret; |
@@ -1527,15 +1697,23 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, | |||
1527 | } | 1697 | } |
1528 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { | 1698 | if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { |
1529 | inet_forward_change(net); | 1699 | inet_forward_change(net); |
1530 | } else if (*valp) { | 1700 | } else { |
1531 | struct ipv4_devconf *cnf = ctl->extra1; | 1701 | struct ipv4_devconf *cnf = ctl->extra1; |
1532 | struct in_device *idev = | 1702 | struct in_device *idev = |
1533 | container_of(cnf, struct in_device, cnf); | 1703 | container_of(cnf, struct in_device, cnf); |
1534 | dev_disable_lro(idev->dev); | 1704 | if (*valp) |
1705 | dev_disable_lro(idev->dev); | ||
1706 | inet_netconf_notify_devconf(net, | ||
1707 | NETCONFA_FORWARDING, | ||
1708 | idev->dev->ifindex, | ||
1709 | cnf); | ||
1535 | } | 1710 | } |
1536 | rtnl_unlock(); | 1711 | rtnl_unlock(); |
1537 | rt_cache_flush(net); | 1712 | rt_cache_flush(net); |
1538 | } | 1713 | } else |
1714 | inet_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
1715 | NETCONFA_IFINDEX_DEFAULT, | ||
1716 | net->ipv4.devconf_dflt); | ||
1539 | } | 1717 | } |
1540 | 1718 | ||
1541 | return ret; | 1719 | return ret; |
@@ -1809,5 +1987,7 @@ void __init devinet_init(void) | |||
1809 | rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, NULL); | 1987 | rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, NULL); |
1810 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL); | 1988 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL); |
1811 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL); | 1989 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL); |
1990 | rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf, | ||
1991 | NULL, NULL); | ||
1812 | } | 1992 | } |
1813 | 1993 | ||
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 71b125cd5db1..4797a800faf8 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -803,7 +803,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
803 | unsigned int bytes; | 803 | unsigned int bytes; |
804 | 804 | ||
805 | if (!new_size) | 805 | if (!new_size) |
806 | new_size = 1; | 806 | new_size = 16; |
807 | bytes = new_size * sizeof(struct hlist_head *); | 807 | bytes = new_size * sizeof(struct hlist_head *); |
808 | new_info_hash = fib_info_hash_alloc(bytes); | 808 | new_info_hash = fib_info_hash_alloc(bytes); |
809 | new_laddrhash = fib_info_hash_alloc(bytes); | 809 | new_laddrhash = fib_info_hash_alloc(bytes); |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index d34ce2972c8f..2026542d6836 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -521,21 +521,31 @@ static inline void syn_ack_recalc(struct request_sock *req, const int thresh, | |||
521 | int *expire, int *resend) | 521 | int *expire, int *resend) |
522 | { | 522 | { |
523 | if (!rskq_defer_accept) { | 523 | if (!rskq_defer_accept) { |
524 | *expire = req->retrans >= thresh; | 524 | *expire = req->num_timeout >= thresh; |
525 | *resend = 1; | 525 | *resend = 1; |
526 | return; | 526 | return; |
527 | } | 527 | } |
528 | *expire = req->retrans >= thresh && | 528 | *expire = req->num_timeout >= thresh && |
529 | (!inet_rsk(req)->acked || req->retrans >= max_retries); | 529 | (!inet_rsk(req)->acked || req->num_timeout >= max_retries); |
530 | /* | 530 | /* |
531 | * Do not resend while waiting for data after ACK, | 531 | * Do not resend while waiting for data after ACK, |
532 | * start to resend on end of deferring period to give | 532 | * start to resend on end of deferring period to give |
533 | * last chance for data or ACK to create established socket. | 533 | * last chance for data or ACK to create established socket. |
534 | */ | 534 | */ |
535 | *resend = !inet_rsk(req)->acked || | 535 | *resend = !inet_rsk(req)->acked || |
536 | req->retrans >= rskq_defer_accept - 1; | 536 | req->num_timeout >= rskq_defer_accept - 1; |
537 | } | 537 | } |
538 | 538 | ||
539 | int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req) | ||
540 | { | ||
541 | int err = req->rsk_ops->rtx_syn_ack(parent, req, NULL); | ||
542 | |||
543 | if (!err) | ||
544 | req->num_retrans++; | ||
545 | return err; | ||
546 | } | ||
547 | EXPORT_SYMBOL(inet_rtx_syn_ack); | ||
548 | |||
539 | void inet_csk_reqsk_queue_prune(struct sock *parent, | 549 | void inet_csk_reqsk_queue_prune(struct sock *parent, |
540 | const unsigned long interval, | 550 | const unsigned long interval, |
541 | const unsigned long timeout, | 551 | const unsigned long timeout, |
@@ -599,13 +609,14 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
599 | req->rsk_ops->syn_ack_timeout(parent, req); | 609 | req->rsk_ops->syn_ack_timeout(parent, req); |
600 | if (!expire && | 610 | if (!expire && |
601 | (!resend || | 611 | (!resend || |
602 | !req->rsk_ops->rtx_syn_ack(parent, req, NULL) || | 612 | !inet_rtx_syn_ack(parent, req) || |
603 | inet_rsk(req)->acked)) { | 613 | inet_rsk(req)->acked)) { |
604 | unsigned long timeo; | 614 | unsigned long timeo; |
605 | 615 | ||
606 | if (req->retrans++ == 0) | 616 | if (req->num_timeout++ == 0) |
607 | lopt->qlen_young--; | 617 | lopt->qlen_young--; |
608 | timeo = min((timeout << req->retrans), max_rto); | 618 | timeo = min(timeout << req->num_timeout, |
619 | max_rto); | ||
609 | req->expires = now + timeo; | 620 | req->expires = now + timeo; |
610 | reqp = &req->dl_next; | 621 | reqp = &req->dl_next; |
611 | continue; | 622 | continue; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 0c34bfabc11f..cb98cbed1973 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -105,6 +105,9 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
105 | r->id.idiag_src[0] = inet->inet_rcv_saddr; | 105 | r->id.idiag_src[0] = inet->inet_rcv_saddr; |
106 | r->id.idiag_dst[0] = inet->inet_daddr; | 106 | r->id.idiag_dst[0] = inet->inet_daddr; |
107 | 107 | ||
108 | if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown)) | ||
109 | goto errout; | ||
110 | |||
108 | /* IPv6 dual-stack sockets use inet->tos for IPv4 connections, | 111 | /* IPv6 dual-stack sockets use inet->tos for IPv4 connections, |
109 | * hence this needs to be included regardless of socket family. | 112 | * hence this needs to be included regardless of socket family. |
110 | */ | 113 | */ |
@@ -617,7 +620,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
617 | r->idiag_family = sk->sk_family; | 620 | r->idiag_family = sk->sk_family; |
618 | r->idiag_state = TCP_SYN_RECV; | 621 | r->idiag_state = TCP_SYN_RECV; |
619 | r->idiag_timer = 1; | 622 | r->idiag_timer = 1; |
620 | r->idiag_retrans = req->retrans; | 623 | r->idiag_retrans = req->num_retrans; |
621 | 624 | ||
622 | r->id.idiag_if = sk->sk_bound_dev_if; | 625 | r->id.idiag_if = sk->sk_bound_dev_if; |
623 | sock_diag_save_cookie(req, r->id.idiag_cookie); | 626 | sock_diag_save_cookie(req, r->id.idiag_cookie); |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 798358b10717..d763701cff1b 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -1500,8 +1500,10 @@ static int __init ip_auto_config(void) | |||
1500 | * Clue in the operator. | 1500 | * Clue in the operator. |
1501 | */ | 1501 | */ |
1502 | pr_info("IP-Config: Complete:\n"); | 1502 | pr_info("IP-Config: Complete:\n"); |
1503 | pr_info(" device=%s, addr=%pI4, mask=%pI4, gw=%pI4\n", | 1503 | |
1504 | ic_dev->name, &ic_myaddr, &ic_netmask, &ic_gateway); | 1504 | pr_info(" device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n", |
1505 | ic_dev->name, ic_dev->addr_len, ic_dev->dev_addr, | ||
1506 | &ic_myaddr, &ic_netmask, &ic_gateway); | ||
1505 | pr_info(" host=%s, domain=%s, nis-domain=%s\n", | 1507 | pr_info(" host=%s, domain=%s, nis-domain=%s\n", |
1506 | utsname()->nodename, ic_domain, utsname()->domainname); | 1508 | utsname()->nodename, ic_domain, utsname()->domainname); |
1507 | pr_info(" bootserver=%pI4, rootserver=%pI4, rootpath=%s", | 1509 | pr_info(" bootserver=%pI4, rootserver=%pI4, rootpath=%s", |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e15b45297c09..720855e41100 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -138,6 +138,7 @@ struct ipip_net { | |||
138 | static int ipip_tunnel_init(struct net_device *dev); | 138 | static int ipip_tunnel_init(struct net_device *dev); |
139 | static void ipip_tunnel_setup(struct net_device *dev); | 139 | static void ipip_tunnel_setup(struct net_device *dev); |
140 | static void ipip_dev_free(struct net_device *dev); | 140 | static void ipip_dev_free(struct net_device *dev); |
141 | static struct rtnl_link_ops ipip_link_ops __read_mostly; | ||
141 | 142 | ||
142 | /* | 143 | /* |
143 | * Locking : hash tables are protected by RCU and RTNL | 144 | * Locking : hash tables are protected by RCU and RTNL |
@@ -305,6 +306,7 @@ static struct ip_tunnel *ipip_tunnel_locate(struct net *net, | |||
305 | goto failed_free; | 306 | goto failed_free; |
306 | 307 | ||
307 | strcpy(nt->parms.name, dev->name); | 308 | strcpy(nt->parms.name, dev->name); |
309 | dev->rtnl_link_ops = &ipip_link_ops; | ||
308 | 310 | ||
309 | dev_hold(dev); | 311 | dev_hold(dev); |
310 | ipip_tunnel_link(ipn, nt); | 312 | ipip_tunnel_link(ipn, nt); |
@@ -479,6 +481,10 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
479 | if (skb->protocol != htons(ETH_P_IP)) | 481 | if (skb->protocol != htons(ETH_P_IP)) |
480 | goto tx_error; | 482 | goto tx_error; |
481 | 483 | ||
484 | if (skb->ip_summed == CHECKSUM_PARTIAL && | ||
485 | skb_checksum_help(skb)) | ||
486 | goto tx_error; | ||
487 | |||
482 | if (tos & 1) | 488 | if (tos & 1) |
483 | tos = old_iph->tos; | 489 | tos = old_iph->tos; |
484 | 490 | ||
@@ -773,6 +779,11 @@ static void ipip_dev_free(struct net_device *dev) | |||
773 | free_netdev(dev); | 779 | free_netdev(dev); |
774 | } | 780 | } |
775 | 781 | ||
782 | #define IPIP_FEATURES (NETIF_F_SG | \ | ||
783 | NETIF_F_FRAGLIST | \ | ||
784 | NETIF_F_HIGHDMA | \ | ||
785 | NETIF_F_HW_CSUM) | ||
786 | |||
776 | static void ipip_tunnel_setup(struct net_device *dev) | 787 | static void ipip_tunnel_setup(struct net_device *dev) |
777 | { | 788 | { |
778 | dev->netdev_ops = &ipip_netdev_ops; | 789 | dev->netdev_ops = &ipip_netdev_ops; |
@@ -787,6 +798,9 @@ static void ipip_tunnel_setup(struct net_device *dev) | |||
787 | dev->features |= NETIF_F_NETNS_LOCAL; | 798 | dev->features |= NETIF_F_NETNS_LOCAL; |
788 | dev->features |= NETIF_F_LLTX; | 799 | dev->features |= NETIF_F_LLTX; |
789 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | 800 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
801 | |||
802 | dev->features |= IPIP_FEATURES; | ||
803 | dev->hw_features |= IPIP_FEATURES; | ||
790 | } | 804 | } |
791 | 805 | ||
792 | static int ipip_tunnel_init(struct net_device *dev) | 806 | static int ipip_tunnel_init(struct net_device *dev) |
@@ -829,6 +843,47 @@ static int __net_init ipip_fb_tunnel_init(struct net_device *dev) | |||
829 | return 0; | 843 | return 0; |
830 | } | 844 | } |
831 | 845 | ||
846 | static size_t ipip_get_size(const struct net_device *dev) | ||
847 | { | ||
848 | return | ||
849 | /* IFLA_IPTUN_LINK */ | ||
850 | nla_total_size(4) + | ||
851 | /* IFLA_IPTUN_LOCAL */ | ||
852 | nla_total_size(4) + | ||
853 | /* IFLA_IPTUN_REMOTE */ | ||
854 | nla_total_size(4) + | ||
855 | /* IFLA_IPTUN_TTL */ | ||
856 | nla_total_size(1) + | ||
857 | /* IFLA_IPTUN_TOS */ | ||
858 | nla_total_size(1) + | ||
859 | 0; | ||
860 | } | ||
861 | |||
862 | static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
863 | { | ||
864 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
865 | struct ip_tunnel_parm *parm = &tunnel->parms; | ||
866 | |||
867 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
868 | nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || | ||
869 | nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || | ||
870 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || | ||
871 | nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) | ||
872 | goto nla_put_failure; | ||
873 | return 0; | ||
874 | |||
875 | nla_put_failure: | ||
876 | return -EMSGSIZE; | ||
877 | } | ||
878 | |||
879 | static struct rtnl_link_ops ipip_link_ops __read_mostly = { | ||
880 | .kind = "ipip", | ||
881 | .maxtype = IFLA_IPTUN_MAX, | ||
882 | .priv_size = sizeof(struct ip_tunnel), | ||
883 | .get_size = ipip_get_size, | ||
884 | .fill_info = ipip_fill_info, | ||
885 | }; | ||
886 | |||
832 | static struct xfrm_tunnel ipip_handler __read_mostly = { | 887 | static struct xfrm_tunnel ipip_handler __read_mostly = { |
833 | .handler = ipip_rcv, | 888 | .handler = ipip_rcv, |
834 | .err_handler = ipip_err, | 889 | .err_handler = ipip_err, |
@@ -925,14 +980,26 @@ static int __init ipip_init(void) | |||
925 | return err; | 980 | return err; |
926 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); | 981 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); |
927 | if (err < 0) { | 982 | if (err < 0) { |
928 | unregister_pernet_device(&ipip_net_ops); | ||
929 | pr_info("%s: can't register tunnel\n", __func__); | 983 | pr_info("%s: can't register tunnel\n", __func__); |
984 | goto xfrm_tunnel_failed; | ||
930 | } | 985 | } |
986 | err = rtnl_link_register(&ipip_link_ops); | ||
987 | if (err < 0) | ||
988 | goto rtnl_link_failed; | ||
989 | |||
990 | out: | ||
931 | return err; | 991 | return err; |
992 | |||
993 | rtnl_link_failed: | ||
994 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | ||
995 | xfrm_tunnel_failed: | ||
996 | unregister_pernet_device(&ipip_net_ops); | ||
997 | goto out; | ||
932 | } | 998 | } |
933 | 999 | ||
934 | static void __exit ipip_fini(void) | 1000 | static void __exit ipip_fini(void) |
935 | { | 1001 | { |
1002 | rtnl_link_unregister(&ipip_link_ops); | ||
936 | if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) | 1003 | if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) |
937 | pr_info("%s: can't deregister tunnel\n", __func__); | 1004 | pr_info("%s: can't deregister tunnel\n", __func__); |
938 | 1005 | ||
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index ba48e799b031..b236ef04914f 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -340,7 +340,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
340 | } | 340 | } |
341 | 341 | ||
342 | req->expires = 0UL; | 342 | req->expires = 0UL; |
343 | req->retrans = 0; | 343 | req->num_retrans = 0; |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * We need to lookup the route here to get at the correct | 346 | * We need to lookup the route here to get at the correct |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 197c0008503c..733f48593ec3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -536,13 +536,14 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
536 | { | 536 | { |
537 | struct tcp_sock *tp = tcp_sk(sk); | 537 | struct tcp_sock *tp = tcp_sk(sk); |
538 | int answ; | 538 | int answ; |
539 | bool slow; | ||
539 | 540 | ||
540 | switch (cmd) { | 541 | switch (cmd) { |
541 | case SIOCINQ: | 542 | case SIOCINQ: |
542 | if (sk->sk_state == TCP_LISTEN) | 543 | if (sk->sk_state == TCP_LISTEN) |
543 | return -EINVAL; | 544 | return -EINVAL; |
544 | 545 | ||
545 | lock_sock(sk); | 546 | slow = lock_sock_fast(sk); |
546 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) | 547 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) |
547 | answ = 0; | 548 | answ = 0; |
548 | else if (sock_flag(sk, SOCK_URGINLINE) || | 549 | else if (sock_flag(sk, SOCK_URGINLINE) || |
@@ -557,7 +558,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
557 | answ--; | 558 | answ--; |
558 | } else | 559 | } else |
559 | answ = tp->urg_seq - tp->copied_seq; | 560 | answ = tp->urg_seq - tp->copied_seq; |
560 | release_sock(sk); | 561 | unlock_sock_fast(sk, slow); |
561 | break; | 562 | break; |
562 | case SIOCATMARK: | 563 | case SIOCATMARK: |
563 | answ = tp->urg_data && tp->urg_seq == tp->copied_seq; | 564 | answ = tp->urg_data && tp->urg_seq == tp->copied_seq; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2c2b13a999ea..7839d51fb65b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3552,6 +3552,24 @@ static bool tcp_process_frto(struct sock *sk, int flag) | |||
3552 | return false; | 3552 | return false; |
3553 | } | 3553 | } |
3554 | 3554 | ||
3555 | /* RFC 5961 7 [ACK Throttling] */ | ||
3556 | static void tcp_send_challenge_ack(struct sock *sk) | ||
3557 | { | ||
3558 | /* unprotected vars, we dont care of overwrites */ | ||
3559 | static u32 challenge_timestamp; | ||
3560 | static unsigned int challenge_count; | ||
3561 | u32 now = jiffies / HZ; | ||
3562 | |||
3563 | if (now != challenge_timestamp) { | ||
3564 | challenge_timestamp = now; | ||
3565 | challenge_count = 0; | ||
3566 | } | ||
3567 | if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { | ||
3568 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); | ||
3569 | tcp_send_ack(sk); | ||
3570 | } | ||
3571 | } | ||
3572 | |||
3555 | /* This routine deals with incoming acks, but not outgoing ones. */ | 3573 | /* This routine deals with incoming acks, but not outgoing ones. */ |
3556 | static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | 3574 | static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) |
3557 | { | 3575 | { |
@@ -3571,8 +3589,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3571 | /* If the ack is older than previous acks | 3589 | /* If the ack is older than previous acks |
3572 | * then we can probably ignore it. | 3590 | * then we can probably ignore it. |
3573 | */ | 3591 | */ |
3574 | if (before(ack, prior_snd_una)) | 3592 | if (before(ack, prior_snd_una)) { |
3593 | /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ | ||
3594 | if (before(ack, prior_snd_una - tp->max_window)) { | ||
3595 | tcp_send_challenge_ack(sk); | ||
3596 | return -1; | ||
3597 | } | ||
3575 | goto old_ack; | 3598 | goto old_ack; |
3599 | } | ||
3576 | 3600 | ||
3577 | /* If the ack includes data we haven't sent yet, discard | 3601 | /* If the ack includes data we haven't sent yet, discard |
3578 | * this segment (RFC793 Section 3.9). | 3602 | * this segment (RFC793 Section 3.9). |
@@ -5244,23 +5268,6 @@ out: | |||
5244 | } | 5268 | } |
5245 | #endif /* CONFIG_NET_DMA */ | 5269 | #endif /* CONFIG_NET_DMA */ |
5246 | 5270 | ||
5247 | static void tcp_send_challenge_ack(struct sock *sk) | ||
5248 | { | ||
5249 | /* unprotected vars, we dont care of overwrites */ | ||
5250 | static u32 challenge_timestamp; | ||
5251 | static unsigned int challenge_count; | ||
5252 | u32 now = jiffies / HZ; | ||
5253 | |||
5254 | if (now != challenge_timestamp) { | ||
5255 | challenge_timestamp = now; | ||
5256 | challenge_count = 0; | ||
5257 | } | ||
5258 | if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { | ||
5259 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); | ||
5260 | tcp_send_ack(sk); | ||
5261 | } | ||
5262 | } | ||
5263 | |||
5264 | /* Does PAWS and seqno based validation of an incoming segment, flags will | 5271 | /* Does PAWS and seqno based validation of an incoming segment, flags will |
5265 | * play significant role here. | 5272 | * play significant role here. |
5266 | */ | 5273 | */ |
@@ -5988,7 +5995,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5988 | */ | 5995 | */ |
5989 | if (req) { | 5996 | if (req) { |
5990 | tcp_synack_rtt_meas(sk, req); | 5997 | tcp_synack_rtt_meas(sk, req); |
5991 | tp->total_retrans = req->retrans; | 5998 | tp->total_retrans = req->num_retrans; |
5992 | 5999 | ||
5993 | reqsk_fastopen_remove(sk, req, false); | 6000 | reqsk_fastopen_remove(sk, req, false); |
5994 | } else { | 6001 | } else { |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 0c4a64355603..9dd5b34eb112 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -877,10 +877,13 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, | |||
877 | } | 877 | } |
878 | 878 | ||
879 | static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, | 879 | static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, |
880 | struct request_values *rvp) | 880 | struct request_values *rvp) |
881 | { | 881 | { |
882 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 882 | int res = tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); |
883 | return tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); | 883 | |
884 | if (!res) | ||
885 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
886 | return res; | ||
884 | } | 887 | } |
885 | 888 | ||
886 | /* | 889 | /* |
@@ -1070,7 +1073,7 @@ int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family) | |||
1070 | } | 1073 | } |
1071 | EXPORT_SYMBOL(tcp_md5_do_del); | 1074 | EXPORT_SYMBOL(tcp_md5_do_del); |
1072 | 1075 | ||
1073 | void tcp_clear_md5_list(struct sock *sk) | 1076 | static void tcp_clear_md5_list(struct sock *sk) |
1074 | { | 1077 | { |
1075 | struct tcp_sock *tp = tcp_sk(sk); | 1078 | struct tcp_sock *tp = tcp_sk(sk); |
1076 | struct tcp_md5sig_key *key; | 1079 | struct tcp_md5sig_key *key; |
@@ -1386,7 +1389,8 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, | |||
1386 | struct sock *child; | 1389 | struct sock *child; |
1387 | int err; | 1390 | int err; |
1388 | 1391 | ||
1389 | req->retrans = 0; | 1392 | req->num_retrans = 0; |
1393 | req->num_timeout = 0; | ||
1390 | req->sk = NULL; | 1394 | req->sk = NULL; |
1391 | 1395 | ||
1392 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); | 1396 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); |
@@ -1741,7 +1745,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1741 | 1745 | ||
1742 | tcp_initialize_rcv_mss(newsk); | 1746 | tcp_initialize_rcv_mss(newsk); |
1743 | tcp_synack_rtt_meas(newsk, req); | 1747 | tcp_synack_rtt_meas(newsk, req); |
1744 | newtp->total_retrans = req->retrans; | 1748 | newtp->total_retrans = req->num_retrans; |
1745 | 1749 | ||
1746 | #ifdef CONFIG_TCP_MD5SIG | 1750 | #ifdef CONFIG_TCP_MD5SIG |
1747 | /* Copy over the MD5 key from the original socket */ | 1751 | /* Copy over the MD5 key from the original socket */ |
@@ -1919,7 +1923,6 @@ EXPORT_SYMBOL(tcp_v4_do_rcv); | |||
1919 | 1923 | ||
1920 | void tcp_v4_early_demux(struct sk_buff *skb) | 1924 | void tcp_v4_early_demux(struct sk_buff *skb) |
1921 | { | 1925 | { |
1922 | struct net *net = dev_net(skb->dev); | ||
1923 | const struct iphdr *iph; | 1926 | const struct iphdr *iph; |
1924 | const struct tcphdr *th; | 1927 | const struct tcphdr *th; |
1925 | struct sock *sk; | 1928 | struct sock *sk; |
@@ -1927,16 +1930,16 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1927 | if (skb->pkt_type != PACKET_HOST) | 1930 | if (skb->pkt_type != PACKET_HOST) |
1928 | return; | 1931 | return; |
1929 | 1932 | ||
1930 | if (!pskb_may_pull(skb, ip_hdrlen(skb) + sizeof(struct tcphdr))) | 1933 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr))) |
1931 | return; | 1934 | return; |
1932 | 1935 | ||
1933 | iph = ip_hdr(skb); | 1936 | iph = ip_hdr(skb); |
1934 | th = (struct tcphdr *) ((char *)iph + ip_hdrlen(skb)); | 1937 | th = tcp_hdr(skb); |
1935 | 1938 | ||
1936 | if (th->doff < sizeof(struct tcphdr) / 4) | 1939 | if (th->doff < sizeof(struct tcphdr) / 4) |
1937 | return; | 1940 | return; |
1938 | 1941 | ||
1939 | sk = __inet_lookup_established(net, &tcp_hashinfo, | 1942 | sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo, |
1940 | iph->saddr, th->source, | 1943 | iph->saddr, th->source, |
1941 | iph->daddr, ntohs(th->dest), | 1944 | iph->daddr, ntohs(th->dest), |
1942 | skb->skb_iif); | 1945 | skb->skb_iif); |
@@ -2640,7 +2643,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, | |||
2640 | 0, 0, /* could print option size, but that is af dependent. */ | 2643 | 0, 0, /* could print option size, but that is af dependent. */ |
2641 | 1, /* timers active (only the expire timer) */ | 2644 | 1, /* timers active (only the expire timer) */ |
2642 | jiffies_delta_to_clock_t(delta), | 2645 | jiffies_delta_to_clock_t(delta), |
2643 | req->retrans, | 2646 | req->num_timeout, |
2644 | from_kuid_munged(seq_user_ns(f), uid), | 2647 | from_kuid_munged(seq_user_ns(f), uid), |
2645 | 0, /* non standard timer */ | 2648 | 0, /* non standard timer */ |
2646 | 0, /* open_requests have no inode */ | 2649 | 0, /* open_requests have no inode */ |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index a7302d974f32..f35f2dfb6401 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -553,7 +553,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
553 | * it can be estimated (approximately) | 553 | * it can be estimated (approximately) |
554 | * from another data. | 554 | * from another data. |
555 | */ | 555 | */ |
556 | tmp_opt.ts_recent_stamp = get_seconds() - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans); | 556 | tmp_opt.ts_recent_stamp = get_seconds() - ((TCP_TIMEOUT_INIT/HZ)<<req->num_timeout); |
557 | paws_reject = tcp_paws_reject(&tmp_opt, th->rst); | 557 | paws_reject = tcp_paws_reject(&tmp_opt, th->rst); |
558 | } | 558 | } |
559 | } | 559 | } |
@@ -582,7 +582,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
582 | * Note that even if there is new data in the SYN packet | 582 | * Note that even if there is new data in the SYN packet |
583 | * they will be thrown away too. | 583 | * they will be thrown away too. |
584 | */ | 584 | */ |
585 | req->rsk_ops->rtx_syn_ack(sk, req, NULL); | 585 | inet_rtx_syn_ack(sk, req); |
586 | return NULL; | 586 | return NULL; |
587 | } | 587 | } |
588 | 588 | ||
@@ -696,7 +696,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
696 | /* Got ACK for our SYNACK, so update baseline for SYNACK RTT sample. */ | 696 | /* Got ACK for our SYNACK, so update baseline for SYNACK RTT sample. */ |
697 | if (tmp_opt.saw_tstamp && tmp_opt.rcv_tsecr) | 697 | if (tmp_opt.saw_tstamp && tmp_opt.rcv_tsecr) |
698 | tcp_rsk(req)->snt_synack = tmp_opt.rcv_tsecr; | 698 | tcp_rsk(req)->snt_synack = tmp_opt.rcv_tsecr; |
699 | else if (req->retrans) /* don't take RTT sample if retrans && ~TS */ | 699 | else if (req->num_retrans) /* don't take RTT sample if retrans && ~TS */ |
700 | tcp_rsk(req)->snt_synack = 0; | 700 | tcp_rsk(req)->snt_synack = 0; |
701 | 701 | ||
702 | /* For Fast Open no more processing is needed (sk is the | 702 | /* For Fast Open no more processing is needed (sk is the |
@@ -706,7 +706,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
706 | return sk; | 706 | return sk; |
707 | 707 | ||
708 | /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */ | 708 | /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */ |
709 | if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | 709 | if (req->num_timeout < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && |
710 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | 710 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { |
711 | inet_rsk(req)->acked = 1; | 711 | inet_rsk(req)->acked = 1; |
712 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDEFERACCEPTDROP); | 712 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDEFERACCEPTDROP); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index d47c1b4421a3..b78aac30c498 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -318,7 +318,7 @@ static void tcp_fastopen_synack_timer(struct sock *sk) | |||
318 | req = tcp_sk(sk)->fastopen_rsk; | 318 | req = tcp_sk(sk)->fastopen_rsk; |
319 | req->rsk_ops->syn_ack_timeout(sk, req); | 319 | req->rsk_ops->syn_ack_timeout(sk, req); |
320 | 320 | ||
321 | if (req->retrans >= max_retries) { | 321 | if (req->num_timeout >= max_retries) { |
322 | tcp_write_err(sk); | 322 | tcp_write_err(sk); |
323 | return; | 323 | return; |
324 | } | 324 | } |
@@ -327,10 +327,10 @@ static void tcp_fastopen_synack_timer(struct sock *sk) | |||
327 | * regular retransmit because if the child socket has been accepted | 327 | * regular retransmit because if the child socket has been accepted |
328 | * it's not good to give up too easily. | 328 | * it's not good to give up too easily. |
329 | */ | 329 | */ |
330 | req->rsk_ops->rtx_syn_ack(sk, req, NULL); | 330 | inet_rtx_syn_ack(sk, req); |
331 | req->retrans++; | 331 | req->num_timeout++; |
332 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 332 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
333 | TCP_TIMEOUT_INIT << req->retrans, TCP_RTO_MAX); | 333 | TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); |
334 | } | 334 | } |
335 | 335 | ||
336 | /* | 336 | /* |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 0424e4e27414..fab23db8ee73 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <net/pkt_sched.h> | 81 | #include <net/pkt_sched.h> |
82 | #include <linux/if_tunnel.h> | 82 | #include <linux/if_tunnel.h> |
83 | #include <linux/rtnetlink.h> | 83 | #include <linux/rtnetlink.h> |
84 | #include <linux/netconf.h> | ||
84 | 85 | ||
85 | #ifdef CONFIG_IPV6_PRIVACY | 86 | #ifdef CONFIG_IPV6_PRIVACY |
86 | #include <linux/random.h> | 87 | #include <linux/random.h> |
@@ -401,7 +402,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) | |||
401 | if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) | 402 | if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) |
402 | ndev->cnf.accept_dad = -1; | 403 | ndev->cnf.accept_dad = -1; |
403 | 404 | ||
404 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 405 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
405 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { | 406 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { |
406 | pr_info("%s: Disabled Multicast RS\n", dev->name); | 407 | pr_info("%s: Disabled Multicast RS\n", dev->name); |
407 | ndev->cnf.rtr_solicits = 0; | 408 | ndev->cnf.rtr_solicits = 0; |
@@ -460,6 +461,141 @@ static struct inet6_dev *ipv6_find_idev(struct net_device *dev) | |||
460 | return idev; | 461 | return idev; |
461 | } | 462 | } |
462 | 463 | ||
464 | static int inet6_netconf_msgsize_devconf(int type) | ||
465 | { | ||
466 | int size = NLMSG_ALIGN(sizeof(struct netconfmsg)) | ||
467 | + nla_total_size(4); /* NETCONFA_IFINDEX */ | ||
468 | |||
469 | /* type -1 is used for ALL */ | ||
470 | if (type == -1 || type == NETCONFA_FORWARDING) | ||
471 | size += nla_total_size(4); | ||
472 | |||
473 | return size; | ||
474 | } | ||
475 | |||
476 | static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | ||
477 | struct ipv6_devconf *devconf, u32 portid, | ||
478 | u32 seq, int event, unsigned int flags, | ||
479 | int type) | ||
480 | { | ||
481 | struct nlmsghdr *nlh; | ||
482 | struct netconfmsg *ncm; | ||
483 | |||
484 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg), | ||
485 | flags); | ||
486 | if (nlh == NULL) | ||
487 | return -EMSGSIZE; | ||
488 | |||
489 | ncm = nlmsg_data(nlh); | ||
490 | ncm->ncm_family = AF_INET6; | ||
491 | |||
492 | if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0) | ||
493 | goto nla_put_failure; | ||
494 | |||
495 | /* type -1 is used for ALL */ | ||
496 | if ((type == -1 || type == NETCONFA_FORWARDING) && | ||
497 | nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0) | ||
498 | goto nla_put_failure; | ||
499 | |||
500 | return nlmsg_end(skb, nlh); | ||
501 | |||
502 | nla_put_failure: | ||
503 | nlmsg_cancel(skb, nlh); | ||
504 | return -EMSGSIZE; | ||
505 | } | ||
506 | |||
507 | static void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex, | ||
508 | struct ipv6_devconf *devconf) | ||
509 | { | ||
510 | struct sk_buff *skb; | ||
511 | int err = -ENOBUFS; | ||
512 | |||
513 | skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC); | ||
514 | if (skb == NULL) | ||
515 | goto errout; | ||
516 | |||
517 | err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, | ||
518 | RTM_NEWNETCONF, 0, type); | ||
519 | if (err < 0) { | ||
520 | /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ | ||
521 | WARN_ON(err == -EMSGSIZE); | ||
522 | kfree_skb(skb); | ||
523 | goto errout; | ||
524 | } | ||
525 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC); | ||
526 | return; | ||
527 | errout: | ||
528 | if (err < 0) | ||
529 | rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err); | ||
530 | } | ||
531 | |||
532 | static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = { | ||
533 | [NETCONFA_IFINDEX] = { .len = sizeof(int) }, | ||
534 | [NETCONFA_FORWARDING] = { .len = sizeof(int) }, | ||
535 | }; | ||
536 | |||
537 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, | ||
538 | struct nlmsghdr *nlh, | ||
539 | void *arg) | ||
540 | { | ||
541 | struct net *net = sock_net(in_skb->sk); | ||
542 | struct nlattr *tb[NETCONFA_MAX+1]; | ||
543 | struct netconfmsg *ncm; | ||
544 | struct sk_buff *skb; | ||
545 | struct ipv6_devconf *devconf; | ||
546 | struct inet6_dev *in6_dev; | ||
547 | struct net_device *dev; | ||
548 | int ifindex; | ||
549 | int err; | ||
550 | |||
551 | err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX, | ||
552 | devconf_ipv6_policy); | ||
553 | if (err < 0) | ||
554 | goto errout; | ||
555 | |||
556 | err = EINVAL; | ||
557 | if (!tb[NETCONFA_IFINDEX]) | ||
558 | goto errout; | ||
559 | |||
560 | ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]); | ||
561 | switch (ifindex) { | ||
562 | case NETCONFA_IFINDEX_ALL: | ||
563 | devconf = net->ipv6.devconf_all; | ||
564 | break; | ||
565 | case NETCONFA_IFINDEX_DEFAULT: | ||
566 | devconf = net->ipv6.devconf_dflt; | ||
567 | break; | ||
568 | default: | ||
569 | dev = __dev_get_by_index(net, ifindex); | ||
570 | if (dev == NULL) | ||
571 | goto errout; | ||
572 | in6_dev = __in6_dev_get(dev); | ||
573 | if (in6_dev == NULL) | ||
574 | goto errout; | ||
575 | devconf = &in6_dev->cnf; | ||
576 | break; | ||
577 | } | ||
578 | |||
579 | err = -ENOBUFS; | ||
580 | skb = nlmsg_new(inet6_netconf_msgsize_devconf(-1), GFP_ATOMIC); | ||
581 | if (skb == NULL) | ||
582 | goto errout; | ||
583 | |||
584 | err = inet6_netconf_fill_devconf(skb, ifindex, devconf, | ||
585 | NETLINK_CB(in_skb).portid, | ||
586 | nlh->nlmsg_seq, RTM_NEWNETCONF, 0, | ||
587 | -1); | ||
588 | if (err < 0) { | ||
589 | /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ | ||
590 | WARN_ON(err == -EMSGSIZE); | ||
591 | kfree_skb(skb); | ||
592 | goto errout; | ||
593 | } | ||
594 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); | ||
595 | errout: | ||
596 | return err; | ||
597 | } | ||
598 | |||
463 | #ifdef CONFIG_SYSCTL | 599 | #ifdef CONFIG_SYSCTL |
464 | static void dev_forward_change(struct inet6_dev *idev) | 600 | static void dev_forward_change(struct inet6_dev *idev) |
465 | { | 601 | { |
@@ -471,7 +607,7 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
471 | dev = idev->dev; | 607 | dev = idev->dev; |
472 | if (idev->cnf.forwarding) | 608 | if (idev->cnf.forwarding) |
473 | dev_disable_lro(dev); | 609 | dev_disable_lro(dev); |
474 | if (dev && (dev->flags & IFF_MULTICAST)) { | 610 | if (dev->flags & IFF_MULTICAST) { |
475 | if (idev->cnf.forwarding) | 611 | if (idev->cnf.forwarding) |
476 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); | 612 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); |
477 | else | 613 | else |
@@ -486,6 +622,8 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
486 | else | 622 | else |
487 | addrconf_leave_anycast(ifa); | 623 | addrconf_leave_anycast(ifa); |
488 | } | 624 | } |
625 | inet6_netconf_notify_devconf(dev_net(dev), NETCONFA_FORWARDING, | ||
626 | dev->ifindex, &idev->cnf); | ||
489 | } | 627 | } |
490 | 628 | ||
491 | 629 | ||
@@ -518,6 +656,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
518 | *p = newf; | 656 | *p = newf; |
519 | 657 | ||
520 | if (p == &net->ipv6.devconf_dflt->forwarding) { | 658 | if (p == &net->ipv6.devconf_dflt->forwarding) { |
659 | if ((!newf) ^ (!old)) | ||
660 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
661 | NETCONFA_IFINDEX_DEFAULT, | ||
662 | net->ipv6.devconf_dflt); | ||
521 | rtnl_unlock(); | 663 | rtnl_unlock(); |
522 | return 0; | 664 | return 0; |
523 | } | 665 | } |
@@ -525,6 +667,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
525 | if (p == &net->ipv6.devconf_all->forwarding) { | 667 | if (p == &net->ipv6.devconf_all->forwarding) { |
526 | net->ipv6.devconf_dflt->forwarding = newf; | 668 | net->ipv6.devconf_dflt->forwarding = newf; |
527 | addrconf_forward_change(net, newf); | 669 | addrconf_forward_change(net, newf); |
670 | if ((!newf) ^ (!old)) | ||
671 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
672 | NETCONFA_IFINDEX_ALL, | ||
673 | net->ipv6.devconf_all); | ||
528 | } else if ((!newf) ^ (!old)) | 674 | } else if ((!newf) ^ (!old)) |
529 | dev_forward_change((struct inet6_dev *)table->extra1); | 675 | dev_forward_change((struct inet6_dev *)table->extra1); |
530 | rtnl_unlock(); | 676 | rtnl_unlock(); |
@@ -553,7 +699,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
553 | pr_warn("Freeing alive inet6 address %p\n", ifp); | 699 | pr_warn("Freeing alive inet6 address %p\n", ifp); |
554 | return; | 700 | return; |
555 | } | 701 | } |
556 | dst_release(&ifp->rt->dst); | 702 | ip6_rt_put(ifp->rt); |
557 | 703 | ||
558 | kfree_rcu(ifp, rcu); | 704 | kfree_rcu(ifp, rcu); |
559 | } | 705 | } |
@@ -805,7 +951,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
805 | rt6_set_expires(rt, expires); | 951 | rt6_set_expires(rt, expires); |
806 | } | 952 | } |
807 | } | 953 | } |
808 | dst_release(&rt->dst); | 954 | ip6_rt_put(rt); |
809 | } | 955 | } |
810 | 956 | ||
811 | /* clean up prefsrc entries */ | 957 | /* clean up prefsrc entries */ |
@@ -1692,7 +1838,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1692 | This thing is done here expecting that the whole | 1838 | This thing is done here expecting that the whole |
1693 | class of non-broadcast devices need not cloning. | 1839 | class of non-broadcast devices need not cloning. |
1694 | */ | 1840 | */ |
1695 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 1841 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
1696 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) | 1842 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) |
1697 | cfg.fc_flags |= RTF_NONEXTHOP; | 1843 | cfg.fc_flags |= RTF_NONEXTHOP; |
1698 | #endif | 1844 | #endif |
@@ -1752,7 +1898,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1752 | ip6_route_add(&cfg); | 1898 | ip6_route_add(&cfg); |
1753 | } | 1899 | } |
1754 | 1900 | ||
1755 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 1901 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
1756 | static void sit_route_add(struct net_device *dev) | 1902 | static void sit_route_add(struct net_device *dev) |
1757 | { | 1903 | { |
1758 | struct fib6_config cfg = { | 1904 | struct fib6_config cfg = { |
@@ -1881,8 +2027,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) | |||
1881 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, | 2027 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, |
1882 | dev, expires, flags); | 2028 | dev, expires, flags); |
1883 | } | 2029 | } |
1884 | if (rt) | 2030 | ip6_rt_put(rt); |
1885 | dst_release(&rt->dst); | ||
1886 | } | 2031 | } |
1887 | 2032 | ||
1888 | /* Try to figure out our local address for this prefix */ | 2033 | /* Try to figure out our local address for this prefix */ |
@@ -2104,7 +2249,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2104 | if (dev == NULL) | 2249 | if (dev == NULL) |
2105 | goto err_exit; | 2250 | goto err_exit; |
2106 | 2251 | ||
2107 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2252 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2108 | if (dev->type == ARPHRD_SIT) { | 2253 | if (dev->type == ARPHRD_SIT) { |
2109 | const struct net_device_ops *ops = dev->netdev_ops; | 2254 | const struct net_device_ops *ops = dev->netdev_ops; |
2110 | struct ifreq ifr; | 2255 | struct ifreq ifr; |
@@ -2315,7 +2460,7 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
2315 | } | 2460 | } |
2316 | } | 2461 | } |
2317 | 2462 | ||
2318 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2463 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2319 | static void sit_add_v4_addrs(struct inet6_dev *idev) | 2464 | static void sit_add_v4_addrs(struct inet6_dev *idev) |
2320 | { | 2465 | { |
2321 | struct in6_addr addr; | 2466 | struct in6_addr addr; |
@@ -2434,7 +2579,7 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2434 | addrconf_add_linklocal(idev, &addr); | 2579 | addrconf_add_linklocal(idev, &addr); |
2435 | } | 2580 | } |
2436 | 2581 | ||
2437 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2582 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2438 | static void addrconf_sit_config(struct net_device *dev) | 2583 | static void addrconf_sit_config(struct net_device *dev) |
2439 | { | 2584 | { |
2440 | struct inet6_dev *idev; | 2585 | struct inet6_dev *idev; |
@@ -2471,7 +2616,7 @@ static void addrconf_sit_config(struct net_device *dev) | |||
2471 | } | 2616 | } |
2472 | #endif | 2617 | #endif |
2473 | 2618 | ||
2474 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | 2619 | #if IS_ENABLED(CONFIG_NET_IPGRE) |
2475 | static void addrconf_gre_config(struct net_device *dev) | 2620 | static void addrconf_gre_config(struct net_device *dev) |
2476 | { | 2621 | { |
2477 | struct inet6_dev *idev; | 2622 | struct inet6_dev *idev; |
@@ -2601,12 +2746,12 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2601 | } | 2746 | } |
2602 | 2747 | ||
2603 | switch (dev->type) { | 2748 | switch (dev->type) { |
2604 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2749 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2605 | case ARPHRD_SIT: | 2750 | case ARPHRD_SIT: |
2606 | addrconf_sit_config(dev); | 2751 | addrconf_sit_config(dev); |
2607 | break; | 2752 | break; |
2608 | #endif | 2753 | #endif |
2609 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | 2754 | #if IS_ENABLED(CONFIG_NET_IPGRE) |
2610 | case ARPHRD_IPGRE: | 2755 | case ARPHRD_IPGRE: |
2611 | addrconf_gre_config(dev); | 2756 | addrconf_gre_config(dev); |
2612 | break; | 2757 | break; |
@@ -3194,7 +3339,7 @@ void if6_proc_exit(void) | |||
3194 | } | 3339 | } |
3195 | #endif /* CONFIG_PROC_FS */ | 3340 | #endif /* CONFIG_PROC_FS */ |
3196 | 3341 | ||
3197 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 3342 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
3198 | /* Check if address is a home address configured on any interface. */ | 3343 | /* Check if address is a home address configured on any interface. */ |
3199 | int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) | 3344 | int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) |
3200 | { | 3345 | { |
@@ -4784,6 +4929,8 @@ int __init addrconf_init(void) | |||
4784 | inet6_dump_ifmcaddr, NULL); | 4929 | inet6_dump_ifmcaddr, NULL); |
4785 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, | 4930 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, |
4786 | inet6_dump_ifacaddr, NULL); | 4931 | inet6_dump_ifacaddr, NULL); |
4932 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, | ||
4933 | NULL, NULL); | ||
4787 | 4934 | ||
4788 | ipv6_addr_label_rtnl_register(); | 4935 | ipv6_addr_label_rtnl_register(); |
4789 | 4936 | ||
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 7e6139508ee7..ecc35b93314b 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define IPV6HDR_BASELEN 8 | 44 | #define IPV6HDR_BASELEN 8 |
45 | 45 | ||
46 | struct tmp_ext { | 46 | struct tmp_ext { |
47 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 47 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
48 | struct in6_addr saddr; | 48 | struct in6_addr saddr; |
49 | #endif | 49 | #endif |
50 | struct in6_addr daddr; | 50 | struct in6_addr daddr; |
@@ -152,7 +152,7 @@ bad: | |||
152 | return false; | 152 | return false; |
153 | } | 153 | } |
154 | 154 | ||
155 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 155 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
156 | /** | 156 | /** |
157 | * ipv6_rearrange_destopt - rearrange IPv6 destination options header | 157 | * ipv6_rearrange_destopt - rearrange IPv6 destination options header |
158 | * @iph: IPv6 header | 158 | * @iph: IPv6 header |
@@ -320,7 +320,7 @@ static void ah6_output_done(struct crypto_async_request *base, int err) | |||
320 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); | 320 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); |
321 | 321 | ||
322 | if (extlen) { | 322 | if (extlen) { |
323 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 323 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
324 | memcpy(&top_iph->saddr, iph_ext, extlen); | 324 | memcpy(&top_iph->saddr, iph_ext, extlen); |
325 | #else | 325 | #else |
326 | memcpy(&top_iph->daddr, iph_ext, extlen); | 326 | memcpy(&top_iph->daddr, iph_ext, extlen); |
@@ -385,7 +385,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
385 | memcpy(iph_base, top_iph, IPV6HDR_BASELEN); | 385 | memcpy(iph_base, top_iph, IPV6HDR_BASELEN); |
386 | 386 | ||
387 | if (extlen) { | 387 | if (extlen) { |
388 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 388 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
389 | memcpy(iph_ext, &top_iph->saddr, extlen); | 389 | memcpy(iph_ext, &top_iph->saddr, extlen); |
390 | #else | 390 | #else |
391 | memcpy(iph_ext, &top_iph->daddr, extlen); | 391 | memcpy(iph_ext, &top_iph->daddr, extlen); |
@@ -434,7 +434,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
434 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); | 434 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); |
435 | 435 | ||
436 | if (extlen) { | 436 | if (extlen) { |
437 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 437 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
438 | memcpy(&top_iph->saddr, iph_ext, extlen); | 438 | memcpy(&top_iph->saddr, iph_ext, extlen); |
439 | #else | 439 | #else |
440 | memcpy(&top_iph->daddr, iph_ext, extlen); | 440 | memcpy(&top_iph->daddr, iph_ext, extlen); |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index cdf02be5f191..4963c769a13f 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -84,7 +84,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
84 | rt = rt6_lookup(net, addr, NULL, 0, 0); | 84 | rt = rt6_lookup(net, addr, NULL, 0, 0); |
85 | if (rt) { | 85 | if (rt) { |
86 | dev = rt->dst.dev; | 86 | dev = rt->dst.dev; |
87 | dst_release(&rt->dst); | 87 | ip6_rt_put(rt); |
88 | } else if (ishost) { | 88 | } else if (ishost) { |
89 | err = -EADDRNOTAVAIL; | 89 | err = -EADDRNOTAVAIL; |
90 | goto error; | 90 | goto error; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index be2b67d631e5..93cbad2c0aa7 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -769,7 +769,7 @@ int datagram_send_ctl(struct net *net, struct sock *sk, | |||
769 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); | 769 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); |
770 | 770 | ||
771 | switch (rthdr->type) { | 771 | switch (rthdr->type) { |
772 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 772 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
773 | case IPV6_SRCRT_TYPE_2: | 773 | case IPV6_SRCRT_TYPE_2: |
774 | if (rthdr->hdrlen != 2 || | 774 | if (rthdr->hdrlen != 2 || |
775 | rthdr->segments_left != 1) { | 775 | rthdr->segments_left != 1) { |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index fa3d9c328092..f005acc58b2a 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <net/ndisc.h> | 43 | #include <net/ndisc.h> |
44 | #include <net/ip6_route.h> | 44 | #include <net/ip6_route.h> |
45 | #include <net/addrconf.h> | 45 | #include <net/addrconf.h> |
46 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 46 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
47 | #include <net/xfrm.h> | 47 | #include <net/xfrm.h> |
48 | #endif | 48 | #endif |
49 | 49 | ||
@@ -224,7 +224,7 @@ bad: | |||
224 | Destination options header. | 224 | Destination options header. |
225 | *****************************/ | 225 | *****************************/ |
226 | 226 | ||
227 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 227 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
228 | static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) | 228 | static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) |
229 | { | 229 | { |
230 | struct ipv6_destopt_hao *hao; | 230 | struct ipv6_destopt_hao *hao; |
@@ -288,7 +288,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) | |||
288 | #endif | 288 | #endif |
289 | 289 | ||
290 | static const struct tlvtype_proc tlvprocdestopt_lst[] = { | 290 | static const struct tlvtype_proc tlvprocdestopt_lst[] = { |
291 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 291 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
292 | { | 292 | { |
293 | .type = IPV6_TLV_HAO, | 293 | .type = IPV6_TLV_HAO, |
294 | .func = ipv6_dest_hao, | 294 | .func = ipv6_dest_hao, |
@@ -300,7 +300,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = { | |||
300 | static int ipv6_destopt_rcv(struct sk_buff *skb) | 300 | static int ipv6_destopt_rcv(struct sk_buff *skb) |
301 | { | 301 | { |
302 | struct inet6_skb_parm *opt = IP6CB(skb); | 302 | struct inet6_skb_parm *opt = IP6CB(skb); |
303 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 303 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
304 | __u16 dstbuf; | 304 | __u16 dstbuf; |
305 | #endif | 305 | #endif |
306 | struct dst_entry *dst = skb_dst(skb); | 306 | struct dst_entry *dst = skb_dst(skb); |
@@ -315,14 +315,14 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
315 | } | 315 | } |
316 | 316 | ||
317 | opt->lastopt = opt->dst1 = skb_network_header_len(skb); | 317 | opt->lastopt = opt->dst1 = skb_network_header_len(skb); |
318 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 318 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
319 | dstbuf = opt->dst1; | 319 | dstbuf = opt->dst1; |
320 | #endif | 320 | #endif |
321 | 321 | ||
322 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { | 322 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { |
323 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; | 323 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; |
324 | opt = IP6CB(skb); | 324 | opt = IP6CB(skb); |
325 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 325 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
326 | opt->nhoff = dstbuf; | 326 | opt->nhoff = dstbuf; |
327 | #else | 327 | #else |
328 | opt->nhoff = opt->dst1; | 328 | opt->nhoff = opt->dst1; |
@@ -378,7 +378,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) | |||
378 | looped_back: | 378 | looped_back: |
379 | if (hdr->segments_left == 0) { | 379 | if (hdr->segments_left == 0) { |
380 | switch (hdr->type) { | 380 | switch (hdr->type) { |
381 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 381 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
382 | case IPV6_SRCRT_TYPE_2: | 382 | case IPV6_SRCRT_TYPE_2: |
383 | /* Silently discard type 2 header unless it was | 383 | /* Silently discard type 2 header unless it was |
384 | * processed by own | 384 | * processed by own |
@@ -404,7 +404,7 @@ looped_back: | |||
404 | } | 404 | } |
405 | 405 | ||
406 | switch (hdr->type) { | 406 | switch (hdr->type) { |
407 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 407 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
408 | case IPV6_SRCRT_TYPE_2: | 408 | case IPV6_SRCRT_TYPE_2: |
409 | if (accept_source_route < 0) | 409 | if (accept_source_route < 0) |
410 | goto unknown_rh; | 410 | goto unknown_rh; |
@@ -461,7 +461,7 @@ looped_back: | |||
461 | addr += i - 1; | 461 | addr += i - 1; |
462 | 462 | ||
463 | switch (hdr->type) { | 463 | switch (hdr->type) { |
464 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 464 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
465 | case IPV6_SRCRT_TYPE_2: | 465 | case IPV6_SRCRT_TYPE_2: |
466 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, | 466 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, |
467 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, | 467 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index d9fb9110f607..2e1a432867c0 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -100,7 +100,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
100 | goto out; | 100 | goto out; |
101 | } | 101 | } |
102 | again: | 102 | again: |
103 | dst_release(&rt->dst); | 103 | ip6_rt_put(rt); |
104 | rt = NULL; | 104 | rt = NULL; |
105 | goto out; | 105 | goto out; |
106 | 106 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 24d69dbca4d6..b4a9fd51dae7 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -280,7 +280,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 283 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
284 | static void mip6_addr_swap(struct sk_buff *skb) | 284 | static void mip6_addr_swap(struct sk_buff *skb) |
285 | { | 285 | { |
286 | struct ipv6hdr *iph = ipv6_hdr(skb); | 286 | struct ipv6hdr *iph = ipv6_hdr(skb); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 24995a93ef8c..710cafd2e1a9 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -672,6 +672,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
672 | iter->rt6i_idev == rt->rt6i_idev && | 672 | iter->rt6i_idev == rt->rt6i_idev && |
673 | ipv6_addr_equal(&iter->rt6i_gateway, | 673 | ipv6_addr_equal(&iter->rt6i_gateway, |
674 | &rt->rt6i_gateway)) { | 674 | &rt->rt6i_gateway)) { |
675 | if (rt->rt6i_nsiblings) | ||
676 | rt->rt6i_nsiblings = 0; | ||
675 | if (!(iter->rt6i_flags & RTF_EXPIRES)) | 677 | if (!(iter->rt6i_flags & RTF_EXPIRES)) |
676 | return -EEXIST; | 678 | return -EEXIST; |
677 | if (!(rt->rt6i_flags & RTF_EXPIRES)) | 679 | if (!(rt->rt6i_flags & RTF_EXPIRES)) |
@@ -680,6 +682,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
680 | rt6_set_expires(iter, rt->dst.expires); | 682 | rt6_set_expires(iter, rt->dst.expires); |
681 | return -EEXIST; | 683 | return -EEXIST; |
682 | } | 684 | } |
685 | /* If we have the same destination and the same metric, | ||
686 | * but not the same gateway, then the route we try to | ||
687 | * add is sibling to this route, increment our counter | ||
688 | * of siblings, and later we will add our route to the | ||
689 | * list. | ||
690 | * Only static routes (which don't have flag | ||
691 | * RTF_EXPIRES) are used for ECMPv6. | ||
692 | * | ||
693 | * To avoid long list, we only had siblings if the | ||
694 | * route have a gateway. | ||
695 | */ | ||
696 | if (rt->rt6i_flags & RTF_GATEWAY && | ||
697 | !(rt->rt6i_flags & RTF_EXPIRES) && | ||
698 | !(iter->rt6i_flags & RTF_EXPIRES)) | ||
699 | rt->rt6i_nsiblings++; | ||
683 | } | 700 | } |
684 | 701 | ||
685 | if (iter->rt6i_metric > rt->rt6i_metric) | 702 | if (iter->rt6i_metric > rt->rt6i_metric) |
@@ -692,6 +709,35 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
692 | if (ins == &fn->leaf) | 709 | if (ins == &fn->leaf) |
693 | fn->rr_ptr = NULL; | 710 | fn->rr_ptr = NULL; |
694 | 711 | ||
712 | /* Link this route to others same route. */ | ||
713 | if (rt->rt6i_nsiblings) { | ||
714 | unsigned int rt6i_nsiblings; | ||
715 | struct rt6_info *sibling, *temp_sibling; | ||
716 | |||
717 | /* Find the first route that have the same metric */ | ||
718 | sibling = fn->leaf; | ||
719 | while (sibling) { | ||
720 | if (sibling->rt6i_metric == rt->rt6i_metric) { | ||
721 | list_add_tail(&rt->rt6i_siblings, | ||
722 | &sibling->rt6i_siblings); | ||
723 | break; | ||
724 | } | ||
725 | sibling = sibling->dst.rt6_next; | ||
726 | } | ||
727 | /* For each sibling in the list, increment the counter of | ||
728 | * siblings. BUG() if counters does not match, list of siblings | ||
729 | * is broken! | ||
730 | */ | ||
731 | rt6i_nsiblings = 0; | ||
732 | list_for_each_entry_safe(sibling, temp_sibling, | ||
733 | &rt->rt6i_siblings, rt6i_siblings) { | ||
734 | sibling->rt6i_nsiblings++; | ||
735 | BUG_ON(sibling->rt6i_nsiblings != rt->rt6i_nsiblings); | ||
736 | rt6i_nsiblings++; | ||
737 | } | ||
738 | BUG_ON(rt6i_nsiblings != rt->rt6i_nsiblings); | ||
739 | } | ||
740 | |||
695 | /* | 741 | /* |
696 | * insert node | 742 | * insert node |
697 | */ | 743 | */ |
@@ -1193,6 +1239,17 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
1193 | if (fn->rr_ptr == rt) | 1239 | if (fn->rr_ptr == rt) |
1194 | fn->rr_ptr = NULL; | 1240 | fn->rr_ptr = NULL; |
1195 | 1241 | ||
1242 | /* Remove this entry from other siblings */ | ||
1243 | if (rt->rt6i_nsiblings) { | ||
1244 | struct rt6_info *sibling, *next_sibling; | ||
1245 | |||
1246 | list_for_each_entry_safe(sibling, next_sibling, | ||
1247 | &rt->rt6i_siblings, rt6i_siblings) | ||
1248 | sibling->rt6i_nsiblings--; | ||
1249 | rt->rt6i_nsiblings = 0; | ||
1250 | list_del_init(&rt->rt6i_siblings); | ||
1251 | } | ||
1252 | |||
1196 | /* Adjust walkers */ | 1253 | /* Adjust walkers */ |
1197 | read_lock(&fib6_walker_lock); | 1254 | read_lock(&fib6_walker_lock); |
1198 | FOR_WALKERS(w) { | 1255 | FOR_WALKERS(w) { |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index d5cb3c4e66f8..12aa473e9793 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -1069,7 +1069,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu) | |||
1069 | dev->mtu = IPV6_MIN_MTU; | 1069 | dev->mtu = IPV6_MIN_MTU; |
1070 | } | 1070 | } |
1071 | } | 1071 | } |
1072 | dst_release(&rt->dst); | 1072 | ip6_rt_put(rt); |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | t->hlen = addend; | 1075 | t->hlen = addend; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index aece3e792f84..3deaa4e2e8e2 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -538,8 +538,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
538 | to->tc_index = from->tc_index; | 538 | to->tc_index = from->tc_index; |
539 | #endif | 539 | #endif |
540 | nf_copy(to, from); | 540 | nf_copy(to, from); |
541 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 541 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
542 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
543 | to->nf_trace = from->nf_trace; | 542 | to->nf_trace = from->nf_trace; |
544 | #endif | 543 | #endif |
545 | skb_copy_secmark(to, from); | 544 | skb_copy_secmark(to, from); |
@@ -564,7 +563,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
564 | found_rhdr = 1; | 563 | found_rhdr = 1; |
565 | break; | 564 | break; |
566 | case NEXTHDR_DEST: | 565 | case NEXTHDR_DEST: |
567 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 566 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
568 | if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) | 567 | if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) |
569 | break; | 568 | break; |
570 | #endif | 569 | #endif |
@@ -756,7 +755,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | if (err == 0) { | 755 | if (err == 0) { |
757 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), | 756 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), |
758 | IPSTATS_MIB_FRAGOKS); | 757 | IPSTATS_MIB_FRAGOKS); |
759 | dst_release(&rt->dst); | 758 | ip6_rt_put(rt); |
760 | return 0; | 759 | return 0; |
761 | } | 760 | } |
762 | 761 | ||
@@ -768,7 +767,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
768 | 767 | ||
769 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), | 768 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), |
770 | IPSTATS_MIB_FRAGFAILS); | 769 | IPSTATS_MIB_FRAGFAILS); |
771 | dst_release(&rt->dst); | 770 | ip6_rt_put(rt); |
772 | return err; | 771 | return err; |
773 | 772 | ||
774 | slow_path_clean: | 773 | slow_path_clean: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index cb7e2ded6f08..424ed45ef122 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -83,6 +83,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) | |||
83 | 83 | ||
84 | static int ip6_tnl_dev_init(struct net_device *dev); | 84 | static int ip6_tnl_dev_init(struct net_device *dev); |
85 | static void ip6_tnl_dev_setup(struct net_device *dev); | 85 | static void ip6_tnl_dev_setup(struct net_device *dev); |
86 | static struct rtnl_link_ops ip6_link_ops __read_mostly; | ||
86 | 87 | ||
87 | static int ip6_tnl_net_id __read_mostly; | 88 | static int ip6_tnl_net_id __read_mostly; |
88 | struct ip6_tnl_net { | 89 | struct ip6_tnl_net { |
@@ -299,6 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | |||
299 | goto failed_free; | 300 | goto failed_free; |
300 | 301 | ||
301 | strcpy(t->parms.name, dev->name); | 302 | strcpy(t->parms.name, dev->name); |
303 | dev->rtnl_link_ops = &ip6_link_ops; | ||
302 | 304 | ||
303 | dev_hold(dev); | 305 | dev_hold(dev); |
304 | ip6_tnl_link(ip6n, t); | 306 | ip6_tnl_link(ip6n, t); |
@@ -663,8 +665,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
663 | 665 | ||
664 | icmpv6_send(skb2, rel_type, rel_code, rel_info); | 666 | icmpv6_send(skb2, rel_type, rel_code, rel_info); |
665 | 667 | ||
666 | if (rt) | 668 | ip6_rt_put(rt); |
667 | dst_release(&rt->dst); | ||
668 | 669 | ||
669 | kfree_skb(skb2); | 670 | kfree_skb(skb2); |
670 | } | 671 | } |
@@ -1208,7 +1209,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1208 | if (dev->mtu < IPV6_MIN_MTU) | 1209 | if (dev->mtu < IPV6_MIN_MTU) |
1209 | dev->mtu = IPV6_MIN_MTU; | 1210 | dev->mtu = IPV6_MIN_MTU; |
1210 | } | 1211 | } |
1211 | dst_release(&rt->dst); | 1212 | ip6_rt_put(rt); |
1212 | } | 1213 | } |
1213 | } | 1214 | } |
1214 | 1215 | ||
@@ -1505,6 +1506,55 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1505 | return 0; | 1506 | return 0; |
1506 | } | 1507 | } |
1507 | 1508 | ||
1509 | static size_t ip6_get_size(const struct net_device *dev) | ||
1510 | { | ||
1511 | return | ||
1512 | /* IFLA_IPTUN_LINK */ | ||
1513 | nla_total_size(4) + | ||
1514 | /* IFLA_IPTUN_LOCAL */ | ||
1515 | nla_total_size(sizeof(struct in6_addr)) + | ||
1516 | /* IFLA_IPTUN_REMOTE */ | ||
1517 | nla_total_size(sizeof(struct in6_addr)) + | ||
1518 | /* IFLA_IPTUN_TTL */ | ||
1519 | nla_total_size(1) + | ||
1520 | /* IFLA_IPTUN_ENCAP_LIMIT */ | ||
1521 | nla_total_size(1) + | ||
1522 | /* IFLA_IPTUN_FLOWINFO */ | ||
1523 | nla_total_size(4) + | ||
1524 | /* IFLA_IPTUN_FLAGS */ | ||
1525 | nla_total_size(4) + | ||
1526 | 0; | ||
1527 | } | ||
1528 | |||
1529 | static int ip6_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1530 | { | ||
1531 | struct ip6_tnl *tunnel = netdev_priv(dev); | ||
1532 | struct __ip6_tnl_parm *parm = &tunnel->parms; | ||
1533 | |||
1534 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1535 | nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), | ||
1536 | &parm->raddr) || | ||
1537 | nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), | ||
1538 | &parm->laddr) || | ||
1539 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) || | ||
1540 | nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || | ||
1541 | nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || | ||
1542 | nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags)) | ||
1543 | goto nla_put_failure; | ||
1544 | return 0; | ||
1545 | |||
1546 | nla_put_failure: | ||
1547 | return -EMSGSIZE; | ||
1548 | } | ||
1549 | |||
1550 | static struct rtnl_link_ops ip6_link_ops __read_mostly = { | ||
1551 | .kind = "ip6tnl", | ||
1552 | .maxtype = IFLA_IPTUN_MAX, | ||
1553 | .priv_size = sizeof(struct ip6_tnl), | ||
1554 | .get_size = ip6_get_size, | ||
1555 | .fill_info = ip6_fill_info, | ||
1556 | }; | ||
1557 | |||
1508 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { | 1558 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { |
1509 | .handler = ip4ip6_rcv, | 1559 | .handler = ip4ip6_rcv, |
1510 | .err_handler = ip4ip6_err, | 1560 | .err_handler = ip4ip6_err, |
@@ -1613,9 +1663,14 @@ static int __init ip6_tunnel_init(void) | |||
1613 | pr_err("%s: can't register ip6ip6\n", __func__); | 1663 | pr_err("%s: can't register ip6ip6\n", __func__); |
1614 | goto out_ip6ip6; | 1664 | goto out_ip6ip6; |
1615 | } | 1665 | } |
1666 | err = rtnl_link_register(&ip6_link_ops); | ||
1667 | if (err < 0) | ||
1668 | goto rtnl_link_failed; | ||
1616 | 1669 | ||
1617 | return 0; | 1670 | return 0; |
1618 | 1671 | ||
1672 | rtnl_link_failed: | ||
1673 | xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); | ||
1619 | out_ip6ip6: | 1674 | out_ip6ip6: |
1620 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); | 1675 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); |
1621 | out_ip4ip6: | 1676 | out_ip4ip6: |
@@ -1630,6 +1685,7 @@ out_pernet: | |||
1630 | 1685 | ||
1631 | static void __exit ip6_tunnel_cleanup(void) | 1686 | static void __exit ip6_tunnel_cleanup(void) |
1632 | { | 1687 | { |
1688 | rtnl_link_unregister(&ip6_link_ops); | ||
1633 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) | 1689 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) |
1634 | pr_info("%s: can't deregister ip4ip6\n", __func__); | 1690 | pr_info("%s: can't deregister ip4ip6\n", __func__); |
1635 | 1691 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e1..a7bee6a91335 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -397,7 +397,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
397 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { | 397 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { |
398 | struct ipv6_rt_hdr *rthdr = opt->srcrt; | 398 | struct ipv6_rt_hdr *rthdr = opt->srcrt; |
399 | switch (rthdr->type) { | 399 | switch (rthdr->type) { |
400 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 400 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
401 | case IPV6_SRCRT_TYPE_2: | 401 | case IPV6_SRCRT_TYPE_2: |
402 | if (rthdr->hdrlen != 2 || | 402 | if (rthdr->hdrlen != 2 || |
403 | rthdr->segments_left != 1) | 403 | rthdr->segments_left != 1) |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 92f8e48e4ba4..b19ed51a45bb 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -163,7 +163,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
163 | rt = rt6_lookup(net, addr, NULL, 0, 0); | 163 | rt = rt6_lookup(net, addr, NULL, 0, 0); |
164 | if (rt) { | 164 | if (rt) { |
165 | dev = rt->dst.dev; | 165 | dev = rt->dst.dev; |
166 | dst_release(&rt->dst); | 166 | ip6_rt_put(rt); |
167 | } | 167 | } |
168 | } else | 168 | } else |
169 | dev = dev_get_by_index_rcu(net, ifindex); | 169 | dev = dev_get_by_index_rcu(net, ifindex); |
@@ -260,7 +260,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, | |||
260 | 260 | ||
261 | if (rt) { | 261 | if (rt) { |
262 | dev = rt->dst.dev; | 262 | dev = rt->dst.dev; |
263 | dst_release(&rt->dst); | 263 | ip6_rt_put(rt); |
264 | } | 264 | } |
265 | } else | 265 | } else |
266 | dev = dev_get_by_index_rcu(net, ifindex); | 266 | dev = dev_get_by_index_rcu(net, ifindex); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2edce30ef733..4f47aa5183ae 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -905,7 +905,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
905 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && | 905 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && |
906 | net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp && | 906 | net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp && |
907 | pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) { | 907 | pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) { |
908 | /* XXX: idev->cnf.prixy_ndp */ | 908 | /* XXX: idev->cnf.proxy_ndp */ |
909 | goto out; | 909 | goto out; |
910 | } | 910 | } |
911 | 911 | ||
@@ -1144,7 +1144,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1144 | ND_PRINTK(0, err, | 1144 | ND_PRINTK(0, err, |
1145 | "RA: %s got default router without neighbour\n", | 1145 | "RA: %s got default router without neighbour\n", |
1146 | __func__); | 1146 | __func__); |
1147 | dst_release(&rt->dst); | 1147 | ip6_rt_put(rt); |
1148 | return; | 1148 | return; |
1149 | } | 1149 | } |
1150 | } | 1150 | } |
@@ -1169,7 +1169,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1169 | ND_PRINTK(0, err, | 1169 | ND_PRINTK(0, err, |
1170 | "RA: %s got default router without neighbour\n", | 1170 | "RA: %s got default router without neighbour\n", |
1171 | __func__); | 1171 | __func__); |
1172 | dst_release(&rt->dst); | 1172 | ip6_rt_put(rt); |
1173 | return; | 1173 | return; |
1174 | } | 1174 | } |
1175 | neigh->flags |= NTF_ROUTER; | 1175 | neigh->flags |= NTF_ROUTER; |
@@ -1325,8 +1325,7 @@ skip_routeinfo: | |||
1325 | ND_PRINTK(2, warn, "RA: invalid RA options\n"); | 1325 | ND_PRINTK(2, warn, "RA: invalid RA options\n"); |
1326 | } | 1326 | } |
1327 | out: | 1327 | out: |
1328 | if (rt) | 1328 | ip6_rt_put(rt); |
1329 | dst_release(&rt->dst); | ||
1330 | if (neigh) | 1329 | if (neigh) |
1331 | neigh_release(neigh); | 1330 | neigh_release(neigh); |
1332 | } | 1331 | } |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index d7cb04506c3d..10ce76a2cb94 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -207,8 +207,7 @@ ip6t_get_target_c(const struct ip6t_entry *e) | |||
207 | return ip6t_get_target((struct ip6t_entry *)e); | 207 | return ip6t_get_target((struct ip6t_entry *)e); |
208 | } | 208 | } |
209 | 209 | ||
210 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 210 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
211 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
212 | /* This cries for unification! */ | 211 | /* This cries for unification! */ |
213 | static const char *const hooknames[] = { | 212 | static const char *const hooknames[] = { |
214 | [NF_INET_PRE_ROUTING] = "PREROUTING", | 213 | [NF_INET_PRE_ROUTING] = "PREROUTING", |
@@ -381,8 +380,7 @@ ip6t_do_table(struct sk_buff *skb, | |||
381 | t = ip6t_get_target_c(e); | 380 | t = ip6t_get_target_c(e); |
382 | IP_NF_ASSERT(t->u.kernel.target); | 381 | IP_NF_ASSERT(t->u.kernel.target); |
383 | 382 | ||
384 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 383 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
385 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
386 | /* The packet is traced: log it */ | 384 | /* The packet is traced: log it */ |
387 | if (unlikely(skb->nf_trace)) | 385 | if (unlikely(skb->nf_trace)) |
388 | trace_packet(skb, hook, in, out, | 386 | trace_packet(skb, hook, in, out, |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index 5d1d8b04d694..5060d54199ab 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -67,7 +67,7 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
67 | if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE)) | 67 | if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE)) |
68 | ret = true; | 68 | ret = true; |
69 | out: | 69 | out: |
70 | dst_release(&rt->dst); | 70 | ip6_rt_put(rt); |
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 8860d23e61cf..ccb5cbe93549 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -295,7 +295,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | |||
295 | }, | 295 | }, |
296 | }; | 296 | }; |
297 | 297 | ||
298 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 298 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
299 | 299 | ||
300 | #include <linux/netfilter/nfnetlink.h> | 300 | #include <linux/netfilter/nfnetlink.h> |
301 | #include <linux/netfilter/nfnetlink_conntrack.h> | 301 | #include <linux/netfilter/nfnetlink_conntrack.h> |
@@ -346,7 +346,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { | |||
346 | .invert_tuple = ipv6_invert_tuple, | 346 | .invert_tuple = ipv6_invert_tuple, |
347 | .print_tuple = ipv6_print_tuple, | 347 | .print_tuple = ipv6_print_tuple, |
348 | .get_l4proto = ipv6_get_l4proto, | 348 | .get_l4proto = ipv6_get_l4proto, |
349 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 349 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
350 | .tuple_to_nlattr = ipv6_tuple_to_nlattr, | 350 | .tuple_to_nlattr = ipv6_tuple_to_nlattr, |
351 | .nlattr_tuple_size = ipv6_nlattr_tuple_size, | 351 | .nlattr_tuple_size = ipv6_nlattr_tuple_size, |
352 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, | 352 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 2d54b2061d68..24df3dde0076 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -232,7 +232,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl, | |||
232 | return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); | 232 | return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); |
233 | } | 233 | } |
234 | 234 | ||
235 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 235 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
236 | 236 | ||
237 | #include <linux/netfilter/nfnetlink.h> | 237 | #include <linux/netfilter/nfnetlink.h> |
238 | #include <linux/netfilter/nfnetlink_conntrack.h> | 238 | #include <linux/netfilter/nfnetlink_conntrack.h> |
@@ -375,7 +375,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = | |||
375 | .get_timeouts = icmpv6_get_timeouts, | 375 | .get_timeouts = icmpv6_get_timeouts, |
376 | .new = icmpv6_new, | 376 | .new = icmpv6_new, |
377 | .error = icmpv6_error, | 377 | .error = icmpv6_error, |
378 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 378 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
379 | .tuple_to_nlattr = icmpv6_tuple_to_nlattr, | 379 | .tuple_to_nlattr = icmpv6_tuple_to_nlattr, |
380 | .nlattr_tuple_size = icmpv6_nlattr_tuple_size, | 380 | .nlattr_tuple_size = icmpv6_nlattr_tuple_size, |
381 | .nlattr_to_tuple = icmpv6_nlattr_to_tuple, | 381 | .nlattr_to_tuple = icmpv6_nlattr_to_tuple, |
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index cdd6d045e42e..aacd121fe8c5 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/netfilter_ipv6.h> | 20 | #include <linux/netfilter_ipv6.h> |
21 | #include <linux/netfilter_bridge.h> | 21 | #include <linux/netfilter_bridge.h> |
22 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 22 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
23 | #include <net/netfilter/nf_conntrack.h> | 23 | #include <net/netfilter/nf_conntrack.h> |
24 | #include <net/netfilter/nf_conntrack_helper.h> | 24 | #include <net/netfilter/nf_conntrack_helper.h> |
25 | #include <net/netfilter/nf_conntrack_l4proto.h> | 25 | #include <net/netfilter/nf_conntrack_l4proto.h> |
@@ -35,7 +35,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | |||
35 | { | 35 | { |
36 | u16 zone = NF_CT_DEFAULT_ZONE; | 36 | u16 zone = NF_CT_DEFAULT_ZONE; |
37 | 37 | ||
38 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 38 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
39 | if (skb->nfct) | 39 | if (skb->nfct) |
40 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | 40 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); |
41 | #endif | 41 | #endif |
@@ -60,7 +60,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum, | |||
60 | { | 60 | { |
61 | struct sk_buff *reasm; | 61 | struct sk_buff *reasm; |
62 | 62 | ||
63 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 63 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
64 | /* Previously seen (loopback)? */ | 64 | /* Previously seen (loopback)? */ |
65 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) | 65 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) |
66 | return NF_ACCEPT; | 66 | return NF_ACCEPT; |
diff --git a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c index 5d6da784305b..61aaf70f376e 100644 --- a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c | |||
@@ -84,7 +84,7 @@ const struct nf_nat_l4proto nf_nat_l4proto_icmpv6 = { | |||
84 | .manip_pkt = icmpv6_manip_pkt, | 84 | .manip_pkt = icmpv6_manip_pkt, |
85 | .in_range = icmpv6_in_range, | 85 | .in_range = icmpv6_in_range, |
86 | .unique_tuple = icmpv6_unique_tuple, | 86 | .unique_tuple = icmpv6_unique_tuple, |
87 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 87 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
88 | .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, | 88 | .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, |
89 | #endif | 89 | #endif |
90 | }; | 90 | }; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d8e95c77db99..6cd29b1e8b92 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <net/udp.h> | 50 | #include <net/udp.h> |
51 | #include <net/inet_common.h> | 51 | #include <net/inet_common.h> |
52 | #include <net/tcp_states.h> | 52 | #include <net/tcp_states.h> |
53 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 53 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
54 | #include <net/mip6.h> | 54 | #include <net/mip6.h> |
55 | #endif | 55 | #endif |
56 | #include <linux/mroute6.h> | 56 | #include <linux/mroute6.h> |
@@ -123,7 +123,7 @@ static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb) | |||
123 | return 1; | 123 | return 1; |
124 | } | 124 | } |
125 | 125 | ||
126 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 126 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
127 | typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb); | 127 | typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb); |
128 | 128 | ||
129 | static mh_filter_t __rcu *mh_filter __read_mostly; | 129 | static mh_filter_t __rcu *mh_filter __read_mostly; |
@@ -184,7 +184,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
184 | filtered = icmpv6_filter(sk, skb); | 184 | filtered = icmpv6_filter(sk, skb); |
185 | break; | 185 | break; |
186 | 186 | ||
187 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 187 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
188 | case IPPROTO_MH: | 188 | case IPPROTO_MH: |
189 | { | 189 | { |
190 | /* XXX: To validate MH only once for each packet, | 190 | /* XXX: To validate MH only once for each packet, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b1e6cf0b95fd..30458726accf 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <net/xfrm.h> | 57 | #include <net/xfrm.h> |
58 | #include <net/netevent.h> | 58 | #include <net/netevent.h> |
59 | #include <net/netlink.h> | 59 | #include <net/netlink.h> |
60 | #include <net/nexthop.h> | ||
60 | 61 | ||
61 | #include <asm/uaccess.h> | 62 | #include <asm/uaccess.h> |
62 | 63 | ||
@@ -289,6 +290,8 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net, | |||
289 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); | 290 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); |
290 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); | 291 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); |
291 | rt->rt6i_genid = rt_genid(net); | 292 | rt->rt6i_genid = rt_genid(net); |
293 | INIT_LIST_HEAD(&rt->rt6i_siblings); | ||
294 | rt->rt6i_nsiblings = 0; | ||
292 | } | 295 | } |
293 | return rt; | 296 | return rt; |
294 | } | 297 | } |
@@ -318,13 +321,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
318 | } | 321 | } |
319 | } | 322 | } |
320 | 323 | ||
321 | static atomic_t __rt6_peer_genid = ATOMIC_INIT(0); | ||
322 | |||
323 | static u32 rt6_peer_genid(void) | ||
324 | { | ||
325 | return atomic_read(&__rt6_peer_genid); | ||
326 | } | ||
327 | |||
328 | void rt6_bind_peer(struct rt6_info *rt, int create) | 324 | void rt6_bind_peer(struct rt6_info *rt, int create) |
329 | { | 325 | { |
330 | struct inet_peer_base *base; | 326 | struct inet_peer_base *base; |
@@ -338,8 +334,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create) | |||
338 | if (peer) { | 334 | if (peer) { |
339 | if (!rt6_set_peer(rt, peer)) | 335 | if (!rt6_set_peer(rt, peer)) |
340 | inet_putpeer(peer); | 336 | inet_putpeer(peer); |
341 | else | ||
342 | rt->rt6i_peer_genid = rt6_peer_genid(); | ||
343 | } | 337 | } |
344 | } | 338 | } |
345 | 339 | ||
@@ -385,6 +379,69 @@ static bool rt6_need_strict(const struct in6_addr *daddr) | |||
385 | (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); | 379 | (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); |
386 | } | 380 | } |
387 | 381 | ||
382 | /* Multipath route selection: | ||
383 | * Hash based function using packet header and flowlabel. | ||
384 | * Adapted from fib_info_hashfn() | ||
385 | */ | ||
386 | static int rt6_info_hash_nhsfn(unsigned int candidate_count, | ||
387 | const struct flowi6 *fl6) | ||
388 | { | ||
389 | unsigned int val = fl6->flowi6_proto; | ||
390 | |||
391 | val ^= (__force u32)fl6->daddr.s6_addr32[0]; | ||
392 | val ^= (__force u32)fl6->daddr.s6_addr32[1]; | ||
393 | val ^= (__force u32)fl6->daddr.s6_addr32[2]; | ||
394 | val ^= (__force u32)fl6->daddr.s6_addr32[3]; | ||
395 | |||
396 | val ^= (__force u32)fl6->saddr.s6_addr32[0]; | ||
397 | val ^= (__force u32)fl6->saddr.s6_addr32[1]; | ||
398 | val ^= (__force u32)fl6->saddr.s6_addr32[2]; | ||
399 | val ^= (__force u32)fl6->saddr.s6_addr32[3]; | ||
400 | |||
401 | /* Work only if this not encapsulated */ | ||
402 | switch (fl6->flowi6_proto) { | ||
403 | case IPPROTO_UDP: | ||
404 | case IPPROTO_TCP: | ||
405 | case IPPROTO_SCTP: | ||
406 | val ^= (__force u16)fl6->fl6_sport; | ||
407 | val ^= (__force u16)fl6->fl6_dport; | ||
408 | break; | ||
409 | |||
410 | case IPPROTO_ICMPV6: | ||
411 | val ^= (__force u16)fl6->fl6_icmp_type; | ||
412 | val ^= (__force u16)fl6->fl6_icmp_code; | ||
413 | break; | ||
414 | } | ||
415 | /* RFC6438 recommands to use flowlabel */ | ||
416 | val ^= (__force u32)fl6->flowlabel; | ||
417 | |||
418 | /* Perhaps, we need to tune, this function? */ | ||
419 | val = val ^ (val >> 7) ^ (val >> 12); | ||
420 | return val % candidate_count; | ||
421 | } | ||
422 | |||
423 | static struct rt6_info *rt6_multipath_select(struct rt6_info *match, | ||
424 | struct flowi6 *fl6) | ||
425 | { | ||
426 | struct rt6_info *sibling, *next_sibling; | ||
427 | int route_choosen; | ||
428 | |||
429 | route_choosen = rt6_info_hash_nhsfn(match->rt6i_nsiblings + 1, fl6); | ||
430 | /* Don't change the route, if route_choosen == 0 | ||
431 | * (siblings does not include ourself) | ||
432 | */ | ||
433 | if (route_choosen) | ||
434 | list_for_each_entry_safe(sibling, next_sibling, | ||
435 | &match->rt6i_siblings, rt6i_siblings) { | ||
436 | route_choosen--; | ||
437 | if (route_choosen == 0) { | ||
438 | match = sibling; | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | return match; | ||
443 | } | ||
444 | |||
388 | /* | 445 | /* |
389 | * Route lookup. Any table->tb6_lock is implied. | 446 | * Route lookup. Any table->tb6_lock is implied. |
390 | */ | 447 | */ |
@@ -666,7 +723,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
666 | else | 723 | else |
667 | rt6_set_expires(rt, jiffies + HZ * lifetime); | 724 | rt6_set_expires(rt, jiffies + HZ * lifetime); |
668 | 725 | ||
669 | dst_release(&rt->dst); | 726 | ip6_rt_put(rt); |
670 | } | 727 | } |
671 | return 0; | 728 | return 0; |
672 | } | 729 | } |
@@ -702,6 +759,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, | |||
702 | restart: | 759 | restart: |
703 | rt = fn->leaf; | 760 | rt = fn->leaf; |
704 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); | 761 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); |
762 | if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) | ||
763 | rt = rt6_multipath_select(rt, fl6); | ||
705 | BACKTRACK(net, &fl6->saddr); | 764 | BACKTRACK(net, &fl6->saddr); |
706 | out: | 765 | out: |
707 | dst_use(&rt->dst, jiffies); | 766 | dst_use(&rt->dst, jiffies); |
@@ -863,7 +922,8 @@ restart_2: | |||
863 | 922 | ||
864 | restart: | 923 | restart: |
865 | rt = rt6_select(fn, oif, strict | reachable); | 924 | rt = rt6_select(fn, oif, strict | reachable); |
866 | 925 | if (rt->rt6i_nsiblings && oif == 0) | |
926 | rt = rt6_multipath_select(rt, fl6); | ||
867 | BACKTRACK(net, &fl6->saddr); | 927 | BACKTRACK(net, &fl6->saddr); |
868 | if (rt == net->ipv6.ip6_null_entry || | 928 | if (rt == net->ipv6.ip6_null_entry || |
869 | rt->rt6i_flags & RTF_CACHE) | 929 | rt->rt6i_flags & RTF_CACHE) |
@@ -879,7 +939,7 @@ restart: | |||
879 | else | 939 | else |
880 | goto out2; | 940 | goto out2; |
881 | 941 | ||
882 | dst_release(&rt->dst); | 942 | ip6_rt_put(rt); |
883 | rt = nrt ? : net->ipv6.ip6_null_entry; | 943 | rt = nrt ? : net->ipv6.ip6_null_entry; |
884 | 944 | ||
885 | dst_hold(&rt->dst); | 945 | dst_hold(&rt->dst); |
@@ -896,7 +956,7 @@ restart: | |||
896 | * Race condition! In the gap, when table->tb6_lock was | 956 | * Race condition! In the gap, when table->tb6_lock was |
897 | * released someone could insert this route. Relookup. | 957 | * released someone could insert this route. Relookup. |
898 | */ | 958 | */ |
899 | dst_release(&rt->dst); | 959 | ip6_rt_put(rt); |
900 | goto relookup; | 960 | goto relookup; |
901 | 961 | ||
902 | out: | 962 | out: |
@@ -1030,14 +1090,9 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
1030 | if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) | 1090 | if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) |
1031 | return NULL; | 1091 | return NULL; |
1032 | 1092 | ||
1033 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { | 1093 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
1034 | if (rt->rt6i_peer_genid != rt6_peer_genid()) { | ||
1035 | if (!rt6_has_peer(rt)) | ||
1036 | rt6_bind_peer(rt, 0); | ||
1037 | rt->rt6i_peer_genid = rt6_peer_genid(); | ||
1038 | } | ||
1039 | return dst; | 1094 | return dst; |
1040 | } | 1095 | |
1041 | return NULL; | 1096 | return NULL; |
1042 | } | 1097 | } |
1043 | 1098 | ||
@@ -1507,7 +1562,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1507 | goto out; | 1562 | goto out; |
1508 | if (dev) { | 1563 | if (dev) { |
1509 | if (dev != grt->dst.dev) { | 1564 | if (dev != grt->dst.dev) { |
1510 | dst_release(&grt->dst); | 1565 | ip6_rt_put(grt); |
1511 | goto out; | 1566 | goto out; |
1512 | } | 1567 | } |
1513 | } else { | 1568 | } else { |
@@ -1518,7 +1573,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1518 | } | 1573 | } |
1519 | if (!(grt->rt6i_flags & RTF_GATEWAY)) | 1574 | if (!(grt->rt6i_flags & RTF_GATEWAY)) |
1520 | err = 0; | 1575 | err = 0; |
1521 | dst_release(&grt->dst); | 1576 | ip6_rt_put(grt); |
1522 | 1577 | ||
1523 | if (err) | 1578 | if (err) |
1524 | goto out; | 1579 | goto out; |
@@ -1604,7 +1659,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) | |||
1604 | write_unlock_bh(&table->tb6_lock); | 1659 | write_unlock_bh(&table->tb6_lock); |
1605 | 1660 | ||
1606 | out: | 1661 | out: |
1607 | dst_release(&rt->dst); | 1662 | ip6_rt_put(rt); |
1608 | return err; | 1663 | return err; |
1609 | } | 1664 | } |
1610 | 1665 | ||
@@ -2249,6 +2304,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { | |||
2249 | [RTA_IIF] = { .type = NLA_U32 }, | 2304 | [RTA_IIF] = { .type = NLA_U32 }, |
2250 | [RTA_PRIORITY] = { .type = NLA_U32 }, | 2305 | [RTA_PRIORITY] = { .type = NLA_U32 }, |
2251 | [RTA_METRICS] = { .type = NLA_NESTED }, | 2306 | [RTA_METRICS] = { .type = NLA_NESTED }, |
2307 | [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, | ||
2252 | }; | 2308 | }; |
2253 | 2309 | ||
2254 | static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | 2310 | static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, |
@@ -2326,11 +2382,71 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2326 | if (tb[RTA_TABLE]) | 2382 | if (tb[RTA_TABLE]) |
2327 | cfg->fc_table = nla_get_u32(tb[RTA_TABLE]); | 2383 | cfg->fc_table = nla_get_u32(tb[RTA_TABLE]); |
2328 | 2384 | ||
2385 | if (tb[RTA_MULTIPATH]) { | ||
2386 | cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]); | ||
2387 | cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); | ||
2388 | } | ||
2389 | |||
2329 | err = 0; | 2390 | err = 0; |
2330 | errout: | 2391 | errout: |
2331 | return err; | 2392 | return err; |
2332 | } | 2393 | } |
2333 | 2394 | ||
2395 | static int ip6_route_multipath(struct fib6_config *cfg, int add) | ||
2396 | { | ||
2397 | struct fib6_config r_cfg; | ||
2398 | struct rtnexthop *rtnh; | ||
2399 | int remaining; | ||
2400 | int attrlen; | ||
2401 | int err = 0, last_err = 0; | ||
2402 | |||
2403 | beginning: | ||
2404 | rtnh = (struct rtnexthop *)cfg->fc_mp; | ||
2405 | remaining = cfg->fc_mp_len; | ||
2406 | |||
2407 | /* Parse a Multipath Entry */ | ||
2408 | while (rtnh_ok(rtnh, remaining)) { | ||
2409 | memcpy(&r_cfg, cfg, sizeof(*cfg)); | ||
2410 | if (rtnh->rtnh_ifindex) | ||
2411 | r_cfg.fc_ifindex = rtnh->rtnh_ifindex; | ||
2412 | |||
2413 | attrlen = rtnh_attrlen(rtnh); | ||
2414 | if (attrlen > 0) { | ||
2415 | struct nlattr *nla, *attrs = rtnh_attrs(rtnh); | ||
2416 | |||
2417 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); | ||
2418 | if (nla) { | ||
2419 | nla_memcpy(&r_cfg.fc_gateway, nla, 16); | ||
2420 | r_cfg.fc_flags |= RTF_GATEWAY; | ||
2421 | } | ||
2422 | } | ||
2423 | err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg); | ||
2424 | if (err) { | ||
2425 | last_err = err; | ||
2426 | /* If we are trying to remove a route, do not stop the | ||
2427 | * loop when ip6_route_del() fails (because next hop is | ||
2428 | * already gone), we should try to remove all next hops. | ||
2429 | */ | ||
2430 | if (add) { | ||
2431 | /* If add fails, we should try to delete all | ||
2432 | * next hops that have been already added. | ||
2433 | */ | ||
2434 | add = 0; | ||
2435 | goto beginning; | ||
2436 | } | ||
2437 | } | ||
2438 | /* Because each route is added like a single route we remove | ||
2439 | * this flag after the first nexthop (if there is a collision, | ||
2440 | * we have already fail to add the first nexthop: | ||
2441 | * fib6_add_rt2node() has reject it). | ||
2442 | */ | ||
2443 | cfg->fc_nlinfo.nlh->nlmsg_flags &= ~NLM_F_EXCL; | ||
2444 | rtnh = rtnh_next(rtnh, &remaining); | ||
2445 | } | ||
2446 | |||
2447 | return last_err; | ||
2448 | } | ||
2449 | |||
2334 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2450 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
2335 | { | 2451 | { |
2336 | struct fib6_config cfg; | 2452 | struct fib6_config cfg; |
@@ -2340,7 +2456,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2340 | if (err < 0) | 2456 | if (err < 0) |
2341 | return err; | 2457 | return err; |
2342 | 2458 | ||
2343 | return ip6_route_del(&cfg); | 2459 | if (cfg.fc_mp) |
2460 | return ip6_route_multipath(&cfg, 0); | ||
2461 | else | ||
2462 | return ip6_route_del(&cfg); | ||
2344 | } | 2463 | } |
2345 | 2464 | ||
2346 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2465 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
@@ -2352,7 +2471,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2352 | if (err < 0) | 2471 | if (err < 0) |
2353 | return err; | 2472 | return err; |
2354 | 2473 | ||
2355 | return ip6_route_add(&cfg); | 2474 | if (cfg.fc_mp) |
2475 | return ip6_route_multipath(&cfg, 1); | ||
2476 | else | ||
2477 | return ip6_route_add(&cfg); | ||
2356 | } | 2478 | } |
2357 | 2479 | ||
2358 | static inline size_t rt6_nlmsg_size(void) | 2480 | static inline size_t rt6_nlmsg_size(void) |
@@ -2596,7 +2718,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2596 | 2718 | ||
2597 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 2719 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
2598 | if (!skb) { | 2720 | if (!skb) { |
2599 | dst_release(&rt->dst); | 2721 | ip6_rt_put(rt); |
2600 | err = -ENOBUFS; | 2722 | err = -ENOBUFS; |
2601 | goto errout; | 2723 | goto errout; |
2602 | } | 2724 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3ed54ffd8d50..b543c56cad28 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -68,6 +68,7 @@ | |||
68 | static int ipip6_tunnel_init(struct net_device *dev); | 68 | static int ipip6_tunnel_init(struct net_device *dev); |
69 | static void ipip6_tunnel_setup(struct net_device *dev); | 69 | static void ipip6_tunnel_setup(struct net_device *dev); |
70 | static void ipip6_dev_free(struct net_device *dev); | 70 | static void ipip6_dev_free(struct net_device *dev); |
71 | static struct rtnl_link_ops sit_link_ops __read_mostly; | ||
71 | 72 | ||
72 | static int sit_net_id __read_mostly; | 73 | static int sit_net_id __read_mostly; |
73 | struct sit_net { | 74 | struct sit_net { |
@@ -282,6 +283,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, | |||
282 | goto failed_free; | 283 | goto failed_free; |
283 | 284 | ||
284 | strcpy(nt->parms.name, dev->name); | 285 | strcpy(nt->parms.name, dev->name); |
286 | dev->rtnl_link_ops = &sit_link_ops; | ||
285 | 287 | ||
286 | dev_hold(dev); | 288 | dev_hold(dev); |
287 | 289 | ||
@@ -1216,6 +1218,47 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1216 | return 0; | 1218 | return 0; |
1217 | } | 1219 | } |
1218 | 1220 | ||
1221 | static size_t sit_get_size(const struct net_device *dev) | ||
1222 | { | ||
1223 | return | ||
1224 | /* IFLA_IPTUN_LINK */ | ||
1225 | nla_total_size(4) + | ||
1226 | /* IFLA_IPTUN_LOCAL */ | ||
1227 | nla_total_size(4) + | ||
1228 | /* IFLA_IPTUN_REMOTE */ | ||
1229 | nla_total_size(4) + | ||
1230 | /* IFLA_IPTUN_TTL */ | ||
1231 | nla_total_size(1) + | ||
1232 | /* IFLA_IPTUN_TOS */ | ||
1233 | nla_total_size(1) + | ||
1234 | 0; | ||
1235 | } | ||
1236 | |||
1237 | static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1238 | { | ||
1239 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
1240 | struct ip_tunnel_parm *parm = &tunnel->parms; | ||
1241 | |||
1242 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1243 | nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || | ||
1244 | nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || | ||
1245 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || | ||
1246 | nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) | ||
1247 | goto nla_put_failure; | ||
1248 | return 0; | ||
1249 | |||
1250 | nla_put_failure: | ||
1251 | return -EMSGSIZE; | ||
1252 | } | ||
1253 | |||
1254 | static struct rtnl_link_ops sit_link_ops __read_mostly = { | ||
1255 | .kind = "sit", | ||
1256 | .maxtype = IFLA_IPTUN_MAX, | ||
1257 | .priv_size = sizeof(struct ip_tunnel), | ||
1258 | .get_size = sit_get_size, | ||
1259 | .fill_info = sit_fill_info, | ||
1260 | }; | ||
1261 | |||
1219 | static struct xfrm_tunnel sit_handler __read_mostly = { | 1262 | static struct xfrm_tunnel sit_handler __read_mostly = { |
1220 | .handler = ipip6_rcv, | 1263 | .handler = ipip6_rcv, |
1221 | .err_handler = ipip6_err, | 1264 | .err_handler = ipip6_err, |
@@ -1302,6 +1345,7 @@ static struct pernet_operations sit_net_ops = { | |||
1302 | 1345 | ||
1303 | static void __exit sit_cleanup(void) | 1346 | static void __exit sit_cleanup(void) |
1304 | { | 1347 | { |
1348 | rtnl_link_unregister(&sit_link_ops); | ||
1305 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1349 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
1306 | 1350 | ||
1307 | unregister_pernet_device(&sit_net_ops); | 1351 | unregister_pernet_device(&sit_net_ops); |
@@ -1319,10 +1363,21 @@ static int __init sit_init(void) | |||
1319 | return err; | 1363 | return err; |
1320 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); | 1364 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); |
1321 | if (err < 0) { | 1365 | if (err < 0) { |
1322 | unregister_pernet_device(&sit_net_ops); | ||
1323 | pr_info("%s: can't add protocol\n", __func__); | 1366 | pr_info("%s: can't add protocol\n", __func__); |
1367 | goto xfrm_tunnel_failed; | ||
1324 | } | 1368 | } |
1369 | err = rtnl_link_register(&sit_link_ops); | ||
1370 | if (err < 0) | ||
1371 | goto rtnl_link_failed; | ||
1372 | |||
1373 | out: | ||
1325 | return err; | 1374 | return err; |
1375 | |||
1376 | rtnl_link_failed: | ||
1377 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | ||
1378 | xfrm_tunnel_failed: | ||
1379 | unregister_pernet_device(&sit_net_ops); | ||
1380 | goto out; | ||
1326 | } | 1381 | } |
1327 | 1382 | ||
1328 | module_init(sit_init); | 1383 | module_init(sit_init); |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 182ab9a85d6c..40161977f7cf 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -214,7 +214,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
214 | ireq6->iif = inet6_iif(skb); | 214 | ireq6->iif = inet6_iif(skb); |
215 | 215 | ||
216 | req->expires = 0UL; | 216 | req->expires = 0UL; |
217 | req->retrans = 0; | 217 | req->num_retrans = 0; |
218 | ireq->ecn_ok = ecn_ok; | 218 | ireq->ecn_ok = ecn_ok; |
219 | ireq->snd_wscale = tcp_opt.snd_wscale; | 219 | ireq->snd_wscale = tcp_opt.snd_wscale; |
220 | ireq->sack_ok = tcp_opt.sack_ok; | 220 | ireq->sack_ok = tcp_opt.sack_ok; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 26175bffbaa0..c73d0ebde9c8 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -495,9 +495,12 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, | |||
495 | struct request_values *rvp) | 495 | struct request_values *rvp) |
496 | { | 496 | { |
497 | struct flowi6 fl6; | 497 | struct flowi6 fl6; |
498 | int res; | ||
498 | 499 | ||
499 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 500 | res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); |
500 | return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); | 501 | if (!res) |
502 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
503 | return res; | ||
501 | } | 504 | } |
502 | 505 | ||
503 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 506 | static void tcp_v6_reqsk_destructor(struct request_sock *req) |
@@ -1364,7 +1367,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1364 | 1367 | ||
1365 | tcp_initialize_rcv_mss(newsk); | 1368 | tcp_initialize_rcv_mss(newsk); |
1366 | tcp_synack_rtt_meas(newsk, req); | 1369 | tcp_synack_rtt_meas(newsk, req); |
1367 | newtp->total_retrans = req->retrans; | 1370 | newtp->total_retrans = req->num_retrans; |
1368 | 1371 | ||
1369 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; | 1372 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; |
1370 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; | 1373 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; |
@@ -1741,11 +1744,11 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1741 | skb->destructor = sock_edemux; | 1744 | skb->destructor = sock_edemux; |
1742 | if (sk->sk_state != TCP_TIME_WAIT) { | 1745 | if (sk->sk_state != TCP_TIME_WAIT) { |
1743 | struct dst_entry *dst = sk->sk_rx_dst; | 1746 | struct dst_entry *dst = sk->sk_rx_dst; |
1744 | struct inet_sock *icsk = inet_sk(sk); | 1747 | |
1745 | if (dst) | 1748 | if (dst) |
1746 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1749 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
1747 | if (dst && | 1750 | if (dst && |
1748 | icsk->rx_dst_ifindex == skb->skb_iif) | 1751 | inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) |
1749 | skb_dst_set_noref(skb, dst); | 1752 | skb_dst_set_noref(skb, dst); |
1750 | } | 1753 | } |
1751 | } | 1754 | } |
@@ -1866,7 +1869,7 @@ static void get_openreq6(struct seq_file *seq, | |||
1866 | 0,0, /* could print option size, but that is af dependent. */ | 1869 | 0,0, /* could print option size, but that is af dependent. */ |
1867 | 1, /* timers active (only the expire timer) */ | 1870 | 1, /* timers active (only the expire timer) */ |
1868 | jiffies_to_clock_t(ttd), | 1871 | jiffies_to_clock_t(ttd), |
1869 | req->retrans, | 1872 | req->num_timeout, |
1870 | from_kuid_munged(seq_user_ns(seq), uid), | 1873 | from_kuid_munged(seq_user_ns(seq), uid), |
1871 | 0, /* non standard timer */ | 1874 | 0, /* non standard timer */ |
1872 | 0, /* open_requests have no inode */ | 1875 | 0, /* open_requests have no inode */ |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index f8c4c08ffb60..f3ed8ca59b94 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
21 | #include <net/ipv6.h> | 21 | #include <net/ipv6.h> |
22 | #include <net/ip6_route.h> | 22 | #include <net/ip6_route.h> |
23 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 23 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
24 | #include <net/mip6.h> | 24 | #include <net/mip6.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
@@ -182,7 +182,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
182 | fl6->flowi6_proto = nexthdr; | 182 | fl6->flowi6_proto = nexthdr; |
183 | return; | 183 | return; |
184 | 184 | ||
185 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 185 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
186 | case IPPROTO_MH: | 186 | case IPPROTO_MH: |
187 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { | 187 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
188 | struct ip6_mh *mh; | 188 | struct ip6_mh *mh; |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 3f2f7c4ab721..d8c70b8efc24 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -101,7 +101,7 @@ static int __xfrm6_state_sort_cmp(void *p) | |||
101 | return 1; | 101 | return 1; |
102 | else | 102 | else |
103 | return 3; | 103 | return 3; |
104 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 104 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
105 | case XFRM_MODE_ROUTEOPTIMIZATION: | 105 | case XFRM_MODE_ROUTEOPTIMIZATION: |
106 | case XFRM_MODE_IN_TRIGGER: | 106 | case XFRM_MODE_IN_TRIGGER: |
107 | return 2; | 107 | return 2; |
@@ -134,7 +134,7 @@ static int __xfrm6_tmpl_sort_cmp(void *p) | |||
134 | switch (v->mode) { | 134 | switch (v->mode) { |
135 | case XFRM_MODE_TRANSPORT: | 135 | case XFRM_MODE_TRANSPORT: |
136 | return 1; | 136 | return 1; |
137 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 137 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
138 | case XFRM_MODE_ROUTEOPTIMIZATION: | 138 | case XFRM_MODE_ROUTEOPTIMIZATION: |
139 | case XFRM_MODE_IN_TRIGGER: | 139 | case XFRM_MODE_IN_TRIGGER: |
140 | return 2; | 140 | return 2; |
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 6c4cc12c7414..bbba3a19e944 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c | |||
@@ -632,7 +632,7 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl | |||
632 | nla_put_u16(skb, L2TP_ATTR_MRU, session->mru))) | 632 | nla_put_u16(skb, L2TP_ATTR_MRU, session->mru))) |
633 | goto nla_put_failure; | 633 | goto nla_put_failure; |
634 | 634 | ||
635 | if ((session->ifname && session->ifname[0] && | 635 | if ((session->ifname[0] && |
636 | nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || | 636 | nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || |
637 | (session->cookie_len && | 637 | (session->cookie_len && |
638 | nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, | 638 | nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, |
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index 8b2cffdfdd99..0c3b1670b0d1 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig | |||
@@ -28,12 +28,11 @@ if IP_VS | |||
28 | config IP_VS_IPV6 | 28 | config IP_VS_IPV6 |
29 | bool "IPv6 support for IPVS" | 29 | bool "IPv6 support for IPVS" |
30 | depends on IPV6 = y || IP_VS = IPV6 | 30 | depends on IPV6 = y || IP_VS = IPV6 |
31 | select IP6_NF_IPTABLES | ||
31 | ---help--- | 32 | ---help--- |
32 | Add IPv6 support to IPVS. This is incomplete and might be dangerous. | 33 | Add IPv6 support to IPVS. |
33 | 34 | ||
34 | See http://www.mindbasket.com/ipvs for more information. | 35 | Say Y if unsure. |
35 | |||
36 | Say N if unsure. | ||
37 | 36 | ||
38 | config IP_VS_DEBUG | 37 | config IP_VS_DEBUG |
39 | bool "IP virtual server debugging" | 38 | bool "IP virtual server debugging" |
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 1548df9a7524..30e764ad021f 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
@@ -308,13 +308,12 @@ struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p) | |||
308 | static int | 308 | static int |
309 | ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, | 309 | ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, |
310 | const struct ip_vs_iphdr *iph, | 310 | const struct ip_vs_iphdr *iph, |
311 | unsigned int proto_off, int inverse, | 311 | int inverse, struct ip_vs_conn_param *p) |
312 | struct ip_vs_conn_param *p) | ||
313 | { | 312 | { |
314 | __be16 _ports[2], *pptr; | 313 | __be16 _ports[2], *pptr; |
315 | struct net *net = skb_net(skb); | 314 | struct net *net = skb_net(skb); |
316 | 315 | ||
317 | pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); | 316 | pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); |
318 | if (pptr == NULL) | 317 | if (pptr == NULL) |
319 | return 1; | 318 | return 1; |
320 | 319 | ||
@@ -329,12 +328,11 @@ ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, | |||
329 | 328 | ||
330 | struct ip_vs_conn * | 329 | struct ip_vs_conn * |
331 | ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, | 330 | ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, |
332 | const struct ip_vs_iphdr *iph, | 331 | const struct ip_vs_iphdr *iph, int inverse) |
333 | unsigned int proto_off, int inverse) | ||
334 | { | 332 | { |
335 | struct ip_vs_conn_param p; | 333 | struct ip_vs_conn_param p; |
336 | 334 | ||
337 | if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) | 335 | if (ip_vs_conn_fill_param_proto(af, skb, iph, inverse, &p)) |
338 | return NULL; | 336 | return NULL; |
339 | 337 | ||
340 | return ip_vs_conn_in_get(&p); | 338 | return ip_vs_conn_in_get(&p); |
@@ -432,12 +430,11 @@ struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p) | |||
432 | 430 | ||
433 | struct ip_vs_conn * | 431 | struct ip_vs_conn * |
434 | ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, | 432 | ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, |
435 | const struct ip_vs_iphdr *iph, | 433 | const struct ip_vs_iphdr *iph, int inverse) |
436 | unsigned int proto_off, int inverse) | ||
437 | { | 434 | { |
438 | struct ip_vs_conn_param p; | 435 | struct ip_vs_conn_param p; |
439 | 436 | ||
440 | if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) | 437 | if (ip_vs_conn_fill_param_proto(af, skb, iph, inverse, &p)) |
441 | return NULL; | 438 | return NULL; |
442 | 439 | ||
443 | return ip_vs_conn_out_get(&p); | 440 | return ip_vs_conn_out_get(&p); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 58918e20f9d5..fb45640dc1fb 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -222,11 +222,10 @@ ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc, | |||
222 | */ | 222 | */ |
223 | static struct ip_vs_conn * | 223 | static struct ip_vs_conn * |
224 | ip_vs_sched_persist(struct ip_vs_service *svc, | 224 | ip_vs_sched_persist(struct ip_vs_service *svc, |
225 | struct sk_buff *skb, | 225 | struct sk_buff *skb, __be16 src_port, __be16 dst_port, |
226 | __be16 src_port, __be16 dst_port, int *ignored) | 226 | int *ignored, struct ip_vs_iphdr *iph) |
227 | { | 227 | { |
228 | struct ip_vs_conn *cp = NULL; | 228 | struct ip_vs_conn *cp = NULL; |
229 | struct ip_vs_iphdr iph; | ||
230 | struct ip_vs_dest *dest; | 229 | struct ip_vs_dest *dest; |
231 | struct ip_vs_conn *ct; | 230 | struct ip_vs_conn *ct; |
232 | __be16 dport = 0; /* destination port to forward */ | 231 | __be16 dport = 0; /* destination port to forward */ |
@@ -236,20 +235,18 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
236 | union nf_inet_addr snet; /* source network of the client, | 235 | union nf_inet_addr snet; /* source network of the client, |
237 | after masking */ | 236 | after masking */ |
238 | 237 | ||
239 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | ||
240 | |||
241 | /* Mask saddr with the netmask to adjust template granularity */ | 238 | /* Mask saddr with the netmask to adjust template granularity */ |
242 | #ifdef CONFIG_IP_VS_IPV6 | 239 | #ifdef CONFIG_IP_VS_IPV6 |
243 | if (svc->af == AF_INET6) | 240 | if (svc->af == AF_INET6) |
244 | ipv6_addr_prefix(&snet.in6, &iph.saddr.in6, svc->netmask); | 241 | ipv6_addr_prefix(&snet.in6, &iph->saddr.in6, svc->netmask); |
245 | else | 242 | else |
246 | #endif | 243 | #endif |
247 | snet.ip = iph.saddr.ip & svc->netmask; | 244 | snet.ip = iph->saddr.ip & svc->netmask; |
248 | 245 | ||
249 | IP_VS_DBG_BUF(6, "p-schedule: src %s:%u dest %s:%u " | 246 | IP_VS_DBG_BUF(6, "p-schedule: src %s:%u dest %s:%u " |
250 | "mnet %s\n", | 247 | "mnet %s\n", |
251 | IP_VS_DBG_ADDR(svc->af, &iph.saddr), ntohs(src_port), | 248 | IP_VS_DBG_ADDR(svc->af, &iph->saddr), ntohs(src_port), |
252 | IP_VS_DBG_ADDR(svc->af, &iph.daddr), ntohs(dst_port), | 249 | IP_VS_DBG_ADDR(svc->af, &iph->daddr), ntohs(dst_port), |
253 | IP_VS_DBG_ADDR(svc->af, &snet)); | 250 | IP_VS_DBG_ADDR(svc->af, &snet)); |
254 | 251 | ||
255 | /* | 252 | /* |
@@ -266,8 +263,8 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
266 | * is created for other persistent services. | 263 | * is created for other persistent services. |
267 | */ | 264 | */ |
268 | { | 265 | { |
269 | int protocol = iph.protocol; | 266 | int protocol = iph->protocol; |
270 | const union nf_inet_addr *vaddr = &iph.daddr; | 267 | const union nf_inet_addr *vaddr = &iph->daddr; |
271 | __be16 vport = 0; | 268 | __be16 vport = 0; |
272 | 269 | ||
273 | if (dst_port == svc->port) { | 270 | if (dst_port == svc->port) { |
@@ -342,14 +339,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
342 | dport = dest->port; | 339 | dport = dest->port; |
343 | 340 | ||
344 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET | 341 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET |
345 | && iph.protocol == IPPROTO_UDP)? | 342 | && iph->protocol == IPPROTO_UDP) ? |
346 | IP_VS_CONN_F_ONE_PACKET : 0; | 343 | IP_VS_CONN_F_ONE_PACKET : 0; |
347 | 344 | ||
348 | /* | 345 | /* |
349 | * Create a new connection according to the template | 346 | * Create a new connection according to the template |
350 | */ | 347 | */ |
351 | ip_vs_conn_fill_param(svc->net, svc->af, iph.protocol, &iph.saddr, | 348 | ip_vs_conn_fill_param(svc->net, svc->af, iph->protocol, &iph->saddr, |
352 | src_port, &iph.daddr, dst_port, ¶m); | 349 | src_port, &iph->daddr, dst_port, ¶m); |
353 | 350 | ||
354 | cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest, skb->mark); | 351 | cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest, skb->mark); |
355 | if (cp == NULL) { | 352 | if (cp == NULL) { |
@@ -392,18 +389,20 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
392 | */ | 389 | */ |
393 | struct ip_vs_conn * | 390 | struct ip_vs_conn * |
394 | ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | 391 | ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, |
395 | struct ip_vs_proto_data *pd, int *ignored) | 392 | struct ip_vs_proto_data *pd, int *ignored, |
393 | struct ip_vs_iphdr *iph) | ||
396 | { | 394 | { |
397 | struct ip_vs_protocol *pp = pd->pp; | 395 | struct ip_vs_protocol *pp = pd->pp; |
398 | struct ip_vs_conn *cp = NULL; | 396 | struct ip_vs_conn *cp = NULL; |
399 | struct ip_vs_iphdr iph; | ||
400 | struct ip_vs_dest *dest; | 397 | struct ip_vs_dest *dest; |
401 | __be16 _ports[2], *pptr; | 398 | __be16 _ports[2], *pptr; |
402 | unsigned int flags; | 399 | unsigned int flags; |
403 | 400 | ||
404 | *ignored = 1; | 401 | *ignored = 1; |
405 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 402 | /* |
406 | pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); | 403 | * IPv6 frags, only the first hit here. |
404 | */ | ||
405 | pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); | ||
407 | if (pptr == NULL) | 406 | if (pptr == NULL) |
408 | return NULL; | 407 | return NULL; |
409 | 408 | ||
@@ -423,7 +422,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | |||
423 | * Do not schedule replies from local real server. | 422 | * Do not schedule replies from local real server. |
424 | */ | 423 | */ |
425 | if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && | 424 | if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && |
426 | (cp = pp->conn_in_get(svc->af, skb, &iph, iph.len, 1))) { | 425 | (cp = pp->conn_in_get(svc->af, skb, iph, 1))) { |
427 | IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, | 426 | IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, |
428 | "Not scheduling reply for existing connection"); | 427 | "Not scheduling reply for existing connection"); |
429 | __ip_vs_conn_put(cp); | 428 | __ip_vs_conn_put(cp); |
@@ -434,7 +433,8 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | |||
434 | * Persistent service | 433 | * Persistent service |
435 | */ | 434 | */ |
436 | if (svc->flags & IP_VS_SVC_F_PERSISTENT) | 435 | if (svc->flags & IP_VS_SVC_F_PERSISTENT) |
437 | return ip_vs_sched_persist(svc, skb, pptr[0], pptr[1], ignored); | 436 | return ip_vs_sched_persist(svc, skb, pptr[0], pptr[1], ignored, |
437 | iph); | ||
438 | 438 | ||
439 | *ignored = 0; | 439 | *ignored = 0; |
440 | 440 | ||
@@ -456,7 +456,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | |||
456 | } | 456 | } |
457 | 457 | ||
458 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET | 458 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET |
459 | && iph.protocol == IPPROTO_UDP)? | 459 | && iph->protocol == IPPROTO_UDP) ? |
460 | IP_VS_CONN_F_ONE_PACKET : 0; | 460 | IP_VS_CONN_F_ONE_PACKET : 0; |
461 | 461 | ||
462 | /* | 462 | /* |
@@ -465,9 +465,9 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | |||
465 | { | 465 | { |
466 | struct ip_vs_conn_param p; | 466 | struct ip_vs_conn_param p; |
467 | 467 | ||
468 | ip_vs_conn_fill_param(svc->net, svc->af, iph.protocol, | 468 | ip_vs_conn_fill_param(svc->net, svc->af, iph->protocol, |
469 | &iph.saddr, pptr[0], &iph.daddr, pptr[1], | 469 | &iph->saddr, pptr[0], &iph->daddr, |
470 | &p); | 470 | pptr[1], &p); |
471 | cp = ip_vs_conn_new(&p, &dest->addr, | 471 | cp = ip_vs_conn_new(&p, &dest->addr, |
472 | dest->port ? dest->port : pptr[1], | 472 | dest->port ? dest->port : pptr[1], |
473 | flags, dest, skb->mark); | 473 | flags, dest, skb->mark); |
@@ -496,19 +496,16 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, | |||
496 | * no destination is available for a new connection. | 496 | * no destination is available for a new connection. |
497 | */ | 497 | */ |
498 | int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | 498 | int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, |
499 | struct ip_vs_proto_data *pd) | 499 | struct ip_vs_proto_data *pd, struct ip_vs_iphdr *iph) |
500 | { | 500 | { |
501 | __be16 _ports[2], *pptr; | 501 | __be16 _ports[2], *pptr; |
502 | struct ip_vs_iphdr iph; | ||
503 | #ifdef CONFIG_SYSCTL | 502 | #ifdef CONFIG_SYSCTL |
504 | struct net *net; | 503 | struct net *net; |
505 | struct netns_ipvs *ipvs; | 504 | struct netns_ipvs *ipvs; |
506 | int unicast; | 505 | int unicast; |
507 | #endif | 506 | #endif |
508 | 507 | ||
509 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 508 | pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph); |
510 | |||
511 | pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); | ||
512 | if (pptr == NULL) { | 509 | if (pptr == NULL) { |
513 | ip_vs_service_put(svc); | 510 | ip_vs_service_put(svc); |
514 | return NF_DROP; | 511 | return NF_DROP; |
@@ -519,10 +516,10 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | |||
519 | 516 | ||
520 | #ifdef CONFIG_IP_VS_IPV6 | 517 | #ifdef CONFIG_IP_VS_IPV6 |
521 | if (svc->af == AF_INET6) | 518 | if (svc->af == AF_INET6) |
522 | unicast = ipv6_addr_type(&iph.daddr.in6) & IPV6_ADDR_UNICAST; | 519 | unicast = ipv6_addr_type(&iph->daddr.in6) & IPV6_ADDR_UNICAST; |
523 | else | 520 | else |
524 | #endif | 521 | #endif |
525 | unicast = (inet_addr_type(net, iph.daddr.ip) == RTN_UNICAST); | 522 | unicast = (inet_addr_type(net, iph->daddr.ip) == RTN_UNICAST); |
526 | 523 | ||
527 | /* if it is fwmark-based service, the cache_bypass sysctl is up | 524 | /* if it is fwmark-based service, the cache_bypass sysctl is up |
528 | and the destination is a non-local unicast, then create | 525 | and the destination is a non-local unicast, then create |
@@ -532,7 +529,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | |||
532 | int ret; | 529 | int ret; |
533 | struct ip_vs_conn *cp; | 530 | struct ip_vs_conn *cp; |
534 | unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && | 531 | unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && |
535 | iph.protocol == IPPROTO_UDP)? | 532 | iph->protocol == IPPROTO_UDP) ? |
536 | IP_VS_CONN_F_ONE_PACKET : 0; | 533 | IP_VS_CONN_F_ONE_PACKET : 0; |
537 | union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } }; | 534 | union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } }; |
538 | 535 | ||
@@ -542,9 +539,9 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | |||
542 | IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); | 539 | IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); |
543 | { | 540 | { |
544 | struct ip_vs_conn_param p; | 541 | struct ip_vs_conn_param p; |
545 | ip_vs_conn_fill_param(svc->net, svc->af, iph.protocol, | 542 | ip_vs_conn_fill_param(svc->net, svc->af, iph->protocol, |
546 | &iph.saddr, pptr[0], | 543 | &iph->saddr, pptr[0], |
547 | &iph.daddr, pptr[1], &p); | 544 | &iph->daddr, pptr[1], &p); |
548 | cp = ip_vs_conn_new(&p, &daddr, 0, | 545 | cp = ip_vs_conn_new(&p, &daddr, 0, |
549 | IP_VS_CONN_F_BYPASS | flags, | 546 | IP_VS_CONN_F_BYPASS | flags, |
550 | NULL, skb->mark); | 547 | NULL, skb->mark); |
@@ -559,7 +556,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | |||
559 | ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd); | 556 | ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd); |
560 | 557 | ||
561 | /* transmit the first SYN packet */ | 558 | /* transmit the first SYN packet */ |
562 | ret = cp->packet_xmit(skb, cp, pd->pp); | 559 | ret = cp->packet_xmit(skb, cp, pd->pp, iph); |
563 | /* do not touch skb anymore */ | 560 | /* do not touch skb anymore */ |
564 | 561 | ||
565 | atomic_inc(&cp->in_pkts); | 562 | atomic_inc(&cp->in_pkts); |
@@ -654,14 +651,6 @@ static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) | |||
654 | return err; | 651 | return err; |
655 | } | 652 | } |
656 | 653 | ||
657 | #ifdef CONFIG_IP_VS_IPV6 | ||
658 | static inline int ip_vs_gather_frags_v6(struct sk_buff *skb, u_int32_t user) | ||
659 | { | ||
660 | /* TODO IPv6: Find out what to do here for IPv6 */ | ||
661 | return 0; | ||
662 | } | ||
663 | #endif | ||
664 | |||
665 | static int ip_vs_route_me_harder(int af, struct sk_buff *skb) | 654 | static int ip_vs_route_me_harder(int af, struct sk_buff *skb) |
666 | { | 655 | { |
667 | #ifdef CONFIG_IP_VS_IPV6 | 656 | #ifdef CONFIG_IP_VS_IPV6 |
@@ -732,10 +721,19 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
732 | struct ip_vs_conn *cp, int inout) | 721 | struct ip_vs_conn *cp, int inout) |
733 | { | 722 | { |
734 | struct ipv6hdr *iph = ipv6_hdr(skb); | 723 | struct ipv6hdr *iph = ipv6_hdr(skb); |
735 | unsigned int icmp_offset = sizeof(struct ipv6hdr); | 724 | unsigned int icmp_offset = 0; |
736 | struct icmp6hdr *icmph = (struct icmp6hdr *)(skb_network_header(skb) + | 725 | unsigned int offs = 0; /* header offset*/ |
737 | icmp_offset); | 726 | int protocol; |
738 | struct ipv6hdr *ciph = (struct ipv6hdr *)(icmph + 1); | 727 | struct icmp6hdr *icmph; |
728 | struct ipv6hdr *ciph; | ||
729 | unsigned short fragoffs; | ||
730 | |||
731 | ipv6_find_hdr(skb, &icmp_offset, IPPROTO_ICMPV6, &fragoffs, NULL); | ||
732 | icmph = (struct icmp6hdr *)(skb_network_header(skb) + icmp_offset); | ||
733 | offs = icmp_offset + sizeof(struct icmp6hdr); | ||
734 | ciph = (struct ipv6hdr *)(skb_network_header(skb) + offs); | ||
735 | |||
736 | protocol = ipv6_find_hdr(skb, &offs, -1, &fragoffs, NULL); | ||
739 | 737 | ||
740 | if (inout) { | 738 | if (inout) { |
741 | iph->saddr = cp->vaddr.in6; | 739 | iph->saddr = cp->vaddr.in6; |
@@ -746,10 +744,13 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
746 | } | 744 | } |
747 | 745 | ||
748 | /* the TCP/UDP/SCTP port */ | 746 | /* the TCP/UDP/SCTP port */ |
749 | if (IPPROTO_TCP == ciph->nexthdr || IPPROTO_UDP == ciph->nexthdr || | 747 | if (!fragoffs && (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol || |
750 | IPPROTO_SCTP == ciph->nexthdr) { | 748 | IPPROTO_SCTP == protocol)) { |
751 | __be16 *ports = (void *)ciph + sizeof(struct ipv6hdr); | 749 | __be16 *ports = (void *)(skb_network_header(skb) + offs); |
752 | 750 | ||
751 | IP_VS_DBG(11, "%s() changed port %d to %d\n", __func__, | ||
752 | ntohs(inout ? ports[1] : ports[0]), | ||
753 | ntohs(inout ? cp->vport : cp->dport)); | ||
753 | if (inout) | 754 | if (inout) |
754 | ports[1] = cp->vport; | 755 | ports[1] = cp->vport; |
755 | else | 756 | else |
@@ -898,51 +899,35 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related, | |||
898 | IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, | 899 | IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, |
899 | "Checking outgoing ICMP for"); | 900 | "Checking outgoing ICMP for"); |
900 | 901 | ||
901 | offset += cih->ihl * 4; | 902 | ip_vs_fill_ip4hdr(cih, &ciph); |
902 | 903 | ciph.len += offset; | |
903 | ip_vs_fill_iphdr(AF_INET, cih, &ciph); | ||
904 | /* The embedded headers contain source and dest in reverse order */ | 904 | /* The embedded headers contain source and dest in reverse order */ |
905 | cp = pp->conn_out_get(AF_INET, skb, &ciph, offset, 1); | 905 | cp = pp->conn_out_get(AF_INET, skb, &ciph, 1); |
906 | if (!cp) | 906 | if (!cp) |
907 | return NF_ACCEPT; | 907 | return NF_ACCEPT; |
908 | 908 | ||
909 | snet.ip = iph->saddr; | 909 | snet.ip = iph->saddr; |
910 | return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp, | 910 | return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp, |
911 | pp, offset, ihl); | 911 | pp, ciph.len, ihl); |
912 | } | 912 | } |
913 | 913 | ||
914 | #ifdef CONFIG_IP_VS_IPV6 | 914 | #ifdef CONFIG_IP_VS_IPV6 |
915 | static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, | 915 | static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, |
916 | unsigned int hooknum) | 916 | unsigned int hooknum, struct ip_vs_iphdr *ipvsh) |
917 | { | 917 | { |
918 | struct ipv6hdr *iph; | ||
919 | struct icmp6hdr _icmph, *ic; | 918 | struct icmp6hdr _icmph, *ic; |
920 | struct ipv6hdr _ciph, *cih; /* The ip header contained | 919 | struct ipv6hdr _ip6h, *ip6h; /* The ip header contained within ICMP */ |
921 | within the ICMP */ | 920 | struct ip_vs_iphdr ciph = {.flags = 0, .fragoffs = 0};/*Contained IP */ |
922 | struct ip_vs_iphdr ciph; | ||
923 | struct ip_vs_conn *cp; | 921 | struct ip_vs_conn *cp; |
924 | struct ip_vs_protocol *pp; | 922 | struct ip_vs_protocol *pp; |
925 | unsigned int offset; | ||
926 | union nf_inet_addr snet; | 923 | union nf_inet_addr snet; |
924 | unsigned int writable; | ||
927 | 925 | ||
928 | *related = 1; | 926 | *related = 1; |
929 | 927 | ic = frag_safe_skb_hp(skb, ipvsh->len, sizeof(_icmph), &_icmph, ipvsh); | |
930 | /* reassemble IP fragments */ | ||
931 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { | ||
932 | if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) | ||
933 | return NF_STOLEN; | ||
934 | } | ||
935 | |||
936 | iph = ipv6_hdr(skb); | ||
937 | offset = sizeof(struct ipv6hdr); | ||
938 | ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph); | ||
939 | if (ic == NULL) | 928 | if (ic == NULL) |
940 | return NF_DROP; | 929 | return NF_DROP; |
941 | 930 | ||
942 | IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) %pI6->%pI6\n", | ||
943 | ic->icmp6_type, ntohs(icmpv6_id(ic)), | ||
944 | &iph->saddr, &iph->daddr); | ||
945 | |||
946 | /* | 931 | /* |
947 | * Work through seeing if this is for us. | 932 | * Work through seeing if this is for us. |
948 | * These checks are supposed to be in an order that means easy | 933 | * These checks are supposed to be in an order that means easy |
@@ -950,42 +935,45 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, | |||
950 | * this means that some packets will manage to get a long way | 935 | * this means that some packets will manage to get a long way |
951 | * down this stack and then be rejected, but that's life. | 936 | * down this stack and then be rejected, but that's life. |
952 | */ | 937 | */ |
953 | if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) && | 938 | if (ic->icmp6_type & ICMPV6_INFOMSG_MASK) { |
954 | (ic->icmp6_type != ICMPV6_PKT_TOOBIG) && | ||
955 | (ic->icmp6_type != ICMPV6_TIME_EXCEED)) { | ||
956 | *related = 0; | 939 | *related = 0; |
957 | return NF_ACCEPT; | 940 | return NF_ACCEPT; |
958 | } | 941 | } |
942 | /* Fragment header that is before ICMP header tells us that: | ||
943 | * it's not an error message since they can't be fragmented. | ||
944 | */ | ||
945 | if (ipvsh->flags & IP6T_FH_F_FRAG) | ||
946 | return NF_DROP; | ||
947 | |||
948 | IP_VS_DBG(8, "Outgoing ICMPv6 (%d,%d) %pI6c->%pI6c\n", | ||
949 | ic->icmp6_type, ntohs(icmpv6_id(ic)), | ||
950 | &ipvsh->saddr, &ipvsh->daddr); | ||
959 | 951 | ||
960 | /* Now find the contained IP header */ | 952 | /* Now find the contained IP header */ |
961 | offset += sizeof(_icmph); | 953 | ciph.len = ipvsh->len + sizeof(_icmph); |
962 | cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph); | 954 | ip6h = skb_header_pointer(skb, ciph.len, sizeof(_ip6h), &_ip6h); |
963 | if (cih == NULL) | 955 | if (ip6h == NULL) |
964 | return NF_ACCEPT; /* The packet looks wrong, ignore */ | 956 | return NF_ACCEPT; /* The packet looks wrong, ignore */ |
965 | 957 | ciph.saddr.in6 = ip6h->saddr; /* conn_out_get() handles reverse order */ | |
966 | pp = ip_vs_proto_get(cih->nexthdr); | 958 | ciph.daddr.in6 = ip6h->daddr; |
959 | /* skip possible IPv6 exthdrs of contained IPv6 packet */ | ||
960 | ciph.protocol = ipv6_find_hdr(skb, &ciph.len, -1, &ciph.fragoffs, NULL); | ||
961 | if (ciph.protocol < 0) | ||
962 | return NF_ACCEPT; /* Contained IPv6 hdr looks wrong, ignore */ | ||
963 | |||
964 | pp = ip_vs_proto_get(ciph.protocol); | ||
967 | if (!pp) | 965 | if (!pp) |
968 | return NF_ACCEPT; | 966 | return NF_ACCEPT; |
969 | 967 | ||
970 | /* Is the embedded protocol header present? */ | ||
971 | /* TODO: we don't support fragmentation at the moment anyways */ | ||
972 | if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) | ||
973 | return NF_ACCEPT; | ||
974 | |||
975 | IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, | ||
976 | "Checking outgoing ICMPv6 for"); | ||
977 | |||
978 | offset += sizeof(struct ipv6hdr); | ||
979 | |||
980 | ip_vs_fill_iphdr(AF_INET6, cih, &ciph); | ||
981 | /* The embedded headers contain source and dest in reverse order */ | 968 | /* The embedded headers contain source and dest in reverse order */ |
982 | cp = pp->conn_out_get(AF_INET6, skb, &ciph, offset, 1); | 969 | cp = pp->conn_out_get(AF_INET6, skb, &ciph, 1); |
983 | if (!cp) | 970 | if (!cp) |
984 | return NF_ACCEPT; | 971 | return NF_ACCEPT; |
985 | 972 | ||
986 | snet.in6 = iph->saddr; | 973 | snet.in6 = ciph.saddr.in6; |
987 | return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp, | 974 | writable = ciph.len; |
988 | pp, offset, sizeof(struct ipv6hdr)); | 975 | return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp, |
976 | pp, writable, sizeof(struct ipv6hdr)); | ||
989 | } | 977 | } |
990 | #endif | 978 | #endif |
991 | 979 | ||
@@ -1018,17 +1006,17 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len) | |||
1018 | */ | 1006 | */ |
1019 | static unsigned int | 1007 | static unsigned int |
1020 | handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 1008 | handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
1021 | struct ip_vs_conn *cp, int ihl) | 1009 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
1022 | { | 1010 | { |
1023 | struct ip_vs_protocol *pp = pd->pp; | 1011 | struct ip_vs_protocol *pp = pd->pp; |
1024 | 1012 | ||
1025 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); | 1013 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); |
1026 | 1014 | ||
1027 | if (!skb_make_writable(skb, ihl)) | 1015 | if (!skb_make_writable(skb, iph->len)) |
1028 | goto drop; | 1016 | goto drop; |
1029 | 1017 | ||
1030 | /* mangle the packet */ | 1018 | /* mangle the packet */ |
1031 | if (pp->snat_handler && !pp->snat_handler(skb, pp, cp)) | 1019 | if (pp->snat_handler && !pp->snat_handler(skb, pp, cp, iph)) |
1032 | goto drop; | 1020 | goto drop; |
1033 | 1021 | ||
1034 | #ifdef CONFIG_IP_VS_IPV6 | 1022 | #ifdef CONFIG_IP_VS_IPV6 |
@@ -1115,17 +1103,22 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1115 | if (!net_ipvs(net)->enable) | 1103 | if (!net_ipvs(net)->enable) |
1116 | return NF_ACCEPT; | 1104 | return NF_ACCEPT; |
1117 | 1105 | ||
1118 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1106 | ip_vs_fill_iph_skb(af, skb, &iph); |
1119 | #ifdef CONFIG_IP_VS_IPV6 | 1107 | #ifdef CONFIG_IP_VS_IPV6 |
1120 | if (af == AF_INET6) { | 1108 | if (af == AF_INET6) { |
1109 | if (!iph.fragoffs && skb_nfct_reasm(skb)) { | ||
1110 | struct sk_buff *reasm = skb_nfct_reasm(skb); | ||
1111 | /* Save fw mark for coming frags */ | ||
1112 | reasm->ipvs_property = 1; | ||
1113 | reasm->mark = skb->mark; | ||
1114 | } | ||
1121 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { | 1115 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { |
1122 | int related; | 1116 | int related; |
1123 | int verdict = ip_vs_out_icmp_v6(skb, &related, | 1117 | int verdict = ip_vs_out_icmp_v6(skb, &related, |
1124 | hooknum); | 1118 | hooknum, &iph); |
1125 | 1119 | ||
1126 | if (related) | 1120 | if (related) |
1127 | return verdict; | 1121 | return verdict; |
1128 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1129 | } | 1122 | } |
1130 | } else | 1123 | } else |
1131 | #endif | 1124 | #endif |
@@ -1135,7 +1128,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1135 | 1128 | ||
1136 | if (related) | 1129 | if (related) |
1137 | return verdict; | 1130 | return verdict; |
1138 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1139 | } | 1131 | } |
1140 | 1132 | ||
1141 | pd = ip_vs_proto_data_get(net, iph.protocol); | 1133 | pd = ip_vs_proto_data_get(net, iph.protocol); |
@@ -1145,39 +1137,31 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1145 | 1137 | ||
1146 | /* reassemble IP fragments */ | 1138 | /* reassemble IP fragments */ |
1147 | #ifdef CONFIG_IP_VS_IPV6 | 1139 | #ifdef CONFIG_IP_VS_IPV6 |
1148 | if (af == AF_INET6) { | 1140 | if (af == AF_INET) |
1149 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { | ||
1150 | if (ip_vs_gather_frags_v6(skb, | ||
1151 | ip_vs_defrag_user(hooknum))) | ||
1152 | return NF_STOLEN; | ||
1153 | } | ||
1154 | |||
1155 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1156 | } else | ||
1157 | #endif | 1141 | #endif |
1158 | if (unlikely(ip_is_fragment(ip_hdr(skb)) && !pp->dont_defrag)) { | 1142 | if (unlikely(ip_is_fragment(ip_hdr(skb)) && !pp->dont_defrag)) { |
1159 | if (ip_vs_gather_frags(skb, | 1143 | if (ip_vs_gather_frags(skb, |
1160 | ip_vs_defrag_user(hooknum))) | 1144 | ip_vs_defrag_user(hooknum))) |
1161 | return NF_STOLEN; | 1145 | return NF_STOLEN; |
1162 | 1146 | ||
1163 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1147 | ip_vs_fill_ip4hdr(skb_network_header(skb), &iph); |
1164 | } | 1148 | } |
1165 | 1149 | ||
1166 | /* | 1150 | /* |
1167 | * Check if the packet belongs to an existing entry | 1151 | * Check if the packet belongs to an existing entry |
1168 | */ | 1152 | */ |
1169 | cp = pp->conn_out_get(af, skb, &iph, iph.len, 0); | 1153 | cp = pp->conn_out_get(af, skb, &iph, 0); |
1170 | 1154 | ||
1171 | if (likely(cp)) | 1155 | if (likely(cp)) |
1172 | return handle_response(af, skb, pd, cp, iph.len); | 1156 | return handle_response(af, skb, pd, cp, &iph); |
1173 | if (sysctl_nat_icmp_send(net) && | 1157 | if (sysctl_nat_icmp_send(net) && |
1174 | (pp->protocol == IPPROTO_TCP || | 1158 | (pp->protocol == IPPROTO_TCP || |
1175 | pp->protocol == IPPROTO_UDP || | 1159 | pp->protocol == IPPROTO_UDP || |
1176 | pp->protocol == IPPROTO_SCTP)) { | 1160 | pp->protocol == IPPROTO_SCTP)) { |
1177 | __be16 _ports[2], *pptr; | 1161 | __be16 _ports[2], *pptr; |
1178 | 1162 | ||
1179 | pptr = skb_header_pointer(skb, iph.len, | 1163 | pptr = frag_safe_skb_hp(skb, iph.len, |
1180 | sizeof(_ports), _ports); | 1164 | sizeof(_ports), _ports, &iph); |
1181 | if (pptr == NULL) | 1165 | if (pptr == NULL) |
1182 | return NF_ACCEPT; /* Not for me */ | 1166 | return NF_ACCEPT; /* Not for me */ |
1183 | if (ip_vs_lookup_real_service(net, af, iph.protocol, | 1167 | if (ip_vs_lookup_real_service(net, af, iph.protocol, |
@@ -1375,13 +1359,13 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
1375 | "Checking incoming ICMP for"); | 1359 | "Checking incoming ICMP for"); |
1376 | 1360 | ||
1377 | offset2 = offset; | 1361 | offset2 = offset; |
1378 | offset += cih->ihl * 4; | 1362 | ip_vs_fill_ip4hdr(cih, &ciph); |
1379 | 1363 | ciph.len += offset; | |
1380 | ip_vs_fill_iphdr(AF_INET, cih, &ciph); | 1364 | offset = ciph.len; |
1381 | /* The embedded headers contain source and dest in reverse order. | 1365 | /* The embedded headers contain source and dest in reverse order. |
1382 | * For IPIP this is error for request, not for reply. | 1366 | * For IPIP this is error for request, not for reply. |
1383 | */ | 1367 | */ |
1384 | cp = pp->conn_in_get(AF_INET, skb, &ciph, offset, ipip ? 0 : 1); | 1368 | cp = pp->conn_in_get(AF_INET, skb, &ciph, ipip ? 0 : 1); |
1385 | if (!cp) | 1369 | if (!cp) |
1386 | return NF_ACCEPT; | 1370 | return NF_ACCEPT; |
1387 | 1371 | ||
@@ -1450,7 +1434,7 @@ ignore_ipip: | |||
1450 | ip_vs_in_stats(cp, skb); | 1434 | ip_vs_in_stats(cp, skb); |
1451 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) | 1435 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) |
1452 | offset += 2 * sizeof(__u16); | 1436 | offset += 2 * sizeof(__u16); |
1453 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum); | 1437 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph); |
1454 | 1438 | ||
1455 | out: | 1439 | out: |
1456 | __ip_vs_conn_put(cp); | 1440 | __ip_vs_conn_put(cp); |
@@ -1459,38 +1443,24 @@ out: | |||
1459 | } | 1443 | } |
1460 | 1444 | ||
1461 | #ifdef CONFIG_IP_VS_IPV6 | 1445 | #ifdef CONFIG_IP_VS_IPV6 |
1462 | static int | 1446 | static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, |
1463 | ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) | 1447 | unsigned int hooknum, struct ip_vs_iphdr *iph) |
1464 | { | 1448 | { |
1465 | struct net *net = NULL; | 1449 | struct net *net = NULL; |
1466 | struct ipv6hdr *iph; | 1450 | struct ipv6hdr _ip6h, *ip6h; |
1467 | struct icmp6hdr _icmph, *ic; | 1451 | struct icmp6hdr _icmph, *ic; |
1468 | struct ipv6hdr _ciph, *cih; /* The ip header contained | 1452 | struct ip_vs_iphdr ciph = {.flags = 0, .fragoffs = 0};/*Contained IP */ |
1469 | within the ICMP */ | ||
1470 | struct ip_vs_iphdr ciph; | ||
1471 | struct ip_vs_conn *cp; | 1453 | struct ip_vs_conn *cp; |
1472 | struct ip_vs_protocol *pp; | 1454 | struct ip_vs_protocol *pp; |
1473 | struct ip_vs_proto_data *pd; | 1455 | struct ip_vs_proto_data *pd; |
1474 | unsigned int offset, verdict; | 1456 | unsigned int offs_ciph, writable, verdict; |
1475 | 1457 | ||
1476 | *related = 1; | 1458 | *related = 1; |
1477 | 1459 | ||
1478 | /* reassemble IP fragments */ | 1460 | ic = frag_safe_skb_hp(skb, iph->len, sizeof(_icmph), &_icmph, iph); |
1479 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { | ||
1480 | if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) | ||
1481 | return NF_STOLEN; | ||
1482 | } | ||
1483 | |||
1484 | iph = ipv6_hdr(skb); | ||
1485 | offset = sizeof(struct ipv6hdr); | ||
1486 | ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph); | ||
1487 | if (ic == NULL) | 1461 | if (ic == NULL) |
1488 | return NF_DROP; | 1462 | return NF_DROP; |
1489 | 1463 | ||
1490 | IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) %pI6->%pI6\n", | ||
1491 | ic->icmp6_type, ntohs(icmpv6_id(ic)), | ||
1492 | &iph->saddr, &iph->daddr); | ||
1493 | |||
1494 | /* | 1464 | /* |
1495 | * Work through seeing if this is for us. | 1465 | * Work through seeing if this is for us. |
1496 | * These checks are supposed to be in an order that means easy | 1466 | * These checks are supposed to be in an order that means easy |
@@ -1498,47 +1468,71 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
1498 | * this means that some packets will manage to get a long way | 1468 | * this means that some packets will manage to get a long way |
1499 | * down this stack and then be rejected, but that's life. | 1469 | * down this stack and then be rejected, but that's life. |
1500 | */ | 1470 | */ |
1501 | if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) && | 1471 | if (ic->icmp6_type & ICMPV6_INFOMSG_MASK) { |
1502 | (ic->icmp6_type != ICMPV6_PKT_TOOBIG) && | ||
1503 | (ic->icmp6_type != ICMPV6_TIME_EXCEED)) { | ||
1504 | *related = 0; | 1472 | *related = 0; |
1505 | return NF_ACCEPT; | 1473 | return NF_ACCEPT; |
1506 | } | 1474 | } |
1475 | /* Fragment header that is before ICMP header tells us that: | ||
1476 | * it's not an error message since they can't be fragmented. | ||
1477 | */ | ||
1478 | if (iph->flags & IP6T_FH_F_FRAG) | ||
1479 | return NF_DROP; | ||
1480 | |||
1481 | IP_VS_DBG(8, "Incoming ICMPv6 (%d,%d) %pI6c->%pI6c\n", | ||
1482 | ic->icmp6_type, ntohs(icmpv6_id(ic)), | ||
1483 | &iph->saddr, &iph->daddr); | ||
1507 | 1484 | ||
1508 | /* Now find the contained IP header */ | 1485 | /* Now find the contained IP header */ |
1509 | offset += sizeof(_icmph); | 1486 | ciph.len = iph->len + sizeof(_icmph); |
1510 | cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph); | 1487 | offs_ciph = ciph.len; /* Save ip header offset */ |
1511 | if (cih == NULL) | 1488 | ip6h = skb_header_pointer(skb, ciph.len, sizeof(_ip6h), &_ip6h); |
1489 | if (ip6h == NULL) | ||
1512 | return NF_ACCEPT; /* The packet looks wrong, ignore */ | 1490 | return NF_ACCEPT; /* The packet looks wrong, ignore */ |
1491 | ciph.saddr.in6 = ip6h->saddr; /* conn_in_get() handles reverse order */ | ||
1492 | ciph.daddr.in6 = ip6h->daddr; | ||
1493 | /* skip possible IPv6 exthdrs of contained IPv6 packet */ | ||
1494 | ciph.protocol = ipv6_find_hdr(skb, &ciph.len, -1, &ciph.fragoffs, NULL); | ||
1495 | if (ciph.protocol < 0) | ||
1496 | return NF_ACCEPT; /* Contained IPv6 hdr looks wrong, ignore */ | ||
1513 | 1497 | ||
1514 | net = skb_net(skb); | 1498 | net = skb_net(skb); |
1515 | pd = ip_vs_proto_data_get(net, cih->nexthdr); | 1499 | pd = ip_vs_proto_data_get(net, ciph.protocol); |
1516 | if (!pd) | 1500 | if (!pd) |
1517 | return NF_ACCEPT; | 1501 | return NF_ACCEPT; |
1518 | pp = pd->pp; | 1502 | pp = pd->pp; |
1519 | 1503 | ||
1520 | /* Is the embedded protocol header present? */ | 1504 | /* Cannot handle fragmented embedded protocol */ |
1521 | /* TODO: we don't support fragmentation at the moment anyways */ | 1505 | if (ciph.fragoffs) |
1522 | if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) | ||
1523 | return NF_ACCEPT; | 1506 | return NF_ACCEPT; |
1524 | 1507 | ||
1525 | IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, | 1508 | IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offs_ciph, |
1526 | "Checking incoming ICMPv6 for"); | 1509 | "Checking incoming ICMPv6 for"); |
1527 | 1510 | ||
1528 | offset += sizeof(struct ipv6hdr); | 1511 | /* The embedded headers contain source and dest in reverse order |
1512 | * if not from localhost | ||
1513 | */ | ||
1514 | cp = pp->conn_in_get(AF_INET6, skb, &ciph, | ||
1515 | (hooknum == NF_INET_LOCAL_OUT) ? 0 : 1); | ||
1529 | 1516 | ||
1530 | ip_vs_fill_iphdr(AF_INET6, cih, &ciph); | ||
1531 | /* The embedded headers contain source and dest in reverse order */ | ||
1532 | cp = pp->conn_in_get(AF_INET6, skb, &ciph, offset, 1); | ||
1533 | if (!cp) | 1517 | if (!cp) |
1534 | return NF_ACCEPT; | 1518 | return NF_ACCEPT; |
1519 | /* VS/TUN, VS/DR and LOCALNODE just let it go */ | ||
1520 | if ((hooknum == NF_INET_LOCAL_OUT) && | ||
1521 | (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)) { | ||
1522 | __ip_vs_conn_put(cp); | ||
1523 | return NF_ACCEPT; | ||
1524 | } | ||
1535 | 1525 | ||
1536 | /* do the statistics and put it back */ | 1526 | /* do the statistics and put it back */ |
1537 | ip_vs_in_stats(cp, skb); | 1527 | ip_vs_in_stats(cp, skb); |
1538 | if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr || | 1528 | |
1539 | IPPROTO_SCTP == cih->nexthdr) | 1529 | /* Need to mangle contained IPv6 header in ICMPv6 packet */ |
1540 | offset += 2 * sizeof(__u16); | 1530 | writable = ciph.len; |
1541 | verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum); | 1531 | if (IPPROTO_TCP == ciph.protocol || IPPROTO_UDP == ciph.protocol || |
1532 | IPPROTO_SCTP == ciph.protocol) | ||
1533 | writable += 2 * sizeof(__u16); /* Also mangle ports */ | ||
1534 | |||
1535 | verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, writable, hooknum, &ciph); | ||
1542 | 1536 | ||
1543 | __ip_vs_conn_put(cp); | 1537 | __ip_vs_conn_put(cp); |
1544 | 1538 | ||
@@ -1574,7 +1568,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1574 | if (unlikely((skb->pkt_type != PACKET_HOST && | 1568 | if (unlikely((skb->pkt_type != PACKET_HOST && |
1575 | hooknum != NF_INET_LOCAL_OUT) || | 1569 | hooknum != NF_INET_LOCAL_OUT) || |
1576 | !skb_dst(skb))) { | 1570 | !skb_dst(skb))) { |
1577 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1571 | ip_vs_fill_iph_skb(af, skb, &iph); |
1578 | IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s" | 1572 | IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s" |
1579 | " ignored in hook %u\n", | 1573 | " ignored in hook %u\n", |
1580 | skb->pkt_type, iph.protocol, | 1574 | skb->pkt_type, iph.protocol, |
@@ -1586,7 +1580,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1586 | if (!net_ipvs(net)->enable) | 1580 | if (!net_ipvs(net)->enable) |
1587 | return NF_ACCEPT; | 1581 | return NF_ACCEPT; |
1588 | 1582 | ||
1589 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1583 | ip_vs_fill_iph_skb(af, skb, &iph); |
1590 | 1584 | ||
1591 | /* Bad... Do not break raw sockets */ | 1585 | /* Bad... Do not break raw sockets */ |
1592 | if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && | 1586 | if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && |
@@ -1600,13 +1594,19 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1600 | 1594 | ||
1601 | #ifdef CONFIG_IP_VS_IPV6 | 1595 | #ifdef CONFIG_IP_VS_IPV6 |
1602 | if (af == AF_INET6) { | 1596 | if (af == AF_INET6) { |
1597 | if (!iph.fragoffs && skb_nfct_reasm(skb)) { | ||
1598 | struct sk_buff *reasm = skb_nfct_reasm(skb); | ||
1599 | /* Save fw mark for coming frags. */ | ||
1600 | reasm->ipvs_property = 1; | ||
1601 | reasm->mark = skb->mark; | ||
1602 | } | ||
1603 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { | 1603 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { |
1604 | int related; | 1604 | int related; |
1605 | int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); | 1605 | int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum, |
1606 | &iph); | ||
1606 | 1607 | ||
1607 | if (related) | 1608 | if (related) |
1608 | return verdict; | 1609 | return verdict; |
1609 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1610 | } | 1610 | } |
1611 | } else | 1611 | } else |
1612 | #endif | 1612 | #endif |
@@ -1616,7 +1616,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1616 | 1616 | ||
1617 | if (related) | 1617 | if (related) |
1618 | return verdict; | 1618 | return verdict; |
1619 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1620 | } | 1619 | } |
1621 | 1620 | ||
1622 | /* Protocol supported? */ | 1621 | /* Protocol supported? */ |
@@ -1627,12 +1626,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1627 | /* | 1626 | /* |
1628 | * Check if the packet belongs to an existing connection entry | 1627 | * Check if the packet belongs to an existing connection entry |
1629 | */ | 1628 | */ |
1630 | cp = pp->conn_in_get(af, skb, &iph, iph.len, 0); | 1629 | cp = pp->conn_in_get(af, skb, &iph, 0); |
1631 | 1630 | if (unlikely(!cp) && !iph.fragoffs) { | |
1632 | if (unlikely(!cp)) { | 1631 | /* No (second) fragments need to enter here, as nf_defrag_ipv6 |
1632 | * replayed fragment zero will already have created the cp | ||
1633 | */ | ||
1633 | int v; | 1634 | int v; |
1634 | 1635 | ||
1635 | if (!pp->conn_schedule(af, skb, pd, &v, &cp)) | 1636 | /* Schedule and create new connection entry into &cp */ |
1637 | if (!pp->conn_schedule(af, skb, pd, &v, &cp, &iph)) | ||
1636 | return v; | 1638 | return v; |
1637 | } | 1639 | } |
1638 | 1640 | ||
@@ -1640,6 +1642,14 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1640 | /* sorry, all this trouble for a no-hit :) */ | 1642 | /* sorry, all this trouble for a no-hit :) */ |
1641 | IP_VS_DBG_PKT(12, af, pp, skb, 0, | 1643 | IP_VS_DBG_PKT(12, af, pp, skb, 0, |
1642 | "ip_vs_in: packet continues traversal as normal"); | 1644 | "ip_vs_in: packet continues traversal as normal"); |
1645 | if (iph.fragoffs && !skb_nfct_reasm(skb)) { | ||
1646 | /* Fragment that couldn't be mapped to a conn entry | ||
1647 | * and don't have any pointer to a reasm skb | ||
1648 | * is missing module nf_defrag_ipv6 | ||
1649 | */ | ||
1650 | IP_VS_DBG_RL("Unhandled frag, load nf_defrag_ipv6\n"); | ||
1651 | IP_VS_DBG_PKT(7, af, pp, skb, 0, "unhandled fragment"); | ||
1652 | } | ||
1643 | return NF_ACCEPT; | 1653 | return NF_ACCEPT; |
1644 | } | 1654 | } |
1645 | 1655 | ||
@@ -1662,7 +1672,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1662 | ip_vs_in_stats(cp, skb); | 1672 | ip_vs_in_stats(cp, skb); |
1663 | ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd); | 1673 | ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd); |
1664 | if (cp->packet_xmit) | 1674 | if (cp->packet_xmit) |
1665 | ret = cp->packet_xmit(skb, cp, pp); | 1675 | ret = cp->packet_xmit(skb, cp, pp, &iph); |
1666 | /* do not touch skb anymore */ | 1676 | /* do not touch skb anymore */ |
1667 | else { | 1677 | else { |
1668 | IP_VS_DBG_RL("warning: packet_xmit is null"); | 1678 | IP_VS_DBG_RL("warning: packet_xmit is null"); |
@@ -1724,6 +1734,38 @@ ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb, | |||
1724 | #ifdef CONFIG_IP_VS_IPV6 | 1734 | #ifdef CONFIG_IP_VS_IPV6 |
1725 | 1735 | ||
1726 | /* | 1736 | /* |
1737 | * AF_INET6 fragment handling | ||
1738 | * Copy info from first fragment, to the rest of them. | ||
1739 | */ | ||
1740 | static unsigned int | ||
1741 | ip_vs_preroute_frag6(unsigned int hooknum, struct sk_buff *skb, | ||
1742 | const struct net_device *in, | ||
1743 | const struct net_device *out, | ||
1744 | int (*okfn)(struct sk_buff *)) | ||
1745 | { | ||
1746 | struct sk_buff *reasm = skb_nfct_reasm(skb); | ||
1747 | struct net *net; | ||
1748 | |||
1749 | /* Skip if not a "replay" from nf_ct_frag6_output or first fragment. | ||
1750 | * ipvs_property is set when checking first fragment | ||
1751 | * in ip_vs_in() and ip_vs_out(). | ||
1752 | */ | ||
1753 | if (reasm) | ||
1754 | IP_VS_DBG(2, "Fragment recv prop:%d\n", reasm->ipvs_property); | ||
1755 | if (!reasm || !reasm->ipvs_property) | ||
1756 | return NF_ACCEPT; | ||
1757 | |||
1758 | net = skb_net(skb); | ||
1759 | if (!net_ipvs(net)->enable) | ||
1760 | return NF_ACCEPT; | ||
1761 | |||
1762 | /* Copy stored fw mark, saved in ip_vs_{in,out} */ | ||
1763 | skb->mark = reasm->mark; | ||
1764 | |||
1765 | return NF_ACCEPT; | ||
1766 | } | ||
1767 | |||
1768 | /* | ||
1727 | * AF_INET6 handler in NF_INET_LOCAL_IN chain | 1769 | * AF_INET6 handler in NF_INET_LOCAL_IN chain |
1728 | * Schedule and forward packets from remote clients | 1770 | * Schedule and forward packets from remote clients |
1729 | */ | 1771 | */ |
@@ -1793,8 +1835,10 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, | |||
1793 | { | 1835 | { |
1794 | int r; | 1836 | int r; |
1795 | struct net *net; | 1837 | struct net *net; |
1838 | struct ip_vs_iphdr iphdr; | ||
1796 | 1839 | ||
1797 | if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6) | 1840 | ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr); |
1841 | if (iphdr.protocol != IPPROTO_ICMPV6) | ||
1798 | return NF_ACCEPT; | 1842 | return NF_ACCEPT; |
1799 | 1843 | ||
1800 | /* ipvs enabled in this netns ? */ | 1844 | /* ipvs enabled in this netns ? */ |
@@ -1802,7 +1846,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, | |||
1802 | if (!net_ipvs(net)->enable) | 1846 | if (!net_ipvs(net)->enable) |
1803 | return NF_ACCEPT; | 1847 | return NF_ACCEPT; |
1804 | 1848 | ||
1805 | return ip_vs_in_icmp_v6(skb, &r, hooknum); | 1849 | return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr); |
1806 | } | 1850 | } |
1807 | #endif | 1851 | #endif |
1808 | 1852 | ||
@@ -1860,6 +1904,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
1860 | .priority = 100, | 1904 | .priority = 100, |
1861 | }, | 1905 | }, |
1862 | #ifdef CONFIG_IP_VS_IPV6 | 1906 | #ifdef CONFIG_IP_VS_IPV6 |
1907 | /* After mangle & nat fetch 2:nd fragment and following */ | ||
1908 | { | ||
1909 | .hook = ip_vs_preroute_frag6, | ||
1910 | .owner = THIS_MODULE, | ||
1911 | .pf = NFPROTO_IPV6, | ||
1912 | .hooknum = NF_INET_PRE_ROUTING, | ||
1913 | .priority = NF_IP6_PRI_NAT_DST + 1, | ||
1914 | }, | ||
1863 | /* After packet filtering, change source only for VS/NAT */ | 1915 | /* After packet filtering, change source only for VS/NAT */ |
1864 | { | 1916 | { |
1865 | .hook = ip_vs_reply6, | 1917 | .hook = ip_vs_reply6, |
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c index 8b7dca9ea422..7f3b0cc00b7a 100644 --- a/net/netfilter/ipvs/ip_vs_dh.c +++ b/net/netfilter/ipvs/ip_vs_dh.c | |||
@@ -215,7 +215,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) | |||
215 | struct ip_vs_dh_bucket *tbl; | 215 | struct ip_vs_dh_bucket *tbl; |
216 | struct ip_vs_iphdr iph; | 216 | struct ip_vs_iphdr iph; |
217 | 217 | ||
218 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 218 | ip_vs_fill_iph_addr_only(svc->af, skb, &iph); |
219 | 219 | ||
220 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); | 220 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); |
221 | 221 | ||
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index df646ccf08a7..cbd37489ac77 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c | |||
@@ -479,7 +479,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) | |||
479 | struct ip_vs_dest *dest = NULL; | 479 | struct ip_vs_dest *dest = NULL; |
480 | struct ip_vs_lblc_entry *en; | 480 | struct ip_vs_lblc_entry *en; |
481 | 481 | ||
482 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 482 | ip_vs_fill_iph_addr_only(svc->af, skb, &iph); |
483 | 483 | ||
484 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); | 484 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); |
485 | 485 | ||
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c index 570e31ea427a..161b67972e3f 100644 --- a/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/net/netfilter/ipvs/ip_vs_lblcr.c | |||
@@ -649,7 +649,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) | |||
649 | struct ip_vs_dest *dest = NULL; | 649 | struct ip_vs_dest *dest = NULL; |
650 | struct ip_vs_lblcr_entry *en; | 650 | struct ip_vs_lblcr_entry *en; |
651 | 651 | ||
652 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 652 | ip_vs_fill_iph_addr_only(svc->af, skb, &iph); |
653 | 653 | ||
654 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); | 654 | IP_VS_DBG(6, "%s(): Scheduling...\n", __func__); |
655 | 655 | ||
diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c index 1aa5cac748c4..12475ef88daf 100644 --- a/net/netfilter/ipvs/ip_vs_pe_sip.c +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c | |||
@@ -68,23 +68,31 @@ static int get_callid(const char *dptr, unsigned int dataoff, | |||
68 | static int | 68 | static int |
69 | ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) | 69 | ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) |
70 | { | 70 | { |
71 | struct sk_buff *reasm = skb_nfct_reasm(skb); | ||
71 | struct ip_vs_iphdr iph; | 72 | struct ip_vs_iphdr iph; |
72 | unsigned int dataoff, datalen, matchoff, matchlen; | 73 | unsigned int dataoff, datalen, matchoff, matchlen; |
73 | const char *dptr; | 74 | const char *dptr; |
74 | int retc; | 75 | int retc; |
75 | 76 | ||
76 | ip_vs_fill_iphdr(p->af, skb_network_header(skb), &iph); | 77 | ip_vs_fill_iph_skb(p->af, skb, &iph); |
77 | 78 | ||
78 | /* Only useful with UDP */ | 79 | /* Only useful with UDP */ |
79 | if (iph.protocol != IPPROTO_UDP) | 80 | if (iph.protocol != IPPROTO_UDP) |
80 | return -EINVAL; | 81 | return -EINVAL; |
82 | /* todo: IPv6 fragments: | ||
83 | * I think this only should be done for the first fragment. /HS | ||
84 | */ | ||
85 | if (reasm) { | ||
86 | skb = reasm; | ||
87 | dataoff = iph.thoff_reasm + sizeof(struct udphdr); | ||
88 | } else | ||
89 | dataoff = iph.len + sizeof(struct udphdr); | ||
81 | 90 | ||
82 | /* No Data ? */ | ||
83 | dataoff = iph.len + sizeof(struct udphdr); | ||
84 | if (dataoff >= skb->len) | 91 | if (dataoff >= skb->len) |
85 | return -EINVAL; | 92 | return -EINVAL; |
86 | 93 | /* todo: Check if this will mess-up the reasm skb !!! /HS */ | |
87 | if ((retc=skb_linearize(skb)) < 0) | 94 | retc = skb_linearize(skb); |
95 | if (retc < 0) | ||
88 | return retc; | 96 | return retc; |
89 | dptr = skb->data + dataoff; | 97 | dptr = skb->data + dataoff; |
90 | datalen = skb->len - dataoff; | 98 | datalen = skb->len - dataoff; |
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index 50d82186da87..939f7fbe9b46 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c | |||
@@ -280,17 +280,17 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp, | |||
280 | if (ih == NULL) | 280 | if (ih == NULL) |
281 | sprintf(buf, "TRUNCATED"); | 281 | sprintf(buf, "TRUNCATED"); |
282 | else if (ih->nexthdr == IPPROTO_FRAGMENT) | 282 | else if (ih->nexthdr == IPPROTO_FRAGMENT) |
283 | sprintf(buf, "%pI6->%pI6 frag", &ih->saddr, &ih->daddr); | 283 | sprintf(buf, "%pI6c->%pI6c frag", &ih->saddr, &ih->daddr); |
284 | else { | 284 | else { |
285 | __be16 _ports[2], *pptr; | 285 | __be16 _ports[2], *pptr; |
286 | 286 | ||
287 | pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr), | 287 | pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr), |
288 | sizeof(_ports), _ports); | 288 | sizeof(_ports), _ports); |
289 | if (pptr == NULL) | 289 | if (pptr == NULL) |
290 | sprintf(buf, "TRUNCATED %pI6->%pI6", | 290 | sprintf(buf, "TRUNCATED %pI6c->%pI6c", |
291 | &ih->saddr, &ih->daddr); | 291 | &ih->saddr, &ih->daddr); |
292 | else | 292 | else |
293 | sprintf(buf, "%pI6:%u->%pI6:%u", | 293 | sprintf(buf, "%pI6c:%u->%pI6c:%u", |
294 | &ih->saddr, ntohs(pptr[0]), | 294 | &ih->saddr, ntohs(pptr[0]), |
295 | &ih->daddr, ntohs(pptr[1])); | 295 | &ih->daddr, ntohs(pptr[1])); |
296 | } | 296 | } |
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c index 5b8eb8b12c3e..5de3dd312c0f 100644 --- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c +++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c | |||
@@ -57,7 +57,7 @@ ah_esp_conn_fill_param_proto(struct net *net, int af, | |||
57 | 57 | ||
58 | static struct ip_vs_conn * | 58 | static struct ip_vs_conn * |
59 | ah_esp_conn_in_get(int af, const struct sk_buff *skb, | 59 | ah_esp_conn_in_get(int af, const struct sk_buff *skb, |
60 | const struct ip_vs_iphdr *iph, unsigned int proto_off, | 60 | const struct ip_vs_iphdr *iph, |
61 | int inverse) | 61 | int inverse) |
62 | { | 62 | { |
63 | struct ip_vs_conn *cp; | 63 | struct ip_vs_conn *cp; |
@@ -85,9 +85,7 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, | |||
85 | 85 | ||
86 | static struct ip_vs_conn * | 86 | static struct ip_vs_conn * |
87 | ah_esp_conn_out_get(int af, const struct sk_buff *skb, | 87 | ah_esp_conn_out_get(int af, const struct sk_buff *skb, |
88 | const struct ip_vs_iphdr *iph, | 88 | const struct ip_vs_iphdr *iph, int inverse) |
89 | unsigned int proto_off, | ||
90 | int inverse) | ||
91 | { | 89 | { |
92 | struct ip_vs_conn *cp; | 90 | struct ip_vs_conn *cp; |
93 | struct ip_vs_conn_param p; | 91 | struct ip_vs_conn_param p; |
@@ -110,7 +108,8 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb, | |||
110 | 108 | ||
111 | static int | 109 | static int |
112 | ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 110 | ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
113 | int *verdict, struct ip_vs_conn **cpp) | 111 | int *verdict, struct ip_vs_conn **cpp, |
112 | struct ip_vs_iphdr *iph) | ||
114 | { | 113 | { |
115 | /* | 114 | /* |
116 | * AH/ESP is only related traffic. Pass the packet to IP stack. | 115 | * AH/ESP is only related traffic. Pass the packet to IP stack. |
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 9f3fb751c491..746048b13ef3 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c | |||
@@ -10,28 +10,26 @@ | |||
10 | 10 | ||
11 | static int | 11 | static int |
12 | sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 12 | sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
13 | int *verdict, struct ip_vs_conn **cpp) | 13 | int *verdict, struct ip_vs_conn **cpp, |
14 | struct ip_vs_iphdr *iph) | ||
14 | { | 15 | { |
15 | struct net *net; | 16 | struct net *net; |
16 | struct ip_vs_service *svc; | 17 | struct ip_vs_service *svc; |
17 | sctp_chunkhdr_t _schunkh, *sch; | 18 | sctp_chunkhdr_t _schunkh, *sch; |
18 | sctp_sctphdr_t *sh, _sctph; | 19 | sctp_sctphdr_t *sh, _sctph; |
19 | struct ip_vs_iphdr iph; | ||
20 | 20 | ||
21 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 21 | sh = skb_header_pointer(skb, iph->len, sizeof(_sctph), &_sctph); |
22 | |||
23 | sh = skb_header_pointer(skb, iph.len, sizeof(_sctph), &_sctph); | ||
24 | if (sh == NULL) | 22 | if (sh == NULL) |
25 | return 0; | 23 | return 0; |
26 | 24 | ||
27 | sch = skb_header_pointer(skb, iph.len + sizeof(sctp_sctphdr_t), | 25 | sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t), |
28 | sizeof(_schunkh), &_schunkh); | 26 | sizeof(_schunkh), &_schunkh); |
29 | if (sch == NULL) | 27 | if (sch == NULL) |
30 | return 0; | 28 | return 0; |
31 | net = skb_net(skb); | 29 | net = skb_net(skb); |
32 | if ((sch->type == SCTP_CID_INIT) && | 30 | if ((sch->type == SCTP_CID_INIT) && |
33 | (svc = ip_vs_service_get(net, af, skb->mark, iph.protocol, | 31 | (svc = ip_vs_service_get(net, af, skb->mark, iph->protocol, |
34 | &iph.daddr, sh->dest))) { | 32 | &iph->daddr, sh->dest))) { |
35 | int ignored; | 33 | int ignored; |
36 | 34 | ||
37 | if (ip_vs_todrop(net_ipvs(net))) { | 35 | if (ip_vs_todrop(net_ipvs(net))) { |
@@ -47,10 +45,10 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
47 | * Let the virtual server select a real server for the | 45 | * Let the virtual server select a real server for the |
48 | * incoming connection, and create a connection entry. | 46 | * incoming connection, and create a connection entry. |
49 | */ | 47 | */ |
50 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored); | 48 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored, iph); |
51 | if (!*cpp && ignored <= 0) { | 49 | if (!*cpp && ignored <= 0) { |
52 | if (!ignored) | 50 | if (!ignored) |
53 | *verdict = ip_vs_leave(svc, skb, pd); | 51 | *verdict = ip_vs_leave(svc, skb, pd, iph); |
54 | else { | 52 | else { |
55 | ip_vs_service_put(svc); | 53 | ip_vs_service_put(svc); |
56 | *verdict = NF_DROP; | 54 | *verdict = NF_DROP; |
@@ -64,20 +62,18 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
64 | } | 62 | } |
65 | 63 | ||
66 | static int | 64 | static int |
67 | sctp_snat_handler(struct sk_buff *skb, | 65 | sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
68 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 66 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
69 | { | 67 | { |
70 | sctp_sctphdr_t *sctph; | 68 | sctp_sctphdr_t *sctph; |
71 | unsigned int sctphoff; | 69 | unsigned int sctphoff = iph->len; |
72 | struct sk_buff *iter; | 70 | struct sk_buff *iter; |
73 | __be32 crc32; | 71 | __be32 crc32; |
74 | 72 | ||
75 | #ifdef CONFIG_IP_VS_IPV6 | 73 | #ifdef CONFIG_IP_VS_IPV6 |
76 | if (cp->af == AF_INET6) | 74 | if (cp->af == AF_INET6 && iph->fragoffs) |
77 | sctphoff = sizeof(struct ipv6hdr); | 75 | return 1; |
78 | else | ||
79 | #endif | 76 | #endif |
80 | sctphoff = ip_hdrlen(skb); | ||
81 | 77 | ||
82 | /* csum_check requires unshared skb */ | 78 | /* csum_check requires unshared skb */ |
83 | if (!skb_make_writable(skb, sctphoff + sizeof(*sctph))) | 79 | if (!skb_make_writable(skb, sctphoff + sizeof(*sctph))) |
@@ -108,20 +104,18 @@ sctp_snat_handler(struct sk_buff *skb, | |||
108 | } | 104 | } |
109 | 105 | ||
110 | static int | 106 | static int |
111 | sctp_dnat_handler(struct sk_buff *skb, | 107 | sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
112 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 108 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
113 | { | 109 | { |
114 | sctp_sctphdr_t *sctph; | 110 | sctp_sctphdr_t *sctph; |
115 | unsigned int sctphoff; | 111 | unsigned int sctphoff = iph->len; |
116 | struct sk_buff *iter; | 112 | struct sk_buff *iter; |
117 | __be32 crc32; | 113 | __be32 crc32; |
118 | 114 | ||
119 | #ifdef CONFIG_IP_VS_IPV6 | 115 | #ifdef CONFIG_IP_VS_IPV6 |
120 | if (cp->af == AF_INET6) | 116 | if (cp->af == AF_INET6 && iph->fragoffs) |
121 | sctphoff = sizeof(struct ipv6hdr); | 117 | return 1; |
122 | else | ||
123 | #endif | 118 | #endif |
124 | sctphoff = ip_hdrlen(skb); | ||
125 | 119 | ||
126 | /* csum_check requires unshared skb */ | 120 | /* csum_check requires unshared skb */ |
127 | if (!skb_make_writable(skb, sctphoff + sizeof(*sctph))) | 121 | if (!skb_make_writable(skb, sctphoff + sizeof(*sctph))) |
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index cd609cc62721..9af653a75825 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c | |||
@@ -33,16 +33,14 @@ | |||
33 | 33 | ||
34 | static int | 34 | static int |
35 | tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 35 | tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
36 | int *verdict, struct ip_vs_conn **cpp) | 36 | int *verdict, struct ip_vs_conn **cpp, |
37 | struct ip_vs_iphdr *iph) | ||
37 | { | 38 | { |
38 | struct net *net; | 39 | struct net *net; |
39 | struct ip_vs_service *svc; | 40 | struct ip_vs_service *svc; |
40 | struct tcphdr _tcph, *th; | 41 | struct tcphdr _tcph, *th; |
41 | struct ip_vs_iphdr iph; | ||
42 | 42 | ||
43 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 43 | th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph); |
44 | |||
45 | th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph); | ||
46 | if (th == NULL) { | 44 | if (th == NULL) { |
47 | *verdict = NF_DROP; | 45 | *verdict = NF_DROP; |
48 | return 0; | 46 | return 0; |
@@ -50,8 +48,8 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
50 | net = skb_net(skb); | 48 | net = skb_net(skb); |
51 | /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ | 49 | /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ |
52 | if (th->syn && | 50 | if (th->syn && |
53 | (svc = ip_vs_service_get(net, af, skb->mark, iph.protocol, | 51 | (svc = ip_vs_service_get(net, af, skb->mark, iph->protocol, |
54 | &iph.daddr, th->dest))) { | 52 | &iph->daddr, th->dest))) { |
55 | int ignored; | 53 | int ignored; |
56 | 54 | ||
57 | if (ip_vs_todrop(net_ipvs(net))) { | 55 | if (ip_vs_todrop(net_ipvs(net))) { |
@@ -68,10 +66,10 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
68 | * Let the virtual server select a real server for the | 66 | * Let the virtual server select a real server for the |
69 | * incoming connection, and create a connection entry. | 67 | * incoming connection, and create a connection entry. |
70 | */ | 68 | */ |
71 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored); | 69 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored, iph); |
72 | if (!*cpp && ignored <= 0) { | 70 | if (!*cpp && ignored <= 0) { |
73 | if (!ignored) | 71 | if (!ignored) |
74 | *verdict = ip_vs_leave(svc, skb, pd); | 72 | *verdict = ip_vs_leave(svc, skb, pd, iph); |
75 | else { | 73 | else { |
76 | ip_vs_service_put(svc); | 74 | ip_vs_service_put(svc); |
77 | *verdict = NF_DROP; | 75 | *verdict = NF_DROP; |
@@ -128,20 +126,18 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph, | |||
128 | 126 | ||
129 | 127 | ||
130 | static int | 128 | static int |
131 | tcp_snat_handler(struct sk_buff *skb, | 129 | tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
132 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 130 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
133 | { | 131 | { |
134 | struct tcphdr *tcph; | 132 | struct tcphdr *tcph; |
135 | unsigned int tcphoff; | 133 | unsigned int tcphoff = iph->len; |
136 | int oldlen; | 134 | int oldlen; |
137 | int payload_csum = 0; | 135 | int payload_csum = 0; |
138 | 136 | ||
139 | #ifdef CONFIG_IP_VS_IPV6 | 137 | #ifdef CONFIG_IP_VS_IPV6 |
140 | if (cp->af == AF_INET6) | 138 | if (cp->af == AF_INET6 && iph->fragoffs) |
141 | tcphoff = sizeof(struct ipv6hdr); | 139 | return 1; |
142 | else | ||
143 | #endif | 140 | #endif |
144 | tcphoff = ip_hdrlen(skb); | ||
145 | oldlen = skb->len - tcphoff; | 141 | oldlen = skb->len - tcphoff; |
146 | 142 | ||
147 | /* csum_check requires unshared skb */ | 143 | /* csum_check requires unshared skb */ |
@@ -208,20 +204,18 @@ tcp_snat_handler(struct sk_buff *skb, | |||
208 | 204 | ||
209 | 205 | ||
210 | static int | 206 | static int |
211 | tcp_dnat_handler(struct sk_buff *skb, | 207 | tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
212 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 208 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
213 | { | 209 | { |
214 | struct tcphdr *tcph; | 210 | struct tcphdr *tcph; |
215 | unsigned int tcphoff; | 211 | unsigned int tcphoff = iph->len; |
216 | int oldlen; | 212 | int oldlen; |
217 | int payload_csum = 0; | 213 | int payload_csum = 0; |
218 | 214 | ||
219 | #ifdef CONFIG_IP_VS_IPV6 | 215 | #ifdef CONFIG_IP_VS_IPV6 |
220 | if (cp->af == AF_INET6) | 216 | if (cp->af == AF_INET6 && iph->fragoffs) |
221 | tcphoff = sizeof(struct ipv6hdr); | 217 | return 1; |
222 | else | ||
223 | #endif | 218 | #endif |
224 | tcphoff = ip_hdrlen(skb); | ||
225 | oldlen = skb->len - tcphoff; | 219 | oldlen = skb->len - tcphoff; |
226 | 220 | ||
227 | /* csum_check requires unshared skb */ | 221 | /* csum_check requires unshared skb */ |
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 2fedb2dcb3d1..503a842c90d2 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c | |||
@@ -30,23 +30,22 @@ | |||
30 | 30 | ||
31 | static int | 31 | static int |
32 | udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | 32 | udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, |
33 | int *verdict, struct ip_vs_conn **cpp) | 33 | int *verdict, struct ip_vs_conn **cpp, |
34 | struct ip_vs_iphdr *iph) | ||
34 | { | 35 | { |
35 | struct net *net; | 36 | struct net *net; |
36 | struct ip_vs_service *svc; | 37 | struct ip_vs_service *svc; |
37 | struct udphdr _udph, *uh; | 38 | struct udphdr _udph, *uh; |
38 | struct ip_vs_iphdr iph; | ||
39 | 39 | ||
40 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 40 | /* IPv6 fragments, only first fragment will hit this */ |
41 | 41 | uh = skb_header_pointer(skb, iph->len, sizeof(_udph), &_udph); | |
42 | uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph); | ||
43 | if (uh == NULL) { | 42 | if (uh == NULL) { |
44 | *verdict = NF_DROP; | 43 | *verdict = NF_DROP; |
45 | return 0; | 44 | return 0; |
46 | } | 45 | } |
47 | net = skb_net(skb); | 46 | net = skb_net(skb); |
48 | svc = ip_vs_service_get(net, af, skb->mark, iph.protocol, | 47 | svc = ip_vs_service_get(net, af, skb->mark, iph->protocol, |
49 | &iph.daddr, uh->dest); | 48 | &iph->daddr, uh->dest); |
50 | if (svc) { | 49 | if (svc) { |
51 | int ignored; | 50 | int ignored; |
52 | 51 | ||
@@ -64,10 +63,10 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, | |||
64 | * Let the virtual server select a real server for the | 63 | * Let the virtual server select a real server for the |
65 | * incoming connection, and create a connection entry. | 64 | * incoming connection, and create a connection entry. |
66 | */ | 65 | */ |
67 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored); | 66 | *cpp = ip_vs_schedule(svc, skb, pd, &ignored, iph); |
68 | if (!*cpp && ignored <= 0) { | 67 | if (!*cpp && ignored <= 0) { |
69 | if (!ignored) | 68 | if (!ignored) |
70 | *verdict = ip_vs_leave(svc, skb, pd); | 69 | *verdict = ip_vs_leave(svc, skb, pd, iph); |
71 | else { | 70 | else { |
72 | ip_vs_service_put(svc); | 71 | ip_vs_service_put(svc); |
73 | *verdict = NF_DROP; | 72 | *verdict = NF_DROP; |
@@ -125,20 +124,18 @@ udp_partial_csum_update(int af, struct udphdr *uhdr, | |||
125 | 124 | ||
126 | 125 | ||
127 | static int | 126 | static int |
128 | udp_snat_handler(struct sk_buff *skb, | 127 | udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
129 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 128 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
130 | { | 129 | { |
131 | struct udphdr *udph; | 130 | struct udphdr *udph; |
132 | unsigned int udphoff; | 131 | unsigned int udphoff = iph->len; |
133 | int oldlen; | 132 | int oldlen; |
134 | int payload_csum = 0; | 133 | int payload_csum = 0; |
135 | 134 | ||
136 | #ifdef CONFIG_IP_VS_IPV6 | 135 | #ifdef CONFIG_IP_VS_IPV6 |
137 | if (cp->af == AF_INET6) | 136 | if (cp->af == AF_INET6 && iph->fragoffs) |
138 | udphoff = sizeof(struct ipv6hdr); | 137 | return 1; |
139 | else | ||
140 | #endif | 138 | #endif |
141 | udphoff = ip_hdrlen(skb); | ||
142 | oldlen = skb->len - udphoff; | 139 | oldlen = skb->len - udphoff; |
143 | 140 | ||
144 | /* csum_check requires unshared skb */ | 141 | /* csum_check requires unshared skb */ |
@@ -210,20 +207,18 @@ udp_snat_handler(struct sk_buff *skb, | |||
210 | 207 | ||
211 | 208 | ||
212 | static int | 209 | static int |
213 | udp_dnat_handler(struct sk_buff *skb, | 210 | udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, |
214 | struct ip_vs_protocol *pp, struct ip_vs_conn *cp) | 211 | struct ip_vs_conn *cp, struct ip_vs_iphdr *iph) |
215 | { | 212 | { |
216 | struct udphdr *udph; | 213 | struct udphdr *udph; |
217 | unsigned int udphoff; | 214 | unsigned int udphoff = iph->len; |
218 | int oldlen; | 215 | int oldlen; |
219 | int payload_csum = 0; | 216 | int payload_csum = 0; |
220 | 217 | ||
221 | #ifdef CONFIG_IP_VS_IPV6 | 218 | #ifdef CONFIG_IP_VS_IPV6 |
222 | if (cp->af == AF_INET6) | 219 | if (cp->af == AF_INET6 && iph->fragoffs) |
223 | udphoff = sizeof(struct ipv6hdr); | 220 | return 1; |
224 | else | ||
225 | #endif | 221 | #endif |
226 | udphoff = ip_hdrlen(skb); | ||
227 | oldlen = skb->len - udphoff; | 222 | oldlen = skb->len - udphoff; |
228 | 223 | ||
229 | /* csum_check requires unshared skb */ | 224 | /* csum_check requires unshared skb */ |
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index 08dbdd5bc18f..d6bf20d6cdbe 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c | |||
@@ -159,7 +159,7 @@ void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg) | |||
159 | svc->fwmark, msg); | 159 | svc->fwmark, msg); |
160 | #ifdef CONFIG_IP_VS_IPV6 | 160 | #ifdef CONFIG_IP_VS_IPV6 |
161 | } else if (svc->af == AF_INET6) { | 161 | } else if (svc->af == AF_INET6) { |
162 | IP_VS_ERR_RL("%s: %s [%pI6]:%d - %s\n", | 162 | IP_VS_ERR_RL("%s: %s [%pI6c]:%d - %s\n", |
163 | svc->scheduler->name, | 163 | svc->scheduler->name, |
164 | ip_vs_proto_name(svc->protocol), | 164 | ip_vs_proto_name(svc->protocol), |
165 | &svc->addr.in6, ntohs(svc->port), msg); | 165 | &svc->addr.in6, ntohs(svc->port), msg); |
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c index 05126521743e..e33126994628 100644 --- a/net/netfilter/ipvs/ip_vs_sh.c +++ b/net/netfilter/ipvs/ip_vs_sh.c | |||
@@ -228,7 +228,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) | |||
228 | struct ip_vs_sh_bucket *tbl; | 228 | struct ip_vs_sh_bucket *tbl; |
229 | struct ip_vs_iphdr iph; | 229 | struct ip_vs_iphdr iph; |
230 | 230 | ||
231 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 231 | ip_vs_fill_iph_addr_only(svc->af, skb, &iph); |
232 | 232 | ||
233 | IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n"); | 233 | IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n"); |
234 | 234 | ||
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index cc4c8095681a..12008b47e5ca 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -338,7 +338,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, | |||
338 | local = __ip_vs_is_local_route6(rt); | 338 | local = __ip_vs_is_local_route6(rt); |
339 | if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) & | 339 | if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) & |
340 | rt_mode)) { | 340 | rt_mode)) { |
341 | IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n", | 341 | IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6c\n", |
342 | local ? "local":"non-local", daddr); | 342 | local ? "local":"non-local", daddr); |
343 | dst_release(&rt->dst); | 343 | dst_release(&rt->dst); |
344 | return NULL; | 344 | return NULL; |
@@ -346,8 +346,8 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, | |||
346 | if (local && !(rt_mode & IP_VS_RT_MODE_RDR) && | 346 | if (local && !(rt_mode & IP_VS_RT_MODE_RDR) && |
347 | !((ort = (struct rt6_info *) skb_dst(skb)) && | 347 | !((ort = (struct rt6_info *) skb_dst(skb)) && |
348 | __ip_vs_is_local_route6(ort))) { | 348 | __ip_vs_is_local_route6(ort))) { |
349 | IP_VS_DBG_RL("Redirect from non-local address %pI6 to local " | 349 | IP_VS_DBG_RL("Redirect from non-local address %pI6c to local " |
350 | "requires NAT method, dest: %pI6\n", | 350 | "requires NAT method, dest: %pI6c\n", |
351 | &ipv6_hdr(skb)->daddr, daddr); | 351 | &ipv6_hdr(skb)->daddr, daddr); |
352 | dst_release(&rt->dst); | 352 | dst_release(&rt->dst); |
353 | return NULL; | 353 | return NULL; |
@@ -355,8 +355,8 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, | |||
355 | if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) && | 355 | if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) && |
356 | ipv6_addr_type(&ipv6_hdr(skb)->saddr) & | 356 | ipv6_addr_type(&ipv6_hdr(skb)->saddr) & |
357 | IPV6_ADDR_LOOPBACK)) { | 357 | IPV6_ADDR_LOOPBACK)) { |
358 | IP_VS_DBG_RL("Stopping traffic from loopback address %pI6 " | 358 | IP_VS_DBG_RL("Stopping traffic from loopback address %pI6c " |
359 | "to non-local address, dest: %pI6\n", | 359 | "to non-local address, dest: %pI6c\n", |
360 | &ipv6_hdr(skb)->saddr, daddr); | 360 | &ipv6_hdr(skb)->saddr, daddr); |
361 | dst_release(&rt->dst); | 361 | dst_release(&rt->dst); |
362 | return NULL; | 362 | return NULL; |
@@ -427,7 +427,7 @@ do { \ | |||
427 | */ | 427 | */ |
428 | int | 428 | int |
429 | ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 429 | ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
430 | struct ip_vs_protocol *pp) | 430 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
431 | { | 431 | { |
432 | /* we do not touch skb and do not need pskb ptr */ | 432 | /* we do not touch skb and do not need pskb ptr */ |
433 | IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); | 433 | IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); |
@@ -441,7 +441,7 @@ ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
441 | */ | 441 | */ |
442 | int | 442 | int |
443 | ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 443 | ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
444 | struct ip_vs_protocol *pp) | 444 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
445 | { | 445 | { |
446 | struct rtable *rt; /* Route to the other host */ | 446 | struct rtable *rt; /* Route to the other host */ |
447 | struct iphdr *iph = ip_hdr(skb); | 447 | struct iphdr *iph = ip_hdr(skb); |
@@ -496,16 +496,16 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
496 | #ifdef CONFIG_IP_VS_IPV6 | 496 | #ifdef CONFIG_IP_VS_IPV6 |
497 | int | 497 | int |
498 | ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | 498 | ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
499 | struct ip_vs_protocol *pp) | 499 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph) |
500 | { | 500 | { |
501 | struct rt6_info *rt; /* Route to the other host */ | 501 | struct rt6_info *rt; /* Route to the other host */ |
502 | struct ipv6hdr *iph = ipv6_hdr(skb); | ||
503 | int mtu; | 502 | int mtu; |
504 | 503 | ||
505 | EnterFunction(10); | 504 | EnterFunction(10); |
506 | 505 | ||
507 | if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, | 506 | rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr.in6, NULL, 0, |
508 | IP_VS_RT_MODE_NON_LOCAL))) | 507 | IP_VS_RT_MODE_NON_LOCAL); |
508 | if (!rt) | ||
509 | goto tx_error_icmp; | 509 | goto tx_error_icmp; |
510 | 510 | ||
511 | /* MTU checking */ | 511 | /* MTU checking */ |
@@ -516,7 +516,9 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
516 | 516 | ||
517 | skb->dev = net->loopback_dev; | 517 | skb->dev = net->loopback_dev; |
518 | } | 518 | } |
519 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 519 | /* only send ICMP too big on first fragment */ |
520 | if (!iph->fragoffs) | ||
521 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
520 | dst_release(&rt->dst); | 522 | dst_release(&rt->dst); |
521 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); | 523 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); |
522 | goto tx_error; | 524 | goto tx_error; |
@@ -559,7 +561,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
559 | */ | 561 | */ |
560 | int | 562 | int |
561 | ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 563 | ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
562 | struct ip_vs_protocol *pp) | 564 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
563 | { | 565 | { |
564 | struct rtable *rt; /* Route to the other host */ | 566 | struct rtable *rt; /* Route to the other host */ |
565 | int mtu; | 567 | int mtu; |
@@ -629,7 +631,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
629 | goto tx_error_put; | 631 | goto tx_error_put; |
630 | 632 | ||
631 | /* mangle the packet */ | 633 | /* mangle the packet */ |
632 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) | 634 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp, ipvsh)) |
633 | goto tx_error_put; | 635 | goto tx_error_put; |
634 | ip_hdr(skb)->daddr = cp->daddr.ip; | 636 | ip_hdr(skb)->daddr = cp->daddr.ip; |
635 | ip_send_check(ip_hdr(skb)); | 637 | ip_send_check(ip_hdr(skb)); |
@@ -677,7 +679,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
677 | #ifdef CONFIG_IP_VS_IPV6 | 679 | #ifdef CONFIG_IP_VS_IPV6 |
678 | int | 680 | int |
679 | ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | 681 | ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
680 | struct ip_vs_protocol *pp) | 682 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph) |
681 | { | 683 | { |
682 | struct rt6_info *rt; /* Route to the other host */ | 684 | struct rt6_info *rt; /* Route to the other host */ |
683 | int mtu; | 685 | int mtu; |
@@ -686,10 +688,9 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
686 | EnterFunction(10); | 688 | EnterFunction(10); |
687 | 689 | ||
688 | /* check if it is a connection of no-client-port */ | 690 | /* check if it is a connection of no-client-port */ |
689 | if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) { | 691 | if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT && !iph->fragoffs)) { |
690 | __be16 _pt, *p; | 692 | __be16 _pt, *p; |
691 | p = skb_header_pointer(skb, sizeof(struct ipv6hdr), | 693 | p = skb_header_pointer(skb, iph->len, sizeof(_pt), &_pt); |
692 | sizeof(_pt), &_pt); | ||
693 | if (p == NULL) | 694 | if (p == NULL) |
694 | goto tx_error; | 695 | goto tx_error; |
695 | ip_vs_conn_fill_cport(cp, *p); | 696 | ip_vs_conn_fill_cport(cp, *p); |
@@ -737,7 +738,9 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
737 | 738 | ||
738 | skb->dev = net->loopback_dev; | 739 | skb->dev = net->loopback_dev; |
739 | } | 740 | } |
740 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 741 | /* only send ICMP too big on first fragment */ |
742 | if (!iph->fragoffs) | ||
743 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
741 | IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0, | 744 | IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0, |
742 | "ip_vs_nat_xmit_v6(): frag needed for"); | 745 | "ip_vs_nat_xmit_v6(): frag needed for"); |
743 | goto tx_error_put; | 746 | goto tx_error_put; |
@@ -751,7 +754,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
751 | goto tx_error_put; | 754 | goto tx_error_put; |
752 | 755 | ||
753 | /* mangle the packet */ | 756 | /* mangle the packet */ |
754 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) | 757 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp, iph)) |
755 | goto tx_error; | 758 | goto tx_error; |
756 | ipv6_hdr(skb)->daddr = cp->daddr.in6; | 759 | ipv6_hdr(skb)->daddr = cp->daddr.in6; |
757 | 760 | ||
@@ -812,7 +815,7 @@ tx_error_put: | |||
812 | */ | 815 | */ |
813 | int | 816 | int |
814 | ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 817 | ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
815 | struct ip_vs_protocol *pp) | 818 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
816 | { | 819 | { |
817 | struct netns_ipvs *ipvs = net_ipvs(skb_net(skb)); | 820 | struct netns_ipvs *ipvs = net_ipvs(skb_net(skb)); |
818 | struct rtable *rt; /* Route to the other host */ | 821 | struct rtable *rt; /* Route to the other host */ |
@@ -932,7 +935,7 @@ tx_error_put: | |||
932 | #ifdef CONFIG_IP_VS_IPV6 | 935 | #ifdef CONFIG_IP_VS_IPV6 |
933 | int | 936 | int |
934 | ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | 937 | ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
935 | struct ip_vs_protocol *pp) | 938 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
936 | { | 939 | { |
937 | struct rt6_info *rt; /* Route to the other host */ | 940 | struct rt6_info *rt; /* Route to the other host */ |
938 | struct in6_addr saddr; /* Source for tunnel */ | 941 | struct in6_addr saddr; /* Source for tunnel */ |
@@ -972,7 +975,9 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
972 | 975 | ||
973 | skb->dev = net->loopback_dev; | 976 | skb->dev = net->loopback_dev; |
974 | } | 977 | } |
975 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 978 | /* only send ICMP too big on first fragment */ |
979 | if (!ipvsh->fragoffs) | ||
980 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
976 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); | 981 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); |
977 | goto tx_error_put; | 982 | goto tx_error_put; |
978 | } | 983 | } |
@@ -1053,7 +1058,7 @@ tx_error_put: | |||
1053 | */ | 1058 | */ |
1054 | int | 1059 | int |
1055 | ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 1060 | ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1056 | struct ip_vs_protocol *pp) | 1061 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) |
1057 | { | 1062 | { |
1058 | struct rtable *rt; /* Route to the other host */ | 1063 | struct rtable *rt; /* Route to the other host */ |
1059 | struct iphdr *iph = ip_hdr(skb); | 1064 | struct iphdr *iph = ip_hdr(skb); |
@@ -1115,7 +1120,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1115 | #ifdef CONFIG_IP_VS_IPV6 | 1120 | #ifdef CONFIG_IP_VS_IPV6 |
1116 | int | 1121 | int |
1117 | ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | 1122 | ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1118 | struct ip_vs_protocol *pp) | 1123 | struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph) |
1119 | { | 1124 | { |
1120 | struct rt6_info *rt; /* Route to the other host */ | 1125 | struct rt6_info *rt; /* Route to the other host */ |
1121 | int mtu; | 1126 | int mtu; |
@@ -1139,7 +1144,9 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1139 | 1144 | ||
1140 | skb->dev = net->loopback_dev; | 1145 | skb->dev = net->loopback_dev; |
1141 | } | 1146 | } |
1142 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 1147 | /* only send ICMP too big on first fragment */ |
1148 | if (!iph->fragoffs) | ||
1149 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
1143 | dst_release(&rt->dst); | 1150 | dst_release(&rt->dst); |
1144 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); | 1151 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); |
1145 | goto tx_error; | 1152 | goto tx_error; |
@@ -1183,7 +1190,8 @@ tx_error: | |||
1183 | */ | 1190 | */ |
1184 | int | 1191 | int |
1185 | ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | 1192 | ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, |
1186 | struct ip_vs_protocol *pp, int offset, unsigned int hooknum) | 1193 | struct ip_vs_protocol *pp, int offset, unsigned int hooknum, |
1194 | struct ip_vs_iphdr *iph) | ||
1187 | { | 1195 | { |
1188 | struct rtable *rt; /* Route to the other host */ | 1196 | struct rtable *rt; /* Route to the other host */ |
1189 | int mtu; | 1197 | int mtu; |
@@ -1198,7 +1206,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1198 | translate address/port back */ | 1206 | translate address/port back */ |
1199 | if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) { | 1207 | if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) { |
1200 | if (cp->packet_xmit) | 1208 | if (cp->packet_xmit) |
1201 | rc = cp->packet_xmit(skb, cp, pp); | 1209 | rc = cp->packet_xmit(skb, cp, pp, iph); |
1202 | else | 1210 | else |
1203 | rc = NF_ACCEPT; | 1211 | rc = NF_ACCEPT; |
1204 | /* do not touch skb anymore */ | 1212 | /* do not touch skb anymore */ |
@@ -1304,7 +1312,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1304 | #ifdef CONFIG_IP_VS_IPV6 | 1312 | #ifdef CONFIG_IP_VS_IPV6 |
1305 | int | 1313 | int |
1306 | ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | 1314 | ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, |
1307 | struct ip_vs_protocol *pp, int offset, unsigned int hooknum) | 1315 | struct ip_vs_protocol *pp, int offset, unsigned int hooknum, |
1316 | struct ip_vs_iphdr *iph) | ||
1308 | { | 1317 | { |
1309 | struct rt6_info *rt; /* Route to the other host */ | 1318 | struct rt6_info *rt; /* Route to the other host */ |
1310 | int mtu; | 1319 | int mtu; |
@@ -1319,7 +1328,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1319 | translate address/port back */ | 1328 | translate address/port back */ |
1320 | if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) { | 1329 | if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) { |
1321 | if (cp->packet_xmit) | 1330 | if (cp->packet_xmit) |
1322 | rc = cp->packet_xmit(skb, cp, pp); | 1331 | rc = cp->packet_xmit(skb, cp, pp, iph); |
1323 | else | 1332 | else |
1324 | rc = NF_ACCEPT; | 1333 | rc = NF_ACCEPT; |
1325 | /* do not touch skb anymore */ | 1334 | /* do not touch skb anymore */ |
@@ -1375,7 +1384,9 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1375 | 1384 | ||
1376 | skb->dev = net->loopback_dev; | 1385 | skb->dev = net->loopback_dev; |
1377 | } | 1386 | } |
1378 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 1387 | /* only send ICMP too big on first fragment */ |
1388 | if (!iph->fragoffs) | ||
1389 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | ||
1379 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); | 1390 | IP_VS_DBG_RL("%s(): frag needed\n", __func__); |
1380 | goto tx_error_put; | 1391 | goto tx_error_put; |
1381 | } | 1392 | } |
diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c index bb10b0717f1b..8d47c3780fda 100644 --- a/net/netfilter/xt_ipvs.c +++ b/net/netfilter/xt_ipvs.c | |||
@@ -67,7 +67,7 @@ ipvs_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
67 | goto out; | 67 | goto out; |
68 | } | 68 | } |
69 | 69 | ||
70 | ip_vs_fill_iphdr(family, skb_network_header(skb), &iph); | 70 | ip_vs_fill_iph_skb(family, skb, &iph); |
71 | 71 | ||
72 | if (data->bitmask & XT_IPVS_PROTO) | 72 | if (data->bitmask & XT_IPVS_PROTO) |
73 | if ((iph.protocol == data->l4proto) ^ | 73 | if ((iph.protocol == data->l4proto) ^ |
@@ -85,7 +85,7 @@ ipvs_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
85 | /* | 85 | /* |
86 | * Check if the packet belongs to an existing entry | 86 | * Check if the packet belongs to an existing entry |
87 | */ | 87 | */ |
88 | cp = pp->conn_out_get(family, skb, &iph, iph.len, 1 /* inverse */); | 88 | cp = pp->conn_out_get(family, skb, &iph, 1 /* inverse */); |
89 | if (unlikely(cp == NULL)) { | 89 | if (unlikely(cp == NULL)) { |
90 | match = false; | 90 | match = false; |
91 | goto out; | 91 | goto out; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 94060edbbd70..f262dbfc7f06 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1881,7 +1881,35 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1881 | skb_reserve(skb, hlen); | 1881 | skb_reserve(skb, hlen); |
1882 | skb_reset_network_header(skb); | 1882 | skb_reset_network_header(skb); |
1883 | 1883 | ||
1884 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); | 1884 | if (po->tp_tx_has_off) { |
1885 | int off_min, off_max, off; | ||
1886 | off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); | ||
1887 | off_max = po->tx_ring.frame_size - tp_len; | ||
1888 | if (sock->type == SOCK_DGRAM) { | ||
1889 | switch (po->tp_version) { | ||
1890 | case TPACKET_V2: | ||
1891 | off = ph.h2->tp_net; | ||
1892 | break; | ||
1893 | default: | ||
1894 | off = ph.h1->tp_net; | ||
1895 | break; | ||
1896 | } | ||
1897 | } else { | ||
1898 | switch (po->tp_version) { | ||
1899 | case TPACKET_V2: | ||
1900 | off = ph.h2->tp_mac; | ||
1901 | break; | ||
1902 | default: | ||
1903 | off = ph.h1->tp_mac; | ||
1904 | break; | ||
1905 | } | ||
1906 | } | ||
1907 | if (unlikely((off < off_min) || (off_max < off))) | ||
1908 | return -EINVAL; | ||
1909 | data = ph.raw + off; | ||
1910 | } else { | ||
1911 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); | ||
1912 | } | ||
1885 | to_write = tp_len; | 1913 | to_write = tp_len; |
1886 | 1914 | ||
1887 | if (sock->type == SOCK_DGRAM) { | 1915 | if (sock->type == SOCK_DGRAM) { |
@@ -1907,7 +1935,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1907 | to_write -= dev->hard_header_len; | 1935 | to_write -= dev->hard_header_len; |
1908 | } | 1936 | } |
1909 | 1937 | ||
1910 | err = -EFAULT; | ||
1911 | offset = offset_in_page(data); | 1938 | offset = offset_in_page(data); |
1912 | len_max = PAGE_SIZE - offset; | 1939 | len_max = PAGE_SIZE - offset; |
1913 | len = ((to_write > len_max) ? len_max : to_write); | 1940 | len = ((to_write > len_max) ? len_max : to_write); |
@@ -1957,7 +1984,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
1957 | 1984 | ||
1958 | mutex_lock(&po->pg_vec_lock); | 1985 | mutex_lock(&po->pg_vec_lock); |
1959 | 1986 | ||
1960 | err = -EBUSY; | ||
1961 | if (saddr == NULL) { | 1987 | if (saddr == NULL) { |
1962 | dev = po->prot_hook.dev; | 1988 | dev = po->prot_hook.dev; |
1963 | proto = po->num; | 1989 | proto = po->num; |
@@ -3111,6 +3137,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | |||
3111 | 3137 | ||
3112 | return fanout_add(sk, val & 0xffff, val >> 16); | 3138 | return fanout_add(sk, val & 0xffff, val >> 16); |
3113 | } | 3139 | } |
3140 | case PACKET_TX_HAS_OFF: | ||
3141 | { | ||
3142 | unsigned int val; | ||
3143 | |||
3144 | if (optlen != sizeof(val)) | ||
3145 | return -EINVAL; | ||
3146 | if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) | ||
3147 | return -EBUSY; | ||
3148 | if (copy_from_user(&val, optval, sizeof(val))) | ||
3149 | return -EFAULT; | ||
3150 | po->tp_tx_has_off = !!val; | ||
3151 | return 0; | ||
3152 | } | ||
3114 | default: | 3153 | default: |
3115 | return -ENOPROTOOPT; | 3154 | return -ENOPROTOOPT; |
3116 | } | 3155 | } |
@@ -3202,6 +3241,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, | |||
3202 | ((u32)po->fanout->type << 16)) : | 3241 | ((u32)po->fanout->type << 16)) : |
3203 | 0); | 3242 | 0); |
3204 | break; | 3243 | break; |
3244 | case PACKET_TX_HAS_OFF: | ||
3245 | val = po->tp_tx_has_off; | ||
3246 | break; | ||
3205 | default: | 3247 | default: |
3206 | return -ENOPROTOOPT; | 3248 | return -ENOPROTOOPT; |
3207 | } | 3249 | } |
diff --git a/net/packet/internal.h b/net/packet/internal.h index 44945f6b7252..e84cab8cb7a9 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h | |||
@@ -109,6 +109,7 @@ struct packet_sock { | |||
109 | unsigned int tp_hdrlen; | 109 | unsigned int tp_hdrlen; |
110 | unsigned int tp_reserve; | 110 | unsigned int tp_reserve; |
111 | unsigned int tp_loss:1; | 111 | unsigned int tp_loss:1; |
112 | unsigned int tp_tx_has_off:1; | ||
112 | unsigned int tp_tstamp; | 113 | unsigned int tp_tstamp; |
113 | struct packet_type prot_hook ____cacheline_aligned_in_smp; | 114 | struct packet_type prot_hook ____cacheline_aligned_in_smp; |
114 | }; | 115 | }; |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 2ecde225ae60..709b0fb38a18 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
18 | #include <linux/cgroup.h> | 18 | #include <linux/cgroup.h> |
19 | #include <linux/rcupdate.h> | 19 | #include <linux/rcupdate.h> |
20 | #include <linux/fdtable.h> | ||
20 | #include <net/rtnetlink.h> | 21 | #include <net/rtnetlink.h> |
21 | #include <net/pkt_cls.h> | 22 | #include <net/pkt_cls.h> |
22 | #include <net/sock.h> | 23 | #include <net/sock.h> |
@@ -53,6 +54,28 @@ static void cgrp_destroy(struct cgroup *cgrp) | |||
53 | kfree(cgrp_cls_state(cgrp)); | 54 | kfree(cgrp_cls_state(cgrp)); |
54 | } | 55 | } |
55 | 56 | ||
57 | static int update_classid(const void *v, struct file *file, unsigned n) | ||
58 | { | ||
59 | int err; | ||
60 | struct socket *sock = sock_from_file(file, &err); | ||
61 | if (sock) | ||
62 | sock->sk->sk_classid = (u32)(unsigned long)v; | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static void cgrp_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | ||
67 | { | ||
68 | struct task_struct *p; | ||
69 | void *v; | ||
70 | |||
71 | cgroup_taskset_for_each(p, cgrp, tset) { | ||
72 | task_lock(p); | ||
73 | v = (void *)(unsigned long)task_cls_classid(p); | ||
74 | iterate_fd(p->files, 0, update_classid, v); | ||
75 | task_unlock(p); | ||
76 | } | ||
77 | } | ||
78 | |||
56 | static u64 read_classid(struct cgroup *cgrp, struct cftype *cft) | 79 | static u64 read_classid(struct cgroup *cgrp, struct cftype *cft) |
57 | { | 80 | { |
58 | return cgrp_cls_state(cgrp)->classid; | 81 | return cgrp_cls_state(cgrp)->classid; |
@@ -77,6 +100,7 @@ struct cgroup_subsys net_cls_subsys = { | |||
77 | .name = "net_cls", | 100 | .name = "net_cls", |
78 | .create = cgrp_create, | 101 | .create = cgrp_create, |
79 | .destroy = cgrp_destroy, | 102 | .destroy = cgrp_destroy, |
103 | .attach = cgrp_attach, | ||
80 | .subsys_id = net_cls_subsys_id, | 104 | .subsys_id = net_cls_subsys_id, |
81 | .base_cftypes = ss_files, | 105 | .base_cftypes = ss_files, |
82 | .module = THIS_MODULE, | 106 | .module = THIS_MODULE, |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index a18d975db59c..13cc744a2498 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -495,16 +495,15 @@ EXPORT_SYMBOL(qdisc_watchdog_init); | |||
495 | 495 | ||
496 | void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires) | 496 | void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires) |
497 | { | 497 | { |
498 | ktime_t time; | ||
499 | |||
500 | if (test_bit(__QDISC_STATE_DEACTIVATED, | 498 | if (test_bit(__QDISC_STATE_DEACTIVATED, |
501 | &qdisc_root_sleeping(wd->qdisc)->state)) | 499 | &qdisc_root_sleeping(wd->qdisc)->state)) |
502 | return; | 500 | return; |
503 | 501 | ||
504 | qdisc_throttled(wd->qdisc); | 502 | qdisc_throttled(wd->qdisc); |
505 | time = ktime_set(0, 0); | 503 | |
506 | time = ktime_add_ns(time, PSCHED_TICKS2NS(expires)); | 504 | hrtimer_start(&wd->timer, |
507 | hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS); | 505 | ns_to_ktime(PSCHED_TICKS2NS(expires)), |
506 | HRTIMER_MODE_ABS); | ||
508 | } | 507 | } |
509 | EXPORT_SYMBOL(qdisc_watchdog_schedule); | 508 | EXPORT_SYMBOL(qdisc_watchdog_schedule); |
510 | 509 | ||
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 564b9fc8efd3..0e19948470b8 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -509,8 +509,7 @@ static void cbq_ovl_delay(struct cbq_class *cl) | |||
509 | cl->cpriority = TC_CBQ_MAXPRIO; | 509 | cl->cpriority = TC_CBQ_MAXPRIO; |
510 | q->pmask |= (1<<TC_CBQ_MAXPRIO); | 510 | q->pmask |= (1<<TC_CBQ_MAXPRIO); |
511 | 511 | ||
512 | expires = ktime_set(0, 0); | 512 | expires = ns_to_ktime(PSCHED_TICKS2NS(sched)); |
513 | expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched)); | ||
514 | if (hrtimer_try_to_cancel(&q->delay_timer) && | 513 | if (hrtimer_try_to_cancel(&q->delay_timer) && |
515 | ktime_to_ns(ktime_sub( | 514 | ktime_to_ns(ktime_sub( |
516 | hrtimer_get_expires(&q->delay_timer), | 515 | hrtimer_get_expires(&q->delay_timer), |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 9d75b7761313..d2922c0ef57a 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -71,6 +71,12 @@ enum htb_cmode { | |||
71 | HTB_CAN_SEND /* class can send */ | 71 | HTB_CAN_SEND /* class can send */ |
72 | }; | 72 | }; |
73 | 73 | ||
74 | struct htb_rate_cfg { | ||
75 | u64 rate_bps; | ||
76 | u32 mult; | ||
77 | u32 shift; | ||
78 | }; | ||
79 | |||
74 | /* interior & leaf nodes; props specific to leaves are marked L: */ | 80 | /* interior & leaf nodes; props specific to leaves are marked L: */ |
75 | struct htb_class { | 81 | struct htb_class { |
76 | struct Qdisc_class_common common; | 82 | struct Qdisc_class_common common; |
@@ -118,11 +124,11 @@ struct htb_class { | |||
118 | int filter_cnt; | 124 | int filter_cnt; |
119 | 125 | ||
120 | /* token bucket parameters */ | 126 | /* token bucket parameters */ |
121 | struct qdisc_rate_table *rate; /* rate table of the class itself */ | 127 | struct htb_rate_cfg rate; |
122 | struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ | 128 | struct htb_rate_cfg ceil; |
123 | long buffer, cbuffer; /* token bucket depth/rate */ | 129 | s64 buffer, cbuffer; /* token bucket depth/rate */ |
124 | psched_tdiff_t mbuffer; /* max wait time */ | 130 | psched_tdiff_t mbuffer; /* max wait time */ |
125 | long tokens, ctokens; /* current number of tokens */ | 131 | s64 tokens, ctokens; /* current number of tokens */ |
126 | psched_time_t t_c; /* checkpoint time */ | 132 | psched_time_t t_c; /* checkpoint time */ |
127 | }; | 133 | }; |
128 | 134 | ||
@@ -162,6 +168,45 @@ struct htb_sched { | |||
162 | struct work_struct work; | 168 | struct work_struct work; |
163 | }; | 169 | }; |
164 | 170 | ||
171 | static u64 l2t_ns(struct htb_rate_cfg *r, unsigned int len) | ||
172 | { | ||
173 | return ((u64)len * r->mult) >> r->shift; | ||
174 | } | ||
175 | |||
176 | static void htb_precompute_ratedata(struct htb_rate_cfg *r) | ||
177 | { | ||
178 | u64 factor; | ||
179 | u64 mult; | ||
180 | int shift; | ||
181 | |||
182 | r->shift = 0; | ||
183 | r->mult = 1; | ||
184 | /* | ||
185 | * Calibrate mult, shift so that token counting is accurate | ||
186 | * for smallest packet size (64 bytes). Token (time in ns) is | ||
187 | * computed as (bytes * 8) * NSEC_PER_SEC / rate_bps. It will | ||
188 | * work as long as the smallest packet transfer time can be | ||
189 | * accurately represented in nanosec. | ||
190 | */ | ||
191 | if (r->rate_bps > 0) { | ||
192 | /* | ||
193 | * Higher shift gives better accuracy. Find the largest | ||
194 | * shift such that mult fits in 32 bits. | ||
195 | */ | ||
196 | for (shift = 0; shift < 16; shift++) { | ||
197 | r->shift = shift; | ||
198 | factor = 8LLU * NSEC_PER_SEC * (1 << r->shift); | ||
199 | mult = div64_u64(factor, r->rate_bps); | ||
200 | if (mult > UINT_MAX) | ||
201 | break; | ||
202 | } | ||
203 | |||
204 | r->shift = shift - 1; | ||
205 | factor = 8LLU * NSEC_PER_SEC * (1 << r->shift); | ||
206 | r->mult = div64_u64(factor, r->rate_bps); | ||
207 | } | ||
208 | } | ||
209 | |||
165 | /* find class in global hash table using given handle */ | 210 | /* find class in global hash table using given handle */ |
166 | static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) | 211 | static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) |
167 | { | 212 | { |
@@ -273,7 +318,7 @@ static void htb_add_to_id_tree(struct rb_root *root, | |||
273 | * already in the queue. | 318 | * already in the queue. |
274 | */ | 319 | */ |
275 | static void htb_add_to_wait_tree(struct htb_sched *q, | 320 | static void htb_add_to_wait_tree(struct htb_sched *q, |
276 | struct htb_class *cl, long delay) | 321 | struct htb_class *cl, s64 delay) |
277 | { | 322 | { |
278 | struct rb_node **p = &q->wait_pq[cl->level].rb_node, *parent = NULL; | 323 | struct rb_node **p = &q->wait_pq[cl->level].rb_node, *parent = NULL; |
279 | 324 | ||
@@ -441,14 +486,14 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl) | |||
441 | htb_remove_class_from_row(q, cl, mask); | 486 | htb_remove_class_from_row(q, cl, mask); |
442 | } | 487 | } |
443 | 488 | ||
444 | static inline long htb_lowater(const struct htb_class *cl) | 489 | static inline s64 htb_lowater(const struct htb_class *cl) |
445 | { | 490 | { |
446 | if (htb_hysteresis) | 491 | if (htb_hysteresis) |
447 | return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0; | 492 | return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0; |
448 | else | 493 | else |
449 | return 0; | 494 | return 0; |
450 | } | 495 | } |
451 | static inline long htb_hiwater(const struct htb_class *cl) | 496 | static inline s64 htb_hiwater(const struct htb_class *cl) |
452 | { | 497 | { |
453 | if (htb_hysteresis) | 498 | if (htb_hysteresis) |
454 | return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0; | 499 | return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0; |
@@ -469,9 +514,9 @@ static inline long htb_hiwater(const struct htb_class *cl) | |||
469 | * mode transitions per time unit. The speed gain is about 1/6. | 514 | * mode transitions per time unit. The speed gain is about 1/6. |
470 | */ | 515 | */ |
471 | static inline enum htb_cmode | 516 | static inline enum htb_cmode |
472 | htb_class_mode(struct htb_class *cl, long *diff) | 517 | htb_class_mode(struct htb_class *cl, s64 *diff) |
473 | { | 518 | { |
474 | long toks; | 519 | s64 toks; |
475 | 520 | ||
476 | if ((toks = (cl->ctokens + *diff)) < htb_lowater(cl)) { | 521 | if ((toks = (cl->ctokens + *diff)) < htb_lowater(cl)) { |
477 | *diff = -toks; | 522 | *diff = -toks; |
@@ -495,7 +540,7 @@ htb_class_mode(struct htb_class *cl, long *diff) | |||
495 | * to mode other than HTB_CAN_SEND (see htb_add_to_wait_tree). | 540 | * to mode other than HTB_CAN_SEND (see htb_add_to_wait_tree). |
496 | */ | 541 | */ |
497 | static void | 542 | static void |
498 | htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, long *diff) | 543 | htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, s64 *diff) |
499 | { | 544 | { |
500 | enum htb_cmode new_mode = htb_class_mode(cl, diff); | 545 | enum htb_cmode new_mode = htb_class_mode(cl, diff); |
501 | 546 | ||
@@ -581,26 +626,26 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
581 | return NET_XMIT_SUCCESS; | 626 | return NET_XMIT_SUCCESS; |
582 | } | 627 | } |
583 | 628 | ||
584 | static inline void htb_accnt_tokens(struct htb_class *cl, int bytes, long diff) | 629 | static inline void htb_accnt_tokens(struct htb_class *cl, int bytes, s64 diff) |
585 | { | 630 | { |
586 | long toks = diff + cl->tokens; | 631 | s64 toks = diff + cl->tokens; |
587 | 632 | ||
588 | if (toks > cl->buffer) | 633 | if (toks > cl->buffer) |
589 | toks = cl->buffer; | 634 | toks = cl->buffer; |
590 | toks -= (long) qdisc_l2t(cl->rate, bytes); | 635 | toks -= (s64) l2t_ns(&cl->rate, bytes); |
591 | if (toks <= -cl->mbuffer) | 636 | if (toks <= -cl->mbuffer) |
592 | toks = 1 - cl->mbuffer; | 637 | toks = 1 - cl->mbuffer; |
593 | 638 | ||
594 | cl->tokens = toks; | 639 | cl->tokens = toks; |
595 | } | 640 | } |
596 | 641 | ||
597 | static inline void htb_accnt_ctokens(struct htb_class *cl, int bytes, long diff) | 642 | static inline void htb_accnt_ctokens(struct htb_class *cl, int bytes, s64 diff) |
598 | { | 643 | { |
599 | long toks = diff + cl->ctokens; | 644 | s64 toks = diff + cl->ctokens; |
600 | 645 | ||
601 | if (toks > cl->cbuffer) | 646 | if (toks > cl->cbuffer) |
602 | toks = cl->cbuffer; | 647 | toks = cl->cbuffer; |
603 | toks -= (long) qdisc_l2t(cl->ceil, bytes); | 648 | toks -= (s64) l2t_ns(&cl->ceil, bytes); |
604 | if (toks <= -cl->mbuffer) | 649 | if (toks <= -cl->mbuffer) |
605 | toks = 1 - cl->mbuffer; | 650 | toks = 1 - cl->mbuffer; |
606 | 651 | ||
@@ -623,10 +668,10 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, | |||
623 | { | 668 | { |
624 | int bytes = qdisc_pkt_len(skb); | 669 | int bytes = qdisc_pkt_len(skb); |
625 | enum htb_cmode old_mode; | 670 | enum htb_cmode old_mode; |
626 | long diff; | 671 | s64 diff; |
627 | 672 | ||
628 | while (cl) { | 673 | while (cl) { |
629 | diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer); | 674 | diff = min_t(s64, q->now - cl->t_c, cl->mbuffer); |
630 | if (cl->level >= level) { | 675 | if (cl->level >= level) { |
631 | if (cl->level == level) | 676 | if (cl->level == level) |
632 | cl->xstats.lends++; | 677 | cl->xstats.lends++; |
@@ -673,7 +718,7 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level, | |||
673 | unsigned long stop_at = start + 2; | 718 | unsigned long stop_at = start + 2; |
674 | while (time_before(jiffies, stop_at)) { | 719 | while (time_before(jiffies, stop_at)) { |
675 | struct htb_class *cl; | 720 | struct htb_class *cl; |
676 | long diff; | 721 | s64 diff; |
677 | struct rb_node *p = rb_first(&q->wait_pq[level]); | 722 | struct rb_node *p = rb_first(&q->wait_pq[level]); |
678 | 723 | ||
679 | if (!p) | 724 | if (!p) |
@@ -684,7 +729,7 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level, | |||
684 | return cl->pq_key; | 729 | return cl->pq_key; |
685 | 730 | ||
686 | htb_safe_rb_erase(p, q->wait_pq + level); | 731 | htb_safe_rb_erase(p, q->wait_pq + level); |
687 | diff = psched_tdiff_bounded(q->now, cl->t_c, cl->mbuffer); | 732 | diff = min_t(s64, q->now - cl->t_c, cl->mbuffer); |
688 | htb_change_class_mode(q, cl, &diff); | 733 | htb_change_class_mode(q, cl, &diff); |
689 | if (cl->cmode != HTB_CAN_SEND) | 734 | if (cl->cmode != HTB_CAN_SEND) |
690 | htb_add_to_wait_tree(q, cl, diff); | 735 | htb_add_to_wait_tree(q, cl, diff); |
@@ -871,10 +916,10 @@ ok: | |||
871 | 916 | ||
872 | if (!sch->q.qlen) | 917 | if (!sch->q.qlen) |
873 | goto fin; | 918 | goto fin; |
874 | q->now = psched_get_time(); | 919 | q->now = ktime_to_ns(ktime_get()); |
875 | start_at = jiffies; | 920 | start_at = jiffies; |
876 | 921 | ||
877 | next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; | 922 | next_event = q->now + 5 * NSEC_PER_SEC; |
878 | 923 | ||
879 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { | 924 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { |
880 | /* common case optimization - skip event handler quickly */ | 925 | /* common case optimization - skip event handler quickly */ |
@@ -884,7 +929,7 @@ ok: | |||
884 | if (q->now >= q->near_ev_cache[level]) { | 929 | if (q->now >= q->near_ev_cache[level]) { |
885 | event = htb_do_events(q, level, start_at); | 930 | event = htb_do_events(q, level, start_at); |
886 | if (!event) | 931 | if (!event) |
887 | event = q->now + PSCHED_TICKS_PER_SEC; | 932 | event = q->now + NSEC_PER_SEC; |
888 | q->near_ev_cache[level] = event; | 933 | q->near_ev_cache[level] = event; |
889 | } else | 934 | } else |
890 | event = q->near_ev_cache[level]; | 935 | event = q->near_ev_cache[level]; |
@@ -903,10 +948,17 @@ ok: | |||
903 | } | 948 | } |
904 | } | 949 | } |
905 | sch->qstats.overlimits++; | 950 | sch->qstats.overlimits++; |
906 | if (likely(next_event > q->now)) | 951 | if (likely(next_event > q->now)) { |
907 | qdisc_watchdog_schedule(&q->watchdog, next_event); | 952 | if (!test_bit(__QDISC_STATE_DEACTIVATED, |
908 | else | 953 | &qdisc_root_sleeping(q->watchdog.qdisc)->state)) { |
954 | ktime_t time = ns_to_ktime(next_event); | ||
955 | qdisc_throttled(q->watchdog.qdisc); | ||
956 | hrtimer_start(&q->watchdog.timer, time, | ||
957 | HRTIMER_MODE_ABS); | ||
958 | } | ||
959 | } else { | ||
909 | schedule_work(&q->work); | 960 | schedule_work(&q->work); |
961 | } | ||
910 | fin: | 962 | fin: |
911 | return skb; | 963 | return skb; |
912 | } | 964 | } |
@@ -1082,9 +1134,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, | |||
1082 | 1134 | ||
1083 | memset(&opt, 0, sizeof(opt)); | 1135 | memset(&opt, 0, sizeof(opt)); |
1084 | 1136 | ||
1085 | opt.rate = cl->rate->rate; | 1137 | opt.rate.rate = cl->rate.rate_bps >> 3; |
1086 | opt.buffer = cl->buffer; | 1138 | opt.buffer = cl->buffer; |
1087 | opt.ceil = cl->ceil->rate; | 1139 | opt.ceil.rate = cl->ceil.rate_bps >> 3; |
1088 | opt.cbuffer = cl->cbuffer; | 1140 | opt.cbuffer = cl->cbuffer; |
1089 | opt.quantum = cl->quantum; | 1141 | opt.quantum = cl->quantum; |
1090 | opt.prio = cl->prio; | 1142 | opt.prio = cl->prio; |
@@ -1203,9 +1255,6 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) | |||
1203 | qdisc_destroy(cl->un.leaf.q); | 1255 | qdisc_destroy(cl->un.leaf.q); |
1204 | } | 1256 | } |
1205 | gen_kill_estimator(&cl->bstats, &cl->rate_est); | 1257 | gen_kill_estimator(&cl->bstats, &cl->rate_est); |
1206 | qdisc_put_rtab(cl->rate); | ||
1207 | qdisc_put_rtab(cl->ceil); | ||
1208 | |||
1209 | tcf_destroy_chain(&cl->filter_list); | 1258 | tcf_destroy_chain(&cl->filter_list); |
1210 | kfree(cl); | 1259 | kfree(cl); |
1211 | } | 1260 | } |
@@ -1307,7 +1356,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1307 | struct htb_sched *q = qdisc_priv(sch); | 1356 | struct htb_sched *q = qdisc_priv(sch); |
1308 | struct htb_class *cl = (struct htb_class *)*arg, *parent; | 1357 | struct htb_class *cl = (struct htb_class *)*arg, *parent; |
1309 | struct nlattr *opt = tca[TCA_OPTIONS]; | 1358 | struct nlattr *opt = tca[TCA_OPTIONS]; |
1310 | struct qdisc_rate_table *rtab = NULL, *ctab = NULL; | ||
1311 | struct nlattr *tb[__TCA_HTB_MAX]; | 1359 | struct nlattr *tb[__TCA_HTB_MAX]; |
1312 | struct tc_htb_opt *hopt; | 1360 | struct tc_htb_opt *hopt; |
1313 | 1361 | ||
@@ -1326,10 +1374,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1326 | parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch); | 1374 | parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch); |
1327 | 1375 | ||
1328 | hopt = nla_data(tb[TCA_HTB_PARMS]); | 1376 | hopt = nla_data(tb[TCA_HTB_PARMS]); |
1329 | 1377 | if (!hopt->rate.rate || !hopt->ceil.rate) | |
1330 | rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]); | ||
1331 | ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]); | ||
1332 | if (!rtab || !ctab) | ||
1333 | goto failure; | 1378 | goto failure; |
1334 | 1379 | ||
1335 | if (!cl) { /* new class */ | 1380 | if (!cl) { /* new class */ |
@@ -1439,7 +1484,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1439 | * is really leaf before changing cl->un.leaf ! | 1484 | * is really leaf before changing cl->un.leaf ! |
1440 | */ | 1485 | */ |
1441 | if (!cl->level) { | 1486 | if (!cl->level) { |
1442 | cl->quantum = rtab->rate.rate / q->rate2quantum; | 1487 | cl->quantum = hopt->rate.rate / q->rate2quantum; |
1443 | if (!hopt->quantum && cl->quantum < 1000) { | 1488 | if (!hopt->quantum && cl->quantum < 1000) { |
1444 | pr_warning( | 1489 | pr_warning( |
1445 | "HTB: quantum of class %X is small. Consider r2q change.\n", | 1490 | "HTB: quantum of class %X is small. Consider r2q change.\n", |
@@ -1460,12 +1505,16 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1460 | 1505 | ||
1461 | cl->buffer = hopt->buffer; | 1506 | cl->buffer = hopt->buffer; |
1462 | cl->cbuffer = hopt->cbuffer; | 1507 | cl->cbuffer = hopt->cbuffer; |
1463 | if (cl->rate) | 1508 | |
1464 | qdisc_put_rtab(cl->rate); | 1509 | cl->rate.rate_bps = (u64)hopt->rate.rate << 3; |
1465 | cl->rate = rtab; | 1510 | cl->ceil.rate_bps = (u64)hopt->ceil.rate << 3; |
1466 | if (cl->ceil) | 1511 | |
1467 | qdisc_put_rtab(cl->ceil); | 1512 | htb_precompute_ratedata(&cl->rate); |
1468 | cl->ceil = ctab; | 1513 | htb_precompute_ratedata(&cl->ceil); |
1514 | |||
1515 | cl->buffer = hopt->buffer << PSCHED_SHIFT; | ||
1516 | cl->cbuffer = hopt->buffer << PSCHED_SHIFT; | ||
1517 | |||
1469 | sch_tree_unlock(sch); | 1518 | sch_tree_unlock(sch); |
1470 | 1519 | ||
1471 | qdisc_class_hash_grow(sch, &q->clhash); | 1520 | qdisc_class_hash_grow(sch, &q->clhash); |
@@ -1474,10 +1523,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1474 | return 0; | 1523 | return 0; |
1475 | 1524 | ||
1476 | failure: | 1525 | failure: |
1477 | if (rtab) | ||
1478 | qdisc_put_rtab(rtab); | ||
1479 | if (ctab) | ||
1480 | qdisc_put_rtab(ctab); | ||
1481 | return err; | 1526 | return err; |
1482 | } | 1527 | } |
1483 | 1528 | ||
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 126b014eb79b..a9edd2e205f4 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig | |||
@@ -9,7 +9,6 @@ menuconfig IP_SCTP | |||
9 | select CRYPTO | 9 | select CRYPTO |
10 | select CRYPTO_HMAC | 10 | select CRYPTO_HMAC |
11 | select CRYPTO_SHA1 | 11 | select CRYPTO_SHA1 |
12 | select CRYPTO_MD5 if SCTP_HMAC_MD5 | ||
13 | select LIBCRC32C | 12 | select LIBCRC32C |
14 | ---help--- | 13 | ---help--- |
15 | Stream Control Transmission Protocol | 14 | Stream Control Transmission Protocol |
@@ -68,33 +67,21 @@ config SCTP_DBG_OBJCNT | |||
68 | 67 | ||
69 | If unsure, say N | 68 | If unsure, say N |
70 | 69 | ||
71 | choice | 70 | config SCTP_COOKIE_HMAC_MD5 |
72 | prompt "SCTP: Cookie HMAC Algorithm" | 71 | bool "Enable optional MD5 hmac cookie generation" |
73 | default SCTP_HMAC_MD5 | ||
74 | help | 72 | help |
75 | HMAC algorithm to be used during association initialization. It | 73 | Enable optional MD5 hmac based SCTP cookie generation |
76 | is strongly recommended to use HMAC-SHA1 or HMAC-MD5. See | 74 | default y |
77 | configuration for Cryptographic API and enable those algorithms | 75 | select CRYPTO_HMAC if SCTP_COOKIE_HMAC_MD5 |
78 | to make usable by SCTP. | 76 | select CRYPTO_MD5 if SCTP_COOKIE_HMAC_MD5 |
79 | 77 | ||
80 | config SCTP_HMAC_NONE | 78 | config SCTP_COOKIE_HMAC_SHA1 |
81 | bool "None" | 79 | bool "Enable optional SHA1 hmac cookie generation" |
82 | help | ||
83 | Choosing this disables the use of an HMAC during association | ||
84 | establishment. It is advised to use either HMAC-MD5 or HMAC-SHA1. | ||
85 | |||
86 | config SCTP_HMAC_SHA1 | ||
87 | bool "HMAC-SHA1" | ||
88 | help | ||
89 | Enable the use of HMAC-SHA1 during association establishment. It | ||
90 | is advised to use either HMAC-MD5 or HMAC-SHA1. | ||
91 | |||
92 | config SCTP_HMAC_MD5 | ||
93 | bool "HMAC-MD5" | ||
94 | help | 80 | help |
95 | Enable the use of HMAC-MD5 during association establishment. It is | 81 | Enable optional SHA1 hmac based SCTP cookie generation |
96 | advised to use either HMAC-MD5 or HMAC-SHA1. | 82 | default y |
83 | select CRYPTO_HMAC if SCTP_COOKIE_HMAC_SHA1 | ||
84 | select CRYPTO_SHA1 if SCTP_COOKIE_HMAC_SHA1 | ||
97 | 85 | ||
98 | endchoice | ||
99 | 86 | ||
100 | endif # IP_SCTP | 87 | endif # IP_SCTP |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2d518425d598..456bc3dbdd51 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1190,6 +1190,15 @@ static int sctp_net_init(struct net *net) | |||
1190 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | 1190 | /* Whether Cookie Preservative is enabled(1) or not(0) */ |
1191 | net->sctp.cookie_preserve_enable = 1; | 1191 | net->sctp.cookie_preserve_enable = 1; |
1192 | 1192 | ||
1193 | /* Default sctp sockets to use md5 as their hmac alg */ | ||
1194 | #if defined (CONFIG_CRYPTO_MD5) | ||
1195 | net->sctp.sctp_hmac_alg = "md5"; | ||
1196 | #elif defined (CONFIG_CRYPTO_SHA1) | ||
1197 | net->sctp.sctp_hmac_alg = "sha1"; | ||
1198 | #else | ||
1199 | net->sctp.sctp_hmac_alg = NULL; | ||
1200 | #endif | ||
1201 | |||
1193 | /* Max.Burst - 4 */ | 1202 | /* Max.Burst - 4 */ |
1194 | net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST; | 1203 | net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST; |
1195 | 1204 | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 6773d7803627..6eecf7e6338d 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1268,14 +1268,14 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1268 | sctp_outq_uncork(&asoc->outqueue); | 1268 | sctp_outq_uncork(&asoc->outqueue); |
1269 | local_cork = 0; | 1269 | local_cork = 0; |
1270 | } | 1270 | } |
1271 | asoc = cmd->obj.ptr; | 1271 | asoc = cmd->obj.asoc; |
1272 | /* Register with the endpoint. */ | 1272 | /* Register with the endpoint. */ |
1273 | sctp_endpoint_add_asoc(ep, asoc); | 1273 | sctp_endpoint_add_asoc(ep, asoc); |
1274 | sctp_hash_established(asoc); | 1274 | sctp_hash_established(asoc); |
1275 | break; | 1275 | break; |
1276 | 1276 | ||
1277 | case SCTP_CMD_UPDATE_ASSOC: | 1277 | case SCTP_CMD_UPDATE_ASSOC: |
1278 | sctp_assoc_update(asoc, cmd->obj.ptr); | 1278 | sctp_assoc_update(asoc, cmd->obj.asoc); |
1279 | break; | 1279 | break; |
1280 | 1280 | ||
1281 | case SCTP_CMD_PURGE_OUTQUEUE: | 1281 | case SCTP_CMD_PURGE_OUTQUEUE: |
@@ -1315,7 +1315,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1315 | break; | 1315 | break; |
1316 | 1316 | ||
1317 | case SCTP_CMD_PROCESS_FWDTSN: | 1317 | case SCTP_CMD_PROCESS_FWDTSN: |
1318 | sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.ptr); | 1318 | sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.chunk); |
1319 | break; | 1319 | break; |
1320 | 1320 | ||
1321 | case SCTP_CMD_GEN_SACK: | 1321 | case SCTP_CMD_GEN_SACK: |
@@ -1331,7 +1331,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1331 | case SCTP_CMD_PROCESS_SACK: | 1331 | case SCTP_CMD_PROCESS_SACK: |
1332 | /* Process an inbound SACK. */ | 1332 | /* Process an inbound SACK. */ |
1333 | error = sctp_cmd_process_sack(commands, asoc, | 1333 | error = sctp_cmd_process_sack(commands, asoc, |
1334 | cmd->obj.ptr); | 1334 | cmd->obj.chunk); |
1335 | break; | 1335 | break; |
1336 | 1336 | ||
1337 | case SCTP_CMD_GEN_INIT_ACK: | 1337 | case SCTP_CMD_GEN_INIT_ACK: |
@@ -1352,15 +1352,15 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1352 | * layer which will bail. | 1352 | * layer which will bail. |
1353 | */ | 1353 | */ |
1354 | error = sctp_cmd_process_init(commands, asoc, chunk, | 1354 | error = sctp_cmd_process_init(commands, asoc, chunk, |
1355 | cmd->obj.ptr, gfp); | 1355 | cmd->obj.init, gfp); |
1356 | break; | 1356 | break; |
1357 | 1357 | ||
1358 | case SCTP_CMD_GEN_COOKIE_ECHO: | 1358 | case SCTP_CMD_GEN_COOKIE_ECHO: |
1359 | /* Generate a COOKIE ECHO chunk. */ | 1359 | /* Generate a COOKIE ECHO chunk. */ |
1360 | new_obj = sctp_make_cookie_echo(asoc, chunk); | 1360 | new_obj = sctp_make_cookie_echo(asoc, chunk); |
1361 | if (!new_obj) { | 1361 | if (!new_obj) { |
1362 | if (cmd->obj.ptr) | 1362 | if (cmd->obj.chunk) |
1363 | sctp_chunk_free(cmd->obj.ptr); | 1363 | sctp_chunk_free(cmd->obj.chunk); |
1364 | goto nomem; | 1364 | goto nomem; |
1365 | } | 1365 | } |
1366 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1366 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
@@ -1369,9 +1369,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1369 | /* If there is an ERROR chunk to be sent along with | 1369 | /* If there is an ERROR chunk to be sent along with |
1370 | * the COOKIE_ECHO, send it, too. | 1370 | * the COOKIE_ECHO, send it, too. |
1371 | */ | 1371 | */ |
1372 | if (cmd->obj.ptr) | 1372 | if (cmd->obj.chunk) |
1373 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1373 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
1374 | SCTP_CHUNK(cmd->obj.ptr)); | 1374 | SCTP_CHUNK(cmd->obj.chunk)); |
1375 | 1375 | ||
1376 | if (new_obj->transport) { | 1376 | if (new_obj->transport) { |
1377 | new_obj->transport->init_sent_count++; | 1377 | new_obj->transport->init_sent_count++; |
@@ -1417,18 +1417,18 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1417 | case SCTP_CMD_CHUNK_ULP: | 1417 | case SCTP_CMD_CHUNK_ULP: |
1418 | /* Send a chunk to the sockets layer. */ | 1418 | /* Send a chunk to the sockets layer. */ |
1419 | SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", | 1419 | SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", |
1420 | "chunk_up:", cmd->obj.ptr, | 1420 | "chunk_up:", cmd->obj.chunk, |
1421 | "ulpq:", &asoc->ulpq); | 1421 | "ulpq:", &asoc->ulpq); |
1422 | sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.ptr, | 1422 | sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.chunk, |
1423 | GFP_ATOMIC); | 1423 | GFP_ATOMIC); |
1424 | break; | 1424 | break; |
1425 | 1425 | ||
1426 | case SCTP_CMD_EVENT_ULP: | 1426 | case SCTP_CMD_EVENT_ULP: |
1427 | /* Send a notification to the sockets layer. */ | 1427 | /* Send a notification to the sockets layer. */ |
1428 | SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", | 1428 | SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n", |
1429 | "event_up:",cmd->obj.ptr, | 1429 | "event_up:",cmd->obj.ulpevent, |
1430 | "ulpq:",&asoc->ulpq); | 1430 | "ulpq:",&asoc->ulpq); |
1431 | sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ptr); | 1431 | sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ulpevent); |
1432 | break; | 1432 | break; |
1433 | 1433 | ||
1434 | case SCTP_CMD_REPLY: | 1434 | case SCTP_CMD_REPLY: |
@@ -1438,12 +1438,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1438 | local_cork = 1; | 1438 | local_cork = 1; |
1439 | } | 1439 | } |
1440 | /* Send a chunk to our peer. */ | 1440 | /* Send a chunk to our peer. */ |
1441 | error = sctp_outq_tail(&asoc->outqueue, cmd->obj.ptr); | 1441 | error = sctp_outq_tail(&asoc->outqueue, cmd->obj.chunk); |
1442 | break; | 1442 | break; |
1443 | 1443 | ||
1444 | case SCTP_CMD_SEND_PKT: | 1444 | case SCTP_CMD_SEND_PKT: |
1445 | /* Send a full packet to our peer. */ | 1445 | /* Send a full packet to our peer. */ |
1446 | packet = cmd->obj.ptr; | 1446 | packet = cmd->obj.packet; |
1447 | sctp_packet_transmit(packet); | 1447 | sctp_packet_transmit(packet); |
1448 | sctp_ootb_pkt_free(packet); | 1448 | sctp_ootb_pkt_free(packet); |
1449 | break; | 1449 | break; |
@@ -1480,7 +1480,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1480 | break; | 1480 | break; |
1481 | 1481 | ||
1482 | case SCTP_CMD_SETUP_T2: | 1482 | case SCTP_CMD_SETUP_T2: |
1483 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); | 1483 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.chunk); |
1484 | break; | 1484 | break; |
1485 | 1485 | ||
1486 | case SCTP_CMD_TIMER_START_ONCE: | 1486 | case SCTP_CMD_TIMER_START_ONCE: |
@@ -1514,7 +1514,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1514 | break; | 1514 | break; |
1515 | 1515 | ||
1516 | case SCTP_CMD_INIT_CHOOSE_TRANSPORT: | 1516 | case SCTP_CMD_INIT_CHOOSE_TRANSPORT: |
1517 | chunk = cmd->obj.ptr; | 1517 | chunk = cmd->obj.chunk; |
1518 | t = sctp_assoc_choose_alter_transport(asoc, | 1518 | t = sctp_assoc_choose_alter_transport(asoc, |
1519 | asoc->init_last_sent_to); | 1519 | asoc->init_last_sent_to); |
1520 | asoc->init_last_sent_to = t; | 1520 | asoc->init_last_sent_to = t; |
@@ -1665,17 +1665,16 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1665 | break; | 1665 | break; |
1666 | 1666 | ||
1667 | case SCTP_CMD_PART_DELIVER: | 1667 | case SCTP_CMD_PART_DELIVER: |
1668 | sctp_ulpq_partial_delivery(&asoc->ulpq, cmd->obj.ptr, | 1668 | sctp_ulpq_partial_delivery(&asoc->ulpq, GFP_ATOMIC); |
1669 | GFP_ATOMIC); | ||
1670 | break; | 1669 | break; |
1671 | 1670 | ||
1672 | case SCTP_CMD_RENEGE: | 1671 | case SCTP_CMD_RENEGE: |
1673 | sctp_ulpq_renege(&asoc->ulpq, cmd->obj.ptr, | 1672 | sctp_ulpq_renege(&asoc->ulpq, cmd->obj.chunk, |
1674 | GFP_ATOMIC); | 1673 | GFP_ATOMIC); |
1675 | break; | 1674 | break; |
1676 | 1675 | ||
1677 | case SCTP_CMD_SETUP_T4: | 1676 | case SCTP_CMD_SETUP_T4: |
1678 | sctp_cmd_setup_t4(commands, asoc, cmd->obj.ptr); | 1677 | sctp_cmd_setup_t4(commands, asoc, cmd->obj.chunk); |
1679 | break; | 1678 | break; |
1680 | 1679 | ||
1681 | case SCTP_CMD_PROCESS_OPERR: | 1680 | case SCTP_CMD_PROCESS_OPERR: |
@@ -1734,8 +1733,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1734 | break; | 1733 | break; |
1735 | 1734 | ||
1736 | default: | 1735 | default: |
1737 | pr_warn("Impossible command: %u, %p\n", | 1736 | pr_warn("Impossible command: %u\n", |
1738 | cmd->verb, cmd->obj.ptr); | 1737 | cmd->verb); |
1739 | break; | 1738 | break; |
1740 | } | 1739 | } |
1741 | 1740 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a60d1f8b41c5..15379acd9c08 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -110,7 +110,6 @@ static int sctp_do_bind(struct sock *, union sctp_addr *, int); | |||
110 | static int sctp_autobind(struct sock *sk); | 110 | static int sctp_autobind(struct sock *sk); |
111 | static void sctp_sock_migrate(struct sock *, struct sock *, | 111 | static void sctp_sock_migrate(struct sock *, struct sock *, |
112 | struct sctp_association *, sctp_socket_type_t); | 112 | struct sctp_association *, sctp_socket_type_t); |
113 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; | ||
114 | 113 | ||
115 | extern struct kmem_cache *sctp_bucket_cachep; | 114 | extern struct kmem_cache *sctp_bucket_cachep; |
116 | extern long sysctl_sctp_mem[3]; | 115 | extern long sysctl_sctp_mem[3]; |
@@ -3890,6 +3889,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3890 | sp->default_rcv_context = 0; | 3889 | sp->default_rcv_context = 0; |
3891 | sp->max_burst = net->sctp.max_burst; | 3890 | sp->max_burst = net->sctp.max_burst; |
3892 | 3891 | ||
3892 | sp->sctp_hmac_alg = net->sctp.sctp_hmac_alg; | ||
3893 | |||
3893 | /* Initialize default setup parameters. These parameters | 3894 | /* Initialize default setup parameters. These parameters |
3894 | * can be modified with the SCTP_INITMSG socket option or | 3895 | * can be modified with the SCTP_INITMSG socket option or |
3895 | * overridden by the SCTP_INIT CMSG. | 3896 | * overridden by the SCTP_INIT CMSG. |
@@ -5981,13 +5982,15 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) | |||
5981 | struct sctp_sock *sp = sctp_sk(sk); | 5982 | struct sctp_sock *sp = sctp_sk(sk); |
5982 | struct sctp_endpoint *ep = sp->ep; | 5983 | struct sctp_endpoint *ep = sp->ep; |
5983 | struct crypto_hash *tfm = NULL; | 5984 | struct crypto_hash *tfm = NULL; |
5985 | char alg[32]; | ||
5984 | 5986 | ||
5985 | /* Allocate HMAC for generating cookie. */ | 5987 | /* Allocate HMAC for generating cookie. */ |
5986 | if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { | 5988 | if (!sp->hmac && sp->sctp_hmac_alg) { |
5987 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5989 | sprintf(alg, "hmac(%s)", sp->sctp_hmac_alg); |
5990 | tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC); | ||
5988 | if (IS_ERR(tfm)) { | 5991 | if (IS_ERR(tfm)) { |
5989 | net_info_ratelimited("failed to load transform for %s: %ld\n", | 5992 | net_info_ratelimited("failed to load transform for %s: %ld\n", |
5990 | sctp_hmac_alg, PTR_ERR(tfm)); | 5993 | sp->sctp_hmac_alg, PTR_ERR(tfm)); |
5991 | return -ENOSYS; | 5994 | return -ENOSYS; |
5992 | } | 5995 | } |
5993 | sctp_sk(sk)->hmac = tfm; | 5996 | sctp_sk(sk)->hmac = tfm; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 70e3ba5cb50b..043889ac86c0 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -62,6 +62,11 @@ extern long sysctl_sctp_mem[3]; | |||
62 | extern int sysctl_sctp_rmem[3]; | 62 | extern int sysctl_sctp_rmem[3]; |
63 | extern int sysctl_sctp_wmem[3]; | 63 | extern int sysctl_sctp_wmem[3]; |
64 | 64 | ||
65 | static int proc_sctp_do_hmac_alg(ctl_table *ctl, | ||
66 | int write, | ||
67 | void __user *buffer, size_t *lenp, | ||
68 | |||
69 | loff_t *ppos); | ||
65 | static ctl_table sctp_table[] = { | 70 | static ctl_table sctp_table[] = { |
66 | { | 71 | { |
67 | .procname = "sctp_mem", | 72 | .procname = "sctp_mem", |
@@ -147,6 +152,12 @@ static ctl_table sctp_net_table[] = { | |||
147 | .proc_handler = proc_dointvec, | 152 | .proc_handler = proc_dointvec, |
148 | }, | 153 | }, |
149 | { | 154 | { |
155 | .procname = "cookie_hmac_alg", | ||
156 | .maxlen = 8, | ||
157 | .mode = 0644, | ||
158 | .proc_handler = proc_sctp_do_hmac_alg, | ||
159 | }, | ||
160 | { | ||
150 | .procname = "valid_cookie_life", | 161 | .procname = "valid_cookie_life", |
151 | .data = &init_net.sctp.valid_cookie_life, | 162 | .data = &init_net.sctp.valid_cookie_life, |
152 | .maxlen = sizeof(unsigned int), | 163 | .maxlen = sizeof(unsigned int), |
@@ -289,6 +300,54 @@ static ctl_table sctp_net_table[] = { | |||
289 | { /* sentinel */ } | 300 | { /* sentinel */ } |
290 | }; | 301 | }; |
291 | 302 | ||
303 | static int proc_sctp_do_hmac_alg(ctl_table *ctl, | ||
304 | int write, | ||
305 | void __user *buffer, size_t *lenp, | ||
306 | loff_t *ppos) | ||
307 | { | ||
308 | struct net *net = current->nsproxy->net_ns; | ||
309 | char tmp[8]; | ||
310 | ctl_table tbl; | ||
311 | int ret; | ||
312 | int changed = 0; | ||
313 | char *none = "none"; | ||
314 | |||
315 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
316 | |||
317 | if (write) { | ||
318 | tbl.data = tmp; | ||
319 | tbl.maxlen = 8; | ||
320 | } else { | ||
321 | tbl.data = net->sctp.sctp_hmac_alg ? : none; | ||
322 | tbl.maxlen = strlen(tbl.data); | ||
323 | } | ||
324 | ret = proc_dostring(&tbl, write, buffer, lenp, ppos); | ||
325 | |||
326 | if (write) { | ||
327 | #ifdef CONFIG_CRYPTO_MD5 | ||
328 | if (!strncmp(tmp, "md5", 3)) { | ||
329 | net->sctp.sctp_hmac_alg = "md5"; | ||
330 | changed = 1; | ||
331 | } | ||
332 | #endif | ||
333 | #ifdef CONFIG_CRYPTO_SHA1 | ||
334 | if (!strncmp(tmp, "sha1", 4)) { | ||
335 | net->sctp.sctp_hmac_alg = "sha1"; | ||
336 | changed = 1; | ||
337 | } | ||
338 | #endif | ||
339 | if (!strncmp(tmp, "none", 4)) { | ||
340 | net->sctp.sctp_hmac_alg = NULL; | ||
341 | changed = 1; | ||
342 | } | ||
343 | |||
344 | if (!changed) | ||
345 | ret = -EINVAL; | ||
346 | } | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | |||
292 | int sctp_sysctl_net_register(struct net *net) | 351 | int sctp_sysctl_net_register(struct net *net) |
293 | { | 352 | { |
294 | struct ctl_table *table; | 353 | struct ctl_table *table; |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 360d8697b95c..ada17464b65b 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -997,7 +997,6 @@ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed) | |||
997 | 997 | ||
998 | /* Partial deliver the first message as there is pressure on rwnd. */ | 998 | /* Partial deliver the first message as there is pressure on rwnd. */ |
999 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, | 999 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, |
1000 | struct sctp_chunk *chunk, | ||
1001 | gfp_t gfp) | 1000 | gfp_t gfp) |
1002 | { | 1001 | { |
1003 | struct sctp_ulpevent *event; | 1002 | struct sctp_ulpevent *event; |
@@ -1060,7 +1059,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
1060 | sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); | 1059 | sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); |
1061 | sctp_ulpq_tail_data(ulpq, chunk, gfp); | 1060 | sctp_ulpq_tail_data(ulpq, chunk, gfp); |
1062 | 1061 | ||
1063 | sctp_ulpq_partial_delivery(ulpq, chunk, gfp); | 1062 | sctp_ulpq_partial_delivery(ulpq, gfp); |
1064 | } | 1063 | } |
1065 | 1064 | ||
1066 | sk_mem_reclaim(asoc->base.sk); | 1065 | sk_mem_reclaim(asoc->base.sk); |
diff --git a/net/socket.c b/net/socket.c index d92c490e66fa..2ca51c719ef9 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -620,8 +620,6 @@ static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, | |||
620 | { | 620 | { |
621 | struct sock_iocb *si = kiocb_to_siocb(iocb); | 621 | struct sock_iocb *si = kiocb_to_siocb(iocb); |
622 | 622 | ||
623 | sock_update_classid(sock->sk); | ||
624 | |||
625 | si->sock = sock; | 623 | si->sock = sock; |
626 | si->scm = NULL; | 624 | si->scm = NULL; |
627 | si->msg = msg; | 625 | si->msg = msg; |
@@ -784,8 +782,6 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | |||
784 | { | 782 | { |
785 | struct sock_iocb *si = kiocb_to_siocb(iocb); | 783 | struct sock_iocb *si = kiocb_to_siocb(iocb); |
786 | 784 | ||
787 | sock_update_classid(sock->sk); | ||
788 | |||
789 | si->sock = sock; | 785 | si->sock = sock; |
790 | si->scm = NULL; | 786 | si->scm = NULL; |
791 | si->msg = msg; | 787 | si->msg = msg; |
@@ -896,8 +892,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
896 | if (unlikely(!sock->ops->splice_read)) | 892 | if (unlikely(!sock->ops->splice_read)) |
897 | return -EINVAL; | 893 | return -EINVAL; |
898 | 894 | ||
899 | sock_update_classid(sock->sk); | ||
900 | |||
901 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 895 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
902 | } | 896 | } |
903 | 897 | ||
@@ -3437,8 +3431,6 @@ EXPORT_SYMBOL(kernel_setsockopt); | |||
3437 | int kernel_sendpage(struct socket *sock, struct page *page, int offset, | 3431 | int kernel_sendpage(struct socket *sock, struct page *page, int offset, |
3438 | size_t size, int flags) | 3432 | size_t size, int flags) |
3439 | { | 3433 | { |
3440 | sock_update_classid(sock->sk); | ||
3441 | |||
3442 | if (sock->ops->sendpage) | 3434 | if (sock->ops->sendpage) |
3443 | return sock->ops->sendpage(sock, page, offset, size, flags); | 3435 | return sock->ops->sendpage(sock, page, offset, size, flags); |
3444 | 3436 | ||
diff --git a/net/unix/diag.c b/net/unix/diag.c index 06748f108a57..5ac19dc1d5e4 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c | |||
@@ -151,6 +151,9 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r | |||
151 | sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) | 151 | sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) |
152 | goto out_nlmsg_trim; | 152 | goto out_nlmsg_trim; |
153 | 153 | ||
154 | if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) | ||
155 | goto out_nlmsg_trim; | ||
156 | |||
154 | return nlmsg_end(skb, nlh); | 157 | return nlmsg_end(skb, nlh); |
155 | 158 | ||
156 | out_nlmsg_trim: | 159 | out_nlmsg_trim: |